Revision: 13439
http://jikesrvm.svn.sourceforge.net/jikesrvm/?rev=13439&view=revAuthor: dframpton-oss
Date: 2007-08-31 19:07:54 -0700 (Fri, 31 Aug 2007)
Log Message:
-----------
Base class for a simple concurrent-tracing collector utilizing a snapshot-at-the-beginning approach.
Modified Paths:
--------------
rvmroot/trunk/MMTk/src/org/mmtk/utility/options/Options.java
Added Paths:
-----------
rvmroot/trunk/MMTk/src/org/mmtk/plan/concurrent/
rvmroot/trunk/MMTk/src/org/mmtk/plan/concurrent/Concurrent.java
rvmroot/trunk/MMTk/src/org/mmtk/plan/concurrent/ConcurrentCollector.java
rvmroot/trunk/MMTk/src/org/mmtk/plan/concurrent/ConcurrentConstraints.java
rvmroot/trunk/MMTk/src/org/mmtk/plan/concurrent/ConcurrentMutator.java
rvmroot/trunk/MMTk/src/org/mmtk/utility/options/ConcurrentTrigger.java
Added: rvmroot/trunk/MMTk/src/org/mmtk/plan/concurrent/Concurrent.java
===================================================================
--- rvmroot/trunk/MMTk/src/org/mmtk/plan/concurrent/Concurrent.java (rev 0)
+++ rvmroot/trunk/MMTk/src/org/mmtk/plan/concurrent/Concurrent.java 2007-09-01 02:07:54 UTC (rev 13439)
@@ -0,0 +1,154 @@
+/*
+ * This file is part of the Jikes RVM project (
http://jikesrvm.org).
+ *
+ * This file is licensed to You under the Common Public License (CPL);
+ * You may not use this file except in compliance with the License. You
+ * may obtain a copy of the License at
+ *
+ *
http://www.opensource.org/licenses/cpl1.0.php+ *
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.
+ */
+package org.mmtk.plan.concurrent;
+
+import org.mmtk.plan.Phase;
+import org.mmtk.plan.Simple;
+import org.mmtk.utility.Log;
+import org.mmtk.utility.options.ConcurrentTrigger;
+import org.mmtk.utility.options.Options;
+
+import org.vmmagic.pragma.*;
+
+/**
+ * This class implements the global state of a concurrent collector.
+ */
+@Uninterruptible
+public abstract class Concurrent extends Simple {
+
+ /****************************************************************************
+ * Constants
+ */
+
+ /****************************************************************************
+ * Class variables
+ */
+ public static final short FLUSH_MUTATOR = Phase.createSimple("flush-mutator", null);
+ public static final short SET_BARRIER_ACTIVE = Phase.createSimple("set-barrier", null);
+ public static final short FLUSH_COLLECTOR = Phase.createSimple("flush-collector", null);
+ public static final short CLEAR_BARRIER_ACTIVE = Phase.createSimple("clear-barrier", null);
+
+ // CHECKSTYLE:OFF
+
+ /**
+ * When we preempt a concurrent marking phase we must flush mutators and then continue the closure.
+ */
+ protected static final short preemptConcurrentClosure = Phase.createComplex("preeempt-concurrent-trace", null,
+ Phase.scheduleMutator (FLUSH_MUTATOR),
+ Phase.scheduleCollector(COMPLETE_CLOSURE));
+
+ public static final short CONCURRENT_COMPLETE_CLOSURE = Phase.createConcurrent("concurrent-closure",
+ Phase.scheduleComplex(preemptConcurrentClosure));
+
+ /**
+ * Perform the initial determination of liveness from the roots, we split it into concurrent
+ * and atomic parts for concurrent collection..
+ */
+ protected static final short concurrentStartClosure = Phase.createComplex("concurrent-start-trace", null,
+ Phase.scheduleCollector (START_CLOSURE),
+ Phase.scheduleCollector (COMPLETE_CLOSURE));
+
+ /**
+ * Perform the initial determination of liveness from the roots.
+ */
+ protected static final short concurrentCompleteClosure = Phase.createComplex("concurrent-mark", null,
+ Phase.scheduleMutator (SET_BARRIER_ACTIVE),
+ Phase.scheduleCollector (FLUSH_COLLECTOR),
+ Phase.scheduleConcurrent(CONCURRENT_COMPLETE_CLOSURE),
+ Phase.scheduleMutator (CLEAR_BARRIER_ACTIVE));
+
+ /** Build, validate and then build another sanity table */
+ protected static final short preSanityPhase = Phase.createComplex("sanity", null,
+ Phase.scheduleComplex (sanityBuildPhase),
+ Phase.scheduleGlobal (SANITY_SET_PREGC),
+ Phase.scheduleComplex (sanityCheckPhase),
+ Phase.scheduleComplex (sanityBuildPhase));
+
+ /** Validate, build and validate the second sanity table */
+ protected static final short postSanityPhase = Phase.createComplex("sanity", null,
+ Phase.scheduleGlobal (SANITY_SET_POSTGC),
+ Phase.scheduleComplex (sanityCheckPhase),
+ Phase.scheduleComplex (sanityBuildPhase),
+ Phase.scheduleGlobal (SANITY_SET_PREGC),
+ Phase.scheduleComplex (sanityCheckPhase));
+
+ // CHECKSTYLE:OFF
+
+ /****************************************************************************
+ * Instance variables
+ */
+
+ /****************************************************************************
+ * Constructor.
+ */
+ public Concurrent() {
+ Options.concurrentTrigger = new ConcurrentTrigger();
+ }
+
+ /*****************************************************************************
+ *
+ * Collection
+ */
+
+ /**
+ * The boot method is called early in the boot process before any
+ * allocation.
+ */
+ @Interruptible
+ public void postBoot() {
+ super.postBoot();
+
+ /* Make the start of the closure two parts */
+ replacePhase(Phase.scheduleCollector(START_CLOSURE), Phase.scheduleComplex(concurrentStartClosure));
+
+ /* Set up the concurrent marking phase */
+ replacePhase(Phase.scheduleCollector(COMPLETE_CLOSURE), Phase.scheduleComplex(concurrentCompleteClosure));
+
+ if (Options.sanityCheck.getValue()) {
+ Log.writeln("Collection sanity checking enabled.");
+ replacePhase(Phase.schedulePlaceholder(PRE_SANITY_PLACEHOLDER), Phase.scheduleComplex(preSanityPhase));
+ replacePhase(Phase.schedulePlaceholder(POST_SANITY_PLACEHOLDER), Phase.scheduleComplex(postSanityPhase));
+ }
+ }
+
+ /****************************************************************************
+ *
+ * Collection
+ */
+
+ /**
+ * Perform a (global) collection phase.
+ *
+ * @param phaseId Collection phase to execute.
+ */
+ @Inline
+ public void collectionPhase(short phaseId) {
+ super.collectionPhase(phaseId);
+ }
+
+ /**
+ * This method controls the triggering of an atomic phase of a concurrent
+ * collection. It is called periodically during allocation.
+ *
+ * @return True if a collection is requested by the plan.
+ */
+ protected boolean concurrentCollectionRequired() {
+ return !Phase.concurrentPhaseActive() &&
+ ((getPagesReserved() * 100) / getTotalPages()) > Options.concurrentTrigger.getValue();
+ }
+
+ /*****************************************************************************
+ *
+ * Accounting
+ */
+}
Property changes on: rvmroot/trunk/MMTk/src/org/mmtk/plan/concurrent/Concurrent.java
___________________________________________________________________
Name: svn:eol-style
+ native
Added: rvmroot/trunk/MMTk/src/org/mmtk/plan/concurrent/ConcurrentCollector.java
===================================================================
--- rvmroot/trunk/MMTk/src/org/mmtk/plan/concurrent/ConcurrentCollector.java (rev 0)
+++ rvmroot/trunk/MMTk/src/org/mmtk/plan/concurrent/ConcurrentCollector.java 2007-09-01 02:07:54 UTC (rev 13439)
@@ -0,0 +1,150 @@
+/*
+ * This file is part of the Jikes RVM project (
http://jikesrvm.org).
+ *
+ * This file is licensed to You under the Common Public License (CPL);
+ * You may not use this file except in compliance with the License. You
+ * may obtain a copy of the License at
+ *
+ *
http://www.opensource.org/licenses/cpl1.0.php+ *
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.
+ */
+package org.mmtk.plan.concurrent;
+
+import org.mmtk.plan.Phase;
+import org.mmtk.plan.Plan;
+import org.mmtk.plan.SimpleCollector;
+import org.mmtk.plan.TraceLocal;
+import org.mmtk.utility.Log;
+import org.mmtk.utility.options.Options;
+import org.mmtk.vm.VM;
+
+import org.vmmagic.pragma.*;
+
+/**
+ * This class implements <i>per-collector thread</i> behavior
+ * and state for a concurrent collector.
+ */
+@Uninterruptible
+public abstract class ConcurrentCollector extends SimpleCollector {
+
+ /****************************************************************************
+ * Instance fields
+ */
+
+ /****************************************************************************
+ * Initialization
+ */
+
+ /****************************************************************************
+ *
+ * Collection
+ */
+
+ /** Perform some concurrent garbage collection */
+ public final void concurrentCollect() {
+ if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(!Plan.gcInProgress());
+ if (Phase.startConcurrentPhase()) {
+ /* Can't change while we are 'in' the concurrent phase */
+ short phaseId = Phase.getConcurrentPhaseId();
+ concurrentCollectionPhase(phaseId);
+ }
+ }
+
+ public void collect() {
+ if (!Phase.isPhaseStackEmpty()) {
+ Phase.continuePhaseStack();
+ } else {
+ Phase.beginNewPhaseStack(Phase.scheduleComplex(global().collection));
+ }
+ }
+
+ /**
+ * Perform a per-collector collection phase.
+ *
+ * @param phaseId The collection phase to perform
+ * @param primary Perform any single-threaded activities using this thread.
+ */
+ @Inline
+ public void collectionPhase(short phaseId, boolean primary) {
+ if (phaseId == Concurrent.FLUSH_COLLECTOR) {
+ getConcurrentTrace().flush();
+ return;
+ }
+
+ super.collectionPhase(phaseId, primary);
+ }
+
+ /**
+ * Perform some concurrent collection work.
+ *
+ * @param phaseId The unique phase identifier
+ */
+ public void concurrentCollectionPhase(short phaseId) {
+ if (phaseId == Concurrent.CONCURRENT_COMPLETE_CLOSURE) {
+ if (VM.VERIFY_ASSERTIONS) {
+ VM.assertions._assert(!Plan.gcInProgress());
+ for(int i=0; i < VM.activePlan.mutatorCount(); i++) {
+ VM.assertions._assert(((ConcurrentMutator)VM.activePlan.mutator(i)).barrierActive);
+ }
+ }
+ TraceLocal trace = getConcurrentTrace();
+ while(!trace.traceIncrement(100)) {
+ /* Check if we should yield */
+ if (VM.collection.yieldpoint()) {
+ if (resetConcurrentWork) {
+ /* We have been preempted by a full collection */
+ return;
+ }
+ }
+ }
+
+ if (Phase.completeConcurrentPhase()) {
+ /* We are responsible for ensuring termination. */
+ if (Options.verbose.getValue() >= 2) Log.writeln("< requesting mutator flush >");
+ VM.collection.requestMutatorFlush();
+
+ if (resetConcurrentWork) {
+ /* We have been preempted by a full collection */
+ return;
+ }
+
+ if (Options.verbose.getValue() >= 2) Log.writeln("< mutators flushed >");
+
+ if (concurrentTraceComplete()) {
+ Phase.notifyConcurrentPhaseComplete();
+ } else {
+ Phase.notifyConcurrentPhaseIncomplete();
+ }
+ }
+ return;
+ }
+
+ Log.write("Concurrent phase "); Log.write(Phase.getName(phaseId));
+ Log.writeln(" not handled.");
+ VM.assertions.fail("Concurrent phase not handled!");
+ }
+
+ /**
+ * Return the current trace to be used during concurrent collection.
+ */
+ protected abstract TraceLocal getConcurrentTrace();
+
+ /**
+ * Has all work been completed?
+ */
+ protected abstract boolean concurrentTraceComplete();
+
+
+ /****************************************************************************
+ *
+ * Miscellaneous.
+ */
+
+ /** @return The active global plan as a <code>Concurrent</code> instance. */
+ @Inline
+ private static Concurrent global() {
+ return (Concurrent) VM.activePlan.global();
+ }
+}
Property changes on: rvmroot/trunk/MMTk/src/org/mmtk/plan/concurrent/ConcurrentCollector.java
___________________________________________________________________
Name: svn:eol-style
+ native
Added: rvmroot/trunk/MMTk/src/org/mmtk/plan/concurrent/ConcurrentConstraints.java
===================================================================
--- rvmroot/trunk/MMTk/src/org/mmtk/plan/concurrent/ConcurrentConstraints.java (rev 0)
+++ rvmroot/trunk/MMTk/src/org/mmtk/plan/concurrent/ConcurrentConstraints.java 2007-09-01 02:07:54 UTC (rev 13439)
@@ -0,0 +1,33 @@
+/*
+ * This file is part of the Jikes RVM project (
http://jikesrvm.org).
+ *
+ * This file is licensed to You under the Common Public License (CPL);
+ * You may not use this file except in compliance with the License. You
+ * may obtain a copy of the License at
+ *
+ *
http://www.opensource.org/licenses/cpl1.0.php+ *
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.
+ */
+package org.mmtk.plan.concurrent;
+
+import org.mmtk.plan.SimpleConstraints;
+import org.vmmagic.pragma.*;
+
+/**
+ * This class and its subclasses communicate to the host VM/Runtime
+ * any features of the selected plan that it needs to know. This is
+ * separate from the main Plan/PlanLocal class in order to bypass any
+ * issues with ordering of static initialization.
+ */
+@Uninterruptible
+public abstract class ConcurrentConstraints extends SimpleConstraints {
+ public boolean needsConcurrentWorkers() { return true; }
+
+ public boolean needsWriteBarrier() { return true; }
+
+ public boolean needsReferenceTypeReadBarrier() { return true; }
+
+ public boolean needsStaticWriteBarrier() { return false; /* TODO: true */ }
+}
Property changes on: rvmroot/trunk/MMTk/src/org/mmtk/plan/concurrent/ConcurrentConstraints.java
___________________________________________________________________
Name: svn:eol-style
+ native
Added: rvmroot/trunk/MMTk/src/org/mmtk/plan/concurrent/ConcurrentMutator.java
===================================================================
--- rvmroot/trunk/MMTk/src/org/mmtk/plan/concurrent/ConcurrentMutator.java (rev 0)
+++ rvmroot/trunk/MMTk/src/org/mmtk/plan/concurrent/ConcurrentMutator.java 2007-09-01 02:07:54 UTC (rev 13439)
@@ -0,0 +1,182 @@
+/*
+ * This file is part of the Jikes RVM project (
http://jikesrvm.org).
+ *
+ * This file is licensed to You under the Common Public License (CPL);
+ * You may not use this file except in compliance with the License. You
+ * may obtain a copy of the License at
+ *
+ *
http://www.opensource.org/licenses/cpl1.0.php+ *
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.
+ */
+package org.mmtk.plan.concurrent;
+
+import org.mmtk.plan.*;
+
+import org.mmtk.vm.VM;
+
+import org.vmmagic.pragma.*;
+import org.vmmagic.unboxed.*;
+
+/**
+ * This class implements <i>per-mutator thread</i> behavior
+ * and state for a simple whole-heap concurrent collector.
+ *
+ * @see Concurrent
+ * @see ConcurrentCollector
+ * @see StopTheWorldMutator
+ * @see MutatorContext
+ */
+@Uninterruptible
+public abstract class ConcurrentMutator extends SimpleMutator {
+
+ /****************************************************************************
+ * Instance fields
+ */
+ protected boolean barrierActive;
+
+ /****************************************************************************
+ *
+ * Collection
+ */
+
+ /**
+ * Perform a per-mutator collection phase.
+ *
+ * @param phaseId The collection phase to perform
+ * @param primary Perform any single-threaded activities using this thread.
+ */
+ @Inline
+ public void collectionPhase(short phaseId, boolean primary) {
+ if (phaseId == Concurrent.SET_BARRIER_ACTIVE) {
+ barrierActive = true;
+ return;
+ }
+
+ if (phaseId == Concurrent.CLEAR_BARRIER_ACTIVE) {
+ barrierActive = false;
+ return;
+ }
+
+ if (phaseId == Concurrent.FLUSH_MUTATOR) {
+ flush();
+ return;
+ }
+
+ super.collectionPhase(phaseId, primary);
+ }
+
+ /****************************************************************************
+ *
+ * Write and read barriers.
+ */
+
+ /**
+ * A new reference is about to be created. Take appropriate write
+ * barrier actions.<p>
+ *
+ * <b>In this case we employ a Yuasa style snapshot barrier.</b>
+ *
+ * @param src The object into which the new reference will be stored
+ * @param slot The address into which the new reference will be
+ * stored.
+ * @param tgt The target of the new reference
+ * @param metaDataA An int that assists the host VM in creating a store
+ * @param metaDataB An int that assists the host VM in creating a store
+ * @param mode The context in which the store occured
+ */
+ @Inline
+ public void writeBarrier(ObjectReference src, Address slot, ObjectReference tgt, Offset metaDataA, int metaDataB, int mode) {
+ if (barrierActive) checkAndEnqueueReference(slot.loadObjectReference());
+ VM.barriers.performWriteInBarrier(src, slot, tgt, metaDataA, metaDataB, mode);
+ }
+
+ /**
+ * Attempt to atomically exchange the value in the given slot
+ * with the passed replacement value. If a new reference is
+ * created, we must then take appropriate write barrier actions.<p>
+ *
+ * <b>By default do nothing, override if appropriate.</b>
+ *
+ * @param src The object into which the new reference will be stored
+ * @param slot The address into which the new reference will be
+ * stored.
+ * @param old The old reference to be swapped out
+ * @param tgt The target of the new reference
+ * @param metaDataA An int that assists the host VM in creating a store
+ * @param metaDataB An int that assists the host VM in creating a store
+ * @param mode The context in which the store occured
+ * @return True if the swap was successful.
+ */
+ @Inline
+ public boolean tryCompareAndSwapWriteBarrier(ObjectReference src, Address slot, ObjectReference old,
+ ObjectReference tgt, Offset metaDataA, int metaDataB, int mode) {
+ boolean result = VM.barriers.tryCompareAndSwapWriteInBarrier(src, slot, old, tgt, metaDataA, metaDataB, mode);
+ if (barrierActive) checkAndEnqueueReference(old);
+ return result;
+ }
+
+ /**
+ * A number of references are about to be copied from object
+ * <code>src</code> to object <code>dst</code> (as in an array
+ * copy). Thus, <code>dst</code> is the mutated object. Take
+ * appropriate write barrier actions.<p>
+ *
+ * @param src The source of the values to be copied
+ * @param srcOffset The offset of the first source address, in
+ * bytes, relative to <code>src</code> (in principle, this could be
+ * negative).
+ * @param dst The mutated object, i.e. the destination of the copy.
+ * @param dstOffset The offset of the first destination address, in
+ * bytes relative to <code>tgt</code> (in principle, this could be
+ * negative).
+ * @param bytes The size of the region being copied, in bytes.
+ * @return True if the update was performed by the barrier, false if
+ * left to the caller (always false in this case).
+ */
+ @Inline
+ public boolean writeBarrier(ObjectReference src, Offset srcOffset,
+ ObjectReference dst, Offset dstOffset, int bytes) {
+ Address cursor = dst.toAddress().plus(dstOffset);
+ Address limit = cursor.plus(bytes);
+ while (cursor.LT(limit)) {
+ ObjectReference ref = cursor.loadObjectReference();
+ if (barrierActive) checkAndEnqueueReference(ref);
+ cursor = cursor.plus(BYTES_IN_ADDRESS);
+ }
+ return false;
+ }
+
+ /**
+ * Read a reference type. In a concurrent collector this may
+ * involve adding the referent to the marking queue.
+ *
+ * @param src The referent being read.
+ * @return The new referent.
+ */
+ @Inline
+ public ObjectReference referenceTypeReadBarrier(ObjectReference ref) {
+ if (barrierActive) checkAndEnqueueReference(ref);
+ return ref;
+ }
+
+ /**
+ * Process a reference that may require being enqueued as part of a concurrent
+ * collection.
+ *
+ * @param ref The reference to check.
+ */
+ protected abstract void checkAndEnqueueReference(ObjectReference ref);
+
+ /****************************************************************************
+ *
+ * Miscellaneous
+ */
+
+ /** @return The active global plan as a <code>Gen</code> instance. */
+ @Inline
+ private static Concurrent global() {
+ return (Concurrent) VM.activePlan.global();
+ }
+}
Property changes on: rvmroot/trunk/MMTk/src/org/mmtk/plan/concurrent/ConcurrentMutator.java
___________________________________________________________________
Name: svn:eol-style
+ native
Added: rvmroot/trunk/MMTk/src/org/mmtk/utility/options/ConcurrentTrigger.java
===================================================================
--- rvmroot/trunk/MMTk/src/org/mmtk/utility/options/ConcurrentTrigger.java (rev 0)
+++ rvmroot/trunk/MMTk/src/org/mmtk/utility/options/ConcurrentTrigger.java 2007-09-01 02:07:54 UTC (rev 13439)
@@ -0,0 +1,35 @@
+/*
+ * This file is part of the Jikes RVM project (
http://jikesrvm.org).
+ *
+ * This file is licensed to You under the Common Public License (CPL);
+ * You may not use this file except in compliance with the License. You
+ * may obtain a copy of the License at
+ *
+ *
http://www.opensource.org/licenses/cpl1.0.php+ *
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.
+ */
+package org.mmtk.utility.options;
+
+/**
+ * Concurrent trigger percentage
+ */
+public class ConcurrentTrigger extends IntOption {
+ /**
+ * Create the option.
+ */
+ public ConcurrentTrigger() {
+ super("Concurrent Trigger",
+ "Concurrent trigger percentage",
+ 50);
+ }
+
+ /**
+ * Only accept values between 1 and 100 (inclusive)
+ */
+ protected void validate() {
+ failIf(this.value <= 0, "Trigger must be between 1 and 100");
+ failIf(this.value > 100, "Trigger must be between 1 and 100");
+ }
+}
Property changes on: rvmroot/trunk/MMTk/src/org/mmtk/utility/options/ConcurrentTrigger.java
___________________________________________________________________
Name: svn:eol-style
+ native
Modified: rvmroot/trunk/MMTk/src/org/mmtk/utility/options/Options.java
===================================================================
--- rvmroot/trunk/MMTk/src/org/mmtk/utility/options/Options.java 2007-09-01 01:31:01 UTC (rev 13438)
+++ rvmroot/trunk/MMTk/src/org/mmtk/utility/options/Options.java 2007-09-01 02:07:54 UTC (rev 13439)
@@ -24,6 +24,7 @@
/* Other options */
public static BoundedNursery boundedNursery;
+ public static ConcurrentTrigger concurrentTrigger;
public static CycleFilterThreshold cycleFilterThreshold;
public static CycleMetaDataLimit cycleMetaDataLimit;
public static CycleTriggerThreshold cycleTriggerThreshold;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>
http://get.splunk.com/_______________________________________________
Jikesrvm-commits mailing list
Jikesrvm-commits@...
https://lists.sourceforge.net/lists/listinfo/jikesrvm-commits