public VM_Thread (byte[] stack, Thread thread, String myName) { this.stack = stack; this.thread = thread; this.myName = myName;  chosenProcessorId = (VM.runningVM ? VM_Processor.getCurrentProcessorId() : 0); suspendLock = new VM_ProcessorLock();  contextRegisters           = new VM_Registers(); hardwareExceptionRegisters = new VM_Registers();       if (!VM.runningVM) { VM_Scheduler.threads[threadSlot = VM_Scheduler.PRIMORDIAL_THREAD_INDEX] = this;   VM_Scheduler.numActiveThreads += 1;    return; }   if ( thread == null ) thread = java.lang.JikesRVMSupport.createThread(this, myName);    if (trace) VM_Scheduler.trace("VM_Thread", "create");  stackLimit = VM_Magic.objectAsAddress(stack).plus(STACK_SIZE_GUARD);    VM_CodeArray instructions = VM_Entrypoints.threadStartoffMethod.getCurrentEntryCodeArray();  VM.disableGC();    Address ip = VM_Magic.objectAsAddress(instructions); Address sp = VM_Magic.objectAsAddress(stack).plus(stack.length); Address fp = STACKFRAME_SENTINEL_FP;       sp = sp.minus(STACKFRAME_HEADER_SIZE); fp = sp.minus(BYTES_IN_ADDRESS + STACKFRAME_BODY_OFFSET); VM_Magic.setCallerFramePointer(fp, STACKFRAME_SENTINEL_FP); VM_Magic.setCompiledMethodID(fp, INVISIBLE_METHOD_ID);  sp = sp.minus(BYTES_IN_ADDRESS); contextRegisters.gprs.set(ESP, sp); contextRegisters.gprs.set(VM_BaselineConstants.JTOC, VM_Magic.objectAsAddress(VM_Magic.getJTOC())); contextRegisters.fp  = fp; contextRegisters.ip  = ip;     int INITIAL_FRAME_SIZE = STACKFRAME_HEADER_SIZE; fp = VM_Memory.alignDown(sp.minus(INITIAL_FRAME_SIZE), STACKFRAME_ALIGNMENT); fp.plus(STACKFRAME_FRAME_POINTER_OFFSET).store(STACKFRAME_SENTINEL_FP); fp.plus(STACKFRAME_NEXT_INSTRUCTION_OFFSET).store(ip); fp.plus(STACKFRAME_METHOD_ID_OFFSET).store(INVISIBLE_METHOD_ID);  contextRegisters.gprs.set(FRAME_POINTER, fp); contextRegisters.ip  = ip;   VM_Scheduler.threadCreationMutex.lock(); assignThreadSlot();   if (VM_HardwarePerformanceMonitors.booted()) { if (hpm_counters == null) hpm_counters = new HPM_counters(); String name = getClass().toString(); assignGlobalTID(); if (VM_HardwarePerformanceMonitors.trace) { VM_HardwarePerformanceMonitors.writeThreadToHeaderFile(global_tid, threadSlot, name); }  VM_HardwarePerformanceMonitors.putThreadName(name, global_tid); }   VM_Scheduler.threadCreationMutex.unlock();  VM.enableGC();    if (VM.runningVM) jniEnv = VM_JNIEnvironment.allocateEnvironment();   onStackReplacementEvent = new OSR_OnStackReplacementEvent();
public VM_Thread () { this(null);
  public VM_Thread (byte[] stack, Thread thread, String myName) {    this.stack = stack;    this.thread = thread;    this.myName = myName;    chosenProcessorId = (VM.runningVM ? VM_Processor.getCurrentProcessorId() : 0); // for load balancing    suspendLock = new VM_ProcessorLock();    contextRegisters           = new VM_Registers();    hardwareExceptionRegisters = new VM_Registers();    // 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;            /* Don't create the Thread object for the primordial thread; we'll have         to do that later. */      return;    }        /* We're running the VM; if we weren't, we'd have to wait until boot time     * to do this. */    if ( thread == null )      thread = java.lang.JikesRVMSupport.createThread(this, myName);    // create a normal (ie. non-primordial) thread    //    if (trace) VM_Scheduler.trace("VM_Thread", "create");          stackLimit = VM_Magic.objectAsAddress(stack).plus(STACK_SIZE_GUARD);    // get instructions for method to be executed as thread startoff    //    VM_CodeArray instructions = VM_Entrypoints.threadStartoffMethod.getCurrentEntryCodeArray();    VM.disableGC();    // initialize thread registers    //    Address ip = VM_Magic.objectAsAddress(instructions);    Address sp = VM_Magic.objectAsAddress(stack).plus(stack.length);    Address fp = STACKFRAME_SENTINEL_FP;//-#if RVM_FOR_IA32     // initialize thread stack as if "startoff" method had been called    // by an empty baseline-compiled "sentinel" frame with one local variable    //    sp = sp.minus(STACKFRAME_HEADER_SIZE);                   // last word of header    fp = sp.minus(BYTES_IN_ADDRESS + STACKFRAME_BODY_OFFSET);      VM_Magic.setCallerFramePointer(fp, STACKFRAME_SENTINEL_FP);    VM_Magic.setCompiledMethodID(fp, INVISIBLE_METHOD_ID);    sp = sp.minus(BYTES_IN_ADDRESS);                                 // allow for one local    contextRegisters.gprs.set(ESP, sp);    contextRegisters.gprs.set(VM_BaselineConstants.JTOC,                              VM_Magic.objectAsAddress(VM_Magic.getJTOC()));    contextRegisters.fp  = fp;    contextRegisters.ip  = ip;//-#else    // align stack frame    int INITIAL_FRAME_SIZE = STACKFRAME_HEADER_SIZE;    fp = VM_Memory.alignDown(sp.minus(INITIAL_FRAME_SIZE), STACKFRAME_ALIGNMENT);    fp.plus(STACKFRAME_FRAME_POINTER_OFFSET).store(STACKFRAME_SENTINEL_FP);    fp.plus(STACKFRAME_NEXT_INSTRUCTION_OFFSET).store(ip); // need to fix    fp.plus(STACKFRAME_METHOD_ID_OFFSET).store(INVISIBLE_METHOD_ID);            contextRegisters.gprs.set(FRAME_POINTER, fp);    contextRegisters.ip  = ip;    //-#endif    VM_Scheduler.threadCreationMutex.lock();    assignThreadSlot();    //-#if RVM_WITH_HPM    if (VM_HardwarePerformanceMonitors.booted()) {      if (hpm_counters == null) hpm_counters = new HPM_counters();      String name = getClass().toString();      assignGlobalTID();      if (VM_HardwarePerformanceMonitors.trace) {        VM_HardwarePerformanceMonitors.writeThreadToHeaderFile(global_tid, threadSlot, name);      }      // stash away name for future use      VM_HardwarePerformanceMonitors.putThreadName(name, global_tid);    }    //-#endif    VM_Scheduler.threadCreationMutex.unlock();    VM.enableGC();    // only do this at runtime because it will call VM_Magic;    // we set this explictly for the boot thread as part of booting.    if (VM.runningVM)      jniEnv = VM_JNIEnvironment.allocateEnvironment();    //-#if RVM_WITH_OSR    onStackReplacementEvent = new OSR_OnStackReplacementEvent();    //-#endif  }