asm.emitCALL_RegDisp(JTOC, VM_Entrypoints.invokeNativeFunctionInstructionsField.getOffsetAsInt());
asm.emitCALL_RegDisp(JTOC, VM_Entrypoints.invokeNativeFunctionInstructionsField.getOffset());
  public static synchronized VM_CompiledMethod compile (VM_NativeMethod method) {    VM_JNICompiledMethod cm = (VM_JNICompiledMethod)VM_CompiledMethods.createCompiledMethod(method, VM_CompiledMethod.JNI);    VM_Assembler asm     = new VM_Assembler(100);   // some size for the instruction array    Address nativeIP         = method.getNativeIP();    // recompute some constants    int parameterWords   = method.getParameterWords();    // Meaning of constant offset into frame:    // STACKFRAME_HEADER_SIZE =  12              (CHECK ??)    // SAVED_GPRS = 4 words/registers    // Stack frame:    //        on entry          after prolog    //    //      high address        high address    //      |          |        |          | Caller frame    //      |          |        |          |    // +    |arg 0     |        |arg 0     |    -> firstParameterOffset    // +    |arg 1     |        |arg 1     |    // +    |...       |        |...       |    // +8   |arg n-1   |        |arg n-1   |        // +4   |returnAddr|        |returnAddr|    //  0   +          +        +saved FP  + <---- FP for glue frame    // -4   |          |        |methodID  |    // -8   |          |        |saved EDI |    -> STACKFRAME_BODY_OFFSET = -8    // -C   |          |        |saved EBX |    // -10  |          |        |saved EBP |    // -14  |          |        |returnAddr|  (return from OutOfLine to generated epilog)        // -18  |          |        |saved ENV |  (VM_JNIEnvironment)    // -1C  |          |        |arg n-1   |  reordered args to native method    // -20  |          |        | ...      |  ...    // -24  |          |        |arg 1     |  ...    // -28  |          |        |arg 0     |  ...    // -2C  |          |        |class/obj |  required second arg to native method    // -30  |          |        |jniEnv    |  required first arg to native method    // -34  |          |        |          |        //      |          |        |          |        //      |          |        |          |        //       low address         low address    // TODO:  check and resize stack once on the lowest Java to C transition    // on the stack.  Not needed if we use the thread original stack    // Fill in frame header - similar to normal prolog    prepareStackHeader(asm, method, cm.getId());    // Process the arguments - specific to method being called    storeParametersForLintel(asm, method);        // load address of native code to invoke into S0    asm.emitMOV_Reg_Imm (S0, nativeIP.toInt());      // branch to outofline code in bootimage    asm.emitCALL_RegDisp(JTOC, VM_Entrypoints.invokeNativeFunctionInstructionsField.getOffsetAsInt());    // return here from VM_OutOfLineMachineCode upon return from native code    // PR and RVM JTOC restored, T0,T1 contain return from native call    // If the return type is reference, look up the real value in the JNIref array     // S0 <- threads' VM_JNIEnvironment    VM_ProcessorLocalState.emitMoveFieldToReg(asm, S0,                                              VM_Entrypoints.activeThreadField.getOffsetAsInt());    asm.emitMOV_Reg_RegDisp (S0, S0, VM_Entrypoints.jniEnvField.getOffsetAsInt());    if (method.getReturnType().isReferenceType()) {        // XXX TODO: This code is broken. It only handles Local references.      asm.emitADD_Reg_RegDisp(T0, S0, VM_Entrypoints.JNIRefsField.getOffsetAsInt());      // T0 <- address of entry (not index)      asm.emitMOV_Reg_RegInd (T0, T0);   // get the reference    } else if (method.getReturnType().isLongType()) {      asm.emitPUSH_Reg(T1);    // need to use T1 in popJNIrefForEpilog and to swap order T0-T1      }    // pop frame in JNIRefs array (assumes S0 holds VM_JNIEnvironment)    popJNIrefForEpilog(asm);                                        // then swap order of T0 and T1 for long    if (method.getReturnType().isLongType()) {      asm.emitMOV_Reg_Reg(T1, T0);        asm.emitPOP_Reg(T0);    }    // CHECK EXCEPTION AND BRANCH TO ATHROW CODE OR RETURN NORMALLY    // get pending exception from JNIEnv    asm.emitMOV_Reg_RegDisp (EBX, S0, VM_Entrypoints.JNIPendingExceptionField.getOffsetAsInt());  // EBX <- JNIPendingException    asm.emitMOV_RegDisp_Imm (S0, VM_Entrypoints.JNIPendingExceptionField.getOffsetAsInt(), 0);    // clear the current pending exception    asm.emitCMP_Reg_Imm(EBX, 0);   // check for exception pending:  JNIPendingException = non zero    VM_ForwardReference fr = asm.forwardJcc(asm.EQ);            // Br if yes    // if pending exception, discard the return value and current stack frame    // then jump to athrow     asm.emitMOV_Reg_Reg     (T0, EBX);    asm.emitMOV_Reg_RegDisp (T1, JTOC, VM_Entrypoints.athrowMethod.getOffsetAsInt()); // acquire jump addr before restoring nonvolatiles    asm.emitMOV_Reg_Reg     (SP, EBP);                     // discard current stack frame    asm.emitMOV_Reg_RegDisp (JTOC, SP, EDI_SAVE_OFFSET);   // restore nonvolatile EDI register    asm.emitMOV_Reg_RegDisp (EBX, SP, EBX_SAVE_OFFSET);    // restore nonvolatile EBX register    asm.emitMOV_Reg_RegDisp (EBP, SP, EBP_SAVE_OFFSET);    // restore nonvolatile EBP register    asm.emitPOP_RegDisp     (PR, VM_Entrypoints.framePointerField.getOffsetAsInt());    // don't use CALL since it will push on the stack frame the return address to here     asm.emitJMP_Reg(T1); // jumps to VM_Runtime.athrow    fr.resolve(asm);  // branch to here if no exception     // no exception, proceed to return to caller        asm.emitMOV_Reg_Reg(SP, EBP);                           // discard current stack frame    asm.emitMOV_Reg_RegDisp (JTOC, SP, EDI_SAVE_OFFSET);   // restore nonvolatile EDI register    asm.emitMOV_Reg_RegDisp (EBX, SP, EBX_SAVE_OFFSET);    // restore nonvolatile EBX register    asm.emitMOV_Reg_RegDisp (EBP, SP, EBP_SAVE_OFFSET);    // restore nonvolatile EBP register    asm.emitPOP_RegDisp     (PR, VM_Entrypoints.framePointerField.getOffsetAsInt());    // return to caller     // pop parameters from stack (Note that parameterWords does not include "this")    if (method.isStatic())      asm.emitRET_Imm(parameterWords << LG_WORDSIZE);     else      asm.emitRET_Imm((parameterWords+1) << LG_WORDSIZE);     VM_MachineCode machineCode = new VM_MachineCode(asm.getMachineCodes(), null);    cm.compileComplete(machineCode.getInstructions());    return cm;  }