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;
+ }
}