Search in sources :

Example 61 with RVMClass

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;
}
Also used : RVMMember(org.jikesrvm.classloader.RVMMember) TypeReference(org.jikesrvm.classloader.TypeReference) Atom(org.jikesrvm.classloader.Atom) RVMClass(org.jikesrvm.classloader.RVMClass)

Example 62 with RVMClass

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);
}
Also used : RVMField(org.jikesrvm.classloader.RVMField) TypeReference(org.jikesrvm.classloader.TypeReference) Atom(org.jikesrvm.classloader.Atom) RVMClass(org.jikesrvm.classloader.RVMClass)

Example 63 with RVMClass

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);
}
Also used : ForwardReference(org.jikesrvm.compilers.common.assembler.ForwardReference) InterfaceMethodSignature(org.jikesrvm.classloader.InterfaceMethodSignature) RVMMethod(org.jikesrvm.classloader.RVMMethod) RVMClass(org.jikesrvm.classloader.RVMClass) Offset(org.vmmagic.unboxed.Offset)

Example 64 with RVMClass

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;
    }
}
Also used : RVMClass(org.jikesrvm.classloader.RVMClass) RVMClass(org.jikesrvm.classloader.RVMClass)

Example 65 with RVMClass

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;
    }
}
Also used : RVMType(org.jikesrvm.classloader.RVMType) RVMField(org.jikesrvm.classloader.RVMField) RVMClass(org.jikesrvm.classloader.RVMClass) Atom(org.jikesrvm.classloader.Atom) RVMClass(org.jikesrvm.classloader.RVMClass)

Aggregations

RVMClass (org.jikesrvm.classloader.RVMClass)69 RVMMethod (org.jikesrvm.classloader.RVMMethod)28 TypeReference (org.jikesrvm.classloader.TypeReference)22 RVMType (org.jikesrvm.classloader.RVMType)20 Atom (org.jikesrvm.classloader.Atom)14 RVMField (org.jikesrvm.classloader.RVMField)11 RVMArray (org.jikesrvm.classloader.RVMArray)8 Instruction (org.jikesrvm.compilers.opt.ir.Instruction)8 IntConstantOperand (org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand)8 MethodOperand (org.jikesrvm.compilers.opt.ir.operand.MethodOperand)8 Operand (org.jikesrvm.compilers.opt.ir.operand.Operand)8 RegisterOperand (org.jikesrvm.compilers.opt.ir.operand.RegisterOperand)8 BranchProfileOperand (org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand)7 ConditionOperand (org.jikesrvm.compilers.opt.ir.operand.ConditionOperand)7 LocationOperand (org.jikesrvm.compilers.opt.ir.operand.LocationOperand)7 Address (org.vmmagic.unboxed.Address)7 NormalMethod (org.jikesrvm.classloader.NormalMethod)6 CompiledMethod (org.jikesrvm.compilers.common.CompiledMethod)6 TrapCodeOperand (org.jikesrvm.compilers.opt.ir.operand.TrapCodeOperand)6 BasicBlock (org.jikesrvm.compilers.opt.ir.BasicBlock)5