51
51
52
52
import com .oracle .graal .pointsto .BigBang ;
53
53
import com .oracle .graal .pointsto .PointsToAnalysis ;
54
+ import com .oracle .graal .pointsto .api .HostVM ;
54
55
import com .oracle .graal .pointsto .api .ImageLayerLoader ;
55
56
import com .oracle .graal .pointsto .api .ImageLayerWriter ;
56
57
import com .oracle .graal .pointsto .constraints .UnsupportedFeatureException ;
@@ -126,6 +127,7 @@ public record Signature(String name, AnalysisType[] parameterTypes) {
126
127
public final ResolvedJavaMethod wrapped ;
127
128
128
129
private final int id ;
130
+ private final boolean buildingSharedLayer ;
129
131
/** Marks a method loaded from a base layer. */
130
132
private final boolean isInBaseLayer ;
131
133
private final boolean analyzedInPriorLayer ;
@@ -196,9 +198,12 @@ public record Signature(String name, AnalysisType[] parameterTypes) {
196
198
*/
197
199
private boolean hasOpaqueReturn ;
198
200
201
+ private CompilationBehavior compilationBehavior = CompilationBehavior .DEFAULT ;
202
+
199
203
@ SuppressWarnings ({"this-escape" , "unchecked" })
200
204
protected AnalysisMethod (AnalysisUniverse universe , ResolvedJavaMethod wrapped , MultiMethodKey multiMethodKey , Map <MultiMethodKey , MultiMethod > multiMethodMap ) {
201
205
super (universe .hostVM .enableTrackAcrossLayers ());
206
+ HostVM hostVM = universe .hostVM ();
202
207
this .wrapped = wrapped ;
203
208
204
209
declaringClass = universe .lookup (wrapped .getDeclaringClass ());
@@ -213,13 +218,14 @@ protected AnalysisMethod(AnalysisUniverse universe, ResolvedJavaMethod wrapped,
213
218
} else {
214
219
signature = getUniverse ().lookup (wrappedSignature , wrapped .getDeclaringClass ());
215
220
}
216
- hasNeverInlineDirective = universe . hostVM () .hasNeverInlineDirective (wrapped );
221
+ hasNeverInlineDirective = hostVM .hasNeverInlineDirective (wrapped );
217
222
218
223
name = createName (wrapped , multiMethodKey );
219
224
qualifiedName = format ("%H.%n(%P)" );
220
225
modifiers = wrapped .getModifiers ();
221
226
222
- if (universe .hostVM ().useBaseLayer () && declaringClass .isInBaseLayer ()) {
227
+ buildingSharedLayer = hostVM .buildingSharedLayer ();
228
+ if (hostVM .buildingExtensionLayer () && declaringClass .isInBaseLayer ()) {
223
229
int mid = universe .getImageLayerLoader ().lookupHostedMethodInBaseLayer (this );
224
230
if (mid != -1 ) {
225
231
/*
@@ -236,7 +242,7 @@ protected AnalysisMethod(AnalysisUniverse universe, ResolvedJavaMethod wrapped,
236
242
id = universe .computeNextMethodId ();
237
243
isInBaseLayer = false ;
238
244
}
239
- analyzedInPriorLayer = isInBaseLayer && universe . hostVM () .analyzedInPriorLayer (this );
245
+ analyzedInPriorLayer = isInBaseLayer && hostVM .analyzedInPriorLayer (this );
240
246
241
247
ExceptionHandler [] original = wrapped .getExceptionHandlers ();
242
248
exceptionHandlers = new ExceptionHandler [original .length ];
@@ -281,6 +287,7 @@ protected AnalysisMethod(AnalysisMethod original, MultiMethodKey multiMethodKey)
281
287
super (original .enableTrackAcrossLayers );
282
288
wrapped = original .wrapped ;
283
289
id = original .id ;
290
+ buildingSharedLayer = original .buildingSharedLayer ;
284
291
isInBaseLayer = original .isInBaseLayer ;
285
292
analyzedInPriorLayer = original .analyzedInPriorLayer ;
286
293
declaringClass = original .declaringClass ;
@@ -306,6 +313,35 @@ protected AnalysisMethod(AnalysisMethod original, MultiMethodKey multiMethodKey)
306
313
this .enableReachableInCurrentLayer = original .enableReachableInCurrentLayer ;
307
314
}
308
315
316
+ public void setCompilationBehavior (CompilationBehavior compilationBehavior ) {
317
+ this .compilationBehavior = compilationBehavior ;
318
+ }
319
+
320
+ public CompilationBehavior getCompilationBehavior () {
321
+ return compilationBehavior ;
322
+ }
323
+
324
+ /**
325
+ * Delays this method to the application layer. This should not be called after the method was
326
+ * already parsed to avoid analyzing all the method's callees.
327
+ */
328
+ public void setFullyDelayedToApplicationLayer () {
329
+ HostVM hostVM = getUniverse ().getBigbang ().getHostVM ();
330
+ AnalysisError .guarantee (hostVM .buildingImageLayer (), "Methods can only be delayed in layered images" );
331
+ AnalysisError .guarantee (parsedGraphCacheState .get () == GraphCacheEntry .UNPARSED , "The method %s was marked as delayed to the application layer but was already parsed" , this );
332
+ AnalysisError .guarantee (!hostVM .hasAlwaysInlineDirective (this ), "Method %s with an always inline directive cannot be delayed to the application layer as such methods cannot be inlined" , this );
333
+ AnalysisError .guarantee (isConcrete (), "Method %s is not concrete and cannot be delayed to the application layer" , this );
334
+ this .compilationBehavior = CompilationBehavior .FULLY_DELAYED_TO_APPLICATION_LAYER ;
335
+ }
336
+
337
+ /**
338
+ * Returns true if this method is marked as delayed to the application layer and the current
339
+ * layer is a shared layer.
340
+ */
341
+ public boolean isDelayed () {
342
+ return compilationBehavior == CompilationBehavior .FULLY_DELAYED_TO_APPLICATION_LAYER && buildingSharedLayer ;
343
+ }
344
+
309
345
private static String createName (ResolvedJavaMethod wrapped , MultiMethodKey multiMethodKey ) {
310
346
String aName = wrapped .getName ();
311
347
if (multiMethodKey != ORIGINAL_METHOD ) {
@@ -847,7 +883,8 @@ public Type[] getGenericParameterTypes() {
847
883
848
884
@ Override
849
885
public boolean canBeInlined () {
850
- return !hasNeverInlineDirective ();
886
+ /* Delayed methods should not be inlined in the current layer */
887
+ return !hasNeverInlineDirective () && !isDelayed ();
851
888
}
852
889
853
890
@ Override
@@ -1202,6 +1239,7 @@ private AnalysisParsedGraph setGraph(BigBang bb, Stage stage, GraphCacheEntry ex
1202
1239
/* We lost the race, another thread is doing the parsing. */
1203
1240
return null ;
1204
1241
}
1242
+ AnalysisError .guarantee (!isDelayed (), "The method %s was parsed even though it was marked as delayed to the application layer" , this );
1205
1243
1206
1244
GraphCacheEntry newEntry = graphSupplier .get (bb , this , expectedValue );
1207
1245
@@ -1360,4 +1398,40 @@ public boolean hasOpaqueReturn() {
1360
1398
}
1361
1399
1362
1400
protected abstract AnalysisMethod createMultiMethod (AnalysisMethod analysisMethod , MultiMethodKey newMultiMethodKey );
1401
+
1402
+ /**
1403
+ * This state represents how a method should be compiled in layered images. The state of a
1404
+ * method can only be decided in the first layer if it is marked as tracked across layers. The
1405
+ * state has to stay the same across all the extension layers. If not specified, the state of a
1406
+ * method will be {@link CompilationBehavior#DEFAULT}.
1407
+ */
1408
+ public enum CompilationBehavior {
1409
+
1410
+ /**
1411
+ * Method remains unanalyzed until the application layer and any inlining in a shared layer
1412
+ * is prevented. A call to the method in a shared layer will be replaced by an indirect
1413
+ * call. The compilation of those methods is then forced in the application layer and the
1414
+ * corresponding symbol is declared as global.
1415
+ *
1416
+ * A delayed method that is not referenced in any shared layer is treated as a
1417
+ * {@link CompilationBehavior#DEFAULT} method in the application layer and does not have to
1418
+ * be compiled. If it is only referenced in the application layer, it might be inlined and
1419
+ * not compiled at all.
1420
+ */
1421
+ FULLY_DELAYED_TO_APPLICATION_LAYER ,
1422
+
1423
+ /**
1424
+ * Method can be inlined into other methods, both before analysis and during compilation,
1425
+ * and will be compiled as a distinct compilation unit as stipulated by the normal native
1426
+ * image generation process (i.e., the method is installed as a root and/or a reference to
1427
+ * the method exists via a call and/or an explicit MethodReference).
1428
+ */
1429
+ DEFAULT ,
1430
+
1431
+ /**
1432
+ * Method is pinned to a specific shared layer, meaning it has to be analyzed and compiled
1433
+ * in this specific layer. A method can only be pinned to a shared layer.
1434
+ */
1435
+ PINNED_TO_SHARED_LAYER ,
1436
+ }
1363
1437
}
0 commit comments