use of com.oracle.truffle.espresso.nodes.quick.BaseQuickNode in project graal by oracle.
the class BytecodeNode method quickenInvoke.
private int quickenInvoke(VirtualFrame frame, int top, int curBCI, int opcode, int statementIndex) {
QUICKENED_INVOKES.inc();
CompilerDirectives.transferToInterpreterAndInvalidate();
assert Bytecodes.isInvoke(opcode);
BaseQuickNode quick = tryPatchQuick(curBCI, () -> {
// During resolution of the symbolic reference to the method, any of the exceptions
// pertaining to method resolution (§5.4.3.3) can be thrown.
char cpi = readCPI(curBCI);
Method resolutionSeed = resolveMethod(opcode, cpi);
return dispatchQuickened(top, curBCI, cpi, opcode, statementIndex, resolutionSeed, getContext().InlineFieldAccessors);
});
// Perform the call outside of the lock.
return quick.execute(frame) - Bytecodes.stackEffectOf(opcode);
}
use of com.oracle.truffle.espresso.nodes.quick.BaseQuickNode in project graal by oracle.
the class BytecodeNode method quickenArrayLoad.
private int quickenArrayLoad(VirtualFrame frame, int top, int curBCI, int loadOpcode) {
CompilerDirectives.transferToInterpreterAndInvalidate();
assert IALOAD <= loadOpcode && loadOpcode <= SALOAD;
BaseQuickNode arrayLoadNode;
synchronized (this) {
if (bs.currentVolatileBC(curBCI) == SLIM_QUICK) {
arrayLoadNode = sparseNodes[curBCI];
} else {
// @formatter:off
switch(loadOpcode) {
case BALOAD:
arrayLoadNode = new ByteArrayLoadQuickNode(top, curBCI);
break;
case SALOAD:
arrayLoadNode = new ShortArrayLoadQuickNode(top, curBCI);
break;
case CALOAD:
arrayLoadNode = new CharArrayLoadQuickNode(top, curBCI);
break;
case IALOAD:
arrayLoadNode = new IntArrayLoadQuickNode(top, curBCI);
break;
case FALOAD:
arrayLoadNode = new FloatArrayLoadQuickNode(top, curBCI);
break;
case LALOAD:
arrayLoadNode = new LongArrayLoadQuickNode(top, curBCI);
break;
case DALOAD:
arrayLoadNode = new DoubleArrayLoadQuickNode(top, curBCI);
break;
case AALOAD:
arrayLoadNode = new ReferenceArrayLoadQuickNode(top, curBCI);
break;
default:
CompilerDirectives.transferToInterpreter();
throw EspressoError.shouldNotReachHere("unexpected kind");
}
// @formatter:on
arrayLoadNode = injectQuick(curBCI, arrayLoadNode, SLIM_QUICK);
}
}
return arrayLoadNode.execute(frame) - Bytecodes.stackEffectOf(loadOpcode);
}
use of com.oracle.truffle.espresso.nodes.quick.BaseQuickNode in project graal by oracle.
the class BytecodeNode method quickenArrayStore.
private int quickenArrayStore(final VirtualFrame frame, int top, int curBCI, int storeOpcode) {
CompilerDirectives.transferToInterpreterAndInvalidate();
assert IASTORE <= storeOpcode && storeOpcode <= SASTORE;
BaseQuickNode arrayStoreNode;
synchronized (this) {
if (bs.currentVolatileBC(curBCI) == SLIM_QUICK) {
arrayStoreNode = sparseNodes[curBCI];
} else {
// @formatter:off
switch(storeOpcode) {
case BASTORE:
arrayStoreNode = new ByteArrayStoreQuickNode(top, curBCI);
break;
case SASTORE:
arrayStoreNode = new ShortArrayStoreQuickNode(top, curBCI);
break;
case CASTORE:
arrayStoreNode = new CharArrayStoreQuickNode(top, curBCI);
break;
case IASTORE:
arrayStoreNode = new IntArrayStoreQuickNode(top, curBCI);
break;
case FASTORE:
arrayStoreNode = new FloatArrayStoreQuickNode(top, curBCI);
break;
case LASTORE:
arrayStoreNode = new LongArrayStoreQuickNode(top, curBCI);
break;
case DASTORE:
arrayStoreNode = new DoubleArrayStoreQuickNode(top, curBCI);
break;
case AASTORE:
arrayStoreNode = new ReferenceArrayStoreQuickNode(top, curBCI);
break;
default:
CompilerDirectives.transferToInterpreter();
throw EspressoError.shouldNotReachHere("unexpected kind");
}
// @formatter:on
arrayStoreNode = injectQuick(curBCI, arrayStoreNode, SLIM_QUICK);
}
}
return arrayStoreNode.execute(frame) - Bytecodes.stackEffectOf(storeOpcode);
}
use of com.oracle.truffle.espresso.nodes.quick.BaseQuickNode in project graal by oracle.
the class BytecodeNode method quickenGetField.
// region quickenForeign
public int quickenGetField(final VirtualFrame frame, int top, int curBCI, int opcode, int statementIndex, Field field) {
CompilerDirectives.transferToInterpreterAndInvalidate();
assert opcode == GETFIELD;
BaseQuickNode getField = tryPatchQuick(curBCI, () -> new QuickenedGetFieldNode(top, curBCI, statementIndex, field));
return getField.execute(frame) - Bytecodes.stackEffectOf(opcode);
}
use of com.oracle.truffle.espresso.nodes.quick.BaseQuickNode in project graal by oracle.
the class BytecodeNode method dispatchQuickened.
// endregion quickenForeign
private BaseQuickNode dispatchQuickened(int top, int curBCI, char cpi, int opcode, int statementIndex, Method resolutionSeed, boolean allowFieldAccessInlining) {
assert !allowFieldAccessInlining || getContext().InlineFieldAccessors;
BaseQuickNode invoke;
Method resolved = resolutionSeed;
switch(opcode) {
case INVOKESTATIC:
// instruction throws an IncompatibleClassChangeError.
if (!resolved.isStatic()) {
CompilerDirectives.transferToInterpreter();
Meta meta = getMeta();
throw meta.throwException(meta.java_lang_IncompatibleClassChangeError);
}
break;
case INVOKEINTERFACE:
// invokeinterface instruction throws an IncompatibleClassChangeError.
if (resolved.isStatic() || (getContext().getJavaVersion().java8OrEarlier() && resolved.isPrivate())) {
CompilerDirectives.transferToInterpreter();
Meta meta = getMeta();
throw meta.throwException(meta.java_lang_IncompatibleClassChangeError);
}
break;
case INVOKEVIRTUAL:
// instruction throws an IncompatibleClassChangeError.
if (resolved.isStatic()) {
CompilerDirectives.transferToInterpreter();
Meta meta = getMeta();
throw meta.throwException(meta.java_lang_IncompatibleClassChangeError);
}
break;
case INVOKESPECIAL:
// instruction, a NoSuchMethodError is thrown.
if (resolved.isConstructor()) {
if (resolved.getDeclaringKlass().getName() != getConstantPool().methodAt(cpi).getHolderKlassName(getConstantPool())) {
CompilerDirectives.transferToInterpreter();
Meta meta = getMeta();
throw meta.throwExceptionWithMessage(meta.java_lang_NoSuchMethodError, meta.toGuestString(resolved.getDeclaringKlass().getNameAsString() + "." + resolved.getName() + resolved.getRawSignature()));
}
}
// instruction throws an IncompatibleClassChangeError.
if (resolved.isStatic()) {
CompilerDirectives.transferToInterpreter();
Meta meta = getMeta();
throw meta.throwException(meta.java_lang_IncompatibleClassChangeError);
}
// version of the class file.
if (!resolved.isConstructor()) {
Klass declaringKlass = getMethod().getDeclaringKlass();
Klass symbolicRef = ((MethodRefConstant.Indexes) getConstantPool().methodAt(cpi)).getResolvedHolderKlass(declaringKlass, getConstantPool());
if (!symbolicRef.isInterface() && symbolicRef != declaringKlass && declaringKlass.getSuperKlass() != null && symbolicRef != declaringKlass.getSuperKlass() && symbolicRef.isAssignableFrom(declaringKlass)) {
resolved = declaringKlass.getSuperKlass().lookupMethod(resolved.getName(), resolved.getRawSignature(), declaringKlass);
}
}
break;
default:
CompilerDirectives.transferToInterpreter();
throw EspressoError.unimplemented("Quickening for " + Bytecodes.nameOf(opcode));
}
if (allowFieldAccessInlining && resolved.isInlinableGetter()) {
invoke = InlinedGetterNode.create(resolved, top, opcode, curBCI, statementIndex);
} else if (allowFieldAccessInlining && resolved.isInlinableSetter()) {
invoke = InlinedSetterNode.create(resolved, top, opcode, curBCI, statementIndex);
} else if (resolved.isPolySignatureIntrinsic()) {
invoke = new InvokeHandleNode(resolved, getDeclaringKlass(), top, curBCI);
} else if (opcode == INVOKEINTERFACE && resolved.getITableIndex() < 0) {
if (resolved.isPrivate()) {
assert getJavaVersion().java9OrLater();
// Interface private methods do not appear in itables.
invoke = new InvokeSpecialQuickNode(resolved, top, curBCI);
} else {
// Can happen in old classfiles that calls j.l.Object on interfaces.
invoke = new InvokeVirtualQuickNode(resolved, top, curBCI);
}
} else if (opcode == INVOKEVIRTUAL && (resolved.isFinalFlagSet() || resolved.getDeclaringKlass().isFinalFlagSet() || resolved.isPrivate())) {
invoke = new InvokeSpecialQuickNode(resolved, top, curBCI);
} else {
// @formatter:off
switch(opcode) {
case INVOKESTATIC:
invoke = new InvokeStaticQuickNode(resolved, top, curBCI);
break;
case INVOKEINTERFACE:
invoke = new InvokeInterfaceQuickNode(resolved, top, curBCI);
break;
case INVOKEVIRTUAL:
invoke = new InvokeVirtualQuickNode(resolved, top, curBCI);
break;
case INVOKESPECIAL:
invoke = new InvokeSpecialQuickNode(resolved, top, curBCI);
break;
default:
CompilerDirectives.transferToInterpreter();
throw EspressoError.unimplemented("Quickening for " + Bytecodes.nameOf(opcode));
}
// @formatter:on
}
return invoke;
}
Aggregations