VM_Address envAddress = startUpThread.getJNIEnv().JNIEnvAddress;
VM_Address envAddress = startUpThread.getJNIEnv().getJNIenvAddress();
  public void run() //- overrides VM_Thread  {    if (VM.TraceThreads) VM_Scheduler.trace("StartupThread", "run");    // tell the JNIStartUpThread that I am ready    ready = true;    // spin wait for the JNIStartUp thread to signal it's ready    while (!proceedToFinish) {      yield();    }    // This thread is bound to the same VM_Processor as the JNIStartUpThread,    // so when we get to this point in the code, the JNIStartUpThread has     // enqueued itself on the transfer queue of its native VM_Processor and    // yielded from the current VM_Processor    // It is now safe to signal to the external pthread that the VM and the     // Java main thread are ready    // For the JNIStartUp thread, set its stack limit to 0: this effectively disable     // stack overflow checking but it's OK since this Java thread will be using     // the external pthread stack and cannot resize it anyway    startUpThread.stackLimit = VM_Address.zero();    // Don't remove the stack, save it to run the termination code     // Also remove its stack since it won't be using it anymore    // startUpThread.stack = null;       // Old way to save termination context    // save the FP and IP as offset so that we can resume execution on this stack    // in the future     // TODO: Should disable GC for the address calculation     // VM_Registers contextRegisters = startUpThread.contextRegisters;    // int fp = contextRegisters.gprs[FP];    // int compiledMethodId = VM_Magic.getCompiledMethodID(fp);    // VM_CompiledMethod     compiledMethod     = VM_ClassLoader.getCompiledMethod(compiledMethodId);    // env.terminationFPOffset = fp - VM_Magic.objectAsAddress(startUpThread.stack);    // int ip = VM_Magic.getNextInstructionAddress(fp);    // env.terminationIPOffset = ip - VM_Magic.objectAsAddress(compiledMethod.getInstructions());    // New way to save termination context    VM_JNIEnvironment env = startUpThread.getJNIEnv();    env.savedContextForTermination = startUpThread.contextRegisters;    startUpThread.contextRegisters = new VM_Registers();        //     if (trace)    // 	 System.out.println("JNICreateVMFinishThread: fp = " + VM.intAsHexString(fp) + ", offset = " +    // 			    env.terminationFPOffset + ", ip = " + VM.intAsHexString(ip) + ", offset = " +    // 			    env.terminationIPOffset);        // fill in the JNIEnv address for the external pthread with the address of the     // pointer to the JNI function table    VM_Address envAddress = startUpThread.getJNIEnv().JNIEnvAddress;    if (trace)      System.out.println("JNICreateVMFinishThread: env " + VM.intAsHexString(envAddress.toInt()) +			 " to external address " + VM.intAsHexString(externalEnvAddress.toInt()));    VM_Magic.setMemoryAddress(externalEnvAddress, envAddress);    if (trace)      System.out.println("JNICreateVMFinishThread: done, exiting");    // we've done our job, exit ourselves    //    if (VM.TraceThreads) VM_Scheduler.trace("StartupThread", "terminating");  }