diff jvmci/jdk.vm.ci.code/src/jdk/vm/ci/code/CompilationResult.java @ 22740:22110ef74a40

8144083 [JVMCI] CompilationResult should be finalized by JVMCI compiler and made effectively final
author Doug Simon <doug.simon@oracle.com>
date Thu, 26 Nov 2015 00:47:01 +0100
parents f41ed1d87d68
children
line wrap: on
line diff
--- a/jvmci/jdk.vm.ci.code/src/jdk/vm/ci/code/CompilationResult.java	Wed Nov 25 20:41:26 2015 +0100
+++ b/jvmci/jdk.vm.ci.code/src/jdk/vm/ci/code/CompilationResult.java	Thu Nov 26 00:47:01 2015 +0100
@@ -498,6 +498,8 @@
         }
     }
 
+    private boolean closed;
+
     private int entryBCI = -1;
 
     private final DataSection dataSection = new DataSection();
@@ -598,6 +600,7 @@
      * @param entryBCI the entryBCI to set
      */
     public void setEntryBCI(int entryBCI) {
+        checkOpen();
         this.entryBCI = entryBCI;
     }
 
@@ -605,11 +608,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;
@@ -622,6 +628,7 @@
      * @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)) {
@@ -649,6 +656,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
@@ -658,6 +667,7 @@
     }
 
     public void setBytecodeSize(int bytecodeSize) {
+        checkOpen();
         this.bytecodeSize = bytecodeSize;
     }
 
@@ -687,6 +697,7 @@
      * @param size the size of the frame in bytes
      */
     public void setTotalFrameSize(int size) {
+        checkOpen();
         totalFrameSize = size;
     }
 
@@ -697,6 +708,7 @@
      * @param size the size of the machine code
      */
     public void setTargetCode(byte[] code, int size) {
+        checkOpen();
         targetCode = code;
         targetCodeSize = size;
     }
@@ -710,6 +722,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));
     }
@@ -724,6 +737,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);
     }
@@ -735,6 +749,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));
     }
@@ -785,6 +800,7 @@
      * @param infopoint the infopoint to record, usually a derived class from {@link Infopoint}
      */
     public void addInfopoint(Infopoint infopoint) {
+        checkOpen();
         infopoints.add(infopoint);
     }
 
@@ -795,6 +811,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;
@@ -814,6 +831,7 @@
      * @param offset
      */
     public void setCustomStackAreaOffset(int offset) {
+        checkOpen();
         customStackAreaOffset = offset;
     }
 
@@ -842,6 +860,7 @@
     }
 
     public void addAnnotation(CodeAnnotation annotation) {
+        checkOpen();
         assert annotation != null;
         if (annotations == null) {
             annotations = new ArrayList<>();
@@ -924,10 +943,46 @@
     }
 
     public void setHasUnsafeAccess(boolean hasUnsafeAccess) {
+        checkOpen();
         this.hasUnsafeAccess = hasUnsafeAccess;
     }
 
     public boolean hasUnsafeAccess() {
         return hasUnsafeAccess;
     }
+
+    /**
+     * 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;
+    }
 }