Skip to content

Commit 69b1ebb

Browse files
committed
Avoid eager initialization of lookup types and option descriptors.
1 parent dc19964 commit 69b1ebb

File tree

2 files changed

+44
-19
lines changed

2 files changed

+44
-19
lines changed

truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/OptimizedTruffleRuntime.java

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -195,9 +195,10 @@ public static OptimizedTruffleRuntime getRuntime() {
195195

196196
private final LoopNodeFactory loopNodeFactory;
197197
private EngineCacheSupport engineCacheSupport;
198-
private final UnmodifiableEconomicMap<String, Class<?>> lookupTypes;
198+
private final Iterable<Class<?>> extraLookupTypes;
199+
private UnmodifiableEconomicMap<String, Class<?>> lookupTypes;
199200
private final FloodControlHandler floodControlHandler;
200-
private final List<OptionDescriptors> runtimeOptionDescriptors;
201+
private final List<OptionDescriptors> extensionOptionDescriptors;
201202
protected volatile OptionDescriptors engineOptions;
202203

203204
protected final TruffleCompilationSupport compilationSupport;
@@ -206,24 +207,22 @@ public static OptimizedTruffleRuntime getRuntime() {
206207
@SuppressWarnings("this-escape")
207208
public OptimizedTruffleRuntime(TruffleCompilationSupport compilationSupport, Iterable<Class<?>> extraLookupTypes) {
208209
this.compilationSupport = compilationSupport;
209-
this.lookupTypes = initLookupTypes(extraLookupTypes);
210+
this.extraLookupTypes = extraLookupTypes;
210211
List<OptionDescriptors> options = new ArrayList<>();
211212
this.loopNodeFactory = loadGraalRuntimeServiceProvider(LoopNodeFactory.class, options, true);
212213
EngineCacheSupport support = loadEngineCacheSupport(options);
213214
this.engineCacheSupport = support == null ? new EngineCacheSupport.Disabled() : support;
214215
this.previousEngineCacheSupportOptions = engineCacheSupport.getEngineOptions();
215-
options.add(OptimizedRuntimeOptions.getDescriptors());
216-
options.add(new CompilerOptionsDescriptors());
217-
this.runtimeOptionDescriptors = options;
216+
this.extensionOptionDescriptors = options;
218217
this.floodControlHandler = loadGraalRuntimeServiceProvider(FloodControlHandler.class, null, false);
219218
}
220219

221220
public final void initializeEngineCacheSupport(EngineCacheSupport support) {
222-
this.runtimeOptionDescriptors.remove(this.previousEngineCacheSupportOptions);
221+
this.extensionOptionDescriptors.remove(this.previousEngineCacheSupportOptions);
223222
this.engineCacheSupport = support;
224223
OptionDescriptors engineCacheOptions = support.getEngineOptions();
225224
this.previousEngineCacheSupportOptions = engineCacheOptions;
226-
this.runtimeOptionDescriptors.add(engineCacheOptions);
225+
this.extensionOptionDescriptors.add(engineCacheOptions);
227226
}
228227

229228
protected EngineCacheSupport loadEngineCacheSupport(List<OptionDescriptors> options) {
@@ -249,7 +248,15 @@ public String getName() {
249248
* Returns a set of classes that need to be initialized before compilations can be performed.
250249
*/
251250
public final Iterable<Class<?>> getLookupTypes() {
252-
return lookupTypes.getValues();
251+
return getLookupTypesMap().getValues();
252+
}
253+
254+
private UnmodifiableEconomicMap<String, Class<?>> getLookupTypesMap() {
255+
UnmodifiableEconomicMap<String, Class<?>> map = this.lookupTypes;
256+
if (map == null) {
257+
this.lookupTypes = map = initLookupTypes(extraLookupTypes);
258+
}
259+
return map;
253260
}
254261

255262
/**
@@ -500,7 +507,7 @@ private static UnmodifiableEconomicMap<String, Class<?>> initLookupTypes(Iterabl
500507
*/
501508
@Override
502509
public ResolvedJavaType resolveType(MetaAccessProvider metaAccess, String className, boolean required) {
503-
Class<?> c = lookupTypes.get(className);
510+
Class<?> c = getLookupTypesMap().get(className);
504511
if (c == null) {
505512
if (!required) {
506513
return null;
@@ -1121,16 +1128,24 @@ protected long getCompilerIdleDelay(OptimizedCallTarget callTarget) {
11211128
}
11221129

11231130
final OptionDescriptors getOptionDescriptors() {
1124-
// The engineOptions field needs to be initialized lazily because the
1125-
// OptimizedRuntimeAccessor
1126-
// cannot be used in the OptimizedTruffleRuntime constructor. The OptimizedTruffleRuntime
1127-
// must be
1128-
// fully initialized before using the accessor otherwise a NullPointerException will be
1129-
// thrown from the Accessor.Constants static initializer because the Truffle#getRuntime
1130-
// still returns null.
1131+
/*
1132+
* The engineOptions field needs to be initialized lazily because the
1133+
* OptimizedRuntimeAccessor cannot be used in the OptimizedTruffleRuntime constructor. The
1134+
* OptimizedTruffleRuntime must be fully initialized before using the accessor otherwise a
1135+
* NullPointerException will be thrown from the Accessor.Constants static initializer
1136+
* because the Truffle#getRuntime still returns null.
1137+
*/
11311138
OptionDescriptors res = engineOptions;
11321139
if (res == null) {
1133-
res = OptimizedRuntimeAccessor.LANGUAGE.createOptionDescriptorsUnion(runtimeOptionDescriptors.toArray(new OptionDescriptors[runtimeOptionDescriptors.size()]));
1140+
List<OptionDescriptors> options = new ArrayList<>(extensionOptionDescriptors.size() + 2);
1141+
/*
1142+
* We initialize these options lazily so in case no engine options are used we don't
1143+
* need to load them.
1144+
*/
1145+
options.addAll(extensionOptionDescriptors);
1146+
options.add(OptimizedRuntimeOptions.getDescriptors());
1147+
options.add(new CompilerOptionsDescriptors());
1148+
res = OptimizedRuntimeAccessor.LANGUAGE.createOptionDescriptorsUnion(options.toArray(OptionDescriptors[]::new));
11341149
engineOptions = res;
11351150
}
11361151
return res;

truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/hotspot/HotSpotTruffleRuntime.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,16 @@ private static Unsafe getUnsafe() {
130130
}
131131
}
132132

133+
/*
134+
* Invoked before the first compilation, but still on an interpreter thread. This makes it safe
135+
* to initialize certain classes.
136+
*/
137+
private void onFirstCompilation() {
138+
installDefaultListeners();
139+
// make sure lookup types are installed lazily when the first compilation is scheduled
140+
getLookupTypes();
141+
}
142+
133143
/**
134144
* Contains lazily computed data such as the compilation queue and helper for stack
135145
* introspection.
@@ -139,7 +149,7 @@ static final class Lazy extends BackgroundCompileQueue {
139149

140150
Lazy(HotSpotTruffleRuntime runtime) {
141151
super(runtime);
142-
runtime.installDefaultListeners();
152+
runtime.onFirstCompilation();
143153
}
144154

145155
@Override

0 commit comments

Comments
 (0)