use of org.jikesrvm.classloader.RVMMethod in project JikesRVM by JikesRVM.
the class DynamicLinker method unimplementedNativeMethod.
/**
* Report unimplemented native method error.
* <pre>
* Taken: nothing (calling context is implicit)
* Returned: does not return (throws UnsatisfiedLinkError)
* </pre>
*/
@Entrypoint
static void unimplementedNativeMethod() {
DynamicLink dl = DL_Helper.resolveDynamicInvocation();
RVMMethod targMethod = DL_Helper.resolveMethodRef(dl);
throw new UnsatisfiedLinkError(targMethod.toString());
}
use of org.jikesrvm.classloader.RVMMethod in project JikesRVM by JikesRVM.
the class DynamicLinker method sysCallMethod.
/**
* Report a magic SysCall has been mistakenly invoked
*/
@Entrypoint
static void sysCallMethod() {
DynamicLink dl = DL_Helper.resolveDynamicInvocation();
RVMMethod targMethod = DL_Helper.resolveMethodRef(dl);
throw new UnsatisfiedLinkError(targMethod.toString() + " which is a SysCall");
}
use of org.jikesrvm.classloader.RVMMethod in project JikesRVM by JikesRVM.
the class EntrypointHelper method getMethod.
public static RVMMethod getMethod(Class<?> klass, Atom member, Class<?>... argTypes) {
if (!VM.runningVM) {
// avoid compiling this code into the boot image
try {
TypeReference tRef = TypeReference.findOrCreate(klass);
RVMClass cls = tRef.resolve().asClass();
cls.resolve();
Atom descriptor = Atom.findOrCreateAsciiAtom(makeDescriptor(argTypes));
RVMMethod method = cls.findDeclaredMethod(member, descriptor);
if (method != null) {
verifyPresenceOfEntrypointAnnotation(method);
return method;
}
} catch (Throwable t) {
throw new Error("Entrypoints.getMethod: can't resolve class=" + klass + " member=" + member + " desc=" + makeDescriptor(argTypes), t);
}
}
throw new Error("Entrypoints.getMethod: can't resolve class=" + klass + " member=" + member + " desc=" + makeDescriptor(argTypes));
}
use of org.jikesrvm.classloader.RVMMethod in project JikesRVM by JikesRVM.
the class InvokeStatic method stackChanges.
@Override
public int stackChanges() {
RVMMethod callee = targetMethod(tid);
int psize = callee.getParameterWords();
int schanges = -psize;
TypeReference rtype = callee.getReturnType();
byte tcode = rtype.getName().parseForTypeCode();
if (tcode == VoidTypeCode) {
// do nothing
} else {
if ((tcode == LongTypeCode) || (tcode == DoubleTypeCode)) {
schanges++;
}
schanges++;
}
return schanges;
}
use of org.jikesrvm.classloader.RVMMethod in project JikesRVM by JikesRVM.
the class BaselineCompilerImpl method emit_invokeinterface.
@Override
protected void emit_invokeinterface(MethodReference methodRef) {
// +1 for "this" parameter
final int count = methodRef.getParameterWords() + 1;
RVMMethod resolvedMethod = null;
resolvedMethod = methodRef.peekInterfaceMethod();
// (1) Emit dynamic type checking sequence if required to do so inline.
if (VM.BuildForIMTInterfaceInvocation) {
if (methodRef.isMiranda()) {
// TODO: It's not entirely clear that we can just assume that
// the class actually implements the interface.
// However, we don't know what interface we need to be checking
// so there doesn't appear to be much else we can do here.
} else {
if (resolvedMethod == null) {
// Can't successfully resolve it at compile time.
// Call uncommon case typechecking routine to do the right thing when this code actually executes.
// T1 = "this" object
stackMoveHelper(T1, Offset.fromIntZeroExtend((count - 1) << LG_WORDSIZE));
// push dict id of target
asm.emitPUSH_Imm(methodRef.getId());
// push "this"
asm.emitPUSH_Reg(T1);
// pass 2 parameter word
genParameterRegisterLoad(asm, 2);
// check that "this" class implements the interface
asm.generateJTOCcall(Entrypoints.unresolvedInvokeinterfaceImplementsTestMethod.getOffset());
} else {
RVMClass interfaceClass = resolvedMethod.getDeclaringClass();
int interfaceIndex = interfaceClass.getDoesImplementIndex();
int interfaceMask = interfaceClass.getDoesImplementBitMask();
// T1 = "this" object
stackMoveHelper(T1, Offset.fromIntZeroExtend((count - 1) << LG_WORDSIZE));
// S0 = tib of "this" object
asm.baselineEmitLoadTIB(S0, T1);
if (VM.BuildFor32Addr) {
// implements bit vector
asm.emitMOV_Reg_RegDisp(S0, S0, Offset.fromIntZeroExtend(TIB_DOES_IMPLEMENT_INDEX << LG_WORDSIZE));
} else {
// implements bit vector
asm.emitMOV_Reg_RegDisp_Quad(S0, S0, Offset.fromIntZeroExtend(TIB_DOES_IMPLEMENT_INDEX << LG_WORDSIZE));
}
if (DynamicTypeCheck.MIN_DOES_IMPLEMENT_SIZE <= interfaceIndex) {
// must do arraybounds check of implements bit vector
if (ARRAY_LENGTH_BYTES == 4) {
asm.emitCMP_RegDisp_Imm(S0, ObjectModel.getArrayLengthOffset(), interfaceIndex);
} else {
asm.emitCMP_RegDisp_Imm_Quad(S0, ObjectModel.getArrayLengthOffset(), interfaceIndex);
}
asm.emitBranchLikelyNextInstruction();
ForwardReference fr = asm.forwardJcc(LGT);
asm.emitINT_Imm(RuntimeEntrypoints.TRAP_MUST_IMPLEMENT + RVM_TRAP_BASE);
fr.resolve(asm);
}
// Test the appropriate bit and if set, branch around another trap imm
if (interfaceIndex == 0) {
asm.emitTEST_RegInd_Imm(S0, interfaceMask);
} else {
asm.emitTEST_RegDisp_Imm(S0, Offset.fromIntZeroExtend(interfaceIndex << LOG_BYTES_IN_INT), interfaceMask);
}
asm.emitBranchLikelyNextInstruction();
ForwardReference fr = asm.forwardJcc(NE);
asm.emitINT_Imm(RuntimeEntrypoints.TRAP_MUST_IMPLEMENT + RVM_TRAP_BASE);
fr.resolve(asm);
}
}
}
// (2) Emit interface invocation sequence.
if (VM.BuildForIMTInterfaceInvocation) {
InterfaceMethodSignature sig = InterfaceMethodSignature.findOrCreate(methodRef);
// squirrel away signature ID
Offset offset = ArchEntrypoints.hiddenSignatureIdField.getOffset();
asm.emitMOV_RegDisp_Imm(THREAD_REGISTER, offset, sig.getId());
// T1 = "this" object
stackMoveHelper(T1, Offset.fromIntZeroExtend((count - 1) << LG_WORDSIZE));
asm.baselineEmitLoadTIB(S0, T1);
// Load the IMT Base into S0
if (VM.BuildFor32Addr) {
asm.emitMOV_Reg_RegDisp(S0, S0, Offset.fromIntZeroExtend(TIB_INTERFACE_DISPATCH_TABLE_INDEX << LG_WORDSIZE));
} else {
asm.emitMOV_Reg_RegDisp_Quad(S0, S0, Offset.fromIntZeroExtend(TIB_INTERFACE_DISPATCH_TABLE_INDEX << LG_WORDSIZE));
}
genParameterRegisterLoad(methodRef, true);
// the interface call
asm.emitCALL_RegDisp(S0, sig.getIMTOffset());
} else {
int itableIndex = -1;
if (VM.BuildForITableInterfaceInvocation && resolvedMethod != null) {
// get the index of the method in the Itable
itableIndex = InterfaceInvocation.getITableIndex(resolvedMethod.getDeclaringClass(), methodRef.getName(), methodRef.getDescriptor());
}
if (itableIndex == -1) {
// itable index is not known at compile-time.
// call "invokeInterface" to resolve object + method id into
// method address
int methodRefId = methodRef.getId();
// "this" parameter is obj
if (count == 1) {
asm.emitPUSH_RegInd(SP);
} else {
asm.emitPUSH_RegDisp(SP, Offset.fromIntZeroExtend((count - 1) << LG_WORDSIZE));
}
// id of method to call
asm.emitPUSH_Imm(methodRefId);
// pass 2 parameter words
genParameterRegisterLoad(asm, 2);
// invokeinterface(obj, id) returns address to call
asm.generateJTOCcall(Entrypoints.invokeInterfaceMethod.getOffset());
if (VM.BuildFor32Addr) {
// S0 has address of method
asm.emitMOV_Reg_Reg(S0, T0);
} else {
// S0 has address of method
asm.emitMOV_Reg_Reg_Quad(S0, T0);
}
genParameterRegisterLoad(methodRef, true);
// the interface method (its parameters are on stack)
asm.emitCALL_Reg(S0);
} else {
// itable index is known at compile-time.
// call "findITable" to resolve object + interface id into
// itable address
// T0 = "this" object
stackMoveHelper(T0, Offset.fromIntZeroExtend((count - 1) << LG_WORDSIZE));
asm.baselineEmitLoadTIB(S0, T0);
asm.emitPUSH_Reg(S0);
// interface id
asm.emitPUSH_Imm(resolvedMethod.getDeclaringClass().getInterfaceId());
// pass 2 parameter words
genParameterRegisterLoad(asm, 2);
// findItableOffset(tib, id) returns iTable
asm.generateJTOCcall(Entrypoints.findItableMethod.getOffset());
if (VM.BuildFor32Addr) {
// S0 has iTable
asm.emitMOV_Reg_Reg(S0, T0);
} else {
// S0 has iTable
asm.emitMOV_Reg_Reg_Quad(S0, T0);
}
genParameterRegisterLoad(methodRef, true);
// the interface call
asm.emitCALL_RegDisp(S0, Offset.fromIntZeroExtend(itableIndex << LG_WORDSIZE));
}
}
genResultRegisterUnload(methodRef);
}
Aggregations