From 9be2315726d5bd99d0b6c1138a8d2b41b1ae2c49 Mon Sep 17 00:00:00 2001 From: Marc Miltenberger Date: Thu, 7 Nov 2024 15:04:37 +0100 Subject: [PATCH 1/2] Fix recursive array type cache load --- src/main/java/soot/ArrayTypeCache.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/main/java/soot/ArrayTypeCache.java b/src/main/java/soot/ArrayTypeCache.java index 34663859e61..62d57ab8937 100644 --- a/src/main/java/soot/ArrayTypeCache.java +++ b/src/main/java/soot/ArrayTypeCache.java @@ -24,8 +24,8 @@ import heros.solver.Pair; +import java.util.HashMap; import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; import java.util.function.Function; import soot.Singletons.Global; @@ -36,7 +36,7 @@ * @author Marc Miltenberger */ public class ArrayTypeCache { - private final Map, ArrayType> cache = new ConcurrentHashMap<>(); + private final Map, ArrayType> cache = new HashMap<>(); private final Function, ArrayType> mapping = new Function, ArrayType>() { @@ -76,7 +76,11 @@ public ArrayTypeCache(Global g) { * @param numDimensions the number of dimensions * @return the array type */ - public ArrayType getArrayType(Type baseType, int numDimensions) { + //We are doing this synchronized now to ensure correctness: + //Already creating a new ArrayType adds it to the type numberer, so we must not create + //the same array type twice. Furthermore, the ConcurrentHashMap's computeIfAbsent + //method does not allow the update of other keys in while a value is computed. + public synchronized ArrayType getArrayType(Type baseType, int numDimensions) { Pair pairSearch = new Pair<>(baseType, numDimensions); return cache.computeIfAbsent(pairSearch, mapping); From f40c5ce12665e43cafbae93ace16fdf8ecb109fb Mon Sep 17 00:00:00 2001 From: Marc Miltenberger Date: Thu, 7 Nov 2024 15:19:42 +0100 Subject: [PATCH 2/2] Do not use HashMap.computeIfAbsent --- src/main/java/soot/ArrayTypeCache.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/main/java/soot/ArrayTypeCache.java b/src/main/java/soot/ArrayTypeCache.java index 62d57ab8937..0160e6c7470 100644 --- a/src/main/java/soot/ArrayTypeCache.java +++ b/src/main/java/soot/ArrayTypeCache.java @@ -51,7 +51,7 @@ public ArrayType apply(Pair t) { if (ret == null) { int n = orgDimensions - numDimensions + 1; if (n != orgDimensions) { - ret = cache.computeIfAbsent(new Pair<>(baseType, n), mapping); + ret = getArrayType(baseType, n); } else { ret = new ArrayType(baseType, n); } @@ -82,8 +82,13 @@ public ArrayTypeCache(Global g) { //method does not allow the update of other keys in while a value is computed. public synchronized ArrayType getArrayType(Type baseType, int numDimensions) { Pair pairSearch = new Pair<>(baseType, numDimensions); + ArrayType res = cache.get(pairSearch); + if (res == null) { + res = mapping.apply(pairSearch); + cache.put(pairSearch, res); + } - return cache.computeIfAbsent(pairSearch, mapping); + return res; }