Object[] otherArgs, boolean isNonvirtual) {   VM_Method targetMethod; if (method.isStatic() || method.isObjectInitializer() || isNonvirtual) { targetMethod = method; } else { int tibIndex = method.getOffset() >>> 2; targetMethod = VM_Magic.getObjectType(thisArg).asClass().getVirtualMethods()[tibIndex - TIB_FIRST_VIRTUAL_METHOD_INDEX]; }    if (!targetMethod.isCompiled()) { synchronized (VM_ClassLoader.lock) { targetMethod.compile(); } }      VM_Type returnType = method.getReturnType(); boolean returnIsPrimitive = returnType.isPrimitiveType();    int triple     = VM_MachineReflection.countParameters(method); int gprs       = triple & REFLECTION_GPRS_MASK; int[]    GPRs  = new int[gprs]; int fprs       = (triple >> REFLECTION_GPRS_BITS) & 0x1F; double[] FPRs  = new double[fprs];  int spills     = triple >> (REFLECTION_GPRS_BITS+REFLECTION_FPRS_BITS); int spillCount = spills;  int[]   Spills = new int[spillCount];  if (firstUse) {    unwrapBoolean(wrapBoolean(0)); unwrapByte(wrapByte((byte)0)); unwrapChar(wrapChar((char)0)); unwrapShort(wrapShort((short)0)); unwrapInt(wrapInt((int)0)); unwrapLong(wrapLong((long)0)); unwrapFloat(wrapFloat((float)0)); unwrapDouble(wrapDouble((double)0)); firstUse = false; }   VM.disableGC(); VM_MachineReflection.packageParameters(method, thisArg, otherArgs, GPRs, FPRs, Spills);     INSTRUCTION[] code = targetMethod.getMostRecentlyGeneratedInstructions(); VM.enableGC();  if (!returnIsPrimitive) { return VM_Magic.invokeMethodReturningObject(code, GPRs, FPRs, Spills); }  if (returnType == VM_Type.VoidType) { VM_Magic.invokeMethodReturningVoid(code, GPRs, FPRs, Spills); return null; }  if (returnType == VM_Type.BooleanType) { int x = VM_Magic.invokeMethodReturningInt(code, GPRs, FPRs, Spills); return new Boolean(x == 1); }  if (returnType == VM_Type.ByteType) { int x = VM_Magic.invokeMethodReturningInt(code, GPRs, FPRs, Spills); return new Byte((byte)x); }  if (returnType == VM_Type.ShortType) { int x = VM_Magic.invokeMethodReturningInt(code, GPRs, FPRs, Spills); return new Short((short)x); }  if (returnType == VM_Type.CharType) { int x = VM_Magic.invokeMethodReturningInt(code, GPRs, FPRs, Spills); return new Character((char)x); }  if (returnType == VM_Type.IntType) { int x = VM_Magic.invokeMethodReturningInt(code, GPRs, FPRs, Spills); return new Integer(x); }  if (returnType == VM_Type.LongType) { long x = VM_Magic.invokeMethodReturningLong(code, GPRs, FPRs, Spills); return new Long(x); }  if (returnType == VM_Type.FloatType) { float x = VM_Magic.invokeMethodReturningFloat(code, GPRs, FPRs, Spills); return new Float(x); }  if (returnType == VM_Type.DoubleType) { double x = VM_Magic.invokeMethodReturningDouble(code, GPRs, FPRs, Spills); return new Double(x); }  if (VM.VerifyAssertions) VM.assert(NOT_REACHED); return null;
Object[] otherArgs) { return invoke(method, thisArg, otherArgs, false);
  public static Object invoke(VM_Method method, Object thisArg,                               Object[] otherArgs, boolean isNonvirtual) {    // choose actual method to be called    //    VM_Method targetMethod;    if (method.isStatic() || method.isObjectInitializer() || isNonvirtual) {      targetMethod = method;    } else {      int tibIndex = method.getOffset() >>> 2;      targetMethod = VM_Magic.getObjectType(thisArg).asClass().getVirtualMethods()[tibIndex - TIB_FIRST_VIRTUAL_METHOD_INDEX];    }            // make sure it's been compiled    //    if (!targetMethod.isCompiled()) {      synchronized (VM_ClassLoader.lock) {	targetMethod.compile();      }    }            // remember return type    // Determine primitive type-ness early to avoid call (possible yield)     // later while refs are possibly being held in int arrays.    //    VM_Type returnType = method.getReturnType();    boolean returnIsPrimitive = returnType.isPrimitiveType();           // decide how to pass parameters    //    int triple     = VM_MachineReflection.countParameters(method);    int gprs       = triple & REFLECTION_GPRS_MASK;    int[]    GPRs  = new int[gprs];    int fprs       = (triple >> REFLECTION_GPRS_BITS) & 0x1F;    double[] FPRs  = new double[fprs];    int spills     = triple >> (REFLECTION_GPRS_BITS+REFLECTION_FPRS_BITS);    int spillCount = spills;         int[]   Spills = new int[spillCount];    if (firstUse) {       // force dynamic link sites in unwrappers to get resolved,       // before disabling gc.      // this is a bit silly, but I can't think of another way to do it [--DL]      unwrapBoolean(wrapBoolean(0));      unwrapByte(wrapByte((byte)0));      unwrapChar(wrapChar((char)0));      unwrapShort(wrapShort((short)0));      unwrapInt(wrapInt((int)0));      unwrapLong(wrapLong((long)0));      unwrapFloat(wrapFloat((float)0));      unwrapDouble(wrapDouble((double)0));      firstUse = false;    }    // now for real...    VM.disableGC();    VM_MachineReflection.packageParameters(method, thisArg, otherArgs, GPRs,                                            FPRs, Spills);    // We want to make sure that GC does not happen between getting code and    // invoking it. If it's not on a stack during GC, it can be marked    // obsolete and reclaimed.    INSTRUCTION[] code = targetMethod.getMostRecentlyGeneratedInstructions();    VM.enableGC();         if (!returnIsPrimitive) {      return VM_Magic.invokeMethodReturningObject(code, GPRs, FPRs, Spills);    }    if (returnType == VM_Type.VoidType) {      VM_Magic.invokeMethodReturningVoid(code, GPRs, FPRs, Spills);      return null;    }    if (returnType == VM_Type.BooleanType) {      int x = VM_Magic.invokeMethodReturningInt(code, GPRs, FPRs, Spills);      return new Boolean(x == 1);    }    if (returnType == VM_Type.ByteType) {      int x = VM_Magic.invokeMethodReturningInt(code, GPRs, FPRs, Spills);      return new Byte((byte)x);    }    if (returnType == VM_Type.ShortType) {      int x = VM_Magic.invokeMethodReturningInt(code, GPRs, FPRs, Spills);      return new Short((short)x);    }    if (returnType == VM_Type.CharType) {      int x = VM_Magic.invokeMethodReturningInt(code, GPRs, FPRs, Spills);      return new Character((char)x);    }    if (returnType == VM_Type.IntType) {      int x = VM_Magic.invokeMethodReturningInt(code, GPRs, FPRs, Spills);      return new Integer(x);    }    if (returnType == VM_Type.LongType) {      long x = VM_Magic.invokeMethodReturningLong(code, GPRs, FPRs, Spills);      return new Long(x);    }    if (returnType == VM_Type.FloatType) {      float x = VM_Magic.invokeMethodReturningFloat(code, GPRs, FPRs, Spills);      return new Float(x);    }            if (returnType == VM_Type.DoubleType) {      double x = VM_Magic.invokeMethodReturningDouble(code, GPRs, FPRs, Spills);      return new Double(x);    }    if (VM.VerifyAssertions) VM.assert(NOT_REACHED);    return null;  }