Skip to content

Commit

Permalink
Fixed testMoveVarFromSubToSuperclass
Browse files Browse the repository at this point in the history
in ClassBuilderTest and minor refactoring
  • Loading branch information
Johannes Henning authored and fniephaus committed Feb 21, 2019
1 parent 010ea7a commit 100edc3
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 50 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -428,10 +428,7 @@ ClassBuilderTest>>testDoubleByteVariableSubclass=passing
ClassBuilderTest>>testDoubleWordVariableSubclass=passing
ClassBuilderTest>>testDuplicateClassVariableError=passing
ClassBuilderTest>>testDuplicateInstanceVariableError=passing

# Fails because of primitive 173
ClassBuilderTest>>testMoveVarFromSubToSuperclass=failing

ClassBuilderTest>>testMoveVarFromSubToSuperclass=passing
ClassBuilderTest>>testMoveVarFromSuperToSubclass=passing
ClassBuilderTest>>testNew=passing
ClassBuilderTest>>testNewUniclass=passing
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import de.hpi.swa.graal.squeak.model.ContextObject;
import de.hpi.swa.graal.squeak.model.PointersObject;
import de.hpi.swa.graal.squeak.nodes.AbstractNodeWithImage;
import de.hpi.swa.graal.squeak.nodes.accessing.SqueakObjectPointersBecomeOneWayNode;
import de.hpi.swa.graal.squeak.util.FrameAccess;

public final class ObjectGraphNode extends AbstractNodeWithImage {
Expand Down Expand Up @@ -55,6 +56,22 @@ public AbstractCollection<AbstractSqueakObject> executeAllInstances() {
return seen;
}

@TruffleBoundary
public void executePointersBecomeOneWay(final SqueakObjectPointersBecomeOneWayNode pointersBecomeNode, final Object[] fromPointers,
final Object[] toPointers, final boolean copyHash) {
final HashSet<AbstractSqueakObject> seen = new HashSet<>((int) (lastSeenObjects / SEEN_LOAD_FACTOR), SEEN_LOAD_FACTOR);
final ArrayDeque<AbstractSqueakObject> pending = new ArrayDeque<>(PENDING_INITIAL_SIZE);
pending.add(image.specialObjectsArray);
while (!pending.isEmpty()) {
final AbstractSqueakObject currentObject = pending.pop();
if (seen.add(currentObject)) {
pointersBecomeNode.execute(currentObject, fromPointers, toPointers, copyHash);
tracePointers(pending, currentObject);
}
}
lastSeenObjects = seen.size();
}

@TruffleBoundary
public AbstractCollection<AbstractSqueakObject> executeAllInstancesOf(final ClassObject classObj) {
assert classObj != image.nilClass;
Expand Down Expand Up @@ -97,16 +114,17 @@ public AbstractSqueakObject executeSomeInstanceOf(final ClassObject classObj) {
}

@TruffleBoundary
private void addObjectsFromTruffleFrames(final ArrayDeque<AbstractSqueakObject> pending) {
private static void addObjectsFromTruffleFrames(final ArrayDeque<AbstractSqueakObject> pending) {
Truffle.getRuntime().iterateFrames(frameInstance -> {
final Frame current = frameInstance.getFrame(FrameInstance.FrameAccess.READ_ONLY);
if (!FrameAccess.isGraalSqueakFrame(current)) {
return null;
}
for (final Object argument : current.getArguments()) {
addIfHasTraceablePointers(pending, argument);
addIfAbstractSqueakObject(pending, argument);
}
final CompiledCodeObject blockOrMethod = FrameAccess.getBlockOrMethod(current);

final FrameDescriptor frameDescriptor = blockOrMethod.getFrameDescriptor();
final ContextObject context = FrameAccess.getContext(current, blockOrMethod);
if (context != null) {
Expand All @@ -116,7 +134,7 @@ private void addObjectsFromTruffleFrames(final ArrayDeque<AbstractSqueakObject>
for (final FrameSlot slot : stackSlots) {
final FrameSlotKind currentSlotKind = frameDescriptor.getFrameSlotKind(slot);
if (currentSlotKind == FrameSlotKind.Object) {
addIfHasTraceablePointers(pending, FrameUtil.getObjectSafe(current, slot));
addIfAbstractSqueakObject(pending, FrameUtil.getObjectSafe(current, slot));
} else if (currentSlotKind == FrameSlotKind.Illegal) {
return null; // Stop here, because this slot and all following are not used.
}
Expand All @@ -125,84 +143,69 @@ private void addObjectsFromTruffleFrames(final ArrayDeque<AbstractSqueakObject>
});
}

private void tracePointers(final ArrayDeque<AbstractSqueakObject> pending, final AbstractSqueakObject currentObject) {
private static void tracePointers(final ArrayDeque<AbstractSqueakObject> pending, final AbstractSqueakObject currentObject) {
final ClassObject sqClass = currentObject.getSqueakClass();
if (sqClass != null) {
pending.add(sqClass);
}
addTraceablePointers(pending, currentObject);
}

private void addIfHasTraceablePointers(final ArrayDeque<AbstractSqueakObject> pending, final Object argument) {
if (hasTraceablePointers(argument)) {
private static void addIfAbstractSqueakObject(final ArrayDeque<AbstractSqueakObject> pending, final Object argument) {
if (argument instanceof AbstractSqueakObject) {
pending.add((AbstractSqueakObject) argument);
}
}

private boolean hasTraceablePointers(final Object object) {
return object != image.nil && (object instanceof ClassObject ||
object instanceof BlockClosureObject ||
object instanceof ContextObject && ((ContextObject) object).hasTruffleFrame() ||
object instanceof CompiledMethodObject ||
object instanceof ArrayObject && ((ArrayObject) object).isTraceableObjectType() ||
object instanceof PointersObject);
}

private void addTraceablePointers(final ArrayDeque<AbstractSqueakObject> pending, final AbstractSqueakObject object) {
private static void addTraceablePointers(final ArrayDeque<AbstractSqueakObject> pending, final AbstractSqueakObject object) {
if (object instanceof ClassObject) {
final ClassObject classObject = (ClassObject) object;
addIfHasTraceablePointers(pending, classObject.getSuperclass());
addIfHasTraceablePointers(pending, classObject.getMethodDict());
addIfHasTraceablePointers(pending, classObject.getInstanceVariables());
addIfHasTraceablePointers(pending, classObject.getOrganization());
addIfAbstractSqueakObject(pending, classObject.getSuperclass());
addIfAbstractSqueakObject(pending, classObject.getMethodDict());
addIfAbstractSqueakObject(pending, classObject.getInstanceVariables());
addIfAbstractSqueakObject(pending, classObject.getOrganization());
for (final Object value : classObject.getOtherPointers()) {
addIfHasTraceablePointers(pending, value);
addIfAbstractSqueakObject(pending, value);
}
} else if (object instanceof BlockClosureObject) {
final BlockClosureObject closure = (BlockClosureObject) object;
addIfHasTraceablePointers(pending, closure.getReceiver());
addIfHasTraceablePointers(pending, closure.getOuterContext());
addIfAbstractSqueakObject(pending, closure.getReceiver());
addIfAbstractSqueakObject(pending, closure.getOuterContext());
for (final Object value : closure.getCopied()) {
addIfHasTraceablePointers(pending, value);
addIfAbstractSqueakObject(pending, value);
}
} else if (object instanceof ContextObject) {
final ContextObject context = (ContextObject) object;
if (context.hasTruffleFrame()) {
addIfHasTraceablePointers(pending, context.getSender());
addIfHasTraceablePointers(pending, context.getMethod());
addIfAbstractSqueakObject(pending, context.getSender());
addIfAbstractSqueakObject(pending, context.getMethod());
if (context.hasClosure()) {
pending.add(context.getClosure());
}
addIfHasTraceablePointers(pending, context.getReceiver());
addIfAbstractSqueakObject(pending, context.getReceiver());
for (int i = 0; i < context.getBlockOrMethod().getNumStackSlots(); i++) {
addIfHasTraceablePointers(pending, context.atTemp(i));
addIfAbstractSqueakObject(pending, context.atTemp(i));
}
} else {
assert false : "Should not happen";
}
} else if (object instanceof CompiledMethodObject) {
for (final Object literal : ((CompiledMethodObject) object).getLiterals()) {
addIfHasTraceablePointers(pending, literal);
addIfAbstractSqueakObject(pending, literal);
}
} else if (object instanceof ArrayObject) {
final ArrayObject array = (ArrayObject) object;
if (array.isObjectType()) {
for (final Object value : array.getObjectStorage()) {
addIfHasTraceablePointers(pending, value);
addIfAbstractSqueakObject(pending, value);
}
} else if (array.isAbstractSqueakObjectType()) {
for (final Object value : array.getAbstractSqueakObjectStorage()) {
addIfHasTraceablePointers(pending, value);
addIfAbstractSqueakObject(pending, value);
}
} else {
assert false : "Should not happen";
}
} else if (object instanceof PointersObject) {
for (final Object pointer : ((PointersObject) object).getPointers()) {
addIfHasTraceablePointers(pending, pointer);
addIfAbstractSqueakObject(pending, pointer);
}
} else {
assert false : "Should not happen";
}
/**
* No need to trace weak pointers objects. Their pointers are reachable from other objects
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,18 +84,11 @@ protected final AbstractSqueakObject performPointersBecomeOneWay(final ArrayObje
final Object[] toPointers = getObjectArrayNode.execute(toArray);
// Need to operate on copy of `fromPointers` because itself will also be changed.
final Object[] fromPointersClone = fromPointers.clone();
migrateInstances(fromPointersClone, toPointers, copyHash, objectGraphNode.executeAllInstances());
objectGraphNode.executePointersBecomeOneWay(pointersBecomeNode, fromPointersClone, toPointers, copyHash);
patchTruffleFrames(fromPointersClone, toPointers, copyHash);
return fromArray;
}

@TruffleBoundary
private void migrateInstances(final Object[] fromPointers, final Object[] toPointers, final boolean copyHash, final AbstractCollection<AbstractSqueakObject> instances) {
for (final AbstractSqueakObject instance : instances) {
pointersBecomeNode.execute(instance, fromPointers, toPointers, copyHash);
}
}

@TruffleBoundary
private void patchTruffleFrames(final Object[] fromPointers, final Object[] toPointers, final boolean copyHash) {
final int fromPointersLength = fromPointers.length;
Expand Down

0 comments on commit 100edc3

Please sign in to comment.