public void run() {
public void run() throws VM_PragmaLogicallyUninterruptible  {
  public void run() {    int mypid;   // id of processor thread is running on - constant for the duration    // of each collection - actually should always be id of associated processor        //  make sure Opt compiler does not compile this method    //  references stored in registers by the opt compiler will not be relocated by GC    VM_Magic.pragmaNoOptCompile();        while (true) {            // suspend this thread: it will resume when scheduled by VM_Handshake       // initiateCollection().  while suspended, collector threads reside on      // the schedulers collectorQueue      //      VM_Scheduler.collectorMutex.lock();      VM_Thread.getCurrentThread().yield(VM_Scheduler.collectorQueue,					 VM_Scheduler.collectorMutex);            // block mutators from running on the current processor      VM_Processor.getCurrentProcessor().disableThreadSwitching();            if (trace) VM_Scheduler.trace("VM_CollectorThread", "waking up");      // record time it took to stop mutators on this processor and get this      // collector thread dispatched      //      if (MEASURE_WAIT_TIMES) stoppingTime = VM_Time.now() - gcBarrier.rendezvousStartTime;            gcOrdinal = VM_Synchronization.fetchAndAdd(participantCount, 0, 1) + 1;            if (trace)	VM_Scheduler.trace("VM_CollectorThread", "entering first rendezvous - gcOrdinal =",			 gcOrdinal);      // the first RVM VP will wait for all the native VPs not blocked in native      // to reach a SIGWAIT state      //      if( gcOrdinal == 1) {        if (debug_native) VM_Scheduler.trace("VM_CollectorThread", "quiescing native VPs");        for (int i = 1; i <= VM_Processor.numberNativeProcessors; i++) {	  if (debug_native) VM_Scheduler.trace("VM_CollectorThread", "doing a nativeVP");          if ( VM_Processor.vpStatus[VM_Processor.nativeProcessors[i].vpStatusIndex] !=	       VM_Processor.BLOCKED_IN_NATIVE) {	    if (debug_native) VM_Scheduler.trace("VM_CollectorThread", "found one not blocked in native");						    while ( VM_Processor.vpStatus[VM_Processor.nativeProcessors[i].vpStatusIndex] !=		    VM_Processor.IN_SIGWAIT) {	      if (debug_native) {		VM_Scheduler.trace("VM_CollectorThread", "WAITING FOR NATIVE PROCESSOR", i);		VM_Scheduler.trace("VM_CollectorThread", "vpstatus =",				   VM_Processor.vpStatus[VM_Processor.nativeProcessors[i].vpStatusIndex]);	      }	      VM.sysVirtualProcessorYield();	    }	    // Note: threads contextRegisters (ip & fp) are set by thread before	    // entering SIGWAIT, so nothing needs to be done here	  }	  else {	    // BLOCKED_IN_NATIVE - set context regs so that scan of threads stack	    // will start at the java to C transition frame. ip is not used for	    // these frames, so can be set to 0.	    //	    VM_Thread t = VM_Processor.nativeProcessors[i].activeThread;	    //	    t.contextRegisters.gprs[FRAME_POINTER] = t.jniEnv.JNITopJavaFP;	    t.contextRegisters.setInnermost( VM_Address.zero() /*ip*/, t.jniEnv.JNITopJavaFP );	  }        }	// quiesce any attached processors, blocking then IN_NATIVE or IN_SIGWAIT	//	quiesceAttachedProcessors();      }  // gcOrdinal==1      // wait for other collector threads to arrive or be made non-participants      gcBarrier.startupRendezvous();      // record time it took for running collector thread to start GC      //      if (MEASURE_WAIT_TIMES) startingTime = VM_Time.now() - gcBarrier.rendezvousStartTime;      // MOVE THIS INTO collect      //      // setup common workqueue for num VPs participating, used to be called once.      // now count varies for each GC, so call for each GC      if ( gcOrdinal == 1 )	VM_GCWorkQueue.workQueue.initialSetup(participantCount[0]);          if (trace) VM_Scheduler.trace("VM_CollectorThread", "starting collection");      if (getThis().isActive) {	VM_Allocator.collect();     // gc      }      if (trace) VM_Scheduler.trace("VM_CollectorThread", "finished collection");            // wait for other collector threads to arrive here      rendezvousWaitTime += gcBarrier.rendezvous(MEASURE_RENDEZVOUS_TIMES);              // Wake up mutators waiting for this gc cycle and create new collection      // handshake object to be used for next gc cycle.      // Note that mutators will not run until after thread switching is enabled,      // so no mutators can possibly arrive at old handshake object: it's safe to      // replace it with a new one.      //      if ( gcOrdinal == 1 ) {	// Snip reference to any methods that are still marked obsolete after	// we've done stack scans. This allows reclaiming them on next GC.	VM_CompiledMethods.snipObsoleteCompiledMethods();	collectionCount += 1;	// notify mutators waiting on previous handshake object - actually we	// don't notify anymore, mutators are simply in processor ready queues	// waiting to be dispatched.	collect.notifyCompletion();	collect =  new VM_Handshake();  // replace handshake with new one for next collection	// schedule the FinalizerThread, if there is work to do & it is idle	// THIS NOW HAPPENS DURING GC - SWITCH TO DOING IT HERE 	// VM_Finalizer.schedule();      }             // wait for other collector threads to arrive here      rendezvousWaitTime += gcBarrier.rendezvous(MEASURE_RENDEZVOUS_TIMES);        if (MEASURE_RENDEZVOUS_TIMES) {	  gcBarrier.rendezvous(false);  	  // need extra barrier call to let all processors set prev rendezvouz time	  if (VM_Processor.getCurrentProcessorId() == 1)	      gcBarrier.printRendezvousTimes();      }            // final cleanup for initial collector thread      if (gcOrdinal == 1) {	// unblock any native processors executing in native that were blocked	// in native at the start of GC	//	for (int i = 1; i <= VM_Processor.numberNativeProcessors; i++) {	  VM_Processor vp = VM_Processor.nativeProcessors[i];	  if (VM.VerifyAssertions) VM.assert(vp != null);	  if ( VM_Processor.vpStatus[vp.vpStatusIndex] == VM_Processor.BLOCKED_IN_NATIVE ) {	    VM_Processor.vpStatus[vp.vpStatusIndex] = VM_Processor.IN_NATIVE;	    if (debug_native)	      VM_Scheduler.trace("VM_CollectorThread:", "unblocking Native Processor", vp.id);	  }	}	// It is VERY unlikely, but possible that some RVM processors were	// found in C, and were BLOCKED_IN_NATIVE, during the collection, and now	// need to be unblocked.	//	for (int i = 1; i <= VM_Scheduler.numProcessors; i++) {	  VM_Processor vp = VM_Scheduler.processors[i];	  if (VM.VerifyAssertions) VM.assert(vp != null);	  if ( VM_Processor.vpStatus[vp.vpStatusIndex] == VM_Processor.BLOCKED_IN_NATIVE ) {	    VM_Processor.vpStatus[vp.vpStatusIndex] = VM_Processor.IN_NATIVE;	    if (debug_native)	      VM_Scheduler.trace("VM_CollectorThread:", "unblocking RVM Processor", vp.id);	  }	}	if ( !VM.BuildForSingleVirtualProcessor ) {	  // if NativeDaemonProcessor was BLOCKED_IN_SIGWAIT, unblock it	  //	  VM_Processor ndvp = VM_Scheduler.processors[VM_Scheduler.nativeDPndx];	  if ( ndvp!=null && VM_Processor.vpStatus[ndvp.vpStatusIndex] == VM_Processor.BLOCKED_IN_SIGWAIT ) {	    VM_Processor.vpStatus[ndvp.vpStatusIndex] = VM_Processor.IN_SIGWAIT;	    if (debug_native)	      VM_Scheduler.trace("VM_CollectorThread:", "unblocking Native Daemon Processor");	  }	  // resume any attached Processors blocked prior to Collection	  //	  resumeAttachedProcessors();	}	VM_Magic.setIntAtOffset(VM_BootRecord.the_boot_record, VM_Entrypoints.lockoutProcessorField.getOffset(), 0); // clear the GC flag      }