< prev index next >
src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/BytecodeFrame.java
Print this page
@@ -32,11 +32,11 @@
/**
* Represents the Java bytecode frame state(s) at a given position including {@link Value locations}
* where to find the local variables, operand stack values and locked objects of the bytecode
* frame(s).
*/
-public class BytecodeFrame extends BytecodePosition {
+public final class BytecodeFrame extends BytecodePosition {
/**
* An array of values representing how to reconstruct the state of the Java frame. This is array
* is partitioned as follows:
* <p>
@@ -63,18 +63,22 @@
* </tr>
* </table>
* <p>
* Note that the number of locals and the number of stack slots may be smaller than the maximum
* number of locals and stack slots as specified in the compiled method.
+ *
+ * This field is intentionally exposed as a mutable array that a compiler may modify (e.g.
+ * during register allocation).
*/
+ @SuppressFBWarnings(value = "EI_EXPOSE_REP2", justification = "field is intentionally mutable")//
public final JavaValue[] values;
/**
- * An array describing the Java kind of the {@link #values}. It records a kind for the locals
- * and the operand stack.
+ * An array describing the Java kinds in {@link #values}. It records a kind for the locals and
+ * the operand stack.
*/
- public final JavaKind[] slotKinds;
+ private final JavaKind[] slotKinds;
/**
* The number of locals in the values array.
*/
public final int numLocals;
@@ -97,12 +101,12 @@
* instruction at this position.
*/
public final boolean rethrowException;
/**
- * Specifies if this object represents a frame state in the middle of executing a call. If
- * true, the arguments to the call have been popped from the stack and the return value (for a
+ * Specifies if this object represents a frame state in the middle of executing a call. If true,
+ * the arguments to the call have been popped from the stack and the return value (for a
* non-void call) has not yet been pushed.
*/
public final boolean duringCall;
/**
@@ -176,15 +180,18 @@
* @param caller the caller frame (which may be {@code null})
* @param method the method
* @param bci a BCI within the method
* @param rethrowException specifies if the VM should re-throw the pending exception when
* deopt'ing using this frame
- * @param values the frame state {@link #values}
+ * @param values the frame state {@link #values}.
+ * @param slotKinds the kinds in {@code values}. This array is now owned by this object and must
+ * not be mutated by the caller.
* @param numLocals the number of local variables
* @param numStack the depth of the stack
* @param numLocks the number of locked objects
*/
+ @SuppressFBWarnings(value = "EI_EXPOSE_REP2", justification = "caller transfers ownership of `slotKinds`")
public BytecodeFrame(BytecodeFrame caller, ResolvedJavaMethod method, int bci, boolean rethrowException, boolean duringCall, JavaValue[] values, JavaKind[] slotKinds, int numLocals, int numStack,
int numLocks) {
super(caller, method, bci);
assert values != null;
this.rethrowException = rethrowException;
@@ -217,36 +224,76 @@
}
return true;
}
/**
+ * Gets the kind of a local variable.
+ *
+ * @param i the local variable to query
+ * @return the kind of local variable {@code i}
+ * @throw {@link IndexOutOfBoundsException} if {@code i < 0 || i >= this.numLocals}
+ */
+ public JavaKind getLocalValueKind(int i) {
+ if (i < 0 || i >= numLocals) {
+ throw new IndexOutOfBoundsException();
+ }
+ return slotKinds[i];
+ }
+
+ /**
+ * Gets the kind of a stack slot.
+ *
+ * @param i the local variable to query
+ * @return the kind of stack slot {@code i}
+ * @throw {@link IndexOutOfBoundsException} if {@code i < 0 || i >= this.numStack}
+ */
+ public JavaKind getStackValueKind(int i) {
+ if (i < 0 || i >= numStack) {
+ throw new IndexOutOfBoundsException();
+ }
+ return slotKinds[i + numLocals];
+ }
+
+ /**
* Gets the value representing the specified local variable.
*
* @param i the local variable index
* @return the value that can be used to reconstruct the local's current value
+ * @throw {@link IndexOutOfBoundsException} if {@code i < 0 || i >= this.numLocals}
*/
public JavaValue getLocalValue(int i) {
+ if (i < 0 || i >= numLocals) {
+ throw new IndexOutOfBoundsException();
+ }
return values[i];
}
/**
* Gets the value representing the specified stack slot.
*
* @param i the stack index
* @return the value that can be used to reconstruct the stack slot's current value
+ * @throw {@link IndexOutOfBoundsException} if {@code i < 0 || i >= this.numStack}
*/
public JavaValue getStackValue(int i) {
+ if (i < 0 || i >= numStack) {
+ throw new IndexOutOfBoundsException();
+ }
return values[i + numLocals];
}
/**
* Gets the value representing the specified lock.
*
* @param i the lock index
* @return the value that can be used to reconstruct the lock's current value
+ * @throw {@link IndexOutOfBoundsException} if {@code i < 0 || i >= this.numLocks}
*/
public JavaValue getLockValue(int i) {
+ if (i < 0 || i >= numLocks) {
+ throw new IndexOutOfBoundsException();
+ }
return values[i + numLocals + numStack];
}
/**
* Gets the caller of this frame.
@@ -256,10 +303,15 @@
public BytecodeFrame caller() {
return (BytecodeFrame) getCaller();
}
@Override
+ public int hashCode() {
+ return (numLocals + 1) ^ (numStack + 11) ^ (numLocks + 7);
+ }
+
+ @Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof BytecodeFrame && super.equals(obj)) {
< prev index next >