105
105
import java .lang .annotation .Annotation ;
106
106
import java .lang .reflect .Executable ;
107
107
import java .lang .reflect .Field ;
108
+ import java .nio .ByteBuffer ;
109
+ import java .nio .channels .FileChannel ;
108
110
import java .nio .file .Path ;
109
111
import java .util .HashMap ;
110
112
import java .util .List ;
135
137
import com .oracle .graal .pointsto .util .AnalysisFuture ;
136
138
import com .oracle .svm .util .ReflectionUtil ;
137
139
140
+ import jdk .graal .compiler .core .common .NumUtil ;
138
141
import jdk .graal .compiler .core .common .SuppressFBWarnings ;
139
142
import jdk .graal .compiler .debug .GraalError ;
140
143
import jdk .graal .compiler .nodes .EncodedGraph ;
@@ -302,7 +305,7 @@ public class ImageLayerLoader {
302
305
protected final Map <Integer , AnalysisMethod > methods = new ConcurrentHashMap <>();
303
306
protected final Map <Integer , AnalysisField > fields = new ConcurrentHashMap <>();
304
307
protected final Map <Integer , ImageHeapConstant > constants = new ConcurrentHashMap <>();
305
- private final List <Path > loadPaths ;
308
+ private final List <FilePaths > loadPaths ;
306
309
private final Map <Integer , BaseLayerType > baseLayerTypes = new ConcurrentHashMap <>();
307
310
private final Map <Integer , Integer > typeToHubIdentityHashCode = new ConcurrentHashMap <>();
308
311
private final Map <Integer , BaseLayerMethod > baseLayerMethods = new ConcurrentHashMap <>();
@@ -332,22 +335,22 @@ record FieldIdentifier(String tid, String name) {
332
335
protected HostedValuesProvider hostedValuesProvider ;
333
336
334
337
protected EconomicMap <String , Object > jsonMap ;
338
+ protected FileChannel graphsChannel ;
335
339
336
340
private long imageHeapSize ;
337
341
342
+ public record FilePaths (Path snapshot , Path snapshotGraphs ) {
343
+ }
344
+
338
345
public ImageLayerLoader () {
339
346
this (new ImageLayerSnapshotUtil (), List .of ());
340
347
}
341
348
342
- public ImageLayerLoader (ImageLayerSnapshotUtil imageLayerSnapshotUtil , List <Path > loadPaths ) {
349
+ public ImageLayerLoader (ImageLayerSnapshotUtil imageLayerSnapshotUtil , List <FilePaths > loadPaths ) {
343
350
this .imageLayerSnapshotUtil = imageLayerSnapshotUtil ;
344
351
this .loadPaths = loadPaths ;
345
352
}
346
353
347
- public List <Path > getLoadPaths () {
348
- return loadPaths ;
349
- }
350
-
351
354
public AnalysisUniverse getUniverse () {
352
355
return universe ;
353
356
}
@@ -360,16 +363,18 @@ public void setImageLayerLoaderHelper(ImageLayerLoaderHelper imageLayerLoaderHel
360
363
this .imageLayerLoaderHelper = imageLayerLoaderHelper ;
361
364
}
362
365
363
- /**
364
- * Note this code is not thread safe.
365
- */
366
- protected void loadJsonMap () {
366
+ /** This code is not thread safe. */
367
+ protected void openFilesAndLoadJsonMap () {
367
368
assert loadPaths .size () == 1 : "Currently only one path is supported for image layer loading " + loadPaths ;
368
369
if (jsonMap == null ) {
369
- for (Path layerPath : loadPaths ) {
370
- try (InputStreamReader inputStreamReader = new InputStreamReader (new FileInputStream (layerPath .toFile ()))) {
371
- Object json = new JsonParser (inputStreamReader ).parse ();
372
- jsonMap = cast (json );
370
+ for (FilePaths paths : loadPaths ) {
371
+ try {
372
+ graphsChannel = FileChannel .open (paths .snapshotGraphs );
373
+
374
+ try (InputStreamReader inputStreamReader = new InputStreamReader (new FileInputStream (paths .snapshot .toFile ()))) {
375
+ Object json = new JsonParser (inputStreamReader ).parse ();
376
+ jsonMap = cast (json );
377
+ }
373
378
} catch (IOException e ) {
374
379
throw AnalysisError .shouldNotReachHere ("Error during image layer snapshot loading" , e );
375
380
}
@@ -378,10 +383,20 @@ protected void loadJsonMap() {
378
383
}
379
384
380
385
public void loadLayerAnalysis () {
381
- loadJsonMap ();
386
+ openFilesAndLoadJsonMap ();
382
387
loadLayerAnalysis0 ();
383
388
}
384
389
390
+ public void cleanupAfterAnalysis () {
391
+ if (graphsChannel != null ) {
392
+ try {
393
+ graphsChannel .close ();
394
+ } catch (IOException e ) {
395
+ throw AnalysisError .shouldNotReachHere (e );
396
+ }
397
+ }
398
+ }
399
+
385
400
/**
386
401
* Initializes the {@link ImageLayerLoader}.
387
402
*/
@@ -792,7 +807,7 @@ public boolean hasAnalysisParsedGraph(AnalysisMethod analysisMethod) {
792
807
793
808
public AnalysisParsedGraph getAnalysisParsedGraph (AnalysisMethod analysisMethod ) {
794
809
EconomicMap <String , Object > methodData = getMethodData (analysisMethod );
795
- String encodedAnalyzedGraph = get (methodData , ANALYSIS_PARSED_GRAPH_TAG );
810
+ String encodedAnalyzedGraph = readEncodedGraph (methodData , ANALYSIS_PARSED_GRAPH_TAG );
796
811
Boolean intrinsic = get (methodData , INTRINSIC_TAG );
797
812
/*
798
813
* Methods without a persisted graph are folded and static methods.
@@ -802,21 +817,44 @@ public AnalysisParsedGraph getAnalysisParsedGraph(AnalysisMethod analysisMethod)
802
817
if (encodedAnalyzedGraph != null ) {
803
818
EncodedGraph analyzedGraph = (EncodedGraph ) ObjectCopier .decode (imageLayerSnapshotUtil .getGraphDecoder (this , analysisMethod , universe .getSnippetReflection ()), encodedAnalyzedGraph );
804
819
if (hasStrengthenedGraph (analysisMethod )) {
805
- loadAllAnalysisElements (get (methodData , STRENGTHENED_GRAPH_TAG ));
820
+ loadAllAnalysisElements (readEncodedGraph (methodData , STRENGTHENED_GRAPH_TAG ));
806
821
}
807
822
return new AnalysisParsedGraph (analyzedGraph , intrinsic );
808
823
}
809
824
throw AnalysisError .shouldNotReachHere ("The method " + analysisMethod + " does not have a graph from the base layer" );
810
825
}
811
826
827
+ private String readEncodedGraph (EconomicMap <String , Object > methodData , String elementIdentifier ) {
828
+ String location = get (methodData , elementIdentifier );
829
+ int closingBracketAt = location .length () - 1 ;
830
+ AnalysisError .guarantee (location .charAt (0 ) == '@' && location .charAt (closingBracketAt ) == ']' , "Location must start with '@' and end with ']': %s" , location );
831
+ int openingBracketAt = location .indexOf ('[' , 1 , closingBracketAt );
832
+ AnalysisError .guarantee (openingBracketAt < closingBracketAt , "Location does not contain '[' at expected location: %s" , location );
833
+ long offset ;
834
+ long nbytes ;
835
+ try {
836
+ offset = Long .parseUnsignedLong (location .substring (1 , openingBracketAt ));
837
+ nbytes = Long .parseUnsignedLong (location .substring (openingBracketAt + 1 , closingBracketAt ));
838
+ } catch (NumberFormatException e ) {
839
+ throw AnalysisError .shouldNotReachHere ("Location contains invalid positive integer(s): " + location );
840
+ }
841
+ ByteBuffer bb = ByteBuffer .allocate (NumUtil .safeToInt (nbytes ));
842
+ try {
843
+ graphsChannel .read (bb , offset );
844
+ } catch (IOException e ) {
845
+ throw AnalysisError .shouldNotReachHere ("Failed reading a graph from location: " + location , e );
846
+ }
847
+ return new String (bb .array (), ImageLayerWriter .GRAPHS_CHARSET );
848
+ }
849
+
812
850
public boolean hasStrengthenedGraph (AnalysisMethod analysisMethod ) {
813
851
EconomicMap <String , Object > methodData = getMethodData (analysisMethod );
814
852
return get (methodData , STRENGTHENED_GRAPH_TAG ) != null ;
815
853
}
816
854
817
855
public void setStrengthenedGraph (AnalysisMethod analysisMethod ) {
818
856
EconomicMap <String , Object > methodData = getMethodData (analysisMethod );
819
- String encodedAnalyzedGraph = get (methodData , STRENGTHENED_GRAPH_TAG );
857
+ String encodedAnalyzedGraph = readEncodedGraph (methodData , STRENGTHENED_GRAPH_TAG );
820
858
EncodedGraph analyzedGraph = (EncodedGraph ) ObjectCopier .decode (imageLayerSnapshotUtil .getGraphDecoder (this , analysisMethod , universe .getSnippetReflection ()), encodedAnalyzedGraph );
821
859
processGraph (analyzedGraph );
822
860
analysisMethod .setAnalyzedGraph (analyzedGraph );
@@ -827,17 +865,19 @@ protected void processGraph(EncodedGraph encodedGraph) {
827
865
828
866
}
829
867
830
- protected void loadAllAnalysisElements (String encoding ) {
831
- for (String line : encoding .lines ().toList ()) {
832
- if (line .contains (PointsToAnalysisType .class .getName ())) {
833
- getAnalysisType (getId (line ));
834
- } else if (line .contains (PointsToAnalysisMethod .class .getName ())) {
835
- getAnalysisMethod (getId (line ));
836
- } else if (line .contains (PointsToAnalysisField .class .getName ())) {
837
- getAnalysisField (getId (line ));
838
- } else if (line .contains (ImageHeapInstance .class .getName ()) || line .contains (ImageHeapObjectArray .class .getName ()) || line .contains (ImageHeapPrimitiveArray .class .getName ())) {
839
- getOrCreateConstant (getId (line ));
840
- }
868
+ private void loadAllAnalysisElements (String encoding ) {
869
+ encoding .lines ().forEach (this ::loadEncodedGraphLineAnalysisElements );
870
+ }
871
+
872
+ protected void loadEncodedGraphLineAnalysisElements (String line ) {
873
+ if (line .contains (PointsToAnalysisType .class .getName ())) {
874
+ getAnalysisType (getId (line ));
875
+ } else if (line .contains (PointsToAnalysisMethod .class .getName ())) {
876
+ getAnalysisMethod (getId (line ));
877
+ } else if (line .contains (PointsToAnalysisField .class .getName ())) {
878
+ getAnalysisField (getId (line ));
879
+ } else if (line .contains (ImageHeapInstance .class .getName ()) || line .contains (ImageHeapObjectArray .class .getName ()) || line .contains (ImageHeapPrimitiveArray .class .getName ())) {
880
+ getOrCreateConstant (getId (line ));
841
881
}
842
882
}
843
883
0 commit comments