Skip to content

Commit f68232e

Browse files
committed
[GR-29278] Add option --lazy-calltargets to control whether to create any CallTarget Supplier
PullRequest: truffleruby/2421
2 parents fa25299 + ca88b70 commit f68232e

File tree

12 files changed

+74
-50
lines changed

12 files changed

+74
-50
lines changed

src/main/java/org/truffleruby/RubyContext.java

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -151,18 +151,10 @@ public class RubyContext {
151151
private final AssumedValue<Boolean> warningCategoryDeprecated;
152152
private final AssumedValue<Boolean> warningCategoryExperimental;
153153

154-
private static boolean preInitializeContexts = TruffleRuby.PRE_INITIALIZE_CONTEXTS;
155-
156-
private static boolean isPreInitializingContext() {
157-
boolean isPreInitializingContext = preInitializeContexts;
158-
preInitializeContexts = false; // Only the first context is pre-initialized
159-
return isPreInitializingContext;
160-
}
161-
162154
public RubyContext(RubyLanguage language, TruffleLanguage.Env env) {
163155
Metrics.printTime("before-context-constructor");
164156

165-
this.preInitializing = isPreInitializingContext();
157+
this.preInitializing = env.isPreInitialization();
166158
this.preInitialized = preInitializing;
167159

168160
preInitializationManager = preInitializing ? new PreInitializationManager() : null;
@@ -268,8 +260,6 @@ public void initialize() {
268260
} else {
269261
initialized = true;
270262
}
271-
272-
this.preInitializing = false;
273263
}
274264

275265
/** Re-initialize parts of the RubyContext depending on the running process. This is a small subset of the full
@@ -278,6 +268,10 @@ public void initialize() {
278268
protected boolean patch(Env newEnv) {
279269
this.env = newEnv;
280270
this.hasOtherPublicLanguages = computeHasOtherPublicLanguages(newEnv);
271+
this.preInitializing = newEnv.isPreInitialization();
272+
if (preInitializing) {
273+
throw CompilerDirectives.shouldNotReachHere("Expected patch Env#isPreInitialization() to be false");
274+
}
281275

282276
final Options oldOptions = this.options;
283277
final Options newOptions = createOptions(newEnv, language.options);

src/main/java/org/truffleruby/builtins/CoreMethodNodeManager.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -267,8 +267,14 @@ private static void addMethod(
267267
final RubyRootNode rootNode = (RubyRootNode) callTarget.getRootNode();
268268
alwaysInlinedNodeFactory = ((ReRaiseInlinedExceptionNode) rootNode.getBody()).nodeFactory;
269269
} else {
270-
callTarget = null;
271-
callTargetSupplier = new CachedSupplier<>(() -> callTargetFactory.apply(sharedMethodInfo));
270+
if (context.getLanguageSlow().options.LAZY_CALLTARGETS) {
271+
callTarget = null;
272+
callTargetSupplier = new CachedSupplier<>(() -> callTargetFactory.apply(sharedMethodInfo));
273+
} else {
274+
callTarget = callTargetFactory.apply(sharedMethodInfo);
275+
callTargetSupplier = null;
276+
}
277+
272278
alwaysInlinedNodeFactory = null;
273279
}
274280

src/main/java/org/truffleruby/cext/ValueWrapperManager.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ static protected Thread currentJavaThread(ValueWrapper wrapper) {
294294
}
295295

296296
public int getCacheLimit() {
297-
return 3;
297+
return RubyLanguage.getCurrentLanguage().options.THREAD_CACHE;
298298
}
299299

300300
public static GetHandleBlockHolderNode create() {

src/main/java/org/truffleruby/core/format/FormatRootNode.java

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
import java.util.List;
1313

14-
import org.truffleruby.RubyContext;
14+
import org.truffleruby.RubyLanguage;
1515
import org.truffleruby.core.rope.CodeRange;
1616
import org.truffleruby.extra.ffi.Pointer;
1717
import org.truffleruby.language.RubyBaseRootNode;
@@ -27,16 +27,20 @@
2727
/** The node at the root of a pack expression. */
2828
public class FormatRootNode extends RubyBaseRootNode implements InternalRootNode {
2929

30-
private final RubyContext context;
30+
private final RubyLanguage language;
3131
private final FormatEncoding encoding;
3232

3333
@Child private FormatNode child;
3434

3535
@CompilationFinal private int expectedLength = 0;
3636

37-
public FormatRootNode(RubyContext context, SourceSection sourceSection, FormatEncoding encoding, FormatNode child) {
38-
super(context.getLanguageSlow(), FormatFrameDescriptor.FRAME_DESCRIPTOR, sourceSection);
39-
this.context = context;
37+
public FormatRootNode(
38+
RubyLanguage language,
39+
SourceSection sourceSection,
40+
FormatEncoding encoding,
41+
FormatNode child) {
42+
super(language, FormatFrameDescriptor.FRAME_DESCRIPTOR, sourceSection);
43+
this.language = language;
4044
this.encoding = encoding;
4145
this.child = child;
4246
}
@@ -139,8 +143,4 @@ public String getName() {
139143
public String toString() {
140144
return getName();
141145
}
142-
143-
public RubyContext getContext() {
144-
return context;
145-
}
146146
}

src/main/java/org/truffleruby/core/format/pack/PackCompiler.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public RootCallTarget compile(String format) {
4444

4545
return Truffle.getRuntime().createCallTarget(
4646
new FormatRootNode(
47-
context,
47+
context.getLanguageSlow(),
4848
currentNode.getEncapsulatingSourceSection(),
4949
builder.getEncoding(),
5050
builder.getNode()));

src/main/java/org/truffleruby/core/format/printf/PrintfCompiler.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
import java.util.List;
1313

1414
import com.oracle.truffle.api.nodes.Node;
15-
import org.truffleruby.RubyContext;
15+
import org.truffleruby.RubyLanguage;
1616
import org.truffleruby.core.format.FormatEncoding;
1717
import org.truffleruby.core.format.FormatRootNode;
1818
import org.truffleruby.core.rope.Rope;
@@ -22,22 +22,22 @@
2222

2323
public class PrintfCompiler {
2424

25-
private final RubyContext context;
25+
private final RubyLanguage language;
2626
private final Node currentNode;
2727

28-
public PrintfCompiler(RubyContext context, Node currentNode) {
29-
this.context = context;
28+
public PrintfCompiler(RubyLanguage language, Node currentNode) {
29+
this.language = language;
3030
this.currentNode = currentNode;
3131
}
3232

3333
public RootCallTarget compile(Rope format, Object[] arguments, boolean isDebug) {
3434
final PrintfSimpleParser parser = new PrintfSimpleParser(bytesToChars(format.getBytes()), arguments, isDebug);
3535
final List<SprintfConfig> configs = parser.parse();
36-
final PrintfSimpleTreeBuilder builder = new PrintfSimpleTreeBuilder(context, configs);
36+
final PrintfSimpleTreeBuilder builder = new PrintfSimpleTreeBuilder(language, configs);
3737

3838
return Truffle.getRuntime().createCallTarget(
3939
new FormatRootNode(
40-
context,
40+
language,
4141
currentNode.getEncapsulatingSourceSection(),
4242
FormatEncoding.find(format.getEncoding()),
4343
builder.getNode()));

src/main/java/org/truffleruby/core/format/printf/PrintfSimpleTreeBuilder.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
import com.oracle.truffle.api.CompilerDirectives;
1616
import org.jcodings.specific.USASCIIEncoding;
17-
import org.truffleruby.RubyContext;
17+
import org.truffleruby.RubyLanguage;
1818
import org.truffleruby.core.format.FormatNode;
1919
import org.truffleruby.core.format.LiteralFormatNode;
2020
import org.truffleruby.core.format.SharedTreeBuilder;
@@ -40,16 +40,16 @@
4040

4141
public class PrintfSimpleTreeBuilder {
4242

43-
private final RubyContext context;
43+
private final RubyLanguage language;
4444
private final List<FormatNode> sequence = new ArrayList<>();
4545
private final List<SprintfConfig> configs;
4646

4747
public static final int DEFAULT = -1;
4848

4949
private static final byte[] EMPTY_BYTES = RopeConstants.EMPTY_BYTES;
5050

51-
public PrintfSimpleTreeBuilder(RubyContext context, List<SprintfConfig> configs) {
52-
this.context = context;
51+
public PrintfSimpleTreeBuilder(RubyLanguage language, List<SprintfConfig> configs) {
52+
this.language = language;
5353
this.configs = configs;
5454
}
5555

@@ -62,7 +62,7 @@ private void buildTree() {
6262
final FormatNode valueNode;
6363

6464
if (config.getNamesBytes() != null) {
65-
final RubySymbol key = context.getLanguageSlow().getSymbol(RopeOperations.create(
65+
final RubySymbol key = language.getSymbol(RopeOperations.create(
6666
config.getNamesBytes(),
6767
USASCIIEncoding.INSTANCE,
6868
CodeRange.CR_7BIT));

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1838,7 +1838,7 @@ private RubyString finishFormat(int formatLength, BytesResult result) {
18381838
protected RootCallTarget compileFormat(Object format, Object[] arguments, boolean isDebug,
18391839
RubyStringLibrary libFormat) {
18401840
try {
1841-
return new PrintfCompiler(getContext(), this)
1841+
return new PrintfCompiler(getLanguage(), this)
18421842
.compile(libFormat.getRope(format), arguments, isDebug);
18431843
} catch (InvalidFormatException e) {
18441844
throw new RaiseException(getContext(), coreExceptions().argumentError(e.getMessage(), this));

src/main/java/org/truffleruby/options/LanguageOptions.java

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,21 +26,23 @@ public class LanguageOptions {
2626
public final boolean FROZEN_STRING_LITERALS;
2727
/** --lazy-default=true */
2828
public final boolean DEFAULT_LAZY;
29+
/** --lazy-calltargets=DEFAULT_LAZY */
30+
public final boolean LAZY_CALLTARGETS;
2931
/** --core-as-internal=false */
3032
public final boolean CORE_AS_INTERNAL;
3133
/** --stdlib-as-internal=false */
3234
public final boolean STDLIB_AS_INTERNAL;
33-
/** --lazy-translation-user=DEFAULT_LAZY */
35+
/** --lazy-translation-user=LAZY_CALLTARGETS */
3436
public final boolean LAZY_TRANSLATION_USER;
3537
/** --backtraces-omit-unused=true */
3638
public final boolean BACKTRACES_OMIT_UNUSED;
3739
/** --lazy-translation-log=false */
3840
public final boolean LAZY_TRANSLATION_LOG;
3941
/** --constant-dynamic-lookup-log=false */
4042
public final boolean LOG_DYNAMIC_CONSTANT_LOOKUP;
41-
/** --lazy-builtins=DEFAULT_LAZY */
43+
/** --lazy-builtins=LAZY_CALLTARGETS */
4244
public final boolean LAZY_BUILTINS;
43-
/** --lazy-translation-core=DEFAULT_LAZY */
45+
/** --lazy-translation-core=LAZY_CALLTARGETS */
4446
public final boolean LAZY_TRANSLATION_CORE;
4547
/** --basic-ops-inline=true */
4648
public final boolean BASICOPS_INLINE;
@@ -108,14 +110,15 @@ public class LanguageOptions {
108110
public LanguageOptions(Env env, OptionValues options) {
109111
FROZEN_STRING_LITERALS = options.get(OptionsCatalog.FROZEN_STRING_LITERALS_KEY);
110112
DEFAULT_LAZY = options.get(OptionsCatalog.DEFAULT_LAZY_KEY);
113+
LAZY_CALLTARGETS = options.hasBeenSet(OptionsCatalog.LAZY_CALLTARGETS_KEY) ? options.get(OptionsCatalog.LAZY_CALLTARGETS_KEY) : DEFAULT_LAZY;
111114
CORE_AS_INTERNAL = options.get(OptionsCatalog.CORE_AS_INTERNAL_KEY);
112115
STDLIB_AS_INTERNAL = options.get(OptionsCatalog.STDLIB_AS_INTERNAL_KEY);
113-
LAZY_TRANSLATION_USER = options.hasBeenSet(OptionsCatalog.LAZY_TRANSLATION_USER_KEY) ? options.get(OptionsCatalog.LAZY_TRANSLATION_USER_KEY) : DEFAULT_LAZY;
116+
LAZY_TRANSLATION_USER = options.hasBeenSet(OptionsCatalog.LAZY_TRANSLATION_USER_KEY) ? options.get(OptionsCatalog.LAZY_TRANSLATION_USER_KEY) : LAZY_CALLTARGETS;
114117
BACKTRACES_OMIT_UNUSED = options.get(OptionsCatalog.BACKTRACES_OMIT_UNUSED_KEY);
115118
LAZY_TRANSLATION_LOG = options.get(OptionsCatalog.LAZY_TRANSLATION_LOG_KEY);
116119
LOG_DYNAMIC_CONSTANT_LOOKUP = options.get(OptionsCatalog.LOG_DYNAMIC_CONSTANT_LOOKUP_KEY);
117-
LAZY_BUILTINS = options.hasBeenSet(OptionsCatalog.LAZY_BUILTINS_KEY) ? options.get(OptionsCatalog.LAZY_BUILTINS_KEY) : DEFAULT_LAZY;
118-
LAZY_TRANSLATION_CORE = options.hasBeenSet(OptionsCatalog.LAZY_TRANSLATION_CORE_KEY) ? options.get(OptionsCatalog.LAZY_TRANSLATION_CORE_KEY) : DEFAULT_LAZY;
120+
LAZY_BUILTINS = options.hasBeenSet(OptionsCatalog.LAZY_BUILTINS_KEY) ? options.get(OptionsCatalog.LAZY_BUILTINS_KEY) : LAZY_CALLTARGETS;
121+
LAZY_TRANSLATION_CORE = options.hasBeenSet(OptionsCatalog.LAZY_TRANSLATION_CORE_KEY) ? options.get(OptionsCatalog.LAZY_TRANSLATION_CORE_KEY) : LAZY_CALLTARGETS;
119122
BASICOPS_INLINE = options.get(OptionsCatalog.BASICOPS_INLINE_KEY);
120123
PROFILE_ARGUMENTS = options.get(OptionsCatalog.PROFILE_ARGUMENTS_KEY);
121124
DEFAULT_CACHE = options.get(OptionsCatalog.DEFAULT_CACHE_KEY);
@@ -155,6 +158,8 @@ public Object fromDescriptor(OptionDescriptor descriptor) {
155158
return FROZEN_STRING_LITERALS;
156159
case "ruby.lazy-default":
157160
return DEFAULT_LAZY;
161+
case "ruby.lazy-calltargets":
162+
return LAZY_CALLTARGETS;
158163
case "ruby.core-as-internal":
159164
return CORE_AS_INTERNAL;
160165
case "ruby.stdlib-as-internal":
@@ -241,6 +246,7 @@ public Object fromDescriptor(OptionDescriptor descriptor) {
241246
public static boolean areOptionsCompatible(OptionValues one, OptionValues two) {
242247
return one.get(OptionsCatalog.FROZEN_STRING_LITERALS_KEY).equals(two.get(OptionsCatalog.FROZEN_STRING_LITERALS_KEY)) &&
243248
one.get(OptionsCatalog.DEFAULT_LAZY_KEY).equals(two.get(OptionsCatalog.DEFAULT_LAZY_KEY)) &&
249+
one.get(OptionsCatalog.LAZY_CALLTARGETS_KEY).equals(two.get(OptionsCatalog.LAZY_CALLTARGETS_KEY)) &&
244250
one.get(OptionsCatalog.CORE_AS_INTERNAL_KEY).equals(two.get(OptionsCatalog.CORE_AS_INTERNAL_KEY)) &&
245251
one.get(OptionsCatalog.STDLIB_AS_INTERNAL_KEY).equals(two.get(OptionsCatalog.STDLIB_AS_INTERNAL_KEY)) &&
246252
one.get(OptionsCatalog.LAZY_TRANSLATION_USER_KEY).equals(two.get(OptionsCatalog.LAZY_TRANSLATION_USER_KEY)) &&
@@ -300,6 +306,13 @@ public static boolean areOptionsCompatibleOrLog(TruffleLogger logger, LanguageOp
300306
return false;
301307
}
302308

309+
oldValue = oldOptions.LAZY_CALLTARGETS;
310+
newValue = newOptions.LAZY_CALLTARGETS;
311+
if (!newValue.equals(oldValue)) {
312+
logger.fine("not reusing pre-initialized context: --lazy-calltargets differs, was: " + oldValue + " and is now: " + newValue);
313+
return false;
314+
}
315+
303316
oldValue = oldOptions.CORE_AS_INTERNAL;
304317
newValue = newOptions.CORE_AS_INTERNAL;
305318
if (!newValue.equals(oldValue)) {

src/options.yml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ LANGUAGE_OPTIONS:
88
- LOG_DYNAMIC_CONSTANT_LOOKUP
99
- PROFILE_ARGUMENTS
1010
- DEFAULT_LAZY
11+
- LAZY_CALLTARGETS
1112
- BASICOPS_INLINE
1213
- LAZY_BUILTINS
1314
- SHARED_OBJECTS_ENABLED
@@ -65,6 +66,7 @@ EXPERT:
6566
FROZEN_STRING_LITERALS: [frozen-string-literals, boolean, false, Use frozen string literals]
6667
RUBYGEMS: [rubygems, boolean, true, Use RubyGems]
6768
DEFAULT_LAZY: [lazy-default, boolean, true, Enable default lazy options]
69+
LAZY_CALLTARGETS: [lazy-calltargets, boolean, DEFAULT_LAZY, Create CallTargets lazily when possible]
6870
LAZY_RUBYGEMS: [lazy-rubygems, boolean, ['RUBYGEMS && ', DEFAULT_LAZY], Load RubyGems lazily on first failing require]
6971
PATCHING: [patching, boolean, true, Use patching]
7072
DID_YOU_MEAN: [did-you-mean, boolean, true, Use did_you_mean]
@@ -87,7 +89,7 @@ EXPERT:
8789
# Options helpful in for debugging, potentially also for user code
8890
CORE_AS_INTERNAL: [core-as-internal, boolean, false, 'Mark core library sources as internal']
8991
STDLIB_AS_INTERNAL: [stdlib-as-internal, boolean, false, 'Mark stdlib sources as internal']
90-
LAZY_TRANSLATION_USER: [lazy-translation-user, boolean, DEFAULT_LAZY, 'Lazily translation of stdlib, gem and user source files']
92+
LAZY_TRANSLATION_USER: [lazy-translation-user, boolean, LAZY_CALLTARGETS, 'Lazily translation of stdlib, gem and user source files']
9193

9294
# Options to tweak backtraces
9395
EXCEPTIONS_STORE_JAVA: [exceptions-store-java, boolean, false, Store the Java exception with the Ruby backtrace]
@@ -150,8 +152,8 @@ INTERNAL: # Options for debugging the TruffleRuby implementation
150152

151153
# Options to debug the implementation
152154
PREINITIALIZATION: [preinit, boolean, true, Use the pre-initialized context when available]
153-
LAZY_BUILTINS: [lazy-builtins, boolean, DEFAULT_LAZY, Load builtin classes (core methods & primitives) lazily on first use]
154-
LAZY_TRANSLATION_CORE: [lazy-translation-core, boolean, DEFAULT_LAZY, Lazily translation of core source files]
155+
LAZY_BUILTINS: [lazy-builtins, boolean, LAZY_CALLTARGETS, Load builtin classes (core methods & primitives) lazily on first use]
156+
LAZY_TRANSLATION_CORE: [lazy-translation-core, boolean, LAZY_CALLTARGETS, Lazily translation of core source files]
155157

156158
# Options to help debugging the implementation performance
157159
BASICOPS_INLINE: [basic-ops-inline, boolean, true, Inline basic operations (like Fixnum operators) in the AST without a call]

0 commit comments

Comments
 (0)