public static VM_Address unwindNativeStackFrame(VM_Address currfp) throws VM_PragmaUninterruptible { VM_Address ip, callee_fp; VM_Address fp = VM_Magic.getCallerFramePointer(currfp);  do { callee_fp = fp; ip = VM_Magic.getReturnAddress(fp); fp = VM_Magic.getCallerFramePointer(fp); } while ( !VM_Heap.refInAnyHeap(ip) && fp.toInt() != STACKFRAME_SENTINAL_FP); return callee_fp; }   private static void unwindInvisibleStackFrame(VM_Registers registers) { registers.unwindStackFrame(); }
  private static void deliverException(Throwable exceptionObject, 				       VM_Registers exceptionRegisters) {    //-#if RVM_FOR_IA32    VM_Magic.clearFloatingPointState();    //-#endif        // walk stack and look for a catch block    //    VM_Type exceptionType = VM_Magic.getObjectType(exceptionObject);    VM_Address fp = exceptionRegisters.getInnermostFramePointer();    while (VM_Magic.getCallerFramePointer(fp).NE(VM_Address.fromInt(STACKFRAME_SENTINAL_FP))) {      int compiledMethodId = VM_Magic.getCompiledMethodID(fp);      if (compiledMethodId != INVISIBLE_METHOD_ID) { 	  VM_CompiledMethod compiledMethod = VM_CompiledMethods.getCompiledMethod(compiledMethodId);	  VM_ExceptionDeliverer exceptionDeliverer = compiledMethod.getExceptionDeliverer();	  VM_Address ip = exceptionRegisters.getInnermostInstructionAddress();	  VM_Address methodStartAddress = VM_Magic.objectAsAddress(compiledMethod.getInstructions());	  int catchBlockOffset = compiledMethod.findCatchBlockForInstruction(ip.diff(methodStartAddress), exceptionType);	  if (catchBlockOffset >= 0) { 	      // found an appropriate catch block	      exceptionDeliverer.deliverException(compiledMethod, 						  methodStartAddress.add(catchBlockOffset), 						  exceptionObject, 						  exceptionRegisters);	      if (VM.VerifyAssertions) VM.assert(NOT_REACHED);	  }	  	  exceptionDeliverer.unwindStackFrame(compiledMethod, exceptionRegisters);      } else {	  unwindInvisibleStackFrame(exceptionRegisters);      }      fp = exceptionRegisters.getInnermostFramePointer();    }    // no appropriate catch block found    //    VM.enableGC();    exceptionObject.printStackTrace();    VM_Thread.terminate();    if (VM.VerifyAssertions) VM.assert(NOT_REACHED);  }  /**   * The current frame is expected to be one of the JNI functions    * called from C,    * below which is one or more native stack frames   * Skip over all frames below with saved code pointers outside of heap    * (C frames),    * stopping at the native frame immediately preceding the glue frame which    * contains   * the method ID of the native method    * (this is necessary to allow retrieving the    * return address of the glue frame)   * Ton Ngo 7/30/01   */  public static VM_Address unwindNativeStackFrame(VM_Address currfp) throws VM_PragmaUninterruptible {    VM_Address ip, callee_fp;    VM_Address fp = VM_Magic.getCallerFramePointer(currfp);    do {      callee_fp = fp;      ip = VM_Magic.getReturnAddress(fp);      fp = VM_Magic.getCallerFramePointer(fp);    } while ( !VM_Heap.refInAnyHeap(ip) && fp.toInt() != STACKFRAME_SENTINAL_FP);    return callee_fp;  }  /**   * Unwind stack frame for an <invisible method>.   * See also: VM_ExceptionDeliverer.unwindStackFrame()   *    * !!TODO: Could be a reflective method invoker frame.   *        Does it clobber any non-volatiles?   *        If so, how do we restore them?   * (I don't think our current implementations of reflective method   *  invokers save/restore any nonvolatiles, so we're probably ok.    *  --dave 6/29/01   */  private static void unwindInvisibleStackFrame(VM_Registers registers) {    registers.unwindStackFrame();  }