@Uninterruptible public static Address unwindNativeStackFrame(Address currfp){
  if (VM.BuildForIA32) {
    return currfp;
  }
  Address callee_fp;
  Address fp=Magic.getCallerFramePointer(currfp);
  Address ip;
  do {
    callee_fp=fp;
    ip=Magic.getReturnAddressUnchecked(fp);
    fp=Magic.getCallerFramePointer(fp);
  }
 while (!MemoryManager.addressInVM(ip) && fp.NE(StackFrameLayout.getStackFrameSentinelFP()));
  if (VM.BuildForPowerPC) {
    return fp;
  }
 else {
    return callee_fp;
  }
}

@ Uninterruptible public static Address unwindNativeStackFrame ( Address currfp ) { if ( VM . BuildForIA32 ) { return currfp ; } Address callee_fp ; Address fp = Magic . getCallerFramePointer ( currfp ) ; Address ip ; do { callee_fp = fp ; ip = Magic . getReturnAddressUnchecked ( fp ) ; fp = Magic . getCallerFramePointer ( fp ) ; } while ( ! MemoryManager . addressInVM ( ip ) && fp . NE ( StackFrameLayout . getStackFrameSentinelFP ( ) ) ) ; if ( VM . BuildForPowerPC ) { return fp ; } else { return callee_fp ; } }
skip over all frames below currfp 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 ) .
