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();
}
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);
}
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;
}
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);
}
}
}
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));
}
Aggregations