Skip to content

Commit

Permalink
merge of JMTk back into main branch
Browse files Browse the repository at this point in the history
  • Loading branch information
Perry Cheng committed Oct 13, 2002
1 parent b745280 commit 8a1de24
Show file tree
Hide file tree
Showing 251 changed files with 18,603 additions and 1,492 deletions.
323 changes: 323 additions & 0 deletions MMTk/src/org/mmtk/plan/BasePlan.java
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));