Search in sources :

Example 81 with RVMMethod

use of org.jikesrvm.classloader.RVMMethod in project JikesRVM by JikesRVM.

the class JNIFunctions method FromReflectedMethod.

/**
 *****************************************************************
 * These functions were added in Java 2  (JNI 1.2)
 */
/**
 * FromReflectedMethod
 * @param env A JREF index for the JNI environment object
 * @param methodJREF a JREF index for the java.lang.reflect.Method or
 * java.lang.reflect.Constructor object.
 * @return the jmethodID corresponding to methodJREF
 */
private static int FromReflectedMethod(JNIEnvironment env, int methodJREF) {
    if (traceJNI)
        VM.sysWriteln("JNI called: FromReflectedMethod");
    RuntimeEntrypoints.checkJNICountDownToGC();
    Object methodObj = env.getJNIRef(methodJREF);
    RVMMethod meth;
    if (methodObj instanceof Constructor) {
        meth = java.lang.reflect.JikesRVMSupport.getMethodOf((Constructor<?>) methodObj);
    } else {
        meth = java.lang.reflect.JikesRVMSupport.getMethodOf((Method) methodObj);
    }
    if (traceJNI)
        VM.sysWriteln("got method " + meth);
    return meth.getId();
}
Also used : RVMMethod(org.jikesrvm.classloader.RVMMethod) Constructor(java.lang.reflect.Constructor) Method(java.lang.reflect.Method) NativeMethod(org.jikesrvm.classloader.NativeMethod) RVMMethod(org.jikesrvm.classloader.RVMMethod)

Example 82 with RVMMethod

use of org.jikesrvm.classloader.RVMMethod in project JikesRVM by JikesRVM.

the class JNIHelpers method invokeInitializer.

/**
 * Common code shared by the JNI functions NewObjectA, NewObjectV, NewObject
 * (object creation)
 * @param methodID the method ID for a constructor
 * @return a new object created by the specified constructor
 */
public static Object invokeInitializer(Class<?> cls, int methodID, Address argAddress, boolean isJvalue, boolean isDotDotStyle) throws Exception {
    // get the parameter list as Java class
    MemberReference mr = MemberReference.getMemberRef(methodID);
    TypeReference tr = java.lang.JikesRVMSupport.getTypeForClass(cls).getTypeRef();
    MethodReference methodRef = MemberReference.findOrCreate(tr, mr.getName(), mr.getDescriptor()).asMethodReference();
    RVMMethod mth = methodRef.resolve();
    Constructor<?> constMethod = java.lang.reflect.JikesRVMSupport.createConstructor(mth);
    if (!mth.isPublic()) {
        constMethod.setAccessible(true);
    }
    Object[] argObjs;
    if (isJvalue) {
        argObjs = packageParametersFromJValuePtr(methodRef, argAddress);
    } else if (isDotDotStyle) {
        // dot dot var arg
        if (VM.BuildForPower64ELF_ABI) {
            Address varargAddress = pushVarArgToSpillArea(methodID, false);
            argObjs = packageParameterFromVarArg(methodRef, varargAddress);
        } else {
            if (VM.VerifyAssertions)
                VM._assert(VM.BuildForSVR4ABI);
            // pass in the frame pointer of glue stack frames
            // stack frame looks as following:
            // this method ->
            // 
            // architecture.JNIHelpers.method -->
            // 
            // native to java method ->
            // 
            // glue frame ->
            // 
            // native C method ->
            Address gluefp = Magic.getCallerFramePointer(Magic.getCallerFramePointer(Magic.getCallerFramePointer(Magic.getFramePointer())));
            argObjs = packageParameterFromDotArgSVR4(methodRef, gluefp, false);
        }
    } else {
        // mormal var arg
        if (VM.BuildForPower64ELF_ABI) {
            argObjs = packageParameterFromVarArg(methodRef, argAddress);
        } else {
            if (VM.VerifyAssertions)
                VM._assert(VM.BuildForSVR4ABI);
            argObjs = packageParameterFromVarArgSVR4(methodRef, argAddress);
        }
    }
    // construct the new object
    return constMethod.newInstance(argObjs);
}
Also used : RVMMethod(org.jikesrvm.classloader.RVMMethod) Address(org.vmmagic.unboxed.Address) MemberReference(org.jikesrvm.classloader.MemberReference) MethodReference(org.jikesrvm.classloader.MethodReference) TypeReference(org.jikesrvm.classloader.TypeReference)

Example 83 with RVMMethod

use of org.jikesrvm.classloader.RVMMethod in project JikesRVM by JikesRVM.

the class BytecodeTraverser method scanBlocks.

// //////////////////////////
// IMPLEMENTATION
// /////////////////////////
/* return true --> hit the bytecode pointed by PC */
private // which method
boolean scanBlocks(// which method
NormalMethod method, // the bytecodes
BytecodeStream bytecodes, // do a DFS or one-pass scan
boolean doDFS, // the target pcs, if doDFS
int pcs, // the local types if doDFS
byte[] ltypes, // the stack types if doDFS
byte[] stypes, // start pc
int startpc, // stack
TypeStack S, int[] stackHeights) {
    // the stack height if not doDFS
    int localsize = method.getLocalWords() - 1;
    RVMClass declaringClass = method.getDeclaringClass();
    bytecodes.reset(startpc);
    boolean found = false;
    while (bytecodes.hasMoreBytecodes()) {
        // get current pc
        int pc = bytecodes.index();
        if (visitedpc[pc] == 1) {
            return false;
        } else {
            visitedpc[pc] = 1;
        }
        if (doDFS && (pc == pcs)) {
            /* make a copy of stack frame and put into stypes. */
            byte[] stack = S.snapshot();
            System.arraycopy(stack, 0, stypes, 0, stack.length);
            return true;
        }
        if (!doDFS) {
            // record stack heights
            stackHeights[pc] = localsize + S.depth();
        }
        /* let's continue */
        int bcode = bytecodes.nextInstruction();
        if (TRACE) {
            if (bcode <= JBC_jsr_w) {
                VM.sysWriteln(pc + " : " + S.depth() + " : " + JBC_name(bcode));
            } else {
                VM.sysWriteln(pc + " : " + S.depth() + " : impdep1");
            }
        }
        switch(bcode) {
            case JBC_nop:
                break;
            case JBC_aconst_null:
                S.push(ClassTypeCode);
                break;
            case JBC_iconst_m1:
            case JBC_iconst_0:
            case JBC_iconst_1:
            case JBC_iconst_2:
            case JBC_iconst_3:
            case JBC_iconst_4:
            case JBC_iconst_5:
                S.push(IntTypeCode);
                break;
            case JBC_lconst_0:
            case JBC_lconst_1:
                /* we should do the save order as opt compiler */
                S.push(VoidTypeCode);
                S.push(LongTypeCode);
                break;
            case JBC_fconst_0:
            case JBC_fconst_1:
            case JBC_fconst_2:
                S.push(FloatTypeCode);
                break;
            case JBC_dconst_0:
            case JBC_dconst_1:
                S.push(VoidTypeCode);
                S.push(DoubleTypeCode);
                break;
            case JBC_bipush:
                bytecodes.getByteValue();
                S.push(IntTypeCode);
                break;
            case JBC_sipush:
                bytecodes.getShortValue();
                S.push(IntTypeCode);
                break;
            case JBC_ldc:
            case JBC_ldc_w:
                {
                    int cpoolidx = (bcode == JBC_ldc) ? bytecodes.getConstantIndex() : bytecodes.getWideConstantIndex();
                    byte tdesc = declaringClass.getLiteralDescription(cpoolidx);
                    switch(tdesc) {
                        case CP_INT:
                            S.push(IntTypeCode);
                            break;
                        case CP_FLOAT:
                            S.push(FloatTypeCode);
                            break;
                        case CP_STRING:
                            S.push(ClassTypeCode);
                            break;
                        case CP_CLASS:
                            S.push(ClassTypeCode);
                            break;
                        default:
                            if (VM.TraceOnStackReplacement)
                                VM.sysWriteln("ldc unknown type " + tdesc);
                            if (VM.VerifyAssertions)
                                VM._assert(VM.NOT_REACHED);
                            break;
                    }
                // end of switch
                }
                break;
            case JBC_ldc2_w:
                {
                    int cpoolidx = bytecodes.getWideConstantIndex();
                    byte tdesc = declaringClass.getLiteralDescription(cpoolidx);
                    S.push(VoidTypeCode);
                    switch(tdesc) {
                        case CP_LONG:
                            S.push(LongTypeCode);
                            break;
                        case CP_DOUBLE:
                            S.push(DoubleTypeCode);
                            break;
                        default:
                            if (VM.TraceOnStackReplacement)
                                VM.sysWriteln("ldc2_w unknown type " + tdesc);
                            if (VM.VerifyAssertions)
                                VM._assert(VM.NOT_REACHED);
                            break;
                    }
                // end of switch
                }
                break;
            case JBC_iload:
                // skip local
                bytecodes.getLocalNumber();
                S.push(IntTypeCode);
                break;
            case JBC_lload:
                // skip local
                bytecodes.getLocalNumber();
                S.push(VoidTypeCode);
                S.push(LongTypeCode);
                break;
            case JBC_fload:
                // skip local
                bytecodes.getLocalNumber();
                S.push(FloatTypeCode);
                break;
            case JBC_dload:
                bytecodes.getLocalNumber();
                S.push(VoidTypeCode);
                S.push(DoubleTypeCode);
                break;
            case JBC_aload:
                bytecodes.getLocalNumber();
                S.push(ClassTypeCode);
                break;
            case JBC_iload_0:
            case JBC_iload_1:
            case JBC_iload_2:
            case JBC_iload_3:
                S.push(IntTypeCode);
                break;
            case JBC_lload_0:
            case JBC_lload_1:
            case JBC_lload_2:
            case JBC_lload_3:
                S.push(VoidTypeCode);
                S.push(LongTypeCode);
                break;
            case JBC_fload_0:
            case JBC_fload_1:
            case JBC_fload_2:
            case JBC_fload_3:
                S.push(FloatTypeCode);
                break;
            case JBC_dload_0:
            case JBC_dload_1:
            case JBC_dload_2:
            case JBC_dload_3:
                S.push(VoidTypeCode);
                S.push(DoubleTypeCode);
                break;
            case JBC_aload_0:
            case JBC_aload_1:
            case JBC_aload_2:
            case JBC_aload_3:
                S.push(ClassTypeCode);
                break;
            case JBC_iaload:
            case JBC_baload:
            case JBC_caload:
            case JBC_saload:
                S.pop();
                S.pop();
                S.push(IntTypeCode);
                break;
            case JBC_laload:
                S.pop();
                S.pop();
                S.push(VoidTypeCode);
                S.push(LongTypeCode);
                break;
            case JBC_faload:
                S.pop();
                S.pop();
                S.push(FloatTypeCode);
                break;
            case JBC_daload:
                S.pop();
                S.pop();
                S.push(VoidTypeCode);
                S.push(DoubleTypeCode);
                break;
            case JBC_aaload:
                S.pop();
                S.pop();
                S.push(ClassTypeCode);
                break;
            case JBC_istore:
                {
                    S.pop();
                    int index = bytecodes.getLocalNumber();
                    if (doDFS)
                        ltypes[index] = IntTypeCode;
                }
                break;
            case JBC_istore_0:
            case JBC_istore_1:
            case JBC_istore_2:
            case JBC_istore_3:
                {
                    S.pop();
                    int index = bcode - JBC_istore_0;
                    if (doDFS)
                        ltypes[index] = IntTypeCode;
                }
                break;
            case JBC_lstore:
                {
                    S.pop();
                    S.pop();
                    int index = bytecodes.getLocalNumber();
                    if (doDFS) {
                        ltypes[index] = LongTypeCode;
                        ltypes[index + 1] = VoidTypeCode;
                    }
                }
                break;
            case JBC_lstore_0:
            case JBC_lstore_1:
            case JBC_lstore_2:
            case JBC_lstore_3:
                {
                    S.pop();
                    S.pop();
                    int index = bcode - JBC_lstore_0;
                    if (doDFS) {
                        ltypes[index] = LongTypeCode;
                        ltypes[index + 1] = VoidTypeCode;
                    }
                }
                break;
            case JBC_fstore:
                {
                    S.pop();
                    int index = bytecodes.getLocalNumber();
                    if (doDFS)
                        ltypes[index] = FloatTypeCode;
                }
                break;
            case JBC_fstore_0:
            case JBC_fstore_1:
            case JBC_fstore_2:
            case JBC_fstore_3:
                {
                    S.pop();
                    int index = bcode - JBC_fstore_0;
                    if (doDFS)
                        ltypes[index] = FloatTypeCode;
                }
                break;
            case JBC_dstore:
                {
                    S.pop();
                    S.pop();
                    int index = bytecodes.getLocalNumber();
                    if (doDFS) {
                        ltypes[index] = DoubleTypeCode;
                        ltypes[index + 1] = VoidTypeCode;
                    }
                }
                break;
            case JBC_dstore_0:
            case JBC_dstore_1:
            case JBC_dstore_2:
            case JBC_dstore_3:
                {
                    S.pop();
                    S.pop();
                    int index = bcode - JBC_dstore_0;
                    if (doDFS) {
                        ltypes[index] = DoubleTypeCode;
                        ltypes[index + 1] = VoidTypeCode;
                    }
                }
                break;
            case JBC_astore:
                {
                    // caution: astore may save return address type
                    int index = bytecodes.getLocalNumber();
                    byte tcode = S.pop();
                    if (doDFS)
                        ltypes[index] = tcode;
                    // for ret address.
                    if (tcode == ReturnAddressTypeCode) {
                        retaddr[index] = addr;
                        addr = -1;
                    }
                }
                break;
            case JBC_astore_0:
            case JBC_astore_1:
            case JBC_astore_2:
            case JBC_astore_3:
                {
                    // caution: astore may save return address type
                    int index = bcode - JBC_astore_0;
                    byte tcode = S.pop();
                    if (doDFS)
                        ltypes[index] = tcode;
                    // for ret address.
                    if (tcode == ReturnAddressTypeCode) {
                        retaddr[index] = addr;
                        addr = -1;
                    }
                }
                break;
            case JBC_iastore:
            case JBC_bastore:
            case JBC_castore:
            case JBC_sastore:
                S.pop(3);
                break;
            case JBC_lastore:
                S.pop(4);
                break;
            case JBC_fastore:
                S.pop(3);
                break;
            case JBC_dastore:
                S.pop(4);
                break;
            case JBC_aastore:
                S.pop(3);
                break;
            case JBC_pop:
                S.pop();
                break;
            case JBC_pop2:
                S.pop(2);
                break;
            case JBC_dup:
                {
                    byte v1 = S.peek();
                    S.push(v1);
                }
                break;
            case JBC_dup_x1:
                {
                    byte v1 = S.peek();
                    S.pop();
                    byte v2 = S.peek();
                    S.pop();
                    S.push(v1);
                    S.push(v2);
                    S.push(v1);
                }
                break;
            case JBC_dup_x2:
                {
                    byte v1 = S.peek();
                    S.pop();
                    byte v2 = S.peek();
                    S.pop();
                    byte v3 = S.peek();
                    S.pop();
                    S.push(v1);
                    S.push(v3);
                    S.push(v2);
                    S.push(v1);
                }
                break;
            case JBC_dup2:
                {
                    byte v1 = S.peek();
                    S.pop();
                    byte v2 = S.peek();
                    S.push(v1);
                    S.push(v2);
                    S.push(v1);
                }
                break;
            case JBC_dup2_x1:
                {
                    byte v1 = S.peek();
                    S.pop();
                    byte v2 = S.peek();
                    S.pop();
                    byte v3 = S.peek();
                    S.pop();
                    S.push(v2);
                    S.push(v1);
                    S.push(v3);
                    S.push(v2);
                    S.push(v1);
                }
                break;
            case JBC_dup2_x2:
                {
                    byte v1 = S.peek();
                    S.pop();
                    byte v2 = S.peek();
                    S.pop();
                    byte v3 = S.peek();
                    S.pop();
                    byte v4 = S.peek();
                    S.pop();
                    S.push(v2);
                    S.push(v1);
                    S.push(v4);
                    S.push(v3);
                    S.push(v2);
                    S.push(v1);
                }
                break;
            case JBC_swap:
                {
                    byte v1 = S.peek();
                    S.pop();
                    byte v2 = S.peek();
                    S.pop();
                    S.push(v1);
                    S.push(v2);
                }
                break;
            case JBC_iadd:
            case JBC_isub:
            case JBC_imul:
            case JBC_idiv:
            case JBC_irem:
            case JBC_iand:
            case JBC_ior:
            case JBC_ixor:
            case JBC_ishl:
            case JBC_ishr:
            case JBC_iushr:
                S.pop();
                break;
            case JBC_ladd:
            case JBC_lsub:
            case JBC_lmul:
            case JBC_ldiv:
            case JBC_lrem:
            case JBC_land:
            case JBC_lor:
            case JBC_lxor:
                S.pop(2);
                break;
            case JBC_lshl:
            case JBC_lshr:
            case JBC_lushr:
                S.pop();
                break;
            case JBC_fadd:
            case JBC_fsub:
            case JBC_fmul:
            case JBC_fdiv:
            case JBC_frem:
                S.pop();
                break;
            case JBC_dadd:
            case JBC_dsub:
            case JBC_dmul:
            case JBC_ddiv:
            case JBC_drem:
                S.pop(2);
                break;
            case JBC_ineg:
            case JBC_lneg:
            case JBC_fneg:
            case JBC_dneg:
                break;
            case JBC_iinc:
                {
                    int index = bytecodes.getLocalNumber();
                    /* int value = */
                    bytecodes.getIncrement();
                    if (doDFS)
                        ltypes[index] = IntTypeCode;
                }
                break;
            case JBC_i2l:
                S.pop();
                S.push(VoidTypeCode);
                S.push(LongTypeCode);
                break;
            case JBC_i2f:
                S.pop();
                S.push(FloatTypeCode);
                break;
            case JBC_i2d:
                S.pop();
                S.push(VoidTypeCode);
                S.push(DoubleTypeCode);
                break;
            case JBC_l2i:
                S.pop(2);
                S.push(IntTypeCode);
                break;
            case JBC_l2f:
                S.pop(2);
                S.push(FloatTypeCode);
                break;
            case JBC_l2d:
                S.pop(2);
                S.push(VoidTypeCode);
                S.push(DoubleTypeCode);
                break;
            case JBC_f2i:
                S.pop();
                S.push(IntTypeCode);
                break;
            case JBC_f2l:
                S.pop();
                S.push(VoidTypeCode);
                S.push(LongTypeCode);
                break;
            case JBC_f2d:
                S.pop();
                S.push(VoidTypeCode);
                S.push(DoubleTypeCode);
                break;
            case JBC_d2i:
                S.pop(2);
                S.push(IntTypeCode);
                break;
            case JBC_d2l:
                S.pop(2);
                S.push(VoidTypeCode);
                S.push(LongTypeCode);
                break;
            case JBC_d2f:
                S.pop(2);
                S.push(FloatTypeCode);
                break;
            case JBC_int2byte:
            case JBC_int2char:
            case JBC_int2short:
                break;
            case JBC_lcmp:
                S.pop(4);
                S.push(IntTypeCode);
                break;
            case JBC_fcmpl:
            case JBC_fcmpg:
                S.pop(2);
                S.push(IntTypeCode);
                break;
            case JBC_dcmpl:
            case JBC_dcmpg:
                S.pop(4);
                S.push(IntTypeCode);
                break;
            case JBC_ifeq:
            case JBC_ifne:
            case JBC_iflt:
            case JBC_ifge:
            case JBC_ifgt:
            case JBC_ifle:
            case JBC_ifnull:
            case JBC_ifnonnull:
                {
                    S.pop();
                    // flowthrough first
                    int nextpc = pc + 3;
                    int target = pc + bytecodes.getBranchOffset();
                    if (doDFS) {
                        // make a copy of ltypes, stypes to pass in
                        byte[] newltypes = new byte[ltypes.length];
                        byte[] newstypes = new byte[stypes.length];
                        System.arraycopy(ltypes, 0, newltypes, 0, ltypes.length);
                        System.arraycopy(stypes, 0, newstypes, 0, stypes.length);
                        found = scanBlocks(method, bytecodes, true, pcs, newltypes, newstypes, nextpc, new TypeStack(S), null);
                        if (found) {
                            // copy back the ltypes and stypes
                            System.arraycopy(newltypes, 0, ltypes, 0, ltypes.length);
                            System.arraycopy(newstypes, 0, stypes, 0, stypes.length);
                            return true;
                        }
                    } else {
                        found = scanBlocks(method, bytecodes, false, -1, null, null, nextpc, new TypeStack(S), stackHeights);
                    }
                    bytecodes.reset(target);
                }
                break;
            case JBC_if_icmpeq:
            case JBC_if_icmpne:
            case JBC_if_icmplt:
            case JBC_if_icmpge:
            case JBC_if_icmpgt:
            case JBC_if_icmple:
            case JBC_if_acmpeq:
            case JBC_if_acmpne:
                {
                    S.pop(2);
                    // flowthrough first
                    int nextpc = pc + 3;
                    int target = pc + bytecodes.getBranchOffset();
                    if (doDFS) {
                        // make a copy of ltypes, stypes to pass in
                        byte[] newltypes = new byte[ltypes.length];
                        byte[] newstypes = new byte[stypes.length];
                        System.arraycopy(ltypes, 0, newltypes, 0, ltypes.length);
                        System.arraycopy(stypes, 0, newstypes, 0, stypes.length);
                        found = scanBlocks(method, bytecodes, true, pcs, newltypes, newstypes, nextpc, new TypeStack(S), null);
                        if (found) {
                            // copy back the ltypes and stypes
                            System.arraycopy(newltypes, 0, ltypes, 0, ltypes.length);
                            System.arraycopy(newstypes, 0, stypes, 0, stypes.length);
                            return true;
                        }
                    } else {
                        found = scanBlocks(method, bytecodes, false, -1, null, null, nextpc, new TypeStack(S), stackHeights);
                    }
                    bytecodes.reset(target);
                }
                break;
            case JBC_goto:
                {
                    int offset = bytecodes.getBranchOffset();
                    if (!ignoreGotos) {
                        bytecodes.reset(pc + offset);
                    }
                }
                break;
            case JBC_goto_w:
                {
                    int offset = bytecodes.getWideBranchOffset();
                    if (!ignoreGotos) {
                        bytecodes.reset(pc + offset);
                    }
                }
                break;
            case JBC_jsr:
            case JBC_jsr_w:
                {
                    // flow through firs
                    int nextpc = pc + ((bcode == JBC_jsr) ? 3 : 5);
                    int target = pc + ((bcode == JBC_jsr) ? bytecodes.getBranchOffset() : bytecodes.getWideBranchOffset());
                    if (doDFS) {
                        // make a copy of ltypes, stypes to pass in
                        byte[] newltypes = new byte[ltypes.length];
                        byte[] newstypes = new byte[stypes.length];
                        System.arraycopy(ltypes, 0, newltypes, 0, ltypes.length);
                        System.arraycopy(stypes, 0, newstypes, 0, stypes.length);
                        found = scanBlocks(method, bytecodes, true, pcs, newltypes, newstypes, nextpc, new TypeStack(S), null);
                        if (found) {
                            // copy back the ltypes and stypes
                            System.arraycopy(newltypes, 0, ltypes, 0, ltypes.length);
                            System.arraycopy(newstypes, 0, stypes, 0, stypes.length);
                            return true;
                        }
                    } else {
                        found = scanBlocks(method, bytecodes, false, -1, null, null, nextpc, new TypeStack(S), stackHeights);
                    }
                    // branch to jsr subroutine
                    // remember return address for ret.
                    addr = pc + ((bcode == JBC_jsr) ? 3 : 5);
                    S.push(ReturnAddressTypeCode);
                    bytecodes.reset(target);
                }
                break;
            case JBC_ret:
                {
                    // the OPT compiler set local to null after _ret instruction,
                    // then we should clean it here also, otherwise it will
                    // throw a null pointer exception.
                    // HOWEVER, it is not part of JVM spec.
                    int index = bytecodes.getLocalNumber();
                    if (doDFS)
                        ltypes[index] = VoidTypeCode;
                    /* the ret address may be saved by a PSEUDO_LoadRetAddrConstant
          */
                    if (retaddr[index] != -1) {
                        bytecodes.reset(retaddr[index]);
                        retaddr[index] = -1;
                    } else {
                        // now we hit ret, return out
                        return false;
                    }
                }
                break;
            case JBC_tableswitch:
                {
                    S.pop();
                    bytecodes.alignSwitch();
                    int defaultval = bytecodes.getDefaultSwitchOffset();
                    int low = bytecodes.getLowSwitchValue();
                    int high = bytecodes.getHighSwitchValue();
                    // write down a list of targets
                    int npairs = high - low + 1;
                    int[] offsets = new int[npairs];
                    for (int i = 0; i < npairs; i++) {
                        offsets[i] = bytecodes.getTableSwitchOffset(i);
                    }
                    for (int i = 0; i < npairs; i++) {
                        int tgtpc = pc + offsets[i];
                        if (doDFS) {
                            // make a copy of ltypes, stypes to pass in
                            byte[] newltypes = new byte[ltypes.length];
                            byte[] newstypes = new byte[stypes.length];
                            System.arraycopy(ltypes, 0, newltypes, 0, ltypes.length);
                            System.arraycopy(stypes, 0, newstypes, 0, stypes.length);
                            found = scanBlocks(method, bytecodes, true, pcs, newltypes, newstypes, tgtpc, new TypeStack(S), null);
                            if (found) {
                                // copy back the ltypes and stypes
                                System.arraycopy(newltypes, 0, ltypes, 0, ltypes.length);
                                System.arraycopy(newstypes, 0, stypes, 0, stypes.length);
                                return true;
                            }
                        } else {
                            found = scanBlocks(method, bytecodes, false, -1, null, null, tgtpc, new TypeStack(S), stackHeights);
                        }
                    }
                    // default
                    {
                        int tgtpc = pc + defaultval;
                        if (doDFS) {
                            // make a copy of ltypes, stypes to pass in
                            byte[] newltypes = new byte[ltypes.length];
                            byte[] newstypes = new byte[stypes.length];
                            System.arraycopy(ltypes, 0, newltypes, 0, ltypes.length);
                            System.arraycopy(stypes, 0, newstypes, 0, stypes.length);
                            found = scanBlocks(method, bytecodes, true, pcs, newltypes, newstypes, tgtpc, new TypeStack(S), null);
                            if (found) {
                                // copy back the ltypes and stypes
                                System.arraycopy(newltypes, 0, ltypes, 0, ltypes.length);
                                System.arraycopy(newstypes, 0, stypes, 0, stypes.length);
                            }
                        } else {
                            found = scanBlocks(method, bytecodes, false, -1, null, null, tgtpc, new TypeStack(S), stackHeights);
                        }
                        return found;
                    }
                }
            case JBC_lookupswitch:
                {
                    // pop the key
                    S.pop();
                    bytecodes.alignSwitch();
                    int defaultval = bytecodes.getDefaultSwitchOffset();
                    int npairs = bytecodes.getSwitchLength();
                    int[] matches = new int[npairs];
                    int[] offsets = new int[npairs];
                    for (int i = 0; i < npairs; i++) {
                        matches[i] = bytecodes.getLookupSwitchValue(i);
                        offsets[i] = bytecodes.getLookupSwitchOffset(i);
                    }
                    for (int i = 0; i < npairs; i++) {
                        // int match = matches[i];
                        int offset = offsets[i];
                        int tgtpc = pc + offset;
                        if (doDFS) {
                            // make a copy of ltypes, stypes to pass in
                            byte[] newltypes = new byte[ltypes.length];
                            byte[] newstypes = new byte[stypes.length];
                            System.arraycopy(ltypes, 0, newltypes, 0, ltypes.length);
                            System.arraycopy(stypes, 0, newstypes, 0, stypes.length);
                            found = scanBlocks(method, bytecodes, true, pcs, newltypes, newstypes, tgtpc, new TypeStack(S), null);
                            if (found) {
                                // copy back the ltypes and stypes
                                System.arraycopy(newltypes, 0, ltypes, 0, ltypes.length);
                                System.arraycopy(newstypes, 0, stypes, 0, stypes.length);
                                return true;
                            }
                        } else {
                            found = scanBlocks(method, bytecodes, false, -1, null, null, tgtpc, new TypeStack(S), stackHeights);
                        }
                    }
                    // default
                    {
                        int tgtpc = pc + defaultval;
                        if (doDFS) {
                            // make a copy of ltypes, stypes to pass in
                            byte[] newltypes = new byte[ltypes.length];
                            byte[] newstypes = new byte[stypes.length];
                            System.arraycopy(ltypes, 0, newltypes, 0, ltypes.length);
                            System.arraycopy(stypes, 0, newstypes, 0, stypes.length);
                            found = scanBlocks(method, bytecodes, true, pcs, newltypes, newstypes, tgtpc, new TypeStack(S), null);
                            if (found) {
                                // copy back the ltypes and stypes
                                System.arraycopy(newltypes, 0, ltypes, 0, ltypes.length);
                                System.arraycopy(newstypes, 0, stypes, 0, stypes.length);
                            }
                        } else {
                            found = scanBlocks(method, bytecodes, false, -1, null, null, tgtpc, new TypeStack(S), stackHeights);
                        }
                    }
                }
                return found;
            case JBC_ireturn:
                S.pop();
                return false;
            case JBC_lreturn:
                S.pop(2);
                return false;
            case JBC_freturn:
                S.pop();
                return false;
            case JBC_dreturn:
                S.pop(2);
                return false;
            case JBC_areturn:
                S.pop();
                return false;
            case JBC_return:
                return false;
            case JBC_getfield:
                S.pop();
            case JBC_getstatic:
                {
                    FieldReference fieldRef = bytecodes.getFieldReference();
                    TypeReference ftype = fieldRef.getFieldContentsType();
                    byte tcode = ftype.getName().parseForTypeCode();
                    if ((tcode == LongTypeCode) || (tcode == DoubleTypeCode)) {
                        S.push(VoidTypeCode);
                    }
                    S.push(tcode);
                }
                break;
            case JBC_putstatic:
                {
                    FieldReference fieldRef = bytecodes.getFieldReference();
                    TypeReference ftype = fieldRef.getFieldContentsType();
                    byte tcode = ftype.getName().parseForTypeCode();
                    if ((tcode == LongTypeCode) || (tcode == DoubleTypeCode)) {
                        S.pop(2);
                    } else {
                        S.pop();
                    }
                }
                break;
            case JBC_putfield:
                {
                    FieldReference fieldRef = bytecodes.getFieldReference();
                    TypeReference ftype = fieldRef.getFieldContentsType();
                    byte tcode = ftype.getName().parseForTypeCode();
                    if ((tcode == LongTypeCode) || (tcode == DoubleTypeCode)) {
                        S.pop(2);
                    } else {
                        S.pop();
                    }
                }
                S.pop();
                break;
            case JBC_invokevirtual:
            case JBC_invokespecial:
            case JBC_invokestatic:
            case JBC_invokeinterface:
                {
                    MethodReference callee = bytecodes.getMethodReference();
                    int psize = callee.getParameterWords();
                    S.pop(psize);
                    if (bcode != JBC_invokestatic) {
                        // pop the object reference
                        S.pop();
                    }
                    TypeReference rtype = callee.getReturnType();
                    byte tcode = rtype.getName().parseForTypeCode();
                    if (tcode == VoidTypeCode) {
                    // nothing to do with void return type
                    } else {
                        if ((tcode == LongTypeCode) || (tcode == DoubleTypeCode)) {
                            S.push(VoidTypeCode);
                        }
                        S.push(tcode);
                    }
                    if (bcode == JBC_invokeinterface) {
                        bytecodes.alignInvokeInterface();
                    }
                }
                break;
            case JBC_invokedynamic:
                break;
            case JBC_new:
                // skip cpi of type
                bytecodes.getTypeReference();
                S.push(ClassTypeCode);
                break;
            case JBC_newarray:
                S.pop();
                S.push(ArrayTypeCode);
                // skip cpi of element type
                bytecodes.getArrayElementType();
                break;
            case JBC_anewarray:
                S.pop();
                S.push(ArrayTypeCode);
                // skip cpi of reference type
                bytecodes.getTypeReference();
                break;
            case JBC_arraylength:
                S.pop();
                S.push(IntTypeCode);
                break;
            case JBC_athrow:
                S.clear();
                S.push(ClassTypeCode);
                return false;
            case JBC_checkcast:
                // skip cpi of reference type
                bytecodes.getTypeReference();
                break;
            case JBC_instanceof:
                S.pop();
                S.push(IntTypeCode);
                // skip cpi of reference type
                bytecodes.getTypeReference();
                break;
            case JBC_monitorenter:
            case JBC_monitorexit:
                S.pop();
                break;
            case JBC_wide:
                {
                    int widecode = bytecodes.getWideOpcode();
                    int index = bytecodes.getWideLocalNumber();
                    switch(widecode) {
                        case JBC_iload:
                            S.push(IntTypeCode);
                            break;
                        case JBC_lload:
                            S.push(LongTypeCode);
                            break;
                        case JBC_fload:
                            S.push(FloatTypeCode);
                            break;
                        case JBC_dload:
                            S.push(DoubleTypeCode);
                            break;
                        case JBC_aload:
                            S.push(ClassTypeCode);
                            break;
                        case JBC_istore:
                            S.pop();
                            if (doDFS)
                                ltypes[index] = IntTypeCode;
                            break;
                        case JBC_lstore:
                            S.pop();
                            if (doDFS)
                                ltypes[index] = LongTypeCode;
                            break;
                        case JBC_fstore:
                            S.pop();
                            if (doDFS)
                                ltypes[index] = FloatTypeCode;
                            break;
                        case JBC_dstore:
                            S.pop();
                            if (doDFS)
                                ltypes[index] = DoubleTypeCode;
                            break;
                        case JBC_astore:
                            {
                                byte tcode = S.pop();
                                if (doDFS)
                                    ltypes[index] = tcode;
                                // for ret address.
                                if (tcode == ReturnAddressTypeCode) {
                                    retaddr[index] = addr;
                                    addr = -1;
                                }
                            }
                            break;
                        case JBC_iinc:
                            {
                                // skip increment
                                bytecodes.getWideIncrement();
                                if (doDFS)
                                    ltypes[index] = IntTypeCode;
                            }
                            break;
                        case JBC_ret:
                            if (doDFS)
                                ltypes[index] = VoidTypeCode;
                            if (retaddr[index] != -1) {
                                bytecodes.reset(retaddr[index]);
                                retaddr[index] = -1;
                            } else {
                                // now we hit ret, return out
                                return false;
                            }
                            break;
                        default:
                            if (VM.VerifyAssertions)
                                VM._assert(VM.NOT_REACHED);
                            break;
                    }
                    break;
                }
            case JBC_multianewarray:
                {
                    // skip type reference
                    bytecodes.getTypeReference();
                    int dims = bytecodes.getArrayDimension();
                    S.pop(dims);
                    S.push(ArrayTypeCode);
                }
                break;
            case JBC_impdep1:
                {
                    int pseudo_opcode = bytecodes.nextPseudoInstruction();
                    switch(pseudo_opcode) {
                        case PSEUDO_LoadIntConst:
                            // skip value
                            bytecodes.readIntConst();
                            S.push(IntTypeCode);
                            break;
                        case PSEUDO_LoadLongConst:
                            // skip value
                            bytecodes.readLongConst();
                            S.push(VoidTypeCode);
                            S.push(LongTypeCode);
                            break;
                        case PSEUDO_LoadWordConst:
                            if (VM.BuildFor32Addr) {
                                bytecodes.readIntConst();
                            } else {
                                // skip value
                                bytecodes.readLongConst();
                            }
                            S.push(WordTypeCode);
                            break;
                        case PSEUDO_LoadFloatConst:
                            // skip value
                            bytecodes.readIntConst();
                            S.push(FloatTypeCode);
                            break;
                        case PSEUDO_LoadDoubleConst:
                            // skip value
                            bytecodes.readLongConst();
                            S.push(VoidTypeCode);
                            S.push(DoubleTypeCode);
                            break;
                        case PSEUDO_LoadRetAddrConst:
                            // remember the address for ret.
                            // get address
                            addr = bytecodes.readIntConst();
                            S.push(ReturnAddressTypeCode);
                            break;
                        case PSEUDO_InvokeStatic:
                            {
                                // get METHIDX
                                int mid = bytecodes.readIntConst();
                                RVMMethod callee = InvokeStatic.targetMethod(mid);
                                int psize = callee.getParameterWords();
                                S.pop(psize);
                                TypeReference rtype = callee.getReturnType();
                                byte tcode = rtype.getName().parseForTypeCode();
                                if (tcode == VoidTypeCode) {
                                // nothing to do with void return type
                                } else {
                                    if ((tcode == LongTypeCode) || (tcode == DoubleTypeCode)) {
                                        S.push(VoidTypeCode);
                                    }
                                    S.push(tcode);
                                }
                                break;
                            }
                        /*
        case PSEUDO_CheckCast:
          bytecodes.readIntConst(); // skip type id
          break;
*/
                        case PSEUDO_InvokeCompiledMethod:
                            // cmid
                            int cmid = bytecodes.readIntConst();
                            // skip bcindex
                            bytecodes.readIntConst();
                            RVMMethod callee = CompiledMethods.getCompiledMethod(cmid).getMethod();
                            int psize = callee.getParameterWords();
                            S.pop(psize);
                            if (!callee.isStatic()) {
                                // pop receiver
                                S.pop();
                            }
                            TypeReference rtype = callee.getReturnType();
                            byte tcode = rtype.getName().parseForTypeCode();
                            if (tcode == VoidTypeCode) {
                            // nothing to do with void return type
                            } else {
                                if ((tcode == LongTypeCode) || (tcode == DoubleTypeCode)) {
                                    S.push(VoidTypeCode);
                                }
                                S.push(tcode);
                            }
                            break;
                        case PSEUDO_ParamInitEnd:
                            break;
                        default:
                            if (VM.VerifyAssertions) {
                                VM.sysWriteln(" Error, no such pseudo code : " + pseudo_opcode);
                                VM._assert(VM.NOT_REACHED);
                            }
                            return false;
                    }
                    break;
                }
            default:
                VM.sysWriteln("Unknown bytecode : " + bcode);
                return false;
        }
    }
    /* did not found the PC. */
    return false;
}
Also used : RVMMethod(org.jikesrvm.classloader.RVMMethod) FieldReference(org.jikesrvm.classloader.FieldReference) MethodReference(org.jikesrvm.classloader.MethodReference) TypeReference(org.jikesrvm.classloader.TypeReference) RVMClass(org.jikesrvm.classloader.RVMClass)

Example 84 with RVMMethod

use of org.jikesrvm.classloader.RVMMethod in project JikesRVM by JikesRVM.

the class InterfaceMethodConflictResolver method insertStubCase.

// Generate a subtree covering from low to high inclusive.
private static void insertStubCase(Assembler asm, int[] sigIds, RVMMethod[] targets, int[] bcIndices, int low, int high) {
    int middle = (high + low) / 2;
    asm.resolveForwardReferences(bcIndices[middle]);
    if (low == middle && middle == high) {
        // a leaf case; can simply invoke the method directly.
        RVMMethod target = targets[middle];
        if (target.isStatic()) {
            // an error case...
            asm.generateJTOCjmp(target.getOffset());
        } else {
            asm.emitJMP_RegDisp(ECX, target.getOffset());
        }
    } else {
        Offset disp = ArchEntrypoints.hiddenSignatureIdField.getOffset();
        asm.emitCMP_RegDisp_Imm(THREAD_REGISTER, disp, sigIds[middle]);
        if (low < middle) {
            asm.emitJCC_Cond_Label(LT, bcIndices[(low + middle - 1) / 2]);
        }
        if (middle < high) {
            asm.emitJCC_Cond_Label(GT, bcIndices[(middle + 1 + high) / 2]);
        }
        // invoke the method for middle.
        RVMMethod target = targets[middle];
        if (target.isStatic()) {
            // an error case...
            asm.generateJTOCjmp(target.getOffset());
        } else {
            asm.emitJMP_RegDisp(ECX, target.getOffset());
        }
        // Recurse.
        if (low < middle) {
            insertStubCase(asm, sigIds, targets, bcIndices, low, middle - 1);
        }
        if (middle < high) {
            insertStubCase(asm, sigIds, targets, bcIndices, middle + 1, high);
        }
    }
}
Also used : RVMMethod(org.jikesrvm.classloader.RVMMethod) Offset(org.vmmagic.unboxed.Offset)

Example 85 with RVMMethod

use of org.jikesrvm.classloader.RVMMethod in project JikesRVM by JikesRVM.

the class TailRecursionEliminationTest method unannotatedCallsAreSubjectToOptimization.

@Test
public void unannotatedCallsAreSubjectToOptimization() throws Exception {
    Class<?>[] types = {};
    RVMMethod m = TestingTools.getNormalMethod(MethodsForTests.class, "emptyStaticMethodWithoutAnnotations", types);
    MethodOperand methOp = MethodOperand.STATIC(m);
    Instruction call = Call.create(CALL, null, null, methOp, 0);
    assertTrue(tailRecursionElimination.allowedToOptimize(call));
}
Also used : RVMMethod(org.jikesrvm.classloader.RVMMethod) Instruction(org.jikesrvm.compilers.opt.ir.Instruction) MethodOperand(org.jikesrvm.compilers.opt.ir.operand.MethodOperand) Test(org.junit.Test)

Aggregations

RVMMethod (org.jikesrvm.classloader.RVMMethod)86 RVMClass (org.jikesrvm.classloader.RVMClass)29 TypeReference (org.jikesrvm.classloader.TypeReference)17 RVMType (org.jikesrvm.classloader.RVMType)15 CompiledMethod (org.jikesrvm.compilers.common.CompiledMethod)14 MethodOperand (org.jikesrvm.compilers.opt.ir.operand.MethodOperand)13 Atom (org.jikesrvm.classloader.Atom)11 RegisterOperand (org.jikesrvm.compilers.opt.ir.operand.RegisterOperand)11 Offset (org.vmmagic.unboxed.Offset)11 Instruction (org.jikesrvm.compilers.opt.ir.Instruction)10 Operand (org.jikesrvm.compilers.opt.ir.operand.Operand)10 Address (org.vmmagic.unboxed.Address)9 MethodReference (org.jikesrvm.classloader.MethodReference)8 NormalMethod (org.jikesrvm.classloader.NormalMethod)8 BranchProfileOperand (org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand)8 IntConstantOperand (org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand)8 Method (java.lang.reflect.Method)7 ConditionOperand (org.jikesrvm.compilers.opt.ir.operand.ConditionOperand)7 TrapCodeOperand (org.jikesrvm.compilers.opt.ir.operand.TrapCodeOperand)7 OptCompiledMethod (org.jikesrvm.compilers.opt.runtimesupport.OptCompiledMethod)7