Skip to content

Commit

Permalink
Merge branch 'wip/pr-91' into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
fniephaus committed Dec 28, 2019
2 parents 8e1898b + e633184 commit abf8c29
Show file tree
Hide file tree
Showing 15 changed files with 152 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -129,4 +129,20 @@ public void test12InteropJavaMiscellaneous() {
fail(e.toString());
}
}

@Test
public void test13CannotReturnAtStart() {
assertEquals("bla2", evaluate("| result | \n" +
"[ result := [^'bla1'] on: BlockCannotReturn do: [:e | 'bla2' ]] fork. \n" +
"Processor yield.\n" +
"result").toString());
}

@Test
public void test14CannotReturnInTheMiddle() {
assertEquals("bla2", evaluate("| result | \n" +
"[ result := [thisContext yourself. ^'bla1'] on: BlockCannotReturn do: [:e | 'bla2' ]] fork. \n" +
"Processor yield.\n" +
"result").toString());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -256,10 +256,11 @@ public ExecuteTopLevelContextNode getDoItContextNode(final String source) {
final ContextObject doItContext = ContextObject.create(this, doItMethod.getSqueakContextSize());
doItContext.atput0(CONTEXT.METHOD, doItMethod);
doItContext.atput0(CONTEXT.INSTRUCTION_POINTER, (long) doItMethod.getInitialPC());
doItContext.atput0(CONTEXT.RECEIVER, nilClass);
doItContext.atput0(CONTEXT.STACKPOINTER, 0L);
doItContext.atput0(CONTEXT.RECEIVER, NilObject.SINGLETON);
doItContext.atput0(CONTEXT.STACKPOINTER, (long) doItMethod.getNumTemps());
doItContext.atput0(CONTEXT.CLOSURE_OR_NIL, NilObject.SINGLETON);
doItContext.atput0(CONTEXT.SENDER_OR_NIL, NilObject.SINGLETON);
doItContext.setProcess(getActiveProcessSlow());
return ExecuteTopLevelContextNode.create(getLanguage(), doItContext, false);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,10 @@ public SqueakImageContext getImage() {
return image;
}

public SqueakImageReader getReader() {
return reader;
}

public int getPosition() {
return position;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.logging.Level;

import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
Expand All @@ -18,12 +19,14 @@
import de.hpi.swa.graal.squeak.exceptions.SqueakExceptions.SqueakAbortException;
import de.hpi.swa.graal.squeak.image.SqueakImageContext;
import de.hpi.swa.graal.squeak.image.SqueakImageFlags;
import de.hpi.swa.graal.squeak.model.AbstractSqueakObject;
import de.hpi.swa.graal.squeak.model.AbstractSqueakObjectWithHash;
import de.hpi.swa.graal.squeak.model.ArrayObject;
import de.hpi.swa.graal.squeak.model.BooleanObject;
import de.hpi.swa.graal.squeak.model.ClassObject;
import de.hpi.swa.graal.squeak.model.ContextObject;
import de.hpi.swa.graal.squeak.model.NilObject;
import de.hpi.swa.graal.squeak.model.PointersObject;
import de.hpi.swa.graal.squeak.model.layout.ObjectLayouts.METACLASS;
import de.hpi.swa.graal.squeak.model.layout.ObjectLayouts.SPECIAL_OBJECT;
import de.hpi.swa.graal.squeak.model.layout.ObjectLayouts.SPECIAL_OBJECT_TAG;
Expand Down Expand Up @@ -60,6 +63,7 @@ public final class SqueakImageReader {
private final HashMap<Long, SqueakImageChunk> chunktable = new HashMap<>(750000);
private final SqueakImageContext image;
private final byte[] byteArrayBuffer = new byte[8];
private final Map<PointersObject, ContextObject> suspendedContexts = new HashMap<>();

private long headerSize;
private long oldBaseAddress;
Expand Down Expand Up @@ -114,10 +118,15 @@ private Object run() {
}
initObjects();
image.printToStdOut("Image loaded in", System.currentTimeMillis() - start + "ms.");
initializeSuspendedContexts();
image.initializeAfterLoadingImage();
return image.getSqueakImage();
}

public Map<PointersObject, ContextObject> getSuspendedContexts() {
return suspendedContexts;
}

private void readBytes(final byte[] bytes, final int length) {
try {
final int readBytes = stream.read(bytes, 0, length);
Expand Down Expand Up @@ -506,7 +515,7 @@ private void fillInSmallFloatClass() {
image.setSmallFloat((ClassObject) smallFloatClassOrNil);
}

public SqueakImageChunk getChunk(final long ptr) {
protected SqueakImageChunk getChunk(final long ptr) {
return chunktable.get(ptr);
}

Expand All @@ -526,6 +535,19 @@ public static int calculateObjectPadding(final int format) {
}
}

/* Set process in all ContextObjects. */
private void initializeSuspendedContexts() {
for (final PointersObject process : suspendedContexts.keySet()) {
AbstractSqueakObject currentContext = suspendedContexts.get(process);
while (currentContext != NilObject.SINGLETON) {
final ContextObject context = (ContextObject) currentContext;
context.setProcess(process);
currentContext = context.getSender();
}
}
suspendedContexts.clear();
}

/**
* Object Header Specification (see SpurMemoryManager).
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@

public final class ContextObject extends AbstractSqueakObjectWithHash {
@CompilationFinal private MaterializedFrame truffleFrame;
@CompilationFinal private PointersObject process;
@CompilationFinal private int size;
private boolean hasModifiedSender = false;
private boolean escaped = false;
Expand Down Expand Up @@ -537,6 +538,7 @@ public void transferTo(final AbstractPointersObjectReadNode readNode, final Abst
writeNode.execute(scheduler, PROCESS_SCHEDULER.ACTIVE_PROCESS, newProcess);
writeNode.execute(currentProcess, PROCESS.SUSPENDED_CONTEXT, this);
final ContextObject newActiveContext = (ContextObject) readNode.execute(newProcess, PROCESS.SUSPENDED_CONTEXT);
newActiveContext.setProcess(newProcess);
writeNode.execute(newProcess, PROCESS.SUSPENDED_CONTEXT, NilObject.SINGLETON);
if (CompilerDirectives.isPartialEvaluationConstant(newActiveContext)) {
throw ProcessSwitch.create(newActiveContext);
Expand Down Expand Up @@ -609,4 +611,13 @@ public void traceObjects(final ObjectTracer tracer) {
}
}
}

public PointersObject getProcess() {
return process;
}

public void setProcess(final PointersObject process) {
assert process != null && (this.process == null || this.process == process);
this.process = process;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ public void fillin(final SqueakImageChunk chunk) {
writeNode.execute(this, i, pointersObject[i]);
}
assert size() == pointersObject.length;
if (isProcess()) { /* Collect suspended contexts */
final AbstractPointersObjectReadNode readNode = AbstractPointersObjectReadNode.getUncached();
final ContextObject suspendedContext = (ContextObject) readNode.execute(this, PROCESS.SUSPENDED_CONTEXT);
chunk.getReader().getSuspendedContexts().put(this, suspendedContext);
}
}

public void become(final PointersObject other) {
Expand Down Expand Up @@ -89,6 +94,10 @@ public boolean isPoint() {
return getSqueakClass() == image.pointClass;
}

public boolean isProcess() {
return getSqueakClass() == image.processClass;
}

public int[] getFormBits(final AbstractPointersObjectReadNode readNode) {
return readNode.executeNative(this, FORM.BITS).getIntStorage();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ protected final Object doDirect(final VirtualFrame frame, @SuppressWarnings("unu
limit = "INLINE_CACHE_SIZE", assumptions = {"cachedMethod.getCallTargetStable()"}, replaces = {"doPrimitiveEagerly"})
protected static final Object doDirectWithSender(final VirtualFrame frame, @SuppressWarnings("unused") final CompiledMethodObject method, final Object[] receiverAndArguments,
@SuppressWarnings("unused") @Cached("method") final CompiledMethodObject cachedMethod,
@Cached("create(code)") final GetOrCreateContextNode getOrCreateContextNode,
@Cached("create(code, true)") final GetOrCreateContextNode getOrCreateContextNode,
@Cached("create(cachedMethod.getCallTarget())") final DirectCallNode callNode) {
return callDirect(callNode, cachedMethod, getOrCreateContextNode.executeGet(frame), receiverAndArguments);
}
Expand All @@ -70,7 +70,7 @@ protected final Object doIndirect(final VirtualFrame frame, final CompiledMethod

@Specialization(guards = "!method.getDoesNotNeedSenderAssumption().isValid()", replaces = {"doDirect", "doDirectWithSender"})
protected static final Object doIndirectWithSender(final VirtualFrame frame, final CompiledMethodObject method, final Object[] receiverAndArguments,
@Cached("create(code)") final GetOrCreateContextNode getOrCreateContextNode,
@Cached("create(code, true)") final GetOrCreateContextNode getOrCreateContextNode,
@Cached final IndirectCallNode callNode) {
return callIndirect(callNode, method, getOrCreateContextNode.executeGet(frame), receiverAndArguments);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@
import de.hpi.swa.graal.squeak.exceptions.Returns.NonLocalReturn;
import de.hpi.swa.graal.squeak.exceptions.Returns.NonVirtualReturn;
import de.hpi.swa.graal.squeak.model.CompiledCodeObject;
import de.hpi.swa.graal.squeak.model.ContextObject;
import de.hpi.swa.graal.squeak.nodes.ExecuteContextNodeFactory.TriggerInterruptHandlerNodeGen;
import de.hpi.swa.graal.squeak.nodes.accessing.AbstractPointersObjectNodes.AbstractPointersObjectReadNode;
import de.hpi.swa.graal.squeak.nodes.bytecodes.AbstractBytecodeNode;
import de.hpi.swa.graal.squeak.nodes.bytecodes.JumpBytecodes.ConditionalJumpNode;
import de.hpi.swa.graal.squeak.nodes.bytecodes.JumpBytecodes.UnconditionalJumpNode;
Expand All @@ -41,7 +43,6 @@
import de.hpi.swa.graal.squeak.nodes.bytecodes.SendBytecodes.AbstractSendNode;
import de.hpi.swa.graal.squeak.nodes.context.frame.FrameStackInitializationNode;
import de.hpi.swa.graal.squeak.shared.SqueakLanguageConfig;
import de.hpi.swa.graal.squeak.util.ArrayUtils;
import de.hpi.swa.graal.squeak.util.FrameAccess;
import de.hpi.swa.graal.squeak.util.InterruptHandlerNode;
import de.hpi.swa.graal.squeak.util.SqueakBytecodeDecoder;
Expand Down Expand Up @@ -93,7 +94,9 @@ public Object executeFresh(final VirtualFrame frame) {
final boolean enableStackDepthProtection = enableStackDepthProtection();
try {
if (enableStackDepthProtection && code.image.stackDepth++ > STACK_DEPTH_LIMIT) {
throw ProcessSwitch.createWithBoundary(getGetOrCreateContextNode().executeGet(frame));
final ContextObject context = getGetOrCreateContextNode().executeGet(frame);
context.setProcess(code.image.getActiveProcess(AbstractPointersObjectReadNode.getUncached()));
throw ProcessSwitch.createWithBoundary(context);
}
frameInitializationNode.executeInitialize(frame);
return startBytecode(frame);
Expand Down Expand Up @@ -141,7 +144,7 @@ public final Object executeResumeInMiddle(final VirtualFrame frame, final long i
private GetOrCreateContextNode getGetOrCreateContextNode() {
if (getOrCreateContextNode == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
getOrCreateContextNode = insert(GetOrCreateContextNode.create(code));
getOrCreateContextNode = insert(GetOrCreateContextNode.create(code, false));
}
return getOrCreateContextNode;
}
Expand All @@ -165,8 +168,7 @@ private Object startBytecode(final VirtualFrame frame) {
return callPrimitiveNode.primitiveNode.executePrimitive(frame);
} catch (final PrimitiveFailed e) {
getHandlePrimitiveFailedNode().executeHandle(frame, e.getReasonCode());
LOG.log(Level.FINE, () -> callPrimitiveNode.primitiveNode +
" (" + ArrayUtils.toJoinedString(", ", FrameAccess.getReceiverAndArguments(frame)) + ")");
LOG.log(Level.FINE, () -> "Failed primitive " + callPrimitiveNode.primitiveNode.getClass().getName());
/* continue with fallback code. */
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,32 @@

import de.hpi.swa.graal.squeak.model.CompiledCodeObject;
import de.hpi.swa.graal.squeak.model.ContextObject;
import de.hpi.swa.graal.squeak.nodes.accessing.AbstractPointersObjectNodes.AbstractPointersObjectReadNode;

public abstract class GetOrCreateContextNode extends AbstractNodeWithCode {

protected GetOrCreateContextNode(final CompiledCodeObject code) {
@Child private AbstractPointersObjectReadNode readNode = AbstractPointersObjectReadNode.create();

private final boolean setActiveProcess;

protected GetOrCreateContextNode(final CompiledCodeObject code, final boolean fromActiveProcess) {
super(code);
this.setActiveProcess = fromActiveProcess;
}

public static GetOrCreateContextNode create(final CompiledCodeObject code) {
return GetOrCreateContextNodeGen.create(code);
public static GetOrCreateContextNode create(final CompiledCodeObject code, final boolean fromActiveProcess) {
return GetOrCreateContextNodeGen.create(code, fromActiveProcess);
}

public abstract ContextObject executeGet(Frame frame);

@Specialization(guards = {"isVirtualized(frame)"})
protected final ContextObject doCreate(final VirtualFrame frame) {
return ContextObject.create(frame.materialize(), code);
final ContextObject result = ContextObject.create(frame.materialize(), code);
if (setActiveProcess) {
result.setProcess(code.image.getActiveProcess(readNode));
}
return result;
}

@Fallback
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ protected final void doStartMaterialization(final VirtualFrame frame) {
protected final void doMaterialize(final VirtualFrame frame,
@Cached("createBinaryProfile()") final ConditionProfile isNotLastSeenContextProfile,
@Cached("createBinaryProfile()") final ConditionProfile continueProfile,
@Cached("create(code)") final GetOrCreateContextNode getOrCreateContextNode) {
@Cached("create(code, true)") final GetOrCreateContextNode getOrCreateContextNode) {
final ContextObject lastSeenContext = code.image.lastSeenContext;
final ContextObject context = getOrCreateContextNode.executeGet(frame);
if (isNotLastSeenContextProfile.profile(context != lastSeenContext)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
package de.hpi.swa.graal.squeak.nodes;

import com.oracle.truffle.api.CompilerAsserts;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
Expand All @@ -16,15 +15,12 @@
import com.oracle.truffle.api.nodes.RootNode;

import de.hpi.swa.graal.squeak.SqueakLanguage;
import de.hpi.swa.graal.squeak.exceptions.SqueakExceptions.SqueakException;
import de.hpi.swa.graal.squeak.model.CompiledCodeObject;
import de.hpi.swa.graal.squeak.model.ContextObject;
import de.hpi.swa.graal.squeak.model.NilObject;

@NodeInfo(cost = NodeCost.NONE)
public abstract class ResumeContextNode extends Node {
@Child private ExecuteContextNode executeContextNode;
@Child private SendSelectorNode cannotReturnNode;

protected ResumeContextNode(final CompiledCodeObject code) {
executeContextNode = ExecuteContextNode.create(code, true);
Expand All @@ -45,20 +41,6 @@ protected final Object doResumeInMiddle(final ContextObject context) {
return executeContextNode.executeResumeInMiddle(context.getTruffleFrame(), initialPC);
}

@Specialization(guards = "context.getInstructionPointerForBytecodeLoop() < 0")
protected final Object doCannotReturn(final ContextObject context) {
getCannotReturnNode().executeSend(context.getTruffleFrame(), new Object[]{context, NilObject.SINGLETON});
throw SqueakException.create("Should not be reached");
}

private SendSelectorNode getCannotReturnNode() {
if (cannotReturnNode == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
cannotReturnNode = insert(SendSelectorNode.create(executeContextNode.code, executeContextNode.code.image.cannotReturn));
}
return cannotReturnNode;
}

@NodeInfo(cost = NodeCost.NONE)
public static final class ResumeContextRootNode extends RootNode {
private ContextObject activeContext;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public static final class PushActiveContextNode extends AbstractPushNode {

public PushActiveContextNode(final CompiledCodeObject code, final int index) {
super(code, index);
getContextNode = GetOrCreateContextNode.create(code);
getContextNode = GetOrCreateContextNode.create(code, true);
}

@Override
Expand Down Expand Up @@ -89,7 +89,7 @@ private PushClosureNode(final CompiledCodeObject code, final int index, final in
blockSize = j << 8 | k;
popNNode = FrameStackPopNNode.create(code, numCopied);
pushNode = FrameStackPushNode.create(code);
getOrCreateContextNode = GetOrCreateContextNode.create(code);
getOrCreateContextNode = GetOrCreateContextNode.create(code, true);
}

public PushClosureNode(final PushClosureNode node) {
Expand All @@ -99,7 +99,7 @@ public PushClosureNode(final PushClosureNode node) {
blockSize = node.blockSize;
popNNode = FrameStackPopNNode.create(code, numCopied);
pushNode = FrameStackPushNode.create(code);
getOrCreateContextNode = GetOrCreateContextNode.create(code);
getOrCreateContextNode = GetOrCreateContextNode.create(code, true);
}

public static PushClosureNode create(final CompiledCodeObject code, final int index, final int numBytecodes, final int i, final int j, final int k) {
Expand Down

0 comments on commit abf8c29

Please sign in to comment.