-
Notifications
You must be signed in to change notification settings - Fork 84
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Perry Cheng
committed
Oct 13, 2002
1 parent
b745280
commit 8a1de24
Showing
251 changed files
with
18,603 additions
and
1,492 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,323 @@ | ||
/* | ||
* (C) Copyright Department of Computer Science, | ||
* Australian National University. 2002 | ||
* All rights reserved. | ||
*/ | ||
|
||
package com.ibm.JikesRVM.memoryManagers.JMTk; | ||
|
||
import com.ibm.JikesRVM.memoryManagers.vmInterface.VM_Interface; | ||
import com.ibm.JikesRVM.memoryManagers.vmInterface.VM_CollectorThread; | ||
import com.ibm.JikesRVM.memoryManagers.vmInterface.Constants; | ||
import com.ibm.JikesRVM.memoryManagers.vmInterface.AddressSet; | ||
import com.ibm.JikesRVM.memoryManagers.vmInterface.AddressPairSet; | ||
import com.ibm.JikesRVM.memoryManagers.vmInterface.AddressTripleSet; | ||
import com.ibm.JikesRVM.memoryManagers.vmInterface.ScanObject; | ||
import com.ibm.JikesRVM.memoryManagers.vmInterface.ScanThread; | ||
import com.ibm.JikesRVM.memoryManagers.vmInterface.ScanStatics; | ||
import com.ibm.JikesRVM.memoryManagers.vmInterface.SynchronizationBarrier; | ||
|
||
import com.ibm.JikesRVM.VM; | ||
import com.ibm.JikesRVM.VM_Time; | ||
import com.ibm.JikesRVM.VM_Address; | ||
import com.ibm.JikesRVM.VM_Offset; | ||
import com.ibm.JikesRVM.VM_Magic; | ||
import com.ibm.JikesRVM.VM_Uninterruptible; | ||
import com.ibm.JikesRVM.VM_PragmaInline; | ||
import com.ibm.JikesRVM.VM_PragmaNoInline; | ||
import com.ibm.JikesRVM.VM_PragmaUninterruptible; | ||
import com.ibm.JikesRVM.VM_PragmaInterruptible; | ||
import com.ibm.JikesRVM.VM_Processor; | ||
import com.ibm.JikesRVM.VM_Scheduler; | ||
import com.ibm.JikesRVM.VM_Thread; | ||
|
||
/** | ||
* | ||
* @author <a href="http://cs.anu.edu.au/~Steve.Blackburn">Steve Blackburn</a> | ||
* @version $Revision$ | ||
* @date $Date$ | ||
*/ | ||
public abstract class BasePlan implements Constants, VM_Uninterruptible { | ||
|
||
public final static String Id = "$Id$"; | ||
|
||
public static int verbose = 0; | ||
|
||
protected WorkQueue workQueue; | ||
public AddressSet values; // gray objects | ||
public AddressSet locations; // locations containing white objects | ||
public AddressPairSet interiorLocations; // interior locations | ||
// private AddressQueue values; // gray objects | ||
// private AddressPairQueue interiorLocations; // interior locations | ||
|
||
BasePlan() { | ||
workQueue = new WorkQueue(); | ||
values = new AddressSet(64 * 1024); | ||
locations = new AddressSet(32 * 1024); | ||
interiorLocations = new AddressPairSet(16 * 1024); | ||
} | ||
|
||
/** | ||
* The boot method is called early in the boot process before any allocation. | ||
*/ | ||
static public void boot() throws VM_PragmaInterruptible { | ||
} | ||
|
||
/** | ||
* The boot method is called by the runtime immediately after command-line | ||
* arguments are available. Note that allocation must be supported | ||
* prior to this point because the runtime infrastructure may | ||
* require allocation in order to parse the command line arguments. | ||
* For this reason all plans should operate gracefully on the | ||
* default minimum heap size until the point that boot is called. | ||
*/ | ||
static public void postBoot() { | ||
} | ||
|
||
protected static boolean gcInProgress = false; // This flag should be turned on/off by subclasses. | ||
protected static int gcCount = 0; | ||
|
||
static public boolean gcInProgress() { | ||
return gcInProgress; | ||
} | ||
|
||
static public int gcCount() { | ||
return gcCount; | ||
} | ||
|
||
/** | ||
* Prepare for a collection. In this case, it means flipping | ||
* semi-spaces and preparing each of the collectors. | ||
*/ | ||
protected final void prepare() { | ||
SynchronizationBarrier barrier = VM_CollectorThread.gcBarrier; | ||
double tmp = VM_Time.now(); | ||
int id = barrier.rendezvous(); | ||
if (id == 1) { | ||
gcInProgress = true; | ||
gcCount++; | ||
startTime = tmp; | ||
singlePrepare(); | ||
resetComputeRoots(); | ||
VM_Interface.prepareNonParticipating(); // The will fix collector threads that are not participating in thie GC. | ||
} | ||
VM_Interface.prepareParticipating(); // Every participating thread needs to adjust its context registers. | ||
barrier.rendezvous(); | ||
allPrepare(); | ||
barrier.rendezvous(); | ||
} | ||
|
||
protected final void release() { | ||
SynchronizationBarrier barrier = VM_CollectorThread.gcBarrier; | ||
barrier.rendezvous(); | ||
allRelease(); | ||
int id = barrier.rendezvous(); | ||
if (id == 1) { | ||
singleRelease(); | ||
gcInProgress = false; // GC is in progress until after release! | ||
stopTime = VM_Time.now(); | ||
if (verbose > 0) { | ||
VM.sysWrite(" Collection time: ", (stopTime - startTime)); | ||
VM.sysWriteln(" seconds"); | ||
} | ||
} | ||
barrier.rendezvous(); | ||
} | ||
|
||
// These abstract methods are called in the order singlePrepare, allPrepare, allRelease, | ||
// and singleRelease. They are all separated by a barrier. | ||
abstract protected void singlePrepare(); | ||
abstract protected void allPrepare(); | ||
abstract protected void allRelease(); | ||
abstract protected void singleRelease(); | ||
|
||
static SynchronizedCounter threadCounter = new SynchronizedCounter(); | ||
static double startTime; | ||
static double stopTime; | ||
|
||
private void resetComputeRoots() { | ||
threadCounter.reset(); | ||
} | ||
|
||
private void computeRoots() { | ||
|
||
AddressPairSet codeLocations = VM_Interface.MOVES_OBJECTS ? interiorLocations : null; | ||
|
||
ScanStatics.scanStatics(locations); | ||
|
||
while (true) { | ||
int threadIndex = threadCounter.increment(); | ||
if (threadIndex >= VM_Scheduler.threads.length) break; | ||
VM_Thread th = VM_Scheduler.threads[threadIndex]; | ||
if (th == null) continue; | ||
// VM.sysWrite("Proc ", VM_Processor.getCurrentProcessor().id); VM.sysWriteln(" scanning thread ", threadIndex); | ||
// See comment of ScanThread.scanThread | ||
// | ||
VM_Thread th2 = VM_Magic.addressAsThread(Plan.traceObject(VM_Magic.objectAsAddress(th))); | ||
Plan.traceObject(VM_Magic.objectAsAddress(th.stack)); | ||