use of org.jikesrvm.classloader.RVMClass in project JikesRVM by JikesRVM.
the class EntrypointHelper method getMember.
/**
* Get description of virtual machine component (field or method).
* <p>
* Note: This is method is intended for use only by VM classes that need
* to address their own fields and methods in the runtime virtual machine
* image. It should not be used for general purpose class loading.
* @param classDescriptor class descriptor - something like "Lorg/jikesrvm/RuntimeEntrypoints;"
* @param memberName member name - something like "invokestatic"
* @param memberDescriptor member descriptor - something like "()V"
* @return corresponding RVMMember object
*/
private static RVMMember getMember(String classDescriptor, String memberName, String memberDescriptor) {
Atom clsDescriptor = Atom.findOrCreateAsciiAtom(classDescriptor);
Atom memName = Atom.findOrCreateAsciiAtom(memberName);
Atom memDescriptor = Atom.findOrCreateAsciiAtom(memberDescriptor);
try {
TypeReference tRef = TypeReference.findOrCreate(BootstrapClassLoader.getBootstrapClassLoader(), clsDescriptor);
RVMClass cls = (RVMClass) tRef.resolve();
cls.resolve();
RVMMember member;
if ((member = cls.findDeclaredField(memName, memDescriptor)) != null) {
verifyThatFieldIsNotFinal((RVMField) member);
verifyPresenceOfEntrypointAnnotation(member);
return member;
}
if ((member = cls.findDeclaredMethod(memName, memDescriptor)) != null) {
verifyPresenceOfEntrypointAnnotation(member);
return member;
}
} catch (Exception e) {
e.printStackTrace();
}
// The usual causes for getMember() to fail are:
// 1. you mispelled the class name, member name, or member signature
// 2. the class containing the specified member didn't get compiled
//
VM.sysWriteln("Entrypoints.getMember: can't resolve class=" + classDescriptor + " member=" + memberName + " desc=" + memberDescriptor);
if (VM.VerifyAssertions)
VM._assert(VM.NOT_REACHED);
return null;
}
use of org.jikesrvm.classloader.RVMClass in project JikesRVM by JikesRVM.
the class EntrypointHelper method getField.
/**
* Get description of virtual machine field.
* @param klass class containing field
* @param member member name - something like "invokestatic"
* @param type of field
* @return corresponding RVMField
*/
static RVMField getField(String klass, String member, Class<?> type) {
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 memName = Atom.findOrCreateAsciiAtom(member);
Atom typeName = TypeReference.findOrCreate(type).getName();
RVMField field = cls.findDeclaredField(memName, typeName);
if (field != null) {
verifyPresenceOfEntrypointAnnotation(field);
verifyThatFieldIsNotFinal(field);
return field;
}
} catch (Throwable t) {
throw new Error("Entrypoints.getField: can't resolve class=" + klass + " member=" + member + " desc=" + type, t);
}
}
throw new Error("Entrypoints.getField: can't resolve class=" + klass + " member=" + member + " desc=" + type);
}
use of org.jikesrvm.classloader.RVMClass 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);
}
use of org.jikesrvm.classloader.RVMClass in project JikesRVM by JikesRVM.
the class JNIFunctions method NewObjectA.
/**
* NewObjectA: create a new object instance
* @param env A JREF index for the JNI environment object
* @param classJREF a JREF index for the class object
* @param methodID id of a MethodReference
* @param argAddress a raw address to an array of unions in C, each element is 2-word and
* hold an argument of the appropriate type for the constructor invocation
* @throws InstantiationException if the class is abstract or is an interface
* @throws OutOfMemoryError if no more memory to allocate
* @return the new object instance
*/
private static int NewObjectA(JNIEnvironment env, int classJREF, int methodID, Address argAddress) throws Exception {
if (traceJNI)
VM.sysWriteln("JNI called: NewObjectA");
RuntimeEntrypoints.checkJNICountDownToGC();
try {
Class<?> cls = (Class<?>) env.getJNIRef(classJREF);
RVMClass vmcls = java.lang.JikesRVMSupport.getTypeForClass(cls).asClass();
if (vmcls.isAbstract() || vmcls.isInterface()) {
env.recordException(new InstantiationException());
return 0;
}
Object newobj = JNIHelpers.invokeInitializer(cls, methodID, argAddress, true, false);
return env.pushJNIRef(newobj);
} catch (Throwable unexpected) {
if (traceJNI)
unexpected.printStackTrace(System.err);
env.recordException(unexpected);
return 0;
}
}
use of org.jikesrvm.classloader.RVMClass in project JikesRVM by JikesRVM.
the class JNIFunctions method GetStaticFieldID.
/**
* GetStaticFieldID: return a field id which can be cached in native code and reused
* @param env A JREF index for the JNI environment object
* @param classJREF a JREF index for the RVMClass object
* @param fieldNameAddress a raw address to a null-terminated string in C for the field name
* @param descriptorAddress a raw address to a null-terminated string in C for the descriptor
* @return the offset of a static field given the class, field name
* and type. Return 0 if the field is not found
* @throws NoSuchFieldError if the specified field cannot be found
* @throws ExceptionInInitializerError if the class initializer fails
* @throws OutOfMemoryError if the system runs out of memory
*/
private static int GetStaticFieldID(JNIEnvironment env, int classJREF, Address fieldNameAddress, Address descriptorAddress) {
if (traceJNI)
VM.sysWriteln("JNI called: GetStaticFieldID");
RuntimeEntrypoints.checkJNICountDownToGC();
try {
Class<?> cls = (Class<?>) env.getJNIRef(classJREF);
String fieldString = JNIGenericHelpers.createStringFromC(fieldNameAddress);
Atom fieldName = Atom.findOrCreateAsciiAtom(fieldString);
String descriptorString = JNIGenericHelpers.createStringFromC(descriptorAddress);
Atom descriptor = Atom.findOrCreateAsciiAtom(descriptorString);
RVMType rvmType = java.lang.JikesRVMSupport.getTypeForClass(cls);
if (rvmType.isClassType()) {
// First search for the fields in the class and its superclasses
for (RVMClass curClass = rvmType.asClass(); curClass != null; curClass = curClass.getSuperClass()) {
for (RVMField field : curClass.getStaticFields()) {
if (field.getName() == fieldName && field.getDescriptor() == descriptor) {
return field.getId();
}
}
}
// Now search all implemented interfaces (includes inherited interfaces)
for (RVMClass curClass : rvmType.asClass().getAllImplementedInterfaces()) {
for (RVMField field : curClass.getStaticFields()) {
if (field.getName() == fieldName && field.getDescriptor() == descriptor) {
return field.getId();
}
}
}
}
env.recordException(new NoSuchFieldError(fieldString + ", " + descriptorString + " of " + cls));
return 0;
} catch (Throwable unexpected) {
if (traceJNI)
unexpected.printStackTrace(System.err);
env.recordException(unexpected);
return 0;
}
}
Aggregations