gcmarkvisitor.java
来自「纯java操作系统jnode,安装简单和操作简单的个人使用的Java操作系统」· Java 代码 · 共 270 行
JAVA
270 行
/*
* $Id: GCMarkVisitor.java,v 1.5 2004/02/18 06:59:20 epr Exp $
*/
package org.jnode.vm.memmgr.def;
import org.jnode.vm.Address;
import org.jnode.vm.Monitor;
import org.jnode.vm.ObjectVisitor;
import org.jnode.vm.Uninterruptible;
import org.jnode.vm.Unsafe;
import org.jnode.vm.VmArchitecture;
import org.jnode.vm.VmThread;
import org.jnode.vm.classmgr.ObjectFlags;
import org.jnode.vm.classmgr.VmArrayClass;
import org.jnode.vm.classmgr.VmNormalClass;
import org.jnode.vm.classmgr.VmType;
import org.jnode.vm.memmgr.HeapHelper;
/**
* @author epr
*/
final class GCMarkVisitor extends ObjectVisitor implements ObjectFlags,
Uninterruptible {
/** The marking stack */
private final GCStack stack;
/** The number of marked objects. */
private int markedObjects;
/**
* If true, all white and grey objects will be marked, otherwise only the
* grey objects will be marked
*/
private boolean rootSet;
private final VmArchitecture arch;
private final int slotSize;
private final DefaultHeapManager heapManager;
private final HeapHelper helper;
/**
* Create a new instance
*
* @param stack
*/
public GCMarkVisitor(DefaultHeapManager heapManager, VmArchitecture arch,
GCStack stack) {
this.heapManager = heapManager;
this.stack = stack;
this.markedObjects = 0;
this.rootSet = false;
this.arch = arch;
this.helper = heapManager.getHelper();
this.slotSize = arch.getReferenceSize();
}
/**
* @param object
* @see org.jnode.vm.ObjectVisitor#visit(java.lang.Object)
* @return boolean
*/
public boolean visit(Object object) {
// Be very paranoia for now
/*
* if (!heapManager.isObject(helper.addressOf(object))) {
* Unsafe.debug("visit got non-object");
* Unsafe.debug(helper.addressToLong(helper.addressOf(object)));
* Unsafe.getCurrentProcessor().getArchitecture().getStackReader()
* .debugStackTrace(); helper.die("Internal error"); return false;
*/
//testObject(object, Unsafe.getVmClass(object));
// Check the current color first, since a stackoverflow of
// the mark stack results in another iteration of visits.
final int gcColor = helper.getObjectColor(object);
if (gcColor == GC_BLACK) {
return true;
} else if (rootSet || (gcColor == GC_GREY)) {
switch (gcColor) {
case GC_WHITE:
case GC_YELLOW:
{
final boolean ok;
ok = helper.atomicChangeObjectColor(object, gcColor,
GC_GREY);
if (!ok) {
Unsafe.debug("Could not change object color. ");
}
}
break;
case GC_GREY:
break;
default:
{
Unsafe.debug("color");
Unsafe.debug(gcColor);
helper.die("Unknown GC color on object");
}
}
stack.push(object);
mark();
}
final boolean rc = (!stack.isOverflow());
return rc;
}
/**
* Reset this visitor to its original state.
*/
public void reset() {
this.markedObjects = 0;
}
/**
* Process all objects on the markstack, until the markstack is empty.
*/
protected void mark() {
while (!stack.isEmpty()) {
final Object object = stack.pop();
markedObjects++;
final VmType vmClass = helper.getVmClass(object);
if (vmClass == null) {
Unsafe.debug("Oops vmClass == null in (");
Unsafe.debug(markedObjects);
Unsafe.debug(")");
helper.die("vmClass == null in mark()");
} else if (vmClass.isArray()) {
if (!((VmArrayClass) vmClass).isPrimitiveArray()) {
markArray(object);
}
} else {
markObject(object, (VmNormalClass) vmClass);
if (object instanceof VmThread) {
try {
markThreadStack((VmThread) object);
} catch (ClassCastException ex) {
Unsafe.debug("VmThread");
Unsafe.debug(object.getClass().getName());
helper.die("GCMarkVisitor.mark");
}
}
}
processChild(helper.getTib(object));
final Monitor monitor = helper.getInflatedMonitor(object, arch);
if (monitor != null) {
processChild(monitor);
}
final int gcColor = helper.getObjectColor(object);
helper.atomicChangeObjectColor(object, gcColor, GC_BLACK);
}
}
/**
* Mark all elements in the given array. The array must contain references
* only.
*
* @param object
*/
private void markArray(Object object) {
try {
final Object[] arr = (Object[]) object;
final int length = arr.length;
for (int i = 0; i < length; i++) {
final Object child = arr[ i];
if (child != null) {
processChild(child);
}
}
} catch (ClassCastException ex) {
System.out.println("object.class=" + object.getClass().getName());
throw ex;
}
}
/**
* Mark all instance variables of the given object.
*
* @param object
* @param vmClass
*/
private void markObject(Object object, VmNormalClass vmClass) {
final int[] referenceOffsets = vmClass.getReferenceOffsets();
final int cnt = referenceOffsets.length;
final int size = vmClass.getObjectSize();
for (int i = 0; i < cnt; i++) {
int offset = referenceOffsets[ i];
if ((offset < 0) || (offset >= size)) {
Unsafe.debug("reference offset out of range!");
Unsafe.debug(vmClass.getName());
helper.die("Class internal error");
} else {
final Object child = helper.getObject(object, offset);
if (child != null) {
processChild(child);
}
}
}
}
/**
* Mark all objects on the stack of the given thread
*
* @param thread
*/
private void markThreadStack(VmThread thread) {
// For now do it stupid, but safe, just scan the whole stack.
final int stackSize = thread.getStackSize();
final Object stack = helper.getStack(thread);
if (stack != null) {
for (int i = 0; i < stackSize; i += slotSize) {
Address child = Unsafe.getAddress(stack, i);
if (child != null) {
if (heapManager.isObject(child)) {
processChild(child);
}
}
}
}
}
/**
* Process a child of an object (this child is a reference).
*
* @param child
*/
private void processChild(Object child) {
final int gcColor = helper.getObjectColor(child);
if (gcColor <= GC_WHITE) {
// Yellow or White
helper.atomicChangeObjectColor(child, gcColor, GC_GREY);
stack.push(child);
}
}
/**
* Gets the number of objects marked by this visitor.
*
* @return int
*/
public int getMarkedObjects() {
return markedObjects;
}
/**
* Gets the rootSet attribute.
*
* @return boolean
*/
public boolean isRootSet() {
return rootSet;
}
/**
* Sets the rootSet attribute.
*
* @param b
* If true, all white and grey objects will be marked, otherwise
* only the grey objects will be marked.
*/
public void setRootSet(boolean b) {
rootSet = b;
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?