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

View File

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

View File

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

View File

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