use of com.oracle.truffle.espresso.runtime.StaticObject in project graal by oracle.
the class BytecodeNode method getField.
/**
* Returns the stack effect (slot delta) that cannot be inferred solely from the bytecode. e.g.
* PUTFIELD always pops the receiver, but the result size (1 or 2) is unknown.
*
* <pre>
* top += getField(frame, top, resolveField(...)); break; // stack effect that depends on the field
* top += Bytecodes.stackEffectOf(curOpcode); // stack effect that depends solely on GETFIELD.
* // at this point `top` must have the correct value.
* curBCI = bs.next(curBCI);
* </pre>
*/
private int getField(VirtualFrame frame, int top, Field field, int curBCI, int opcode, int statementIndex) {
assert opcode == GETFIELD || opcode == GETSTATIC;
CompilerAsserts.partialEvaluationConstant(field);
/*
* GETFIELD: Otherwise, if the resolved field is a static field, getfield throws an
* IncompatibleClassChangeError.
*
* GETSTATIC: Otherwise, if the resolved field is not a static (class) field or an interface
* field, getstatic throws an IncompatibleClassChangeError.
*/
if (field.isStatic() != (opcode == GETSTATIC)) {
CompilerDirectives.transferToInterpreter();
Meta meta = getMeta();
throw meta.throwExceptionWithMessage(meta.java_lang_IncompatibleClassChangeError, String.format("Expected %s field %s.%s", (opcode == GETSTATIC) ? "static" : "non-static", field.getDeclaringKlass().getNameAsString(), field.getNameAsString()));
}
assert field.isStatic() == (opcode == GETSTATIC);
int slot = top - 1;
StaticObject receiver = field.isStatic() ? field.getDeclaringKlass().tryInitializeAndGetStatics() : // Do not release the object, it might be read again in GetFieldNode
nullCheck(peekObject(frame, slot));
if (!noForeignObjects.isValid() && opcode == GETFIELD) {
if (receiver.isForeignObject()) {
// Restore the receiver for quickening.
putObject(frame, slot, receiver);
return quickenGetField(frame, top, curBCI, opcode, statementIndex, field);
}
}
if (instrumentation != null) {
instrumentation.notifyFieldAccess(frame, statementIndex, field, receiver);
}
int resultAt = field.isStatic() ? top : (top - 1);
// @formatter:off
switch(field.getKind()) {
case Boolean:
putInt(frame, resultAt, InterpreterToVM.getFieldBoolean(receiver, field) ? 1 : 0);
break;
case Byte:
putInt(frame, resultAt, InterpreterToVM.getFieldByte(receiver, field));
break;
case Char:
putInt(frame, resultAt, InterpreterToVM.getFieldChar(receiver, field));
break;
case Short:
putInt(frame, resultAt, InterpreterToVM.getFieldShort(receiver, field));
break;
case Int:
putInt(frame, resultAt, InterpreterToVM.getFieldInt(receiver, field));
break;
case Double:
putDouble(frame, resultAt, InterpreterToVM.getFieldDouble(receiver, field));
break;
case Float:
putFloat(frame, resultAt, InterpreterToVM.getFieldFloat(receiver, field));
break;
case Long:
putLong(frame, resultAt, InterpreterToVM.getFieldLong(receiver, field));
break;
case Object:
{
StaticObject value = InterpreterToVM.getFieldObject(receiver, field);
putObject(frame, resultAt, value);
checkNoForeignObjectAssumption(value);
break;
}
default:
CompilerDirectives.transferToInterpreter();
throw EspressoError.shouldNotReachHere("unexpected kind");
}
// @formatter:on
return field.getKind().getSlotCount();
}
use of com.oracle.truffle.espresso.runtime.StaticObject in project graal by oracle.
the class BytecodeNode method peekReceiver.
// internal
public static StaticObject peekReceiver(VirtualFrame frame, int top, Method m) {
assert !m.isStatic();
int skipSlots = Signatures.slotsForParameters(m.getParsedSignature());
StaticObject result = peekObject(frame, top - skipSlots - 1);
assert result != null;
return result;
}
use of com.oracle.truffle.espresso.runtime.StaticObject in project graal by oracle.
the class BytecodeNode method initArguments.
@ExplodeLoop
private void initArguments(VirtualFrame frame) {
Object[] arguments = frame.getArguments();
boolean hasReceiver = !getMethod().isStatic();
int receiverSlot = hasReceiver ? 1 : 0;
int curSlot = 0;
if (hasReceiver) {
assert StaticObject.notNull((StaticObject) arguments[0]) : "null receiver in init arguments !";
StaticObject receiver = (StaticObject) arguments[0];
setLocalObject(frame, curSlot, receiver);
checkNoForeignObjectAssumption(receiver);
curSlot += JavaKind.Object.getSlotCount();
}
Symbol<Type>[] methodSignature = getMethod().getParsedSignature();
int argCount = Signatures.parameterCount(methodSignature, false);
CompilerAsserts.partialEvaluationConstant(argCount);
for (int i = 0; i < argCount; ++i) {
Symbol<Type> argType = Signatures.parameterType(methodSignature, i);
if (argType.length() == 1) {
// @formatter:off
switch(argType.byteAt(0)) {
case 'Z':
setLocalInt(frame, curSlot, ((boolean) arguments[i + receiverSlot]) ? 1 : 0);
break;
case 'B':
setLocalInt(frame, curSlot, ((byte) arguments[i + receiverSlot]));
break;
case 'S':
setLocalInt(frame, curSlot, ((short) arguments[i + receiverSlot]));
break;
case 'C':
setLocalInt(frame, curSlot, ((char) arguments[i + receiverSlot]));
break;
case 'I':
setLocalInt(frame, curSlot, (int) arguments[i + receiverSlot]);
break;
case 'F':
setLocalFloat(frame, curSlot, (float) arguments[i + receiverSlot]);
break;
case 'J':
setLocalLong(frame, curSlot, (long) arguments[i + receiverSlot]);
++curSlot;
break;
case 'D':
setLocalDouble(frame, curSlot, (double) arguments[i + receiverSlot]);
++curSlot;
break;
default:
CompilerDirectives.transferToInterpreter();
throw EspressoError.shouldNotReachHere("unexpected kind");
}
// @formatter:on
} else {
// Reference type.
StaticObject argument = (StaticObject) arguments[i + receiverSlot];
setLocalObject(frame, curSlot, argument);
checkNoForeignObjectAssumption(argument);
}
++curSlot;
}
}
use of com.oracle.truffle.espresso.runtime.StaticObject in project graal by oracle.
the class BytecodeNode method arrayLength.
private void arrayLength(VirtualFrame frame, int top, int curBCI) {
StaticObject array = nullCheck(popObject(frame, top - 1));
if (noForeignObjects.isValid() || array.isEspressoObject()) {
putInt(frame, top - 1, InterpreterToVM.arrayLength(array));
} else {
CompilerDirectives.transferToInterpreterAndInvalidate();
// The array was released, it must be restored for the quickening.
putObject(frame, top - 1, array);
// The stack effect difference vs. original bytecode is always 0.
quickenArrayLength(frame, top, curBCI);
}
}
use of com.oracle.truffle.espresso.runtime.StaticObject in project graal by oracle.
the class BytecodeNode method arrayLoad.
private void arrayLoad(VirtualFrame frame, int top, int curBCI, int loadOpcode) {
assert IALOAD <= loadOpcode && loadOpcode <= SALOAD;
CompilerAsserts.partialEvaluationConstant(loadOpcode);
int index = popInt(frame, top - 1);
StaticObject array = nullCheck(popObject(frame, top - 2));
if (noForeignObjects.isValid() || array.isEspressoObject()) {
// @formatter:off
switch(loadOpcode) {
case BALOAD:
putInt(frame, top - 2, getInterpreterToVM().getArrayByte(index, array, this));
break;
case SALOAD:
putInt(frame, top - 2, getInterpreterToVM().getArrayShort(index, array, this));
break;
case CALOAD:
putInt(frame, top - 2, getInterpreterToVM().getArrayChar(index, array, this));
break;
case IALOAD:
putInt(frame, top - 2, getInterpreterToVM().getArrayInt(index, array, this));
break;
case FALOAD:
putFloat(frame, top - 2, getInterpreterToVM().getArrayFloat(index, array, this));
break;
case LALOAD:
putLong(frame, top - 2, getInterpreterToVM().getArrayLong(index, array, this));
break;
case DALOAD:
putDouble(frame, top - 2, getInterpreterToVM().getArrayDouble(index, array, this));
break;
case AALOAD:
putObject(frame, top - 2, getInterpreterToVM().getArrayObject(index, array, this));
break;
default:
CompilerDirectives.transferToInterpreter();
throw EspressoError.shouldNotReachHere();
}
// @formatter:on
} else {
CompilerDirectives.transferToInterpreterAndInvalidate();
// The array was released, it must be restored for the quickening.
putInt(frame, top - 1, index);
putObject(frame, top - 2, array);
// The stack effect difference vs. original bytecode is always 0.
quickenArrayLoad(frame, top, curBCI, loadOpcode);
}
}
Aggregations