Skip to content

Commit

Permalink
Generalized ScanObject to allow pointers to be enumerated with a call…
Browse files Browse the repository at this point in the history
…back

to the initiating plan.  This involves a trivial refactoring.

Given that scan() is inlined, constant folding should ensure that the
generality comes at zero overhead to the normal object scanning process.
  • Loading branch information
steveblackburn committed Apr 13, 2003
1 parent 68e36aa commit e7bc7a0
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 24 deletions.
10 changes: 10 additions & 0 deletions MMTk/src/org/mmtk/plan/BasePlan.java
Expand Up @@ -261,6 +261,16 @@ public static final VM_Address traceInteriorReference(VM_Address obj,
return newObj.add(offset);
}

/**
* A pointer location has been enumerated by ScanObject. This is
* the callback method, allowing the plan to perform an action with
* respect to that location. By default nothing is done.
*
* @param location An address known to contain a pointer. The
* location is within the object being scanned by ScanObject.
*/
public void enumeratePointerLocation(VM_Address location) {}

public static boolean willNotMove (VM_Address obj) {
return !VMResource.refIsMovable(obj);
}
Expand Down
10 changes: 10 additions & 0 deletions rvm/src/vm/memoryManagers/JMTk/plan/BasePlan.java
Expand Up @@ -261,6 +261,16 @@ public static final VM_Address traceInteriorReference(VM_Address obj,
return newObj.add(offset);
}

/**
* A pointer location has been enumerated by ScanObject. This is
* the callback method, allowing the plan to perform an action with
* respect to that location. By default nothing is done.
*
* @param location An address known to contain a pointer. The
* location is within the object being scanned by ScanObject.
*/
public void enumeratePointerLocation(VM_Address location) {}

public static boolean willNotMove (VM_Address obj) {
return !VMResource.refIsMovable(obj);
}
Expand Down
58 changes: 43 additions & 15 deletions rvm/src/vm/memoryManagers/JMTk/vmInterface/ScanObject.java
Expand Up @@ -33,13 +33,47 @@
*/
public class ScanObject implements VM_Constants, Constants {

/**
* Scan a object, processing each pointer field encountered. The
* object is not known to be a root object.
*
* @param object The object to be scanned.
*/
public static void scan(VM_Address object)
throws VM_PragmaUninterruptible, VM_PragmaInline {
scan(object, false, null, true);
}

/**
* Scan a root object, processing each pointer field encountered.
*
* @param object The root object to be scanned.
*/
public static void rootScan(Object objRef)
throws VM_PragmaUninterruptible, VM_PragmaNoInline {
scan(VM_Magic.objectAsAddress(objRef), true, null, true);
}

/**
* Enumerate the pointers in an object, calling back to a given plan
* for each pointer encountered.
*
* @param object The object to be scanned.
* @param plan The plan with respect to which the callback should be made.
*/
public static void enumeratePointers(VM_Address object, Plan plan)
throws VM_PragmaUninterruptible, VM_PragmaInline {
scan(object, false, plan, false);
}

/**
* Scans an object or array for internal object references and
* processes those references (calls processPtrField)
*
* @param objRef reference for object to be scanned (as int)
*/
private static void scan (VM_Address objRef, boolean root)
private static void scan(VM_Address objRef, boolean root, Plan plan,
boolean trace)
throws VM_PragmaUninterruptible, VM_PragmaInline {

if (VM.VerifyAssertions) VM._assert(!objRef.isZero());
Expand Down Expand Up @@ -70,7 +104,10 @@ private static void scan (VM_Address objRef, boolean root)
if (type.isClassType()) {
int[] referenceOffsets = type.asClass().getReferenceOffsets();
for(int i = 0, n=referenceOffsets.length; i < n; i++) {
VM_Interface.processPtrField( objRef.add(referenceOffsets[i]), root );
if (trace)
VM_Interface.processPtrField(objRef.add(referenceOffsets[i]), root);
else
VM_Interface.enumeratePtrLoc(objRef.add(referenceOffsets[i]), plan);
}
Statistics.profileScan(obj, 4 * referenceOffsets.length, tib);
}
Expand All @@ -83,26 +120,17 @@ private static void scan (VM_Address objRef, boolean root)
VM_Address location = objRef; // for arrays = address of [0] entry
VM_Address end = objRef.add(numBytes);
while ( location.LT(end) ) {
VM_Interface.processPtrField( location, root );
if (trace)
VM_Interface.processPtrField(location, root);
else
VM_Interface.enumeratePtrLoc(location, plan);
location = location.add(WORD_SIZE); // is this size_of_pointer ?
}
Statistics.profileScan(obj, numBytes, tib);
}
}
}

static void scan (Object objRef) throws VM_PragmaUninterruptible, VM_PragmaInline {
scan(VM_Magic.objectAsAddress(objRef), false);
}
public static void scan (VM_Address object) throws VM_PragmaUninterruptible, VM_PragmaInline {
scan(object, false);
}
public static void rootScan (Object objRef) throws VM_PragmaUninterruptible, VM_PragmaNoInline {
scan(VM_Magic.objectAsAddress(objRef), true);
}
public static void rootScan (VM_Address object) throws VM_PragmaUninterruptible, VM_PragmaNoInline {
scan(object, true);
}

public static boolean validateRefs( VM_Address ref, int depth )
throws VM_PragmaUninterruptible, VM_PragmaNoInline {
Expand Down
34 changes: 25 additions & 9 deletions rvm/src/vm/memoryManagers/JMTk/vmInterface/VM_Interface.java
Expand Up @@ -421,10 +421,26 @@ public static void processPtrField (VM_Address location) throws VM_PragmaUninter
if (VM.VerifyAssertions) VM._assert(false); // unimplemented
}

public static void processPtrField (VM_Address location, boolean root) throws VM_PragmaUninterruptible, VM_PragmaInline {
public static void processPtrField(VM_Address location, boolean root)
throws VM_PragmaUninterruptible, VM_PragmaInline {
Plan.traceObjectLocation(location, root);
}

/**
* A pointer location has been enumerated by ScanObject. This is
* the callback method, allowing the plan to perform an action with
* respect to that location.
*
* @param location An address known to contain a pointer. The
* location is within the object being scanned by ScanObject.
* @param plan The plan that initiated the object scan. A callback
* should be made to this plan.
*/
public static void enumeratePtrLoc(VM_Address location, Plan plan)
throws VM_PragmaUninterruptible, VM_PragmaInline {
plan.enumeratePointerLocation(location);
}

public static boolean isLive(VM_Address obj) throws VM_PragmaInline {
return Plan.isLive(obj);
}
Expand Down Expand Up @@ -456,16 +472,16 @@ public static void computeAllRoots(AddressQueue rootLocations,
VM_Address thAddr = VM_Magic.objectAsAddress(th);
VM_Thread th2 = VM_Magic.addressAsThread(Plan.traceObject(thAddr, true));
if (VM_Magic.objectAsAddress(th2).EQ(thAddr))
ScanObject.rootScan(thAddr);
ScanObject.rootScan(VM_Magic.objectAsAddress(th.stack));
ScanObject.rootScan(th);
ScanObject.rootScan(th.stack);
if (th.jniEnv != null) {
ScanObject.rootScan(VM_Magic.objectAsAddress(th.jniEnv));
ScanObject.rootScan(VM_Magic.objectAsAddress(th.jniEnv.refsArray()));
ScanObject.rootScan(th.jniEnv);
ScanObject.rootScan(th.jniEnv.refsArray());
}
ScanObject.rootScan(VM_Magic.objectAsAddress(th.contextRegisters));
ScanObject.rootScan(VM_Magic.objectAsAddress(th.contextRegisters.gprs));
ScanObject.rootScan(VM_Magic.objectAsAddress(th.hardwareExceptionRegisters));
ScanObject.rootScan(VM_Magic.objectAsAddress(th.hardwareExceptionRegisters.gprs));
ScanObject.rootScan(th.contextRegisters);
ScanObject.rootScan(th.contextRegisters.gprs);
ScanObject.rootScan(th.hardwareExceptionRegisters);
ScanObject.rootScan(th.hardwareExceptionRegisters.gprs);
ScanThread.scanThread(th2, rootLocations, codeLocations);
}
ScanObject.rootScan(VM_Magic.objectAsAddress(VM_Scheduler.threads));
Expand Down

0 comments on commit e7bc7a0

Please sign in to comment.