Skip to content

Commit

Permalink
Removes the exponential traversal of types in NI
Browse files Browse the repository at this point in the history
The issue is with class initializaiton safety proofs on deep type hierarchies.
  • Loading branch information
vjovanov committed Jan 28, 2022
1 parent e24341d commit ca436f4
Showing 1 changed file with 17 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;

import com.oracle.graal.pointsto.meta.AnalysisMethod;
import com.oracle.graal.pointsto.meta.AnalysisType;
Expand Down Expand Up @@ -126,8 +127,13 @@ public void setUnsafe(AnalysisType t) {
}

private boolean updateTypeInitializerSafety() {
Set<AnalysisType> unsafeOrProcessedTypes = types.entrySet().stream()
.filter(t -> t.getValue() == Safety.UNSAFE)
.map(Map.Entry::getKey)
.collect(Collectors.toSet());

return types.keySet().stream()
.map(t -> tryPromoteToUnsafe(t, methodSafety))
.map(t -> tryPromoteToUnsafe(t, unsafeOrProcessedTypes))
.reduce(false, (lhs, rhs) -> lhs || rhs);
}

Expand Down Expand Up @@ -182,16 +188,18 @@ private boolean isInvokeInitiallyUnsafe(InvokeInfo i) {
*
* @return if pomotion to unsafe happened
*/
private boolean tryPromoteToUnsafe(AnalysisType type, Map<AnalysisMethod, Safety> safeMethods) {
if (types.get(type) == Safety.UNSAFE) {
private boolean tryPromoteToUnsafe(AnalysisType type, Set<AnalysisType> unsafeOrProcessed) {
if (unsafeOrProcessed.contains(type)) {
return false;
} else if (type.getClassInitializer() != null && safeMethods.get(type.getClassInitializer()) == Safety.UNSAFE ||
dependencies.get(type).stream().anyMatch(t -> types.get(t) == Safety.UNSAFE) ||
dependencies.get(type).stream().anyMatch(t -> tryPromoteToUnsafe(t, safeMethods))) {
setUnsafe(type);
return true;
} else {
return false;
unsafeOrProcessed.add(type);
if ((type.getClassInitializer() != null && methodSafety.get(type.getClassInitializer()) == Safety.UNSAFE) ||
dependencies.get(type).stream().anyMatch(t -> types.get(t) == Safety.UNSAFE || tryPromoteToUnsafe(t, unsafeOrProcessed))) {
setUnsafe(type);
return true;
} else {
return false;
}
}
}

Expand Down

0 comments on commit ca436f4

Please sign in to comment.