if (VM.VerifyAssertions) VM.assert(lockCount == 0);
if (VM.VerifyAssertions) VM._assert(lockCount == 0);
  void dispatch () {    if (VM.VerifyAssertions) VM.assert(lockCount == 0);// no processor locks should be held across a thread switch    if (VM.BuildForEventLogging && VM.EventLoggingEnabled) VM_EventLogger.logDispatchEvent();    VM_Thread newThread = getRunnableThread();    while (newThread.suspendPending) {      newThread.suspendLock.lock();      newThread.suspended = true;      newThread.suspendLock.unlock();      newThread = getRunnableThread();    }    previousThread = activeThread;    activeThread   = newThread;    activeThreadStackLimit = newThread.stackLimit;    //-#if RVM_FOR_IA32    threadId       = newThread.getLockingId();    //-#endif    if (!previousThread.isDaemon &&         idleProcessor != null && !readyQueue.isEmpty()         && getCurrentProcessor().processorMode != NATIVEDAEMON) {       // if we've got too much work, transfer some of it to another       // processor that has nothing to do      // don't schedule when switching away from a daemon thread...      // kludge to avoid thrashing when VM is underloaded with real threads.      VM_Thread t = readyQueue.dequeue();      if (trace) VM_Scheduler.trace("VM_Processor", "dispatch: offload ", t.getIndex());      scheduleThread(t);    }    if (VM.BuildForConcurrentGC) newThread.stackBufferNeedScan = true;    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    }    // (sets "previousThread.beingDispatched = false")    VM_Magic.threadSwitch(previousThread, newThread.contextRegisters);  }