src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/CompilationResult.java

Print this page

        

@@ -550,10 +550,12 @@
      * Specifies whether this compilation is a {@code +ImmutableCode} {@code +GeneratePIC}
      * compilation.
      */
     private final boolean isImmutablePIC;
 
+    private boolean closed;
+
     private int entryBCI = -1;
 
     private final DataSection dataSection = new DataSection();
 
     private final List<Infopoint> infopoints = new ArrayList<>();

@@ -664,22 +666,26 @@
 
     /**
      * @param entryBCI the entryBCI to set
      */
     public void setEntryBCI(int entryBCI) {
+        checkOpen();
         this.entryBCI = entryBCI;
     }
 
     /**
      * 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;
     }
 

@@ -688,10 +694,11 @@
      *
      * @param rootMethod the root method of the compilation
      * @param inlinedMethods the methods inlined during compilation
      */
     public void setMethods(ResolvedJavaMethod rootMethod, Collection<ResolvedJavaMethod> inlinedMethods) {
+        checkOpen();
         assert rootMethod != null;
         assert inlinedMethods != null;
         if (inlinedMethods.contains(rootMethod)) {
             methods = inlinedMethods.toArray(new ResolvedJavaMethod[inlinedMethods.size()]);
             for (int i = 0; i < methods.length; i++) {

@@ -715,19 +722,22 @@
     }
 
     /**
      * 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
      */
     public ResolvedJavaMethod[] getMethods() {
         return methods;
     }
 
     public void setBytecodeSize(int bytecodeSize) {
+        checkOpen();
         this.bytecodeSize = bytecodeSize;
     }
 
     public int getBytecodeSize() {
         return bytecodeSize;

@@ -753,20 +763,22 @@
      * if any.
      *
      * @param size the size of the frame in bytes
      */
     public void setTotalFrameSize(int size) {
+        checkOpen();
         totalFrameSize = size;
     }
 
     /**
      * Sets the machine that has been generated by the compiler.
      *
      * @param code the machine code generated
      * @param size the size of the machine code
      */
     public void setTargetCode(byte[] code, int size) {
+        checkOpen();
         targetCode = code;
         targetCodeSize = size;
     }
 
     /**

@@ -776,10 +788,11 @@
      *
      * @param codePos The position in the code that needs to be patched.
      * @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));
     }
 
     /**

@@ -812,10 +825,11 @@
      * @param target the being called
      * @param debugInfo the debug info for the call
      * @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);
     }
 
     /**

@@ -823,10 +837,11 @@
      *
      * @param codePos the position in the code that is covered by the handler
      * @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));
     }
 
     /**

@@ -873,10 +888,11 @@
      * handled by the dedicated methods like {@link #recordCall}.
      *
      * @param infopoint the infopoint to record, usually a derived class from {@link Infopoint}
      */
     public void addInfopoint(Infopoint infopoint) {
+        checkOpen();
         // The infopoints list must always be sorted
         if (!infopoints.isEmpty()) {
             Infopoint previousInfopoint = infopoints.get(infopoints.size() - 1);
             if (previousInfopoint.pcOffset > infopoint.pcOffset) {
                 // This re-sorting should be very rare

@@ -903,10 +919,11 @@
      *
      * @param codePos the position in the code that is covered by the handler
      * @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;
     }
 

@@ -922,10 +939,11 @@
     /**
      * @see #getCustomStackAreaOffset()
      * @param offset
      */
     public void setCustomStackAreaOffset(int offset) {
+        checkOpen();
         customStackAreaOffset = offset;
     }
 
     /**
      * @return the machine code generated for this method

@@ -950,10 +968,11 @@
         }
         return annotations;
     }
 
     public void addAnnotation(CodeAnnotation annotation) {
+        checkOpen();
         assert annotation != null;
         if (annotations == null) {
             annotations = new ArrayList<>();
         }
         annotations.add(annotation);

@@ -1032,24 +1051,48 @@
     public String getName() {
         return name;
     }
 
     public void setHasUnsafeAccess(boolean hasUnsafeAccess) {
+        checkOpen();
         this.hasUnsafeAccess = hasUnsafeAccess;
     }
 
     public boolean hasUnsafeAccess() {
         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();
         marks.clear();
         dataSection.clear();
         if (annotations != null) {
             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;
+    }
 }