Skip to content

Commit

Permalink
Remove inlined blocks from literals and reuse literal index
Browse files Browse the repository at this point in the history
This is a simple approach that simply relies on the blocks being the last literals added, which works for the supported inlinings, and because the parser just added them, before getting to the corresponding message send, where inlining is triggered.

So, we simply, from the back, remove the blocks just added.

Signed-off-by: Stefan Marr <[email protected]>
  • Loading branch information
smarr committed Aug 12, 2024
1 parent ca4a142 commit eb4d2ae
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 75 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@
import static trufflesom.interpreter.bc.Bytecodes.RETURN_SELF;
import static trufflesom.interpreter.bc.Bytecodes.getBytecodeLength;
import static trufflesom.vm.SymbolTable.strSelf;
import static trufflesom.vm.SymbolTable.symSelf;

import java.util.ArrayList;
import java.util.Iterator;
Expand Down Expand Up @@ -300,7 +299,19 @@ public byte addLiteralIfAbsent(final Object lit, final ParserBc parser)
}

public byte addLiteral(final Object lit, final ParserBc parser) throws ParseError {
int i = literals.size();
int i = 0;

// first try to use an empty slot, which may have opend up from inlining
for (; i < literals.size(); i += 1) {
if (literals.get(i) == null) {
literals.set(i, lit);
return (byte) i;
}
}

// otherwise, just add it
// but make sure we don't exceed the maximum number of literals
i = literals.size();
if (i > Byte.MAX_VALUE) {
String methodSignature = holderGenc.getName().getString() + ">>" + signature;
throw new ParseError(
Expand All @@ -309,6 +320,7 @@ public byte addLiteral(final Object lit, final ParserBc parser) throws ParseErro
+ " literal values. Please split the method. The literal to be added is: " + lit,
Symbol.NONE, parser);
}

literals.add(lit);
return (byte) i;
}
Expand Down Expand Up @@ -801,6 +813,16 @@ public boolean optimizeReturnField() {
return true;
}

/**
* This works only, because we have a simple forward-pass parser,
* and inlining, where this is used, happens right after the block was added.
* This also means, we need to remove blocks in reverse order.
*/
private SMethod getLastBlockMethodAndFreeLiteral(final byte blockLiteralIdx) {
assert blockLiteralIdx == literals.size() - 1;
return (SMethod) literals.removeLast();
}

public boolean inlineIfTrueOrIfFalse(final ParserBc parser, final boolean ifTrue)
throws ParseError {
// HACK: we do assume that the receiver on the stack is a boolean
Expand All @@ -819,7 +841,7 @@ public boolean inlineIfTrueOrIfFalse(final ParserBc parser, final boolean ifTrue
int jumpOffsetIdxToSkipTrueBranch = emitJumpOnBoolWithDummyOffset(this, ifTrue, false);

// grab block's method, and inline it
SMethod toBeInlined = (SMethod) literals.get(blockLiteralIdx);
SMethod toBeInlined = getLastBlockMethodAndFreeLiteral(blockLiteralIdx);

isCurrentlyInliningBlock = true;
toBeInlined.getInvokable().inline(this, toBeInlined);
Expand Down Expand Up @@ -848,8 +870,8 @@ public boolean inlineIfTrueIfFalse(final ParserBc parser, final boolean isIfTrue
byte block2LiteralIdx = bytecode.get(bytecode.size() - 1);

// grab block's method, and inline it
SMethod toBeInlined1 = (SMethod) literals.get(block1LiteralIdx);
SMethod toBeInlined2 = (SMethod) literals.get(block2LiteralIdx);
SMethod toBeInlined2 = getLastBlockMethodAndFreeLiteral(block2LiteralIdx);
SMethod toBeInlined1 = getLastBlockMethodAndFreeLiteral(block1LiteralIdx);

removeLastBytecodes(2); // remove the PUSH_BLOCK bytecodes

Expand Down Expand Up @@ -889,7 +911,7 @@ public boolean inlineAndOr(final ParserBc parser, final boolean isOr) throws Par

int jumpOffsetIdxToSkipBranch = emitJumpOnBoolWithDummyOffset(this, !isOr, true);

SMethod toBeInlined = (SMethod) literals.get(blockLiteralIdx);
SMethod toBeInlined = getLastBlockMethodAndFreeLiteral(blockLiteralIdx);

isCurrentlyInliningBlock = true;
toBeInlined.getInvokable().inline(this, toBeInlined);
Expand Down Expand Up @@ -920,8 +942,8 @@ public boolean inlineWhileTrueOrFalse(final ParserBc parser, final boolean isWhi
byte block2LiteralIdx = bytecode.get(bytecode.size() - 1);

// grab block's method, and inline it
SMethod condMethod = (SMethod) literals.get(block1LiteralIdx);
SMethod bodyMethod = (SMethod) literals.get(block2LiteralIdx);
SMethod bodyMethod = getLastBlockMethodAndFreeLiteral(block2LiteralIdx);
SMethod condMethod = getLastBlockMethodAndFreeLiteral(block1LiteralIdx);

removeLastBytecodes(2); // remove the PUSH_BLOCK bytecodes

Expand Down
7 changes: 2 additions & 5 deletions tests/trufflesom/tests/BytecodeBlockTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -159,13 +159,12 @@ public void testBlockIfTrueArg() {
+ " #end\n"
+ "]");

assertEquals(15, bytecodes.length);
check(bytecodes,
t(5, Bytecodes.SEND),
new BC(Bytecodes.JUMP_ON_FALSE_TOP_NIL, 4),
Bytecodes.PUSH_ARG1,
Bytecodes.POP,
Bytecodes.PUSH_CONSTANT);
Bytecodes.PUSH_CONSTANT_2);
}

@Test
Expand All @@ -177,12 +176,11 @@ public void testBlockIfTrueMethodArg() {
+ "]",
"arg");

assertEquals(17, bytecodes.length);
check(bytecodes,
t(7, new BC(Bytecodes.JUMP_ON_FALSE_TOP_NIL, 6)),
new BC(Bytecodes.PUSH_ARGUMENT, 1, 1),
Bytecodes.POP,
Bytecodes.PUSH_CONSTANT);
Bytecodes.PUSH_CONSTANT_2);
}

private void blockIfReturnNonLocal(final String sel, final byte jumpBytecode) {
Expand All @@ -192,7 +190,6 @@ private void blockIfReturnNonLocal(final String sel, final byte jumpBytecode) {
+ " #end\n"
+ "]");

assertEquals(16, bytecodes.length);
check(bytecodes,
t(5, Bytecodes.SEND),
new BC(jumpBytecode, 5),
Expand Down
Loading

0 comments on commit eb4d2ae

Please sign in to comment.