Skip to content

Commit

Permalink
Add support for Sista bytecode set
Browse files Browse the repository at this point in the history
  • Loading branch information
fniephaus committed Dec 9, 2020
1 parent ed3df0c commit 9e53c4c
Show file tree
Hide file tree
Showing 18 changed files with 1,593 additions and 267 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ protected static CompiledCodeObject makeMethod(final Object[] literals, final in
}

protected static long makeHeader(final int numArgs, final int numTemps, final int numLiterals, final boolean hasPrimitive, final boolean needsLargeFrame) { // shortcut
return CompiledCodeObject.makeHeader(numArgs, numTemps, numLiterals, hasPrimitive, needsLargeFrame);
return CompiledCodeObject.makeHeader(true, numArgs, numTemps, numLiterals, hasPrimitive, needsLargeFrame);
}

protected CompiledCodeObject makeMethod(final int... intbytes) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@
import de.hpi.swa.trufflesqueak.model.NilObject;
import de.hpi.swa.trufflesqueak.model.layout.ObjectLayouts.CONTEXT;
import de.hpi.swa.trufflesqueak.nodes.bytecodes.AbstractBytecodeNode;
import de.hpi.swa.trufflesqueak.nodes.bytecodes.JumpBytecodes.ConditionalFalseJumpNode;
import de.hpi.swa.trufflesqueak.nodes.bytecodes.JumpBytecodes.ConditionalJumpOnFalseNode;
import de.hpi.swa.trufflesqueak.nodes.bytecodes.MiscellaneousBytecodes.DupNode;
import de.hpi.swa.trufflesqueak.nodes.bytecodes.MiscellaneousBytecodes.PopNode;
import de.hpi.swa.trufflesqueak.nodes.bytecodes.PushBytecodes.PushConstantNode.PushConstantNilNode;
import de.hpi.swa.trufflesqueak.nodes.bytecodes.PushBytecodes.PushConstantNode.PushConstantOneNode;
import de.hpi.swa.trufflesqueak.nodes.bytecodes.PushBytecodes.PushConstantNode.PushConstantTrueNode;
import de.hpi.swa.trufflesqueak.nodes.bytecodes.PushBytecodes.PushConstantNilNode;
import de.hpi.swa.trufflesqueak.nodes.bytecodes.PushBytecodes.PushConstantOneNode;
import de.hpi.swa.trufflesqueak.nodes.bytecodes.PushBytecodes.PushConstantTrueNode;
import de.hpi.swa.trufflesqueak.nodes.bytecodes.ReturnBytecodes.ReturnReceiverNode;
import de.hpi.swa.trufflesqueak.util.SqueakBytecodeDecoder;
import de.hpi.swa.trufflesqueak.nodes.bytecodes.SqueakBytecodeV3PlusClosuresDecoder;
import de.hpi.swa.trufflesqueak.util.UnsafeUtils;

public class SqueakMiscellaneousTest extends AbstractSqueakTestCaseWithDummyImage {
Expand Down Expand Up @@ -118,15 +118,15 @@ public void testIfNil() {
// pushConstant: true, send: class, pop, returnSelf
final int[] bytes = {0x76, 0x88, 0x73, 0xc6, 0x99, 0x87, 0x71, 0xc7, 0x87, 0x78};
final CompiledCodeObject code = makeMethod(bytes);
final AbstractBytecodeNode[] bytecodeNodes = SqueakBytecodeDecoder.decode(code);
final AbstractBytecodeNode[] bytecodeNodes = SqueakBytecodeV3PlusClosuresDecoder.decode(code);
assertEquals(bytes.length, bytecodeNodes.length);
assertSame(PushConstantOneNode.class, bytecodeNodes[0].getClass());
assertSame(DupNode.class, bytecodeNodes[1].getClass());
assertSame(PushConstantNilNode.class, bytecodeNodes[2].getClass());

assertEquals("send: ==", bytecodeNodes[3].toString());

assertSame(ConditionalFalseJumpNode.class, bytecodeNodes[4].getClass());
assertSame(ConditionalJumpOnFalseNode.class, bytecodeNodes[4].getClass());
assertSame(PopNode.class, bytecodeNodes[5].getClass());
assertSame(PushConstantTrueNode.class, bytecodeNodes[6].getClass());

Expand All @@ -142,7 +142,7 @@ public void testSource() {
// with
// numTemp=55
final CompiledCodeObject code = makeMethod(literals, 0x70, 0x68, 0x10, 0x8F, 0x10, 0x00, 0x02, 0x10, 0x7D, 0xC9, 0x7C);
final CharSequence source = SqueakBytecodeDecoder.decodeToString(code);
final CharSequence source = SqueakBytecodeV3PlusClosuresDecoder.decodeToString(code);
assertEquals(String.join("\n",
"1 <70> self",
"2 <68> popIntoTemp: 0",
Expand Down Expand Up @@ -186,7 +186,7 @@ public void testSourceAllBytecodes() {
176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188,
189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201,
202, 203, 204, 205, 206, 207, 208, 225, 240);
final CharSequence source = SqueakBytecodeDecoder.decodeToString(code);
final CharSequence source = SqueakBytecodeV3PlusClosuresDecoder.decodeToString(code);
assertEquals(ALL_BYTECODES_EXPECTED_RESULT, source);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ public final class SqueakImageContext {
public final ClassObject metaClass = new ClassObject(this);
public final ClassObject nilClass = new ClassObject(this);

public final CompiledCodeObject dummyMethod = new CompiledCodeObject(this, null, new Object[]{CompiledCodeObject.makeHeader(1, 0, 0, false, true)}, compiledMethodClass);
public final CompiledCodeObject dummyMethod = new CompiledCodeObject(this, null, new Object[]{CompiledCodeObject.makeHeader(true, 1, 0, 0, false, true)}, compiledMethodClass);

/* Method Cache */
private static final int METHOD_CACHE_SIZE = 1024;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,9 +168,16 @@ private void initializeCompiledBlock(final CompiledCodeObject method) {
CompilerDirectives.transferToInterpreterAndInvalidate();
assert startPC >= 0;
final int offset = (int) startPC - method.getInitialPC();
final int j = method.getBytes()[offset - 2];
final int k = method.getBytes()[offset - 1];
final int blockSize = j << 8 | k & 0xff;
final int blockSize;
if (method.getSignFlag()) {
final int j = method.getBytes()[offset - 2];
final int k = method.getBytes()[offset - 1];
blockSize = j << 8 | k & 0xff;
} else {
final int possibleExtBIndex = offset - 5;
assert possibleExtBIndex < 0 || method.getBytes()[possibleExtBIndex] != 225 : "FIXME: should calculate extB from bytecode";
blockSize = Byte.toUnsignedInt(method.getBytes()[offset - 1]);
}
block = CompiledCodeObject.createBlock(method, method, (int) numArgs, copied.length, offset, blockSize);
/* Ensure fields dependent on block are initialized. */
getStartPC();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,13 @@
import de.hpi.swa.trufflesqueak.nodes.ResumeContextNode.ResumeContextRootNode;
import de.hpi.swa.trufflesqueak.nodes.accessing.AbstractPointersObjectNodes.AbstractPointersObjectReadNode;
import de.hpi.swa.trufflesqueak.nodes.accessing.AbstractPointersObjectNodes.AbstractPointersObjectWriteNode;
import de.hpi.swa.trufflesqueak.nodes.bytecodes.AbstractBytecodeNode;
import de.hpi.swa.trufflesqueak.nodes.bytecodes.SqueakBytecodeSistaV1Decoder;
import de.hpi.swa.trufflesqueak.nodes.bytecodes.SqueakBytecodeV3PlusClosuresDecoder;
import de.hpi.swa.trufflesqueak.nodes.dispatch.DispatchUneagerlyNode;
import de.hpi.swa.trufflesqueak.shared.SqueakLanguageConfig;
import de.hpi.swa.trufflesqueak.util.MiscUtils;
import de.hpi.swa.trufflesqueak.util.ObjectGraphUtils.ObjectTracer;
import de.hpi.swa.trufflesqueak.util.SqueakBytecodeDecoder;

@ExportLibrary(InteropLibrary.class)
public final class CompiledCodeObject extends AbstractSqueakObjectWithClassAndHash {
Expand Down Expand Up @@ -118,7 +120,7 @@ private CompiledCodeObject(final SqueakImageContext image, final CompiledCodeObj
final Object[] outerLiterals = outerMethod.getLiterals();
final int outerLiteralsLength = outerLiterals.length;
literals = new Object[outerLiteralsLength + 1];
literals[0] = makeHeader(numArguments, numCopied, code.numLiterals, false, outerMethod.needsLargeFrame);
literals[0] = makeHeader(outerMethod.getSignFlag(), numArguments, numCopied, code.numLiterals, false, outerMethod.needsLargeFrame);
System.arraycopy(outerLiterals, 1, literals, 1, outerLiteralsLength - 1);
literals[outerLiteralsLength] = outerMethod; // Last literal is back pointer to method.
bytes = Arrays.copyOfRange(code.getBytes(), bytecodeOffset, bytecodeOffset + blockSize);
Expand Down Expand Up @@ -175,7 +177,7 @@ public Source getSource() {
String contents;
try {
name = toString();
contents = SqueakBytecodeDecoder.decodeToString(this);
contents = SqueakBytecodeV3PlusClosuresDecoder.decodeToString(this);
} catch (final RuntimeException e) {
if (name == null) {
name = SOURCE_UNAVAILABLE_NAME;
Expand Down Expand Up @@ -272,6 +274,10 @@ public int getNumLiterals() {
return numLiterals;
}

public boolean getSignFlag() {
return CompiledCodeHeaderDecoder.getSignFlag((long) literals[0]);
}

public FrameSlot getStackSlot(final int i) {
assert 0 <= i && i < stackSlots.length : "Bad stack access";
if (stackSlots[i] == null) {
Expand Down Expand Up @@ -309,13 +315,41 @@ public void fillin(final SqueakImageChunk chunk) {
assert innerBlocks == null : "Should not have any inner blocks yet";
}

private int getHeader() {
return MiscUtils.toIntExact((long) literals[0]);
public AbstractBytecodeNode[] asBytecodeNodes() {
if (getSignFlag()) {
return SqueakBytecodeV3PlusClosuresDecoder.decode(this);
} else {
return SqueakBytecodeSistaV1Decoder.decode(this);
}
}

public AbstractBytecodeNode[] asBytecodeNodesEmpty() {
if (getSignFlag()) {
return new AbstractBytecodeNode[SqueakBytecodeV3PlusClosuresDecoder.trailerPosition(this)];
} else {
return new AbstractBytecodeNode[SqueakBytecodeSistaV1Decoder.trailerPosition(this)];
}
}

public AbstractBytecodeNode bytecodeNodeAt(final int pc) {
if (getSignFlag()) {
return SqueakBytecodeV3PlusClosuresDecoder.decodeBytecode(this, pc);
} else {
return SqueakBytecodeSistaV1Decoder.decodeBytecode(this, pc);
}
}

public int findLineNumber(final int index) {
if (getSignFlag()) {
return SqueakBytecodeV3PlusClosuresDecoder.findLineNumber(this, index);
} else {
return SqueakBytecodeSistaV1Decoder.findLineNumber(this, index);
}
}

protected void decodeHeader() {
CompilerDirectives.transferToInterpreterAndInvalidate();
final int header = getHeader();
final long header = (long) literals[0];
numLiterals = CompiledCodeHeaderDecoder.getNumLiterals(header);
hasPrimitive = CompiledCodeHeaderDecoder.getHasPrimitive(header);
needsLargeFrame = CompiledCodeHeaderDecoder.getNeedsLargeFrame(header);
Expand Down Expand Up @@ -483,8 +517,8 @@ public byte[] getBytes() {
return bytes;
}

public static long makeHeader(final int numArgs, final int numTemps, final int numLiterals, final boolean hasPrimitive, final boolean needsLargeFrame) {
return (numArgs & 0x0F) << 24 | (numTemps & 0x3F) << 18 | numLiterals & 0x7FFF | (needsLargeFrame ? 0x20000 : 0) | (hasPrimitive ? 0x10000 : 0);
public static long makeHeader(final boolean signFlag, final int numArgs, final int numTemps, final int numLiterals, final boolean hasPrimitive, final boolean needsLargeFrame) {
return (signFlag ? 0 : 1) << 31 | (numArgs & 0x0F) << 24 | (numTemps & 0x3F) << 18 | numLiterals & 0x7FFF | (needsLargeFrame ? 0x20000 : 0) | (hasPrimitive ? 0x10000 : 0);
}

public CompiledCodeObject findBlock(final CompiledCodeObject method, final int numClosureArgs, final int numCopied, final int successorIndex, final int blockSize) {
Expand Down Expand Up @@ -786,5 +820,9 @@ private static int getNumTemps(final long headerWord) {
private static int getNumArguments(final long headerWord) {
return MiscUtils.bitSplit(headerWord, 24, NUM_ARGUMENTS_SIZE);
}

private static boolean getSignFlag(final long headerWord) {
return headerWord >= 0;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,12 @@ public static final class SPECIAL_OBJECT {
public static final int INVOKE_CALLBACK_SELECTOR = 53;
public static final int CLASS_UNSAFE_ALIEN = 54;
public static final int CLASS_WEAK_FINALIZER = 55;
public static final int FOREIGN_CALLBACK_PROCESS = 56;
public static final int SELECTOR_UNKNOWN_BYTECODE = 57;
public static final int SELECTOR_COUNTER_TRIPPED = 58;
public static final int SELECTOR_SISTA_TRAP = 59;
public static final int LOWCODE_CONTEXT_MARK = 60;
public static final int LOWCODE_NATIVE_CONTEXT_CLASS = 61;
}

public static final class SPECIAL_OBJECT_TAG {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@
import de.hpi.swa.trufflesqueak.util.FrameAccess;
import de.hpi.swa.trufflesqueak.util.InterruptHandlerNode;
import de.hpi.swa.trufflesqueak.util.LogUtils;
import de.hpi.swa.trufflesqueak.util.SqueakBytecodeDecoder;

public final class ExecuteContextNode extends AbstractExecuteContextNode {
private static final int LOCAL_RETURN_PC = -2;
Expand All @@ -60,7 +59,7 @@ public final class ExecuteContextNode extends AbstractExecuteContextNode {

protected ExecuteContextNode(final CompiledCodeObject code, final boolean resume) {
this.code = code;
bytecodeNodes = new AbstractBytecodeNode[SqueakBytecodeDecoder.trailerPosition(code)];
bytecodeNodes = code.asBytecodeNodesEmpty();
frameInitializationNode = resume ? null : FrameStackInitializationNode.create();
/*
* Only check for interrupts if method is relatively large. Avoid check if a closure is
Expand Down Expand Up @@ -318,7 +317,7 @@ protected boolean hasModifiedSender(final VirtualFrame frame) {
private AbstractBytecodeNode fetchNextBytecodeNode(final int pc) {
if (bytecodeNodes[pc] == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
bytecodeNodes[pc] = insert(SqueakBytecodeDecoder.decodeBytecode(code, pc));
bytecodeNodes[pc] = insert(code.bytecodeNodeAt(pc));
notifyInserted(bytecodeNodes[pc]);
}
return bytecodeNodes[pc];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
import de.hpi.swa.trufflesqueak.model.FrameMarker;
import de.hpi.swa.trufflesqueak.nodes.AbstractNode;
import de.hpi.swa.trufflesqueak.util.FrameAccess;
import de.hpi.swa.trufflesqueak.util.SqueakBytecodeDecoder;

public abstract class AbstractBytecodeNode extends AbstractNode {
protected final CompiledCodeObject code;
Expand Down Expand Up @@ -71,7 +70,7 @@ public final SourceSection getSourceSection() {
if (CompiledCodeObject.SOURCE_UNAVAILABLE_CONTENTS.contentEquals(source.getCharacters())) {
sourceSection = source.createUnavailableSection();
} else {
final int lineNumber = SqueakBytecodeDecoder.findLineNumber(code, index);
final int lineNumber = code.findLineNumber(index);
sourceSection = source.createSection(lineNumber);
}
}
Expand Down
Loading

0 comments on commit 9e53c4c

Please sign in to comment.