Skip to content

Commit

Permalink
[GR-52843] Improve binary footprint of Truffle interpreters.
Browse files Browse the repository at this point in the history
PullRequest: graal/17892
  • Loading branch information
chumer committed Jun 5, 2024
2 parents ba9e6da + b54fcf4 commit e27620f
Show file tree
Hide file tree
Showing 50 changed files with 198 additions and 644 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,12 @@
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.DirectCallNode;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.nodes.NodeCost;
import com.oracle.truffle.api.nodes.RootNode;
import com.oracle.truffle.api.test.ReflectionUtils;
import com.oracle.truffle.runtime.OptimizedTruffleRuntime;
import com.oracle.truffle.runtime.OptimizedTruffleRuntimeListener;
import com.oracle.truffle.runtime.OptimizedCallTarget;
import com.oracle.truffle.runtime.OptimizedDirectCallNode;
import com.oracle.truffle.runtime.OptimizedTruffleRuntime;
import com.oracle.truffle.runtime.OptimizedTruffleRuntimeListener;

public class AbstractSplittingStrategyTest extends TestWithPolyglotOptions {

Expand Down Expand Up @@ -183,10 +182,6 @@ public void onCompilationSplit(OptimizedDirectCallNode callNode) {
static class DummyRootNode extends RootNode {

@Child private Node polymorphic = new Node() {
@Override
public NodeCost getCost() {
return NodeCost.POLYMORPHIC;
}
};

protected DummyRootNode() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,6 @@
import java.util.List;
import java.util.concurrent.Callable;

import com.oracle.truffle.sl.runtime.SLStrings;
import jdk.graal.compiler.test.SubprocessUtil;
import org.graalvm.polyglot.Context;
import org.graalvm.polyglot.Value;
import org.junit.After;
Expand All @@ -54,17 +52,19 @@
import com.oracle.truffle.api.nodes.BlockNode;
import com.oracle.truffle.api.nodes.BlockNode.ElementExecutor;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.nodes.NodeCost;
import com.oracle.truffle.api.nodes.NodeVisitor;
import com.oracle.truffle.api.nodes.RootNode;
import com.oracle.truffle.api.nodes.UnexpectedResultException;
import com.oracle.truffle.api.source.Source;
import com.oracle.truffle.api.source.SourceSection;
import com.oracle.truffle.api.test.polyglot.ProxyLanguage;
import com.oracle.truffle.runtime.OptimizedBlockNode;
import com.oracle.truffle.runtime.OptimizedCallTarget;
import com.oracle.truffle.runtime.OptimizedBlockNode.PartialBlocks;
import com.oracle.truffle.runtime.OptimizedCallTarget;
import com.oracle.truffle.sl.runtime.SLContext;
import com.oracle.truffle.sl.runtime.SLStrings;

import jdk.graal.compiler.test.SubprocessUtil;

public class OptimizedBlockNodeTest {

Expand All @@ -87,7 +87,7 @@ public void testExactlyBlockSize() {
@Test
public void testFirstBlockElementExceedsLimit() {
setup(1);
OptimizedBlockNode<TestElement> block = createBlock(2, 1, null, new TestElementExecutor(), 5);
OptimizedBlockNode<TestElement> block = createBlock(2, 1, null, new TestElementExecutor());
OptimizedCallTarget target = createTest(block);
target.computeBlockCompilations();
target.call();
Expand Down Expand Up @@ -367,7 +367,7 @@ public void testStartsWithCompilation() {

setup(2);

block = createBlock(5, 1, null, new StartsWithExecutor(), 0);
block = createBlock(5, 1, null, new StartsWithExecutor());
target = createTest(block);
elementExecuted = ((TestRootNode) block.getRootNode()).elementExecuted;
expectedResult = 4;
Expand Down Expand Up @@ -429,9 +429,12 @@ public void testHierarchicalBlocks() {
target.compile(true);
partialBlocks = block.getPartialBlocks();

assertEquals(2, partialBlocks.getBlockTargets().length);
assertEquals(1, partialBlocks.getBlockRanges().length);
assertEquals(3, partialBlocks.getBlockRanges()[0]);
assertEquals(5, partialBlocks.getBlockTargets().length);
assertEquals(4, partialBlocks.getBlockRanges().length);
assertEquals(1, partialBlocks.getBlockRanges()[0]);
assertEquals(2, partialBlocks.getBlockRanges()[1]);
assertEquals(3, partialBlocks.getBlockRanges()[2]);
assertEquals(4, partialBlocks.getBlockRanges()[3]);

block = createBlock(5, 3, null);
target = createTest(block);
Expand All @@ -440,9 +443,12 @@ public void testHierarchicalBlocks() {
target.compile(true);
partialBlocks = block.getPartialBlocks();

assertEquals(2, partialBlocks.getBlockTargets().length);
assertEquals(1, partialBlocks.getBlockRanges().length);
assertEquals(3, partialBlocks.getBlockRanges()[0]);
assertEquals(5, partialBlocks.getBlockTargets().length);
assertEquals(4, partialBlocks.getBlockRanges().length);
assertEquals(1, partialBlocks.getBlockRanges()[0]);
assertEquals(2, partialBlocks.getBlockRanges()[1]);
assertEquals(3, partialBlocks.getBlockRanges()[2]);
assertEquals(4, partialBlocks.getBlockRanges()[3]);
}

@Test
Expand All @@ -460,10 +466,12 @@ public void testHierarchicalUnbalanced() {
target.compile(true);
partialBlocks = block.getPartialBlocks();

assertEquals(3, partialBlocks.getBlockTargets().length);
assertEquals(2, partialBlocks.getBlockRanges().length);
assertEquals(4, partialBlocks.getBlockRanges()[0]);
assertEquals(8, partialBlocks.getBlockRanges()[1]);
assertEquals(5, partialBlocks.getBlockTargets().length);
assertEquals(4, partialBlocks.getBlockRanges().length);
assertEquals(2, partialBlocks.getBlockRanges()[0]);
assertEquals(4, partialBlocks.getBlockRanges()[1]);
assertEquals(6, partialBlocks.getBlockRanges()[2]);
assertEquals(8, partialBlocks.getBlockRanges()[3]);
}

@Test
Expand Down Expand Up @@ -581,26 +589,16 @@ private static OptimizedBlockNode<TestElement> createBlock(int blockSize, int de
}

private static OptimizedBlockNode<TestElement> createBlock(int blockSize, int depth, Object returnValue) {
return createBlock(blockSize, depth, returnValue, new TestElementExecutor(), 0);
return createBlock(blockSize, depth, returnValue, new TestElementExecutor());
}

private static OptimizedBlockNode<TestElement> createBlock(int blockSize, int depth, Object returnValue, ElementExecutor<TestElement> executor, int extraChildrenOfFirstElement) {
private static OptimizedBlockNode<TestElement> createBlock(int blockSize, int depth, Object returnValue, ElementExecutor<TestElement> executor) {
if (depth == 0) {
return null;
}
TestElement[] elements = new TestElement[blockSize];
for (int i = 0; i < blockSize; i++) {
Node[] extraDummyChildren;
if (i == 0 && extraChildrenOfFirstElement > 0) {
extraDummyChildren = new Node[extraChildrenOfFirstElement];
for (int j = 0; j < extraDummyChildren.length; j++) {
extraDummyChildren[j] = new Node() {
};
}
} else {
extraDummyChildren = new Node[0];
}
elements[i] = new TestElement(createBlock(blockSize, depth - 1, returnValue), returnValue == null ? i : returnValue, i, extraDummyChildren);
elements[i] = new TestElement(createBlock(blockSize, depth - 1, returnValue), returnValue == null ? i : returnValue, i);
}
return (OptimizedBlockNode<TestElement>) BlockNode.create(elements, executor);
}
Expand Down Expand Up @@ -705,12 +703,6 @@ private void setup(int blockCompilationSize, int maxGraalNodeCount, String... ad

static class ElementChildNode extends Node {

@Override
public NodeCost getCost() {
// we don't want this to contribute to node costs
return NodeCost.NONE;
}

}

static class StartsWithExecutor extends TestElementExecutor {
Expand Down Expand Up @@ -756,28 +748,25 @@ public Object executeGeneric(VirtualFrame frame, TestElement node, int index, in
static class TestElement extends Node {

@Child BlockNode<?> childBlock;
@Child ElementChildNode childNode = new ElementChildNode();
@Children Node[] extraDummyChildren;

final Object returnValue;
final int childIndex;

@CompilationFinal TestRootNode root;
SourceSection sourceSection;

TestElement(BlockNode<?> childBlock, Object returnValue, int childIndex, Node[] extraDummyChildren) {
TestElement(BlockNode<?> childBlock, Object returnValue, int childIndex) {
this.childBlock = childBlock;
this.returnValue = returnValue;
this.childIndex = childIndex;
this.extraDummyChildren = extraDummyChildren;
}

void onAdopt() {
root = (TestRootNode) getRootNode();
}

public void simulateReplace() {
childNode.replace(new ElementChildNode());
this.replace(this);
}

public Object execute(VirtualFrame frame) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2023, Oracle and/or its affiliates.
* Copyright (c) 2017, 2024, Oracle and/or its affiliates.
*
* All rights reserved.
*
Expand Down Expand Up @@ -32,7 +32,7 @@
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.interop.UnsupportedTypeException;
import com.oracle.truffle.api.nodes.NodeCost;
import com.oracle.truffle.api.nodes.UnadoptableNode;
import com.oracle.truffle.api.profiles.BranchProfile;
import com.oracle.truffle.llvm.runtime.except.LLVMPolyglotException;
import com.oracle.truffle.llvm.runtime.floating.LLVM128BitFloat;
Expand Down Expand Up @@ -217,7 +217,7 @@ public static SlowPathForeignToLLVM getSlowPath() {
return SlowPathForeignToLLVM.INSTANCE;
}

public static final class SlowPathForeignToLLVM extends ForeignToLLVM {
public static final class SlowPathForeignToLLVM extends ForeignToLLVM implements UnadoptableNode {

private static final SlowPathForeignToLLVM INSTANCE = new SlowPathForeignToLLVM();

Expand Down Expand Up @@ -277,14 +277,5 @@ public Object executeWithForeignToLLVMType(Object value, LLVMInteropType.Structu
}
}

@Override
public boolean isAdoptable() {
return false;
}

@Override
public NodeCost getCost() {
return NodeCost.MEGAMORPHIC;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2021, Oracle and/or its affiliates.
* Copyright (c) 2017, 2024, Oracle and/or its affiliates.
*
* All rights reserved.
*
Expand Down Expand Up @@ -33,14 +33,11 @@
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.ExplodeLoop;
import com.oracle.truffle.api.nodes.NodeCost;
import com.oracle.truffle.api.nodes.NodeInfo;
import com.oracle.truffle.llvm.runtime.nodes.base.LLVMFrameNullerUtil;

/**
* Nulls out the given set of frame slots after evaluating the given statement.
*/
@NodeInfo(cost = NodeCost.NONE) // this node reduces the compiled code size
public abstract class LLVMFrameNuller extends LLVMStatementNode {

@CompilationFinal(dimensions = 1) private final int[] frameSlots;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2021, Oracle and/or its affiliates.
* Copyright (c) 2017, 2024, Oracle and/or its affiliates.
*
* All rights reserved.
*
Expand Down Expand Up @@ -33,15 +33,12 @@
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.ExplodeLoop;
import com.oracle.truffle.api.nodes.NodeCost;
import com.oracle.truffle.api.nodes.NodeInfo;
import com.oracle.truffle.api.nodes.UnexpectedResultException;
import com.oracle.truffle.llvm.runtime.nodes.base.LLVMFrameNullerUtil;

/**
* Nulls out the given set of frame slots after evaluating the given expression.
*/
@NodeInfo(cost = NodeCost.NONE) // this node reduces the compiled code size
public abstract class LLVMFrameNullerExpression extends LLVMExpressionNode {

@CompilationFinal(dimensions = 1) private final int[] frameSlots;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2019, Oracle and/or its affiliates.
* Copyright (c) 2016, 2024, Oracle and/or its affiliates.
*
* All rights reserved.
*
Expand Down Expand Up @@ -31,14 +31,11 @@

import com.oracle.truffle.api.dsl.NodeChild;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.nodes.NodeCost;
import com.oracle.truffle.api.nodes.NodeInfo;

/**
* This node is used to execute an expression as a statement, discarding the result.
*/
@NodeChild(value = "value", type = LLVMExpressionNode.class)
@NodeInfo(cost = NodeCost.NONE)
public abstract class LLVMVoidStatementNode extends LLVMStatementNode {

@Specialization
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2023, Oracle and/or its affiliates.
* Copyright (c) 2016, 2024, Oracle and/or its affiliates.
*
* All rights reserved.
*
Expand Down Expand Up @@ -38,7 +38,6 @@
import com.oracle.truffle.api.frame.FrameSlotTypeException;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.library.CachedLibrary;
import com.oracle.truffle.api.nodes.NodeCost;
import com.oracle.truffle.llvm.runtime.interop.LLVMTypedForeignObject;
import com.oracle.truffle.llvm.runtime.interop.access.LLVMInteropType;
import com.oracle.truffle.llvm.runtime.library.internal.LLVMAsForeignLibrary;
Expand Down Expand Up @@ -100,10 +99,6 @@ public final boolean isAdoptable() {
return false;
}

@Override
public NodeCost getCost() {
return NodeCost.MONOMORPHIC;
}
}

protected final int slot;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@
import com.oracle.truffle.api.instrumentation.StandardTags.StatementTag;
import com.oracle.truffle.api.instrumentation.TruffleInstrument;
import com.oracle.truffle.api.instrumentation.TruffleInstrument.Env;
import com.oracle.truffle.api.nodes.NodeCost;
import com.oracle.truffle.api.source.SourceSection;
import com.oracle.truffle.tools.profiler.impl.CPUTracerInstrument;
import com.oracle.truffle.tools.profiler.impl.ProfilerToolFactory;
Expand Down Expand Up @@ -302,10 +301,6 @@ protected void onEnter(VirtualFrame frame) {
}
}

@Override
public NodeCost getCost() {
return NodeCost.NONE;
}
}

static ProfilerToolFactory<CPUTracer> createFactory() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@
import com.oracle.truffle.api.instrumentation.SourceSectionFilter;
import com.oracle.truffle.api.instrumentation.StandardTags;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.nodes.NodeCost;

/**
* Custom more efficient stack representations for profilers.
Expand Down Expand Up @@ -226,11 +225,6 @@ private ThreadLocalStack getStack() {
return stack;
}

@Override
public NodeCost getCost() {
return NodeCost.NONE;
}

}

final class ThreadLocalStack {
Expand Down
2 changes: 2 additions & 0 deletions truffle/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ This changelog summarizes major changes between Truffle versions relevant to lan
* GR-49484 Deprecated `RootNode.isCaptureFramesForTrace()`. Implementers should use `RootNode.isCaptureFramesForTrace(Node)` instead.
* GR-28866 Added `TruffleLanguage.Env.getScopePublic(LanguageInfo)` and `TruffleLanguage.Env.getScopeInternal(LanguageInfo)` to allow languages direct access to other language scopes to implement new polyglot builtins.
* GR-28866 Deprecated `TruffleLanguage.Env.isPolyglotEvalAllowed()`. Replace usages with `TruffleLanguage.Env.isPolyglotEvalAllowed(LanguageInfo)`. Please see javadoc for the updated usage.
* GR-52843 Deprecated `Node.getCost()` and the associated `NodeCost` class without replacement. Truffle DSL no longer generates implementations of this method automatically and will therefore always return `NodeCost.MONOMORPHIC` by default. This is intended to reduce the binary footprint.
* GR-52843 Added the `UnadoptableNode` interface. This is interface should be preferred to overriding `Node.isAdoptable()` if the result is statically known.

## Version 24.0.0

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -792,8 +792,8 @@ public void testSingleInstanceNodeCacheNode() throws InterruptedException {
SingleInstanceNodeCacheNode returnNull = adoptNode(SingleInstanceNodeCacheNodeGen.create()).get();
GuardCacheNode.returnNull = true;
assertFails(() -> returnNull.execute(null, 1), NullPointerException.class, (e) -> {
assertEquals("Specialization 's0(int, GuardCacheNode)' cache 'cachedNode' returned a 'null' default value. " +
"The cache initializer must never return a default value for this cache. Use @Cached(neverDefault=false) to allow default values for this cached value or make sure the cache initializer never returns 'null'.",
assertEquals("A specialization cache returned a default value. The cache initializer must never return a default value for this cache. " +
"Use @Cached(neverDefault=false) to allow default values for this cached value or make sure the cache initializer never returns the default value.",
e.getMessage());
});
GuardCacheNode.returnNull = false;
Expand Down
Loading

0 comments on commit e27620f

Please sign in to comment.