[GR-57955] Ensure the persistType and persistMethod methods are thread safe

PullRequest: graal/18823
This commit is contained in:
Sacha Coppey 2024-09-25 02:38:50 +00:00
commit fcbe9047fc
4 changed files with 29 additions and 34 deletions

View File

@ -327,9 +327,7 @@ public class ImageLayerSnapshotUtil {
@Override @Override
public String encode(ObjectCopier.Encoder encoder, Object obj) { public String encode(ObjectCopier.Encoder encoder, Object obj) {
AnalysisType type = (AnalysisType) obj; AnalysisType type = (AnalysisType) obj;
if (!type.isReachable() && !imageLayerWriter.typesMap.containsKey(imageLayerWriter.imageLayerSnapshotUtil.getTypeIdentifier(type))) { imageLayerWriter.persistType(type);
imageLayerWriter.persistType(type);
}
return String.valueOf(type.getId()); return String.valueOf(type.getId());
} }
@ -356,19 +354,13 @@ public class ImageLayerSnapshotUtil {
AnalysisMethod method = (AnalysisMethod) obj; AnalysisMethod method = (AnalysisMethod) obj;
AnalysisType declaringClass = method.getDeclaringClass(); AnalysisType declaringClass = method.getDeclaringClass();
imageLayerWriter.elementsToPersist.add(new AnalysisFuture<>(() -> { imageLayerWriter.elementsToPersist.add(new AnalysisFuture<>(() -> {
if (!method.isReachable() && !imageLayerWriter.methodsMap.containsKey(imageLayerWriter.imageLayerSnapshotUtil.getMethodIdentifier(method))) { imageLayerWriter.persistAnalysisParsedGraph(method);
imageLayerWriter.persistAnalysisParsedGraph(method); imageLayerWriter.persistMethod(method);
imageLayerWriter.persistMethod(method);
}
})); }));
for (AnalysisType parameter : method.toParameterList()) { for (AnalysisType parameter : method.toParameterList()) {
if (!parameter.isReachable() && !imageLayerWriter.typesMap.containsKey(imageLayerWriter.imageLayerSnapshotUtil.getTypeIdentifier(parameter))) { imageLayerWriter.persistType(parameter);
imageLayerWriter.persistType(parameter);
}
}
if (!declaringClass.isReachable() && !imageLayerWriter.typesMap.containsKey(imageLayerWriter.imageLayerSnapshotUtil.getTypeIdentifier(declaringClass))) {
imageLayerWriter.persistType(declaringClass);
} }
imageLayerWriter.persistType(declaringClass);
return String.valueOf(method.getId()); return String.valueOf(method.getId());
} }

View File

@ -104,7 +104,6 @@ import java.nio.file.StandardOpenOption;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.HashSet;
import java.util.IdentityHashMap; import java.util.IdentityHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -150,6 +149,7 @@ public class ImageLayerWriter {
protected final EconomicMap<String, Object> jsonMap; protected final EconomicMap<String, Object> jsonMap;
protected final List<Integer> constantsToRelink; protected final List<Integer> constantsToRelink;
private final Set<Integer> persistedTypeIds; private final Set<Integer> persistedTypeIds;
private final Set<Integer> persistedMethodIds;
protected final Map<String, EconomicMap<String, Object>> typesMap; protected final Map<String, EconomicMap<String, Object>> typesMap;
protected final Map<String, EconomicMap<String, Object>> methodsMap; protected final Map<String, EconomicMap<String, Object>> methodsMap;
protected final Map<String, Map<String, Object>> fieldsMap; protected final Map<String, Map<String, Object>> fieldsMap;
@ -212,7 +212,8 @@ public class ImageLayerWriter {
this.imageLayerSnapshotUtil = imageLayerSnapshotUtil; this.imageLayerSnapshotUtil = imageLayerSnapshotUtil;
this.jsonMap = EconomicMap.create(); this.jsonMap = EconomicMap.create();
this.constantsToRelink = new ArrayList<>(); this.constantsToRelink = new ArrayList<>();
this.persistedTypeIds = new HashSet<>(); this.persistedTypeIds = ConcurrentHashMap.newKeySet();
this.persistedMethodIds = ConcurrentHashMap.newKeySet();
this.typesMap = new ConcurrentHashMap<>(); this.typesMap = new ConcurrentHashMap<>();
this.methodsMap = new ConcurrentHashMap<>(); this.methodsMap = new ConcurrentHashMap<>();
this.fieldsMap = new ConcurrentHashMap<>(); this.fieldsMap = new ConcurrentHashMap<>();
@ -325,9 +326,7 @@ public class ImageLayerWriter {
* Some persisted types are not reachable. In this case, the super class has to be * Some persisted types are not reachable. In this case, the super class has to be
* persisted manually as well. * persisted manually as well.
*/ */
if (!superclass.isReachable()) { persistType(superclass);
persistType(superclass);
}
} }
EconomicMap<String, Object> typeMap = EconomicMap.create(); EconomicMap<String, Object> typeMap = EconomicMap.create();
@ -384,7 +383,14 @@ public class ImageLayerWriter {
} }
public void persistMethod(AnalysisMethod method) { public void persistMethod(AnalysisMethod method) {
if (!persistedMethodIds.add(method.getId())) {
return;
}
EconomicMap<String, Object> methodMap = getMethodMap(method); EconomicMap<String, Object> methodMap = getMethodMap(method);
persistMethod(method, methodMap);
}
protected void persistMethod(AnalysisMethod method, EconomicMap<String, Object> methodMap) {
Executable executable = method.getJavaMethod(); Executable executable = method.getJavaMethod();
if (methodMap.containsKey(ID_TAG)) { if (methodMap.containsKey(ID_TAG)) {
@ -424,11 +430,6 @@ public class ImageLayerWriter {
imageLayerWriterHelper.persistMethod(method, methodMap); imageLayerWriterHelper.persistMethod(method, methodMap);
} }
public boolean isMethodPersisted(AnalysisMethod method) {
String name = imageLayerSnapshotUtil.getMethodIdentifier(method);
return methodsMap.containsKey(name);
}
public void persistMethodGraphs() { public void persistMethodGraphs() {
for (AnalysisMethod method : aUniverse.getMethods()) { for (AnalysisMethod method : aUniverse.getMethods()) {
if (method.isReachable()) { if (method.isReachable()) {
@ -442,18 +443,22 @@ public class ImageLayerWriter {
Object analyzedGraph = method.getGraph(); Object analyzedGraph = method.getGraph();
if (analyzedGraph instanceof AnalysisParsedGraph analysisParsedGraph) { if (analyzedGraph instanceof AnalysisParsedGraph analysisParsedGraph) {
if (!persistGraph(analysisParsedGraph.getEncodedGraph(), methodMap, ANALYSIS_PARSED_GRAPH_TAG)) { if (!methodMap.containsKey(INTRINSIC_TAG)) {
return; if (!persistGraph(analysisParsedGraph.getEncodedGraph(), methodMap, ANALYSIS_PARSED_GRAPH_TAG)) {
return;
}
methodMap.put(INTRINSIC_TAG, analysisParsedGraph.isIntrinsic());
} }
methodMap.put(INTRINSIC_TAG, analysisParsedGraph.isIntrinsic());
} }
} }
public void persistMethodStrengthenedGraph(AnalysisMethod method) { public void persistMethodStrengthenedGraph(AnalysisMethod method) {
EconomicMap<String, Object> methodMap = getMethodMap(method); EconomicMap<String, Object> methodMap = getMethodMap(method);
EncodedGraph analyzedGraph = method.getAnalyzedGraph(); if (!methodMap.containsKey(STRENGTHENED_GRAPH_TAG)) {
persistGraph(analyzedGraph, methodMap, STRENGTHENED_GRAPH_TAG); EncodedGraph analyzedGraph = method.getAnalyzedGraph();
persistGraph(analyzedGraph, methodMap, STRENGTHENED_GRAPH_TAG);
}
} }
private boolean persistGraph(EncodedGraph analyzedGraph, EconomicMap<String, Object> methodMap, String graphTag) { private boolean persistGraph(EncodedGraph analyzedGraph, EconomicMap<String, Object> methodMap, String graphTag) {

View File

@ -216,8 +216,8 @@ public class SVMImageLayerWriter extends ImageLayerWriter {
} }
@Override @Override
public void persistMethod(AnalysisMethod method) { public void persistMethod(AnalysisMethod method, EconomicMap<String, Object> methodMap) {
super.persistMethod(method); super.persistMethod(method, methodMap);
// register this method as persisted for name resolution // register this method as persisted for name resolution
HostedDynamicLayerInfo.singleton().recordPersistedMethod(hUniverse.lookup(method)); HostedDynamicLayerInfo.singleton().recordPersistedMethod(hUniverse.lookup(method));

View File

@ -64,10 +64,8 @@ public class SVMImageLayerWriterHelper extends ImageLayerWriterHelper {
if (method.wrapped instanceof FactoryMethod factoryMethod) { if (method.wrapped instanceof FactoryMethod factoryMethod) {
methodMap.put(WRAPPED_METHOD_TAG, FACTORY_TAG); methodMap.put(WRAPPED_METHOD_TAG, FACTORY_TAG);
AnalysisMethod targetConstructor = method.getUniverse().lookup(factoryMethod.getTargetConstructor()); AnalysisMethod targetConstructor = method.getUniverse().lookup(factoryMethod.getTargetConstructor());
if (!method.isReachable() && !imageLayerWriter.isMethodPersisted(targetConstructor)) { imageLayerWriter.persistAnalysisParsedGraph(targetConstructor);
imageLayerWriter.persistAnalysisParsedGraph(targetConstructor); imageLayerWriter.persistMethod(targetConstructor);
imageLayerWriter.persistMethod(targetConstructor);
}
methodMap.put(TARGET_CONSTRUCTOR_TAG, targetConstructor.getId()); methodMap.put(TARGET_CONSTRUCTOR_TAG, targetConstructor.getId());
methodMap.put(THROW_ALLOCATED_OBJECT_TAG, factoryMethod.throwAllocatedObject()); methodMap.put(THROW_ALLOCATED_OBJECT_TAG, factoryMethod.throwAllocatedObject());
} }