INSTRUCTION[] instructions = VM_Entrypoints.threadStartoffMethod.getMostRecentlyGeneratedInstructions();
INSTRUCTION[] instructions = VM_Entrypoints.threadStartoffMethod.getCurrentInstructions();
  protected final void makeDaemon (boolean on) {    if (isDaemon == on) return;    isDaemon = on;    if (!isAlive) return;     VM_Scheduler.threadCreationMutex.lock();    VM_Scheduler.numDaemons += on ? 1 : -1;    VM_Scheduler.threadCreationMutex.unlock();    if (VM_Scheduler.numDaemons == VM_Scheduler.numActiveThreads) {      if (VM.TraceThreads) VM_Scheduler.trace("VM_Thread", 					      "last non Daemon demonized");      VM.sysExit(0);      if (VM.VerifyAssertions) VM.assert(VM.NOT_REACHED);    }  }    /**   * Create a thread.   * @param stack stack in which to execute the thread   * !!TODO: VM_Scheduler.deadQueue() has a bunch of dead threads that we should   *         recycle from, before new'ing.   */   VM_Thread (int[] stack) {    this.stack = stack;    chosenProcessorId = (VM.runningVM ? VM_Processor.getCurrentProcessorId() : 0); // for load balancing    suspendLock = new VM_ProcessorLock();    contextRegisters           = new VM_Registers();    hardwareExceptionRegisters = new VM_Registers();    // RCGC related field initialization    if (VM.BuildForConcurrentGC) {	stackBufferNeedScan = true;	stackBufferSame = false;	stackBufferCurrent = 0;	stackBuffer = new int[MAX_STACKBUFFER_COUNT];	stackBufferTop = new int[MAX_STACKBUFFER_COUNT];	stackBufferMax = new int[MAX_STACKBUFFER_COUNT];    }        // put self in list of threads known to scheduler and garbage collector    // !!TODO: need growable array here    // !!TODO: must recycle thread ids    //    if (!VM.runningVM) { // create primordial thread (in boot image)      VM_Scheduler.threads[threadSlot =         VM_Scheduler.PRIMORDIAL_THREAD_INDEX] = this;       // note that VM_Scheduler.threadAllocationIndex (search hint)       // is out of date      VM_Scheduler.numActiveThreads += 1;      return;    }    // create a normal (ie. non-primordial) thread    //    //VM_Scheduler.trace("VM_Thread", "create");          stackLimit = VM_Magic.objectAsAddress(stack).add(STACK_SIZE_GUARD);    // get instructions for method to be executed as thread startoff    //    INSTRUCTION[] instructions = VM_Entrypoints.threadStartoffMethod.getMostRecentlyGeneratedInstructions();    VM.disableGC();    // initialize thread registers    //    VM_Address ip = VM_Magic.objectAsAddress(instructions);    VM_Address sp = VM_Magic.objectAsAddress(stack).add(stack.length << 2);    VM_Address fp = VM_Address.fromInt(STACKFRAME_SENTINAL_FP);//-#if RVM_FOR_IA32     // initialize thread stack as if "startoff" method had been called    // by an empty baseline-compiled "sentinal" frame with one local variable    //    sp = sp.sub(STACKFRAME_HEADER_SIZE);                   // last word of header    fp = sp.sub(VM_BaselineConstants.WORDSIZE + STACKFRAME_BODY_OFFSET);      VM_Magic.setCallerFramePointer(fp, VM_Address.fromInt(STACKFRAME_SENTINAL_FP));    VM_Magic.setCompiledMethodID(fp, INVISIBLE_METHOD_ID);    sp = sp.sub(VM_BaselineConstants.WORDSIZE);                                 // allow for one local    contextRegisters.gprs[ESP] = sp.toInt();    contextRegisters.gprs[VM_BaselineConstants.JTOC] = VM_Magic.objectAsAddress(VM_Magic.getJTOC()).toInt();    contextRegisters.fp  = fp;    contextRegisters.ip  = ip;//-#else    // initialize thread stack as if "startoff" method had been called    // by an empty "sentinal" frame  (with a single argument ???)    //    sp = sp.sub(4); VM_Magic.setMemoryWord(sp, ip.toInt());          // STACKFRAME_NEXT_INSTRUCTION_OFFSET    sp = sp.sub(4); VM_Magic.setMemoryWord(sp, INVISIBLE_METHOD_ID); // STACKFRAME_METHOD_ID_OFFSET    sp = sp.sub(4); VM_Magic.setMemoryWord(sp, fp.toInt());          // STACKFRAME_FRAME_POINTER_OFFSET    fp = sp;    contextRegisters.gprs[FRAME_POINTER]  = fp.toInt();    contextRegisters.ip  = ip;//-#endif    VM_Scheduler.threadCreationMutex.lock();    assignThreadSlot();    if (VM.BuildForConcurrentGC) { // RCGC - currently assign a       // thread to a processor - no migration yet      if (VM_Scheduler.allProcessorsInitialized) {	//-#if RVM_WITH_CONCURRENT_GC         //// because VM_RCCollectorThread only available for concurrent         //memory managers	if (VM_RCCollectorThread.GC_ALL_TOGETHER &&             VM_Scheduler.numProcessors > 1) {	  // assign new threads to first N-1 processors, reserve last for gc	  processorAffinity = VM_Scheduler.            processors[(threadSlot % (VM_Scheduler.numProcessors-1)) + 1];	} else {	  processorAffinity = VM_Scheduler.processors            [(threadSlot % VM_Scheduler.numProcessors) + 1];	}	//-#endif      }    }    VM_Scheduler.threadCreationMutex.unlock();//-#if RVM_FOR_IA32 //-#else    contextRegisters.gprs[THREAD_ID_REGISTER] = getLockingId();//-#endif    VM.enableGC();    // only do this at runtime because it will call VM_Magic    // The first thread which does not have this field initialized will die    // so it does not need it    // threadSlot determines which jni function pointer is passed to native C    if (VM.runningVM)         jniEnv = new VM_JNIEnvironment(threadSlot);  }