if (VM.VerifyAssertions) VM_Scheduler.assert(VM.NOT_REACHED);
if (VM.VerifyAssertions) VM.assert(VM.NOT_REACHED);
  void dispatch () {    if (VM.BuildForEventLogging && VM.EventLoggingEnabled)       VM_EventLogger.logDispatchEvent();    // no processor locks should be held across a thread switch    //    if (VM.VerifyAssertions) VM_Scheduler.assert(lockCount == 0);    VM_Thread newThread = getRunnableThread();    while (newThread.suspendPending) {      newThread.suspendLock.lock();      newThread.suspended = true;      newThread.suspendLock.unlock();      newThread = getRunnableThread();    }           // if we've got too much work, transfer some of it to another     // processor that has nothing to do    if (VM_Processor.idleProcessor != null && !readyQueue.isEmpty()		&& VM_Processor.getCurrentProcessor().processorMode                 != NATIVEDAEMON ) {      VM_Thread t = readyQueue.dequeue();      if (trace)         VM_Scheduler.trace("VM_Processor", "dispatch: offload ", t.getIndex());      scheduleThread(t);    }    if (VM.BuildForConcurrentGC)      newThread.stackBufferNeedScan = true;     // RCGC addition    previousThread = activeThread;    activeThread   = newThread;//-#if RVM_FOR_IA32    threadId       = newThread.getLockingId();//-#endif    if (VM.BuildForCpuMonitoring) {      double now = VM_Time.now();      // primordial thread: ignore first time slice      if (previousThread.cpuStartTime == -1) ;       else previousThread.cpuTotalTime += now - previousThread.cpuStartTime;      previousThread.cpuStartTime = 0;    // this thread has stopped running      newThread.cpuStartTime = now;  // this thread has started running    }    //-#if RVM_FOR_IA32    // save this threads next instruction address to be the return     // address of the call to dispatch()    // TODO!! eliminate this ugliness by unifying     // VM_Magic.saveThreadState() and VM_Magic.restoreThreadExecution    previousThread.contextRegisters.ip =       VM_Magic.getReturnAddress(VM_Magic.getFramePointer());    //-#endif    // (sets "previousThread.beingDispatched = false")    VM_Magic.resumeThreadExecution(previousThread, newThread.contextRegisters);     if (VM.VerifyAssertions) VM_Scheduler.assert(VM.NOT_REACHED);  }  //-----------------//  //  Load Balancing //  //-----------------//    /**   * non-null --> a processor that has no work to do   */  static VM_Processor idleProcessor;        /**   * id of next processor to receive load balancing   */  int                 nextTransferId = 1;     /**   * Put thread onto most lightly loaded virtual processor.   */   void scheduleThread (VM_Thread t) {    // if thread wants to stay on specified processor, put it there    if (t.processorAffinity != null) {      if (trace) VM_Scheduler.trace("VM_Processor.scheduleThread", "outgoing to specific processor:", t.getIndex());      t.processorAffinity.transferThread(t);      return;    }    if (VM.BuildForConcurrentGC) {       // currently don't move threads around - so keep on same processor      if (trace) VM_Scheduler.trace("VM_Processor.scheduleThread", " staying on same processor");      VM_Processor.getCurrentProcessor().transferThread(t);      return;    }    // if t is this thread and is the only (runable) thread on this processor, stay here    if (t == VM_Thread.getCurrentThread() && readyQueue.isEmpty() && transferQueue.isEmpty()) {      if (trace) VM_Scheduler.trace("VM_Processor.scheduleThread",  "staying on same processor:", t.getIndex());      readyQueue.enqueue(t);      return;    }    // if a processor is idle, put thread there    VM_Processor idle = idleProcessor;    if (idle != null) {      idleProcessor = null;      if (trace) VM_Scheduler.trace("VM_Processor.scheduleThread", "outgoing to idle processor:", t.getIndex());      idle.transferThread(t);      return;    }    // otherwise round robin    if (trace) VM_Scheduler.trace("VM_Processor.scheduleThread",  "outgoing to round-robin processor:", t.getIndex());    VM_Scheduler.processors[nextTransferId].transferThread(t);    if (++nextTransferId > VM_Scheduler.numProcessors)      nextTransferId = 1 ;  }