org.jikesrvm.mm.mmtk
Class ReferenceProcessor

java.lang.Object
  extended by org.mmtk.vm.ReferenceProcessor
      extended by org.jikesrvm.mm.mmtk.ReferenceProcessor

public final class ReferenceProcessor
extends ReferenceProcessor

This class manages SoftReferences, WeakReferences, and PhantomReferences. When a java/lang/ref/Reference object is created, its address is added to a table of pending reference objects of the appropriate type. An address is used so the reference will not stay alive during GC if it isn't in use elsewhere the mutator. During GC, the various lists are processed in the proper order to determine if any Reference objects are ready to be enqueued or whether referents that have died should be kept alive until the Reference is explicitly cleared. MMTk drives this processing and uses this class, via the VM interface, to scan the lists of pending reference objects.

As an optimization for generational collectors, each reference type maintains two queues: a nursery queue and the main queue.


Nested Class Summary
 
Nested classes/interfaces inherited from class org.mmtk.vm.ReferenceProcessor
ReferenceProcessor.Semantics
 
Field Summary
private  boolean growingTable
          Flag to prevent a race between threads growing the reference object table.
private static double GROWTH_FACTOR
          Grow the reference object table by this multiplier on overflow
private static int INITIAL_SIZE
          Initial size of the reference object table
private static Lock lock
          Class fields
private  int maxIndex
          Index of the first free slot in the reference table.
private  int nurseryIndex
          Index into the references table for the start of the reference nursery.
private static ReferenceProcessor phantomReferenceProcessor
           
private  AddressArray references
          The table of reference objects for the current semantics
private  ReferenceProcessor.Semantics semantics
          Semantics
private  String semanticsStr
          Copy of semantics.toString() for use in uninterruptible code
private static ReferenceProcessor softReferenceProcessor
           
private static boolean STRESS
           
private static boolean TRACE
           
private static boolean TRACE_DETAIL
           
private static boolean TRACE_UNREACHABLE
           
private  AddressArray unforwardedReferences
          In a MarkCompact (or similar) collector, we need to update the references field, and then update its contents.
private static ReferenceProcessor weakReferenceProcessor
           
 
Constructor Summary
private ReferenceProcessor(ReferenceProcessor.Semantics semantics)
          Create a reference processor for a given semantics
 
Method Summary
private  void addCandidate(Reference<?> ref, ObjectReference referent)
          Add a reference to the list of references.
static void addPhantomCandidate(PhantomReference<?> ref, ObjectReference referent)
          Add a reference to the list of phantom references.
private  void addReference(Reference<?> ref, ObjectReference referent)
          Add a reference at the end of the table
static void addSoftCandidate(SoftReference<?> ref, ObjectReference referent)
          Add a reference to the list of soft references.
static void addWeakCandidate(WeakReference<?> ref, ObjectReference referent)
          Add a reference to the list of weak references.
 void clear()
          Clear the contents of the table.
protected  void clearReferent(ObjectReference newReference)
          Weak and soft references always clear the referent before enqueueing.
 int countWaitingReferences()
          Statistics and debugging
 boolean enqueueReference(ObjectReference addr)
          Put this Reference object on its ReferenceQueue (if it has one) when its referent is no longer sufficiently reachable.
 void forward(TraceLocal trace, boolean nursery)
          Iterate over all references and forward.
static ReferenceProcessor get(ReferenceProcessor.Semantics semantics)
          Factory method.
private  ObjectReference getReference(int i)
          Retrieve from the reference table
protected  ObjectReference getReferent(ObjectReference object)
          Get the referent from a reference.
private  AddressArray growReferenceTable()
          Grow the reference table by GROWTH_FACTOR.
 ObjectReference processReference(TraceLocal trace, ObjectReference reference)
          Process a reference with the current semantics.
 void scan(TraceLocal trace, boolean nursery)
          Scan through the list of references.
private  void setReference(int i, ObjectReference ref)
          Update the reference table
protected  void setReferent(ObjectReference ref, ObjectReference referent)
          Set the referent in a reference.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

lock

private static final Lock lock
Class fields


softReferenceProcessor

private static final ReferenceProcessor softReferenceProcessor

weakReferenceProcessor

private static final ReferenceProcessor weakReferenceProcessor

phantomReferenceProcessor

private static final ReferenceProcessor phantomReferenceProcessor

TRACE

private static final boolean TRACE
See Also:
Constant Field Values

TRACE_UNREACHABLE

private static final boolean TRACE_UNREACHABLE
See Also:
Constant Field Values

TRACE_DETAIL

private static final boolean TRACE_DETAIL
See Also:
Constant Field Values

STRESS

private static final boolean STRESS
See Also:
Constant Field Values

INITIAL_SIZE

private static final int INITIAL_SIZE
Initial size of the reference object table

See Also:
Constant Field Values

GROWTH_FACTOR

private static final double GROWTH_FACTOR
Grow the reference object table by this multiplier on overflow

See Also:
Constant Field Values

references

private volatile AddressArray references
The table of reference objects for the current semantics


unforwardedReferences

private volatile AddressArray unforwardedReferences
In a MarkCompact (or similar) collector, we need to update the references field, and then update its contents. We implement this by saving the pointer in this untraced field for use during the forward pass.


nurseryIndex

private int nurseryIndex
Index into the references table for the start of the reference nursery.


maxIndex

private volatile int maxIndex
Index of the first free slot in the reference table.


growingTable

private volatile boolean growingTable
Flag to prevent a race between threads growing the reference object table.


semantics

private final ReferenceProcessor.Semantics semantics
Semantics


semanticsStr

private final String semanticsStr
Copy of semantics.toString() for use in uninterruptible code

Constructor Detail

ReferenceProcessor

private ReferenceProcessor(ReferenceProcessor.Semantics semantics)
Create a reference processor for a given semantics

Parameters:
semantics -
Method Detail

get

public static ReferenceProcessor get(ReferenceProcessor.Semantics semantics)
Factory method. Creates an instance of the appropriate reference type processor.

Returns:
the reference processor

addReference

private void addReference(Reference<?> ref,
                          ObjectReference referent)
Add a reference at the end of the table

Parameters:
ref - The reference to add

setReference

private void setReference(int i,
                          ObjectReference ref)
Update the reference table

Parameters:
i - The table index
ref - The reference to insert

getReference

private ObjectReference getReference(int i)
Retrieve from the reference table

Parameters:
i - Table index
Returns:
The reference object at index i

growReferenceTable

private AddressArray growReferenceTable()
Grow the reference table by GROWTH_FACTOR.

Logically Uninterruptible because it can GC when it allocates, but the rest of the code can't tolerate GC.

This method is called without the reference processor lock held, but with the flag growingTable set.


addCandidate

private void addCandidate(Reference<?> ref,
                          ObjectReference referent)
Add a reference to the list of references. This method is responsible for installing the address of the referent into the Reference object so that the referent is traced at all yield points before the Reference is correctly installed in the reference table. (SJF: This method must NOT be inlined into an inlined allocation sequence, since it contains a lock!)

Parameters:
referent - The referent of the reference
ref - The reference to add

forward

public void forward(TraceLocal trace,
                    boolean nursery)
Iterate over all references and forward.

Collectors like MarkCompact determine liveness and move objects using separate traces.

Currently ignores the nursery hint.

TODO parallelise this code

Specified by:
forward in class ReferenceProcessor
Parameters:
trace - The MMTk trace to forward to
nursery - The nursery collection hint

clear

public void clear()
Description copied from class: ReferenceProcessor
Clear the contents of the table. This is called when reference types are disabled to make it easier for VMs to change this setting at runtime.

Specified by:
clear in class ReferenceProcessor

scan

public void scan(TraceLocal trace,
                 boolean nursery)
Scan through the list of references. Calls ReferenceProcessor's processReference method for each reference and builds a new list of those references still active.

Depending on the value of nursery, we will either scan all references, or just those created since the last scan.

TODO parallelise this code

Specified by:
scan in class ReferenceProcessor
Parameters:
nursery - Scan only the newly created references
trace - the thread local trace element.

enqueueReference

public boolean enqueueReference(ObjectReference addr)
Put this Reference object on its ReferenceQueue (if it has one) when its referent is no longer sufficiently reachable. The definition of "reachable" is defined by the semantics of the particular subclass of Reference. The implementation of this routine is determined by the the implementation of java.lang.ref.ReferenceQueue in GNU classpath. It is in this class rather than the public Reference class to ensure that Jikes has a safe way of enqueueing the object, one that cannot be overridden by the application program. ************************ TODO ********************************* Change this so that we don't call reference.enqueue directly as this can be overridden by the user. ***************************************************************

Parameters:
addr - the address of the Reference object
Returns:
true if the reference was enqueued
See Also:
ReferenceQueue

addSoftCandidate

public static void addSoftCandidate(SoftReference<?> ref,
                                    ObjectReference referent)
Add a reference to the list of soft references.

Parameters:
ref - the SoftReference to add

addWeakCandidate

public static void addWeakCandidate(WeakReference<?> ref,
                                    ObjectReference referent)
Add a reference to the list of weak references.

Parameters:
ref - the WeakReference to add

addPhantomCandidate

public static void addPhantomCandidate(PhantomReference<?> ref,
                                       ObjectReference referent)
Add a reference to the list of phantom references.

Parameters:
ref - the PhantomReference to add

processReference

public ObjectReference processReference(TraceLocal trace,
                                        ObjectReference reference)
Process a reference with the current semantics.

Parameters:
reference - the address of the reference. This may or may not be the address of a heap object, depending on the VM.
trace - the thread local trace element.

clearReferent

protected void clearReferent(ObjectReference newReference)
Weak and soft references always clear the referent before enqueueing. We don't actually call Reference.clear() as the user could have overridden the implementation and we don't want any side-effects to occur.


getReferent

protected ObjectReference getReferent(ObjectReference object)
Get the referent from a reference. For Java the reference is a Reference object.

Parameters:
object - the object reference.
Returns:
the referent object reference.

setReferent

protected void setReferent(ObjectReference ref,
                           ObjectReference referent)
Set the referent in a reference. For Java the reference is a Reference object.

Parameters:
ref - the ObjectReference for the reference (confusing eh?).
referent - the referent object reference.

countWaitingReferences

public int countWaitingReferences()
Statistics and debugging

Specified by:
countWaitingReferences in class ReferenceProcessor
Returns:
the number of references objects on the queue