Skip to content

Commit e348f68

Browse files
committed
[GR-17457] Add check for host inlining to ensure RubyCallNode#execute fits in budget
PullRequest: truffleruby/3806
2 parents 69d7988 + 99b95f0 commit e348f68

21 files changed

+270
-229
lines changed

ci.jsonnet

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,14 @@ local part_definitions = {
6565
"*.log",
6666
],
6767

68+
mx_options:: [],
6869
mx_build_options:: [],
6970
},
7071

7172
build: {
7273
setup+: [["mx", "sversions"]] +
7374
# aot-build.log is used for the build-stats metrics, in other cases it does no harm
74-
jt(["build", "--env", self.mx_env, "--"] + self.mx_build_options + ["|", "tee", "aot-build.log"]) +
75+
jt(["build", "--env", self.mx_env] + self.mx_options + ["--"] + self.mx_build_options + ["|", "tee", "aot-build.log"]) +
7576
[
7677
# make sure jt always uses what was just built
7778
["set-export", "RUBY_BIN", jt(["--use", self.mx_env, "--silent", "launcher"])[0]],
@@ -204,6 +205,14 @@ local part_definitions = {
204205
HOST_VM_CONFIG: "graal-enterprise",
205206
},
206207
},
208+
host_inlining_log: {
209+
# Same as in mx.truffleruby/native-host-inlining
210+
mx_options+:: [
211+
"--extra-image-builder-argument=rubyvm:-H:Log=TruffleHostInliningPhase,~CanonicalizerPhase,~GraphBuilderPhase",
212+
"--extra-image-builder-argument=rubyvm:-H:+TruffleHostInliningPrintExplored",
213+
"--extra-image-builder-argument=rubyvm:-Dgraal.LogFile=host-inlining.txt",
214+
],
215+
},
207216
},
208217

209218
jdk: {
@@ -534,13 +543,13 @@ local composition_environment = utils.add_inclusion_tracking(part_definitions, "
534543
"ruby-test-compiler-graal-enterprise-17": $.platform.linux + $.jdk.v17 + $.env.jvm_ee + gate + $.use.truffleruby + $.run.test_compiler,
535544
"ruby-test-compiler-graal-enterprise-20": $.platform.linux + $.jdk.v20 + $.env.jvm_ee + gate + $.use.truffleruby + $.run.test_compiler,
536545

537-
"ruby-test-svm-graal-core-linux-17": $.platform.linux + $.jdk.v17 + $.env.native + $.env.gdb_svm + gate + native_tests,
546+
"ruby-test-svm-graal-core-linux-17": $.platform.linux + $.jdk.v17 + $.env.native + $.env.gdb_svm + gate + native_tests + $.env.host_inlining_log,
538547
"ruby-test-svm-graal-core-linux-20": $.platform.linux + $.jdk.v20 + $.env.native + $.env.gdb_svm + gate + native_tests,
539548
"ruby-test-svm-graal-core-darwin-amd64-17": $.platform.darwin_amd64 + $.jdk.v17 + $.env.native + $.env.gdb_svm + gate + native_tests + darwin_amd64_enough_ram,
540549
"ruby-test-svm-graal-core-darwin-amd64-20": $.platform.darwin_amd64 + $.jdk.v20 + $.env.native + $.env.gdb_svm + gate + native_tests + darwin_amd64_enough_ram,
541550
"ruby-test-svm-graal-core-darwin-aarch64-17": $.platform.darwin_aarch64 + $.jdk.v17 + $.env.native + gate + native_tests,
542551
"ruby-test-svm-graal-core-darwin-aarch64-20": $.platform.darwin_aarch64 + $.jdk.v20 + $.env.native + gate + native_tests,
543-
"ruby-test-svm-graal-enterprise-linux": $.platform.linux + $.jdk.v17 + $.env.native_ee + $.env.gdb_svm + gate + native_tests,
552+
"ruby-test-svm-graal-enterprise-linux": $.platform.linux + $.jdk.v17 + $.env.native_ee + $.env.gdb_svm + gate + native_tests + $.env.host_inlining_log,
544553
"ruby-test-svm-graal-enterprise-darwin-aarch64 ": $.platform.darwin_aarch64 + $.jdk.v17 + $.env.native_ee + gate + native_tests,
545554
},
546555

mx.truffleruby/native-host-inlining

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
GRAALVM_SKIP_ARCHIVE=true
2+
DYNAMIC_IMPORTS=/tools,/compiler,/substratevm
3+
COMPONENTS=TruffleRuby,suite:tools,GraalVM compiler,SubstrateVM,Native Image
4+
NATIVE_IMAGES=lib:rubyvm
5+
EXTRA_IMAGE_BUILDER_ARGUMENTS=rubyvm:-H:Log=TruffleHostInliningPhase,~CanonicalizerPhase,~GraphBuilderPhase rubyvm:-H:+TruffleHostInliningPrintExplored rubyvm:-Dgraal.LogFile=host-inlining.txt
6+
# To also create the standalone
7+
DISABLE_INSTALLABLES=false

src/main/java/org/truffleruby/core/basicobject/BasicObjectNodes.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,7 @@ public abstract static class InstanceEvalNode extends AlwaysInlinedMethodNode {
357357
protected Object evalWithBlock(Frame callerFrame, Object self, Object[] rubyArgs, RootCallTarget target,
358358
@Cached InstanceExecBlockNode instanceExecNode,
359359
@Cached @Exclusive BranchProfile wrongNumberOfArgumentsProfile) {
360-
final int count = RubyArguments.getPositionalArgumentsCount(rubyArgs, false);
360+
final int count = RubyArguments.getPositionalArgumentsCount(rubyArgs);
361361

362362
if (count > 0) {
363363
wrongNumberOfArgumentsProfile.enter();
@@ -380,7 +380,7 @@ protected Object evalWithString(Frame callerFrame, Object self, Object[] rubyArg
380380
final Object sourceCode;
381381
String fileName = coreStrings().EVAL_FILENAME_STRING.toString();
382382
int line = 1;
383-
int count = RubyArguments.getPositionalArgumentsCount(rubyArgs, false);
383+
int count = RubyArguments.getPositionalArgumentsCount(rubyArgs);
384384

385385
if (count == 0) {
386386
zeroNumberOfArguments.enter();

src/main/java/org/truffleruby/core/kernel/KernelNodes.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -695,7 +695,7 @@ protected Object eval(Frame callerFrame, Object callerSelf, Object[] rubyArgs, R
695695
@Cached ConditionProfile fileAndLineProfile,
696696
@Cached ConditionProfile fileNoLineProfile) {
697697

698-
final Object[] args = RubyArguments.getPositionalArguments(rubyArgs, false);
698+
final Object[] args = RubyArguments.getPositionalArguments(rubyArgs);
699699
final Object source = toStrNode.execute(args[0]);
700700

701701
final RubyBinding binding;
@@ -1446,7 +1446,7 @@ protected boolean doesRespondTo(Frame callerFrame, Object self, Object[] rubyArg
14461446
@Cached DispatchNode respondToMissingNode,
14471447
@Cached BooleanCastNode castMissingResultNode) {
14481448
final Object name = RubyArguments.getArgument(rubyArgs, 0);
1449-
final int nArgs = RubyArguments.getPositionalArgumentsCount(rubyArgs, false);
1449+
final int nArgs = RubyArguments.getPositionalArgumentsCount(rubyArgs);
14501450
final boolean includeProtectedAndPrivate = nArgs >= 2 &&
14511451
castArgumentNode.execute(RubyArguments.getArgument(rubyArgs, 1));
14521452

src/main/java/org/truffleruby/core/kernel/TruffleKernelNodes.java

Lines changed: 33 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -226,41 +226,16 @@ public static GetSpecialVariableStorage create() {
226226
protected SpecialVariableStorage getFromKnownFrameDescriptor(Frame frame,
227227
@Cached("frame.getFrameDescriptor()") FrameDescriptor descriptor,
228228
@Cached("declarationDepth(frame)") int declarationFrameDepth) {
229-
Object variables;
230-
if (declarationFrameDepth == 0) {
231-
variables = SpecialVariableStorage.get(frame);
232-
if (variables == nil) {
233-
CompilerDirectives.transferToInterpreterAndInvalidate();
234-
variables = new SpecialVariableStorage();
235-
SpecialVariableStorage.set(frame, (SpecialVariableStorage) variables);
236-
SpecialVariableStorage.getAssumption(frame.getFrameDescriptor()).invalidate();
237-
}
238-
} else {
239-
Frame storageFrame = RubyArguments.getDeclarationFrame(frame, declarationFrameDepth);
240-
241-
if (storageFrame == null) {
242-
CompilerDirectives.transferToInterpreterAndInvalidate();
243-
int depth = 0;
244-
MaterializedFrame currentFrame = RubyArguments.getDeclarationFrame(frame);
245-
while (currentFrame != null) {
246-
depth += 1;
247-
currentFrame = RubyArguments.getDeclarationFrame(currentFrame);
248-
}
249-
250-
String message = String.format(
251-
"Expected %d declaration frames but only found %d frames.",
252-
declarationFrameDepth,
253-
depth);
254-
throw CompilerDirectives.shouldNotReachHere(message);
255-
}
256-
257-
variables = SpecialVariableStorage.get(storageFrame);
258-
if (variables == nil) {
259-
CompilerDirectives.transferToInterpreterAndInvalidate();
260-
variables = new SpecialVariableStorage();
261-
SpecialVariableStorage.set(storageFrame, (SpecialVariableStorage) variables);
262-
SpecialVariableStorage.getAssumption(storageFrame.getFrameDescriptor()).invalidate();
263-
}
229+
Frame storageFrame = RubyArguments.getDeclarationFrame(frame, declarationFrameDepth);
230+
if (storageFrame == null) {
231+
CompilerDirectives.transferToInterpreterAndInvalidate();
232+
noStorageFrameError(frame, declarationFrameDepth);
233+
}
234+
235+
Object variables = SpecialVariableStorage.get(storageFrame);
236+
if (variables == nil) {
237+
CompilerDirectives.transferToInterpreterAndInvalidate();
238+
variables = initializeSpecialVariablesSlot(storageFrame);
264239
}
265240
return (SpecialVariableStorage) variables;
266241
}
@@ -275,13 +250,33 @@ public static SpecialVariableStorage getSlow(MaterializedFrame aFrame) {
275250
MaterializedFrame frame = FindDeclarationVariableNodes.getOuterDeclarationFrame(aFrame);
276251
Object variables = SpecialVariableStorage.get(frame);
277252
if (variables == Nil.INSTANCE) {
278-
variables = new SpecialVariableStorage();
279-
SpecialVariableStorage.set(frame, (SpecialVariableStorage) variables);
280-
SpecialVariableStorage.getAssumption(frame.getFrameDescriptor()).invalidate();
253+
variables = initializeSpecialVariablesSlot(frame);
281254
}
282255
return (SpecialVariableStorage) variables;
283256
}
284257

258+
private static Object initializeSpecialVariablesSlot(Frame storageFrame) {
259+
var variables = new SpecialVariableStorage();
260+
SpecialVariableStorage.set(storageFrame, variables);
261+
SpecialVariableStorage.getAssumption(storageFrame.getFrameDescriptor()).invalidate();
262+
return variables;
263+
}
264+
265+
private static void noStorageFrameError(Frame frame, int declarationFrameDepth) {
266+
int depth = 0;
267+
MaterializedFrame currentFrame = RubyArguments.getDeclarationFrame(frame);
268+
while (currentFrame != null) {
269+
depth += 1;
270+
currentFrame = RubyArguments.getDeclarationFrame(currentFrame);
271+
}
272+
273+
String message = String.format(
274+
"Expected %d declaration frames but only found %d frames.",
275+
declarationFrameDepth,
276+
depth);
277+
throw CompilerDirectives.shouldNotReachHere(message);
278+
}
279+
285280
}
286281

287282
@Primitive(name = "caller_special_variables")

src/main/java/org/truffleruby/core/module/ModuleNodes.java

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -565,7 +565,7 @@ public abstract static class AttrNode extends GenerateAccessorNode {
565565
@Specialization
566566
protected Object attr(Frame callerFrame, RubyModule module, Object[] rubyArgs, RootCallTarget target) {
567567
final boolean setter;
568-
Object[] names = RubyArguments.getPositionalArguments(rubyArgs, false);
568+
Object[] names = RubyArguments.getPositionalArguments(rubyArgs);
569569
if (names.length == 2 && names[1] instanceof Boolean) {
570570
warnObsoletedBooleanArgument();
571571
setter = (boolean) names[1];
@@ -592,7 +592,7 @@ private void warnObsoletedBooleanArgument() {
592592
public abstract static class AttrAccessorNode extends GenerateAccessorNode {
593593
@Specialization
594594
protected Object attrAccessor(Frame callerFrame, RubyModule module, Object[] rubyArgs, RootCallTarget target) {
595-
Object[] names = RubyArguments.getPositionalArguments(rubyArgs, false);
595+
Object[] names = RubyArguments.getPositionalArguments(rubyArgs);
596596
return createArray(generateAccessors(callerFrame, module, names, BOTH, target));
597597
}
598598
}
@@ -602,7 +602,7 @@ protected Object attrAccessor(Frame callerFrame, RubyModule module, Object[] rub
602602
public abstract static class AttrReaderNode extends GenerateAccessorNode {
603603
@Specialization
604604
protected Object attrReader(Frame callerFrame, RubyModule module, Object[] rubyArgs, RootCallTarget target) {
605-
Object[] names = RubyArguments.getPositionalArguments(rubyArgs, false);
605+
Object[] names = RubyArguments.getPositionalArguments(rubyArgs);
606606
return createArray(generateAccessors(callerFrame, module, names, READER, target));
607607
}
608608
}
@@ -612,7 +612,7 @@ protected Object attrReader(Frame callerFrame, RubyModule module, Object[] rubyA
612612
public abstract static class AttrWriterNode extends GenerateAccessorNode {
613613
@Specialization
614614
protected Object attrWriter(Frame callerFrame, RubyModule module, Object[] rubyArgs, RootCallTarget target) {
615-
Object[] names = RubyArguments.getPositionalArguments(rubyArgs, false);
615+
Object[] names = RubyArguments.getPositionalArguments(rubyArgs);
616616
return createArray(generateAccessors(callerFrame, module, names, WRITER, target));
617617
}
618618
}
@@ -711,7 +711,7 @@ public abstract static class ClassEvalNode extends AlwaysInlinedMethodNode {
711711
protected Object evalWithBlock(Frame callerFrame, RubyModule self, Object[] rubyArgs, RootCallTarget target,
712712
@Cached @Exclusive BranchProfile wrongNumberOfArgumentsProfile,
713713
@Cached ClassExecBlockNode classExecNode) {
714-
final int count = RubyArguments.getPositionalArgumentsCount(rubyArgs, false);
714+
final int count = RubyArguments.getPositionalArgumentsCount(rubyArgs);
715715

716716
if (count > 0) {
717717
wrongNumberOfArgumentsProfile.enter();
@@ -734,7 +734,7 @@ protected Object evalWithString(Frame callerFrame, RubyModule self, Object[] rub
734734
String fileName = coreStrings().EVAL_FILENAME_STRING.toString();
735735
int line = 1;
736736

737-
int count = RubyArguments.getPositionalArgumentsCount(rubyArgs, false);
737+
int count = RubyArguments.getPositionalArgumentsCount(rubyArgs);
738738

739739
if (count == 0) {
740740
wrongNumberOfArgumentsProfile.enter();
@@ -1518,7 +1518,7 @@ private RubySymbol addInternalMethod(RubyModule module, String name, InternalMet
15181518
}
15191519

15201520
protected boolean isMethodParameterProvided(Object[] rubyArgs) {
1521-
final int count = RubyArguments.getPositionalArgumentsCount(rubyArgs, false);
1521+
final int count = RubyArguments.getPositionalArgumentsCount(rubyArgs);
15221522
return count >= 2;
15231523
}
15241524

@@ -1697,7 +1697,7 @@ protected boolean isMethodDefined(RubyModule module, String name, boolean inheri
16971697
public abstract static class ModuleFunctionNode extends AlwaysInlinedMethodNode {
16981698
@Specialization(guards = "names.length == 0")
16991699
protected Object frame(Frame callerFrame, RubyModule module, Object[] rubyArgs, RootCallTarget target,
1700-
@Bind("getPositionalArguments(rubyArgs, false)") Object[] names,
1700+
@Bind("getPositionalArguments(rubyArgs)") Object[] names,
17011701
@Cached @Shared BranchProfile errorProfile) {
17021702
checkNotClass(module, errorProfile);
17031703
needCallerFrame(callerFrame, "Module#module_function with no arguments");
@@ -1707,7 +1707,7 @@ protected Object frame(Frame callerFrame, RubyModule module, Object[] rubyArgs,
17071707

17081708
@Specialization(guards = "names.length > 0")
17091709
protected Object methods(Frame callerFrame, RubyModule module, Object[] rubyArgs, RootCallTarget target,
1710-
@Bind("getPositionalArguments(rubyArgs, false)") Object[] names,
1710+
@Bind("getPositionalArguments(rubyArgs)") Object[] names,
17111711
@Cached SetMethodVisibilityNode setMethodVisibilityNode,
17121712
@Cached @Shared BranchProfile errorProfile,
17131713
@Cached LoopConditionProfile loopProfile,
@@ -1785,15 +1785,15 @@ protected RubyArray nesting() {
17851785
public abstract static class PublicNode extends AlwaysInlinedMethodNode {
17861786
@Specialization(guards = "names.length == 0")
17871787
protected Object frame(Frame callerFrame, RubyModule module, Object[] rubyArgs, RootCallTarget target,
1788-
@Bind("getPositionalArguments(rubyArgs, false)") Object[] names) {
1788+
@Bind("getPositionalArguments(rubyArgs)") Object[] names) {
17891789
needCallerFrame(callerFrame, "Module#public with no arguments");
17901790
DeclarationContext.setCurrentVisibility(callerFrame, Visibility.PUBLIC);
17911791
return nil;
17921792
}
17931793

17941794
@Specialization(guards = "names.length > 0")
17951795
protected Object methods(Frame callerFrame, RubyModule module, Object[] rubyArgs, RootCallTarget target,
1796-
@Bind("getPositionalArguments(rubyArgs, false)") Object[] names,
1796+
@Bind("getPositionalArguments(rubyArgs)") Object[] names,
17971797
@Cached SetMethodVisibilityNode setMethodVisibilityNode,
17981798
@Cached SingleValueCastNode singleValueCastNode) {
17991799
for (Object name : names) {
@@ -1827,15 +1827,15 @@ protected RubyModule publicClassMethod(RubyModule module, Object[] names) {
18271827
public abstract static class PrivateNode extends AlwaysInlinedMethodNode {
18281828
@Specialization(guards = "names.length == 0")
18291829
protected Object frame(Frame callerFrame, RubyModule module, Object[] rubyArgs, RootCallTarget target,
1830-
@Bind("getPositionalArguments(rubyArgs, false)") Object[] names) {
1830+
@Bind("getPositionalArguments(rubyArgs)") Object[] names) {
18311831
needCallerFrame(callerFrame, "Module#private with no arguments");
18321832
DeclarationContext.setCurrentVisibility(callerFrame, Visibility.PRIVATE);
18331833
return nil;
18341834
}
18351835

18361836
@Specialization(guards = "names.length > 0")
18371837
protected Object methods(Frame callerFrame, RubyModule module, Object[] rubyArgs, RootCallTarget target,
1838-
@Bind("getPositionalArguments(rubyArgs, false)") Object[] names,
1838+
@Bind("getPositionalArguments(rubyArgs)") Object[] names,
18391839
@Cached SetMethodVisibilityNode setMethodVisibilityNode,
18401840
@Cached SingleValueCastNode singleValueCastNode) {
18411841
for (Object name : names) {
@@ -2132,15 +2132,15 @@ protected RubyModule publicConstant(RubyModule module, Object[] args) {
21322132
public abstract static class ProtectedNode extends AlwaysInlinedMethodNode {
21332133
@Specialization(guards = "names.length == 0")
21342134
protected Object frame(Frame callerFrame, RubyModule module, Object[] rubyArgs, RootCallTarget target,
2135-
@Bind("getPositionalArguments(rubyArgs, false)") Object[] names) {
2135+
@Bind("getPositionalArguments(rubyArgs)") Object[] names) {
21362136
needCallerFrame(callerFrame, "Module#protected with no arguments");
21372137
DeclarationContext.setCurrentVisibility(callerFrame, Visibility.PROTECTED);
21382138
return nil;
21392139
}
21402140

21412141
@Specialization(guards = "names.length > 0")
21422142
protected Object methods(Frame callerFrame, RubyModule module, Object[] rubyArgs, RootCallTarget target,
2143-
@Bind("getPositionalArguments(rubyArgs, false)") Object[] names,
2143+
@Bind("getPositionalArguments(rubyArgs)") Object[] names,
21442144
@Cached SetMethodVisibilityNode setMethodVisibilityNode,
21452145
@Cached SingleValueCastNode singleValueCastNode) {
21462146
for (Object name : names) {

0 commit comments

Comments
 (0)