# HG changeset patch # User twisti # Date 1449018675 36000 # Node ID 838d37db4223eaba4a014ab2894f742027281667 # Parent 636a88905e3b22edf5cb964b3ee065523df3cbf6 8144083: [JVMCI] CompilationResult should be finalized by JVMCI compiler and made effectively final Reviewed-by: iveresov, twisti diff -r 636a88905e3b -r 838d37db4223 hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/CompilationResult.java --- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/CompilationResult.java Wed Nov 25 18:13:13 2015 +0000 +++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/CompilationResult.java Tue Dec 01 15:11:15 2015 -1000 @@ -552,6 +552,8 @@ */ private final boolean isImmutablePIC; + private boolean closed; + private int entryBCI = -1; private final DataSection dataSection = new DataSection(); @@ -666,6 +668,7 @@ * @param entryBCI the entryBCI to set */ public void setEntryBCI(int entryBCI) { + checkOpen(); this.entryBCI = entryBCI; } @@ -673,11 +676,14 @@ * Sets the assumptions made during compilation. */ public void setAssumptions(Assumption[] assumptions) { + checkOpen(); this.assumptions = assumptions; } /** * Gets the assumptions made during compilation. + * + * The caller must not modify the contents of the returned array. */ public Assumption[] getAssumptions() { return assumptions; @@ -690,6 +696,7 @@ * @param inlinedMethods the methods inlined during compilation */ public void setMethods(ResolvedJavaMethod rootMethod, Collection inlinedMethods) { + checkOpen(); assert rootMethod != null; assert inlinedMethods != null; if (inlinedMethods.contains(rootMethod)) { @@ -717,6 +724,8 @@ /** * Gets the methods whose bytecodes were used as input to the compilation. * + * The caller must not modify the contents of the returned array. + * * @return {@code null} if the compilation did not record method dependencies otherwise the * methods whose bytecodes were used as input to the compilation with the first element * being the root method of the compilation @@ -726,6 +735,7 @@ } public void setBytecodeSize(int bytecodeSize) { + checkOpen(); this.bytecodeSize = bytecodeSize; } @@ -755,6 +765,7 @@ * @param size the size of the frame in bytes */ public void setTotalFrameSize(int size) { + checkOpen(); totalFrameSize = size; } @@ -765,6 +776,7 @@ * @param size the size of the machine code */ public void setTargetCode(byte[] code, int size) { + checkOpen(); targetCode = code; targetCodeSize = size; } @@ -778,6 +790,7 @@ * @param ref The reference that should be inserted in the code. */ public void recordDataPatch(int codePos, Reference ref) { + checkOpen(); assert codePos >= 0 && ref != null; dataPatches.add(new DataPatch(codePos, ref)); } @@ -814,6 +827,7 @@ * @param direct specifies if this is a {@linkplain Call#direct direct} call */ public void recordCall(int codePos, int size, InvokeTarget target, DebugInfo debugInfo, boolean direct) { + checkOpen(); final Call call = new Call(target, codePos, size, direct, debugInfo); addInfopoint(call); } @@ -825,6 +839,7 @@ * @param handlerPos the position of the handler */ public void recordExceptionHandler(int codePos, int handlerPos) { + checkOpen(); assert validateExceptionHandlerAdd(codePos, handlerPos) : String.format("Duplicate exception handler for pc 0x%x handlerPos 0x%x", codePos, handlerPos); exceptionHandlers.add(new ExceptionHandler(codePos, handlerPos)); } @@ -875,6 +890,7 @@ * @param infopoint the infopoint to record, usually a derived class from {@link Infopoint} */ public void addInfopoint(Infopoint infopoint) { + checkOpen(); infopoints.add(infopoint); } @@ -885,6 +901,7 @@ * @param markId the identifier for this mark */ public Mark recordMark(int codePos, Object markId) { + checkOpen(); Mark mark = new Mark(codePos, markId); marks.add(mark); return mark; @@ -904,6 +921,7 @@ * @param offset */ public void setCustomStackAreaOffset(int offset) { + checkOpen(); customStackAreaOffset = offset; } @@ -932,6 +950,7 @@ } public void addAnnotation(CodeAnnotation annotation) { + checkOpen(); assert annotation != null; if (annotations == null) { annotations = new ArrayList<>(); @@ -1014,6 +1033,7 @@ } public void setHasUnsafeAccess(boolean hasUnsafeAccess) { + checkOpen(); this.hasUnsafeAccess = hasUnsafeAccess; } @@ -1021,8 +1041,14 @@ return hasUnsafeAccess; } - public void reset() { - hasUnsafeAccess = false; + /** + * Clears the information in this object pertaining to generating code. That is, the + * {@linkplain #getMarks() marks}, {@linkplain #getInfopoints() infopoints}, + * {@linkplain #getExceptionHandlers() exception handlers}, {@linkplain #getDataPatches() data + * patches} and {@linkplain #getAnnotations() annotations} recorded in this object are cleared. + */ + public void resetForEmittingCode() { + checkOpen(); infopoints.clear(); dataPatches.clear(); exceptionHandlers.clear(); @@ -1032,4 +1058,21 @@ annotations.clear(); } } + + private void checkOpen() { + if (closed) { + throw new IllegalStateException(); + } + } + + /** + * Closes this compilation result to future updates. + */ + public void close() { + if (closed) { + throw new IllegalStateException("Cannot re-close compilation result " + this); + } + dataSection.close(); + closed = true; + } } diff -r 636a88905e3b -r 838d37db4223 hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/DataSection.java --- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/DataSection.java Wed Nov 25 18:13:13 2015 +0000 +++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/DataSection.java Tue Dec 01 15:11:15 2015 -1000 @@ -141,7 +141,7 @@ private final ArrayList dataItems = new ArrayList<>(); - private boolean finalLayout; + private boolean closed; private int sectionAlignment; private int sectionSize; @@ -163,7 +163,7 @@ } if (obj instanceof DataSection) { DataSection that = (DataSection) obj; - if (this.finalLayout == that.finalLayout && this.sectionAlignment == that.sectionAlignment && this.sectionSize == that.sectionSize && Objects.equals(this.dataItems, that.dataItems)) { + if (this.closed == that.closed && this.sectionAlignment == that.sectionAlignment && this.sectionSize == that.sectionSize && Objects.equals(this.dataItems, that.dataItems)) { return true; } } @@ -171,14 +171,14 @@ } /** - * Insert a {@link Data} item into the data section. If the item is already in the data section, - * the same {@link DataSectionReference} is returned. + * Inserts a {@link Data} item into the data section. If the item is already in the data + * section, the same {@link DataSectionReference} is returned. * * @param data the {@link Data} item to be inserted * @return a unique {@link DataSectionReference} identifying the {@link Data} item */ public DataSectionReference insertData(Data data) { - assert !finalLayout; + checkOpen(); synchronized (data) { if (data.ref == null) { data.ref = new DataSectionReference(); @@ -193,7 +193,8 @@ * {@link DataSection}, and empties the other section. */ public void addAll(DataSection other) { - assert !finalLayout && !other.finalLayout; + checkOpen(); + other.checkOpen(); for (Data data : other.dataItems) { assert data.ref != null; @@ -203,12 +204,20 @@ } /** - * Compute the layout of the data section. This can be called only once, and after it has been - * called, the data section can no longer be modified. + * Determines if this object has been {@link #close() closed}. */ - public void finalizeLayout() { - assert !finalLayout; - finalLayout = true; + public boolean closed() { + return closed; + } + + /** + * Computes the layout of the data section and closes this object to further updates. + * + * This must be called exactly once. + */ + void close() { + checkOpen(); + closed = true; // simple heuristic: put items with larger alignment requirement first dataItems.sort((a, b) -> a.alignment - b.alignment); @@ -227,37 +236,38 @@ sectionSize = position; } - public boolean isFinalized() { - return finalLayout; - } - /** - * Get the size of the data section. Can only be called after {@link #finalizeLayout}. + * Gets the size of the data section. + * + * This must only be called once this object has been {@linkplain #closed() closed}. */ public int getSectionSize() { - assert finalLayout; + checkClosed(); return sectionSize; } /** - * Get the minimum alignment requirement of the data section. Can only be called after - * {@link #finalizeLayout}. + * Gets the minimum alignment requirement of the data section. + * + * This must only be called once this object has been {@linkplain #closed() closed}. */ public int getSectionAlignment() { - assert finalLayout; + checkClosed(); return sectionAlignment; } /** - * Build the data section. Can only be called after {@link #finalizeLayout}. + * Builds the data section into a given buffer. + * + * This must only be called once this object has been {@linkplain #closed() closed}. * - * @param buffer The {@link ByteBuffer} where the data section should be built. The buffer must + * @param buffer the {@link ByteBuffer} where the data section should be built. The buffer must * hold at least {@link #getSectionSize()} bytes. - * @param patch A {@link Consumer} to receive {@link DataPatch data patches} for relocations in - * the data section. + * @param patch a {@link Consumer} to receive {@link DataPatch data patches} for relocations in + * the data section */ public void buildDataSection(ByteBuffer buffer, Consumer patch) { - assert finalLayout; + checkClosed(); for (Data d : dataItems) { buffer.position(d.ref.getOffset()); d.builder.emit(buffer, patch); @@ -300,8 +310,20 @@ return ((position + alignment - 1) / alignment) * alignment; } + private void checkClosed() { + if (!closed) { + throw new IllegalStateException(); + } + } + + private void checkOpen() { + if (closed) { + throw new IllegalStateException(); + } + } + public void clear() { - assert !finalLayout; + checkOpen(); this.dataItems.clear(); this.sectionAlignment = 0; this.sectionSize = 0; diff -r 636a88905e3b -r 838d37db4223 hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCompiledCode.java --- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCompiledCode.java Wed Nov 25 18:13:13 2015 +0000 +++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCompiledCode.java Tue Dec 01 15:11:15 2015 -1000 @@ -123,7 +123,6 @@ targetCodeSize = compResult.getTargetCodeSize(); DataSection data = compResult.getDataSection(); - data.finalizeLayout(); dataSection = new byte[data.getSectionSize()]; ByteBuffer buffer = ByteBuffer.wrap(dataSection).order(ByteOrder.nativeOrder());