|
|||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object org.jikesrvm.mm.mmtk.ScanThread
public final class ScanThread
Class that supports scanning thread stacks for references during collections. References are located using GCMapIterators and are inserted into a set of root locations. Optionally, a set of interior pointer locations associated with the object is created.
Threads, stacks, jni environments, and register objects have a complex interaction in terms of scanning. The operation of scanning the stack reveals not only roots inside the stack but also the state of the register objects's gprs and the JNI refs array. They are all associated via the thread object, making it natural for scanThread to be considered a single operation with the method directly accessing these objects via the thread object's fields.
One pitfall occurs when scanning the thread object (plus dependents) when not all of the objects have been copied. Then it may be that the innards of the register object has not been copied while the stack object has. The result is that an inconsistent set of slots is reported. In this case, the copied register object may not be correct if the copy occurs after the root locations are discovered but before those locations are processed. In essence, all of these objects form one logical unit but are physically separated so that sometimes only part of it has been copied causing the scan to be incorrect.
The caller of the stack scanning routine must ensure that all of these components's descendants are consistent (all copied) when this method is called.
Code locations: Identifying pointers into code objects is essential if code objects are allowed to move (and if the code objects were not otherwise kept alive, it would be necessary to ensure the liveness of the code objects). A code pointer is the only case in which we have interior pointers (pointers into the inside of objects). For such pointers, two things must occur: first the pointed to object must be kept alive, and second, if the pointed to object is moved by a copying collector, the pointer into the object must be adjusted so it now points into the newly copied object.
Field Summary | |
---|---|
private CompiledMethod |
compiledMethod
|
private int |
compiledMethodType
|
private static int |
DEFAULT_VERBOSITY
|
private boolean |
failed
|
private static int |
FAILURE_VERBOSITY
|
private Address |
fp
|
private Address |
initialIPLoc
|
private Address |
ip
|
private GCMapIterator |
iterator
|
private GCMapIteratorGroup |
iteratorGroup
|
private Address |
prevFp
|
private boolean |
processCodeLocations
|
private RVMThread |
thread
|
private Address |
topFrame
|
private TraceLocal |
trace
|
(package private) static boolean |
VALIDATE_REFS
quietly validates each ref reported by map iterators |
Fields inherited from interface org.jikesrvm.Constants |
---|
NOT_REACHED, REFLECTION_FPRS_BITS, REFLECTION_FPRS_MASK, REFLECTION_GPRS_BITS, REFLECTION_GPRS_MASK |
Fields inherited from interface org.jikesrvm.objectmodel.ThinLockConstants |
---|
TL_DEDICATED_U16_OFFSET, TL_DEDICATED_U16_SHIFT, TL_LOCK_COUNT_MASK, TL_LOCK_COUNT_SHIFT, TL_LOCK_COUNT_UNIT, TL_LOCK_ID_MASK, TL_LOCK_ID_SHIFT, TL_NUM_BITS_RC, TL_NUM_BITS_STAT, TL_NUM_BITS_TID, TL_STAT_BIASABLE, TL_STAT_FAT, TL_STAT_MASK, TL_STAT_SHIFT, TL_STAT_THIN, TL_THREAD_ID_MASK, TL_THREAD_ID_SHIFT, TL_UNLOCK_MASK |
Fields inherited from interface org.jikesrvm.objectmodel.TIBLayoutConstants |
---|
IMT_METHOD_SLOTS, NEEDS_DYNAMIC_LINK, TIB_ARRAY_ELEMENT_TIB_INDEX, TIB_DOES_IMPLEMENT_INDEX, TIB_FIRST_SPECIALIZED_METHOD_INDEX, TIB_FIRST_VIRTUAL_METHOD_INDEX, TIB_INTERFACE_DISPATCH_TABLE_INDEX, TIB_SUPERCLASS_IDS_INDEX, TIB_TYPE_INDEX |
Fields inherited from interface org.jikesrvm.HeapLayoutConstants |
---|
BAD_MAP_COMPRESSION, BOOT_IMAGE_CODE_END, BOOT_IMAGE_CODE_SIZE, BOOT_IMAGE_CODE_START, BOOT_IMAGE_DATA_END, BOOT_IMAGE_DATA_SIZE, BOOT_IMAGE_DATA_START, BOOT_IMAGE_END, BOOT_IMAGE_RMAP_END, BOOT_IMAGE_RMAP_START, MAX_BOOT_IMAGE_RMAP_SIZE, MAXIMUM_MAPPABLE |
Constructor Summary | |
---|---|
ScanThread()
|
Method Summary | |
---|---|
private void |
assertImmovableInCurrentCollection()
Assert that the stack is immovable. |
private void |
checkJNIBase()
AIX-specific code. |
private static void |
checkReference(Address refaddr)
Check that a reference encountered during scanning is valid. |
private void |
checkReference(Address refaddr,
int verbosity)
Check that a reference encountered during scanning is valid. |
private void |
dumpRef(Address refaddr,
int verbosity)
Print out information associated with a reference. |
private void |
dumpStackFrame(int verbosity)
Dump the contents of a stack frame. |
private void |
dumpTopFrameInfo(int verbosity)
Print out the basic information associated with the top frame on the stack. |
private void |
getHWExceptionRegisters()
When an exception occurs, registers are saved temporarily. |
private void |
printMethod(RVMMethod m)
Print out the name of a method |
private void |
printMethodHeader()
Print out the method header for the method associated with the current frame |
private void |
processCodeLocation(ObjectReference code,
Address ipLoc)
Push a code pointer location onto the code locations deque, optionally performing a sanity check first. |
private void |
processFrameForCode(int verbosity)
Identify all pointers into code pointers associated with a frame. |
private void |
pushFrameIP(ObjectReference code,
int verbosity)
Push the instruction pointer associated with this frame onto the code locations deque. |
private static void |
reportDelayedRootEdge(TraceLocal trace,
Address addr)
Wrapper for TraceLocal.reportDelayedRootEdge(Address) that allows
sanity checking of the address. |
private Address |
scanFrame(int verbosity)
Scan the current stack frame. |
private void |
scanFrameForCode(ObjectReference code)
Scan this frame for internal code pointers. |
private void |
scanFrameForObjects(int verbosity)
Identify all the object pointers stored as local variables associated with (though not necessarily strictly within!) |
static void |
scanThread(RVMThread thread,
TraceLocal trace,
boolean processCodeLocations)
Scan a thread, placing the addresses of pointers into supplied buffers. |
private static void |
scanThread(RVMThread thread,
TraceLocal trace,
boolean processCodeLocations,
Address gprs,
Address topFrame)
A more general interface to thread scanning, which permits the scanning of stack segments which are dislocated from the thread structure. |
private void |
scanThreadInternal(Address gprs,
int verbosity)
The main stack scanning loop. |
private boolean |
setUpFrame(int verbosity)
Set up to scan the current stack frame. |
private void |
startScan(TraceLocal trace,
boolean processCodeLocations,
RVMThread thread,
Address gprs,
Address ip,
Address fp,
Address initialIPLoc,
Address topFrame)
Initializes a ScanThread instance, and then scans a stack associated with a thread, and places references in deques (one for object pointers, one for interior code pointers). |
Methods inherited from class java.lang.Object |
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
Field Detail |
---|
static final boolean VALIDATE_REFS
private static final int DEFAULT_VERBOSITY
private static final int FAILURE_VERBOSITY
private final GCMapIteratorGroup iteratorGroup
private GCMapIterator iterator
private TraceLocal trace
private boolean processCodeLocations
private RVMThread thread
private Address ip
private Address fp
private Address prevFp
private Address initialIPLoc
private Address topFrame
private CompiledMethod compiledMethod
private int compiledMethodType
private boolean failed
Constructor Detail |
---|
public ScanThread()
Method Detail |
---|
public static void scanThread(RVMThread thread, TraceLocal trace, boolean processCodeLocations)
thread
- The thread to be scannedtrace
- The trace instance to use for reporting references.processCodeLocations
- Should code locations be processed?private static void reportDelayedRootEdge(TraceLocal trace, Address addr)
TraceLocal.reportDelayedRootEdge(Address)
that allows
sanity checking of the address.
private static void scanThread(RVMThread thread, TraceLocal trace, boolean processCodeLocations, Address gprs, Address topFrame)
thread
- The thread to be scannedtrace
- The trace instance to use for reporting references.processCodeLocations
- Should code locations be processed?gprs
- The general purpose registers associated with the
stack being scanned (normally extracted from the thread).topFrame
- The top frame of the stack being scanned, or zero
if this is to be inferred from the thread (normally the case).private void startScan(TraceLocal trace, boolean processCodeLocations, RVMThread thread, Address gprs, Address ip, Address fp, Address initialIPLoc, Address topFrame)
The various state associated with stack scanning is captured by instance variables of this type, which are initialized here.
trace
- The trace instance to use for reporting locations.thread
- Thread for the thread whose stack is being scannedgprs
- The general purpose registers associated with the
stack being scanned (normally extracted from the thread).ip
- The instruction pointer for the top frame of the stack
we're about to scan.fp
- The frame pointer for the top frame of the stack we're
about to scan.private void scanThreadInternal(Address gprs, int verbosity)
Walk the stack one frame at a time, top (lo) to bottom (hi),
gprs
- The general purpose registers associated with the
stack being scanned (normally extracted from the thread).verbosity
- The level of verbosity to be used when
performing the scan.private void getHWExceptionRegisters()
private void processCodeLocation(ObjectReference code, Address ipLoc)
code
- The code object into which this interior pointer pointsipLoc
- The location of the pointer into this code objectprivate Address scanFrame(int verbosity)
First the various iterators are set up, then the frame is scanned for regular pointers, before scanning for code pointers. The iterators are then cleaned up, and native frames skipped if necessary.
verbosity
- The level of verbosity to be used when
performing the scan.private boolean setUpFrame(int verbosity)
verbosity
- The level of verbosity to be used when
performing the scan.
private void scanFrameForObjects(int verbosity)
NOTE: Because of the callee save policy of the optimizing compiler, references associated with a given frame may be in callee stack frames (lower memory), outside the current frame. So the iterator may return locations that are outside the frame being scanned.
verbosity
- The level of verbosity to be used when
performing the scan.private void processFrameForCode(int verbosity)
FIXME: SB: Why is it that JNI frames are skipped when considering top of stack frames, while boot image frames are skipped when considering other frames. Shouldn't they both be considered in both cases?
verbosity
- The level of verbosity to be used when
performing the scan.private void pushFrameIP(ObjectReference code, int verbosity)
A stack frame represents an execution context, and thus has an instruction pointer associated with it. In the case of the top frame, the instruction pointer is captured by the IP register, which is preserved in the thread data structure at thread switch time. In the case of all non-top frames, the next instruction pointer is stored as the return address for the previous frame.
The address of the code pointer is pushed onto the code locations deque along with the address of the code object into which it points (both are required since the former is an internal pointer).
The code pointers are updated later (after stack scanning) when the code locations deque is processed. The pointer from RVMMethod to the code object is not updated until after stack scanning, so the pointer to the (uncopied) code object is available throughout the stack scanning process, which enables interior pointer offsets to be correctly computed.
verbosity
- The level of verbosity to be used when
performing the scan.private void scanFrameForCode(ObjectReference code)
code
- The code object associated with this frame.private void checkJNIBase()
If we are scanning the stack of a thread that entered the VM via a createVM or attachVM then the "bottom" of the stack had native C frames instead of the usual java frames. The JNIEnv for the thread may still contain jniRefs that have been returned to the native C code, but have not been reported for GC. calling getNextReferenceAddress without first calling setup... will report the remaining jniRefs in the current "frame" of the jniRefs stack. (this should be the bottom frame)
FIXME: SB: Why is this AIX specific? Why depend on the preprocessor?
private void assertImmovableInCurrentCollection()
Currently we do not allow stacks to be moved within the heap. If a stack contains native stack frames, then it is impossible for us to safely move it. Prior to the implementation of JNI, Jikes RVM did allow the GC system to move thread stacks, and called a special fixup routine, thread.fixupMovedStack to adjust all of the special interior pointers (SP, FP). If we implement split C & Java stacks then we could allow the Java stacks to be moved, but we can't move the native stack.
private void dumpTopFrameInfo(int verbosity)
verbosity
- The level of verbosity to be used when
performing the scan.private void dumpRef(Address refaddr, int verbosity)
refaddr
- The address of the reference in question.verbosity
- The level of verbosity to be used when
performing the scan.private void checkReference(Address refaddr, int verbosity)
refaddr
- The address of the reference in question.verbosity
- The level of verbosity to be used when
performing the scan.private static void checkReference(Address refaddr)
refaddr
- The address of the reference in question.private void printMethod(RVMMethod m)
m
- The method to be printedprivate void printMethodHeader()
private void dumpStackFrame(int verbosity)
verbosity
- The level of verbosity to be used when
performing the scan.
|
|||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |