Hi, everyone, I just meet a strange problem: to maintain corresponding StoreField(a.f = x
), LoadField(x = a.f
), StoreArray(a[*] = x
), LoadArray(x = a[*]
) statements for variable a, if I use the builtin HashMap just like below
private Map<Var, Set<Stmt>> fieldStore;
private Map<Var, Set<Stmt>> fieldLoad;
private Map<Var, Set<Stmt>> arrayLoad;
private Map<Var, Set<Stmt>> arrayStore;
...
protected void initialize() {
String ptaId = getOptions().getString("pta");
PointerAnalysisResult pta = World.get().getResult(ptaId);
// You can do initialization work here
fieldLoad = new HashMap<>();
fieldStore = new HashMap<>();
arrayLoad = new HashMap<>();
arrayStore = new HashMap<>();
for (Var var : pta.getVars()) {
fieldStore.put(var, new HashSet<>());
fieldLoad.put(var, new HashSet<>());
arrayStore.put(var, new HashSet<>());
arrayLoad.put(var, new HashSet<>());
for (Var other : pta.getVars()) {
for (Obj obj : pta.getPointsToSet(var)) {
if (pta.getPointsToSet(other).contains(obj)) {
fieldStore.get(var).addAll(other.getStoreFields());
fieldLoad.get(var).addAll(other.getLoadFields());
arrayLoad.get(var).addAll(other.getLoadArrays());
arrayStore.get(var).addAll(other.getStoreArrays());
break;
}
}
}
}
}
there are always some testcases that I cannot pass through in online judge, however if I switch to Guava HashMultiMap(com.google.common.collect.HashMultimap) and initialize the map like below(others is still)
private final Multimap<Var, Stmt> fieldStore = HashMultimap.create();
private final Multimap<Var, Stmt> fieldLoad = HashMultimap.create();
private final Multimap<Var, Stmt> arrayLoad = HashMultimap.create();
private final Multimap<Var, Stmt> arrayStore = HashMultimap.create();
...
protected void initialize() {
String ptaId = getOptions().getString("pta");
PointerAnalysisResult pta = World.get().getResult(ptaId);
// You can do initialization work here
for (Var var : pta.getVars()) {
for (Var other : pta.getVars()) {
for (Obj obj : pta.getPointsToSet(var)) {
if (pta.getPointsToSet(other).contains(obj)) {
fieldStore.putAll(var, other.getStoreFields());
fieldLoad.putAll(var, other.getLoadFields());
arrayLoad.putAll(var, other.getLoadArrays());
arrayStore.putAll(var, other.getStoreArrays());
break;
}
}
}
}
}
everything is ok. And after the initialization, I only use these maps as lookup tables just look like fieldLoad.get(var).stream().map(fieldStore -> (LoadField) fieldStore) .filter(fieldLoad -> fieldLoad.getFieldRef().resolve() == ((StoreField) stmt).getFieldRef().resolve()).collect(Collectors.toSet())
So if there are some bugs in jvm or someone can point out that I miss some important issues?