Skip to content

Commit

Permalink
Add CauseConnection
Browse files Browse the repository at this point in the history
  • Loading branch information
ChristophTF committed Sep 1, 2024
1 parent 12efe62 commit 0119420
Show file tree
Hide file tree
Showing 6 changed files with 162 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
package com.oracle.graal.pointsto.reports.causality;

import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Deque;
Expand All @@ -37,6 +38,8 @@
import java.util.function.Supplier;
import java.util.stream.Collectors;

import org.graalvm.collections.Pair;

import com.oracle.graal.pointsto.BigBang;
import com.oracle.graal.pointsto.ObjectScanner;
import com.oracle.graal.pointsto.PointsToAnalysis;
Expand All @@ -52,6 +55,7 @@
import com.oracle.graal.pointsto.reports.causality.events.CausalityEvent;
import com.oracle.graal.pointsto.reports.causality.events.CausalityEvents;
import com.oracle.graal.pointsto.reports.causality.events.Feature;
import com.oracle.graal.pointsto.reports.causality.events.ImmutableStackTrace;
import com.oracle.graal.pointsto.reports.causality.events.InlinedMethodCode;
import com.oracle.graal.pointsto.util.AnalysisError;

Expand All @@ -69,6 +73,45 @@ protected TContext getContext() {
return threadContexts.get();
}

private static int getSkipCount(StackTraceElement[] stackTrace) {
return (int) Arrays.stream(stackTrace).takeWhile(ste -> ste.getClassName().startsWith("com.oracle.graal.pointsto.reports.causality.")).count();
}

static final class StackPath {
private final StackTraceElement[] stackTraceDiff;

public StackPath(StackTraceElement[] stackTraceDiff) {
this.stackTraceDiff = stackTraceDiff;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null) return false;
if (o instanceof StackPath path) {
return Arrays.equals(stackTraceDiff, path.stackTraceDiff);
}
return false;
}

@Override
public int hashCode() {
return Arrays.hashCode(stackTraceDiff);
}

@Override
public String toString() {
StringBuilder sb = new StringBuilder();
for (StackTraceElement stackTraceElement : stackTraceDiff) {
sb.append(stackTraceElement);
sb.append("\n");
}
return sb.toString();
}
}

private ConcurrentHashMap<Pair<StackTraceElement, StackTraceElement>, ConcurrentHashMap<StackPath, StackPath>> connections = new ConcurrentHashMap<>();

public static class ThreadContext {
private final Deque<CauseToken> causes = new ArrayDeque<>();

Expand All @@ -89,11 +132,18 @@ private void updateHeapTracing(CauseToken top) {
public final class CauseToken implements CausalityExport.NonThrowingAutoCloseable {
private final CausalityEvent event;
private final CausalityExport.HeapTracing level;
public final StackTraceElement site;
public final int stackDepth;

private CauseToken(CausalityEvent event, CausalityExport.HeapTracing level, boolean overwriteSilently) {
this.event = event;
this.level = level;

var stackTrace = new Throwable().getStackTrace();
int nSkip = getSkipCount(stackTrace);
this.site = stackTrace[nSkip];
this.stackDepth = stackTrace.length - nSkip - 1;

if (!overwriteSilently && !causes.isEmpty()) {
CausalityEvent top = causes.peek().event;
if (event != null && top != null && top != event && event != CausalityEvents.Ignored && top != CausalityEvents.Ignored && !(top instanceof Feature) && !top.root()) {
Expand Down Expand Up @@ -137,14 +187,31 @@ public void registerConjunctiveEdge(CausalityEvent cause1, CausalityEvent cause2
@Override
public void registerEdge(CausalityEvent cause, CausalityEvent consequence) {
if (cause == null || cause.root()) {
CausalityEvent topCause = threadContexts.get().topCause();
if (topCause != null) {
cause = topCause;
ThreadContext.CauseToken topCauseToken = threadContexts.get().topCauseToken();
if (topCauseToken != null) {
StackTraceElement[] stackTrace = new Throwable().getStackTrace();
int nSkip = getSkipCount(stackTrace);
StackTraceElement site = stackTrace[nSkip];
connections.computeIfAbsent(Pair.create(topCauseToken.site, site), k -> new ConcurrentHashMap<>())
.computeIfAbsent(new StackPath(Arrays.copyOfRange(stackTrace, nSkip, stackTrace.length - topCauseToken.stackDepth)), k -> k);
cause = topCauseToken.event;
if (cause == consequence) {
return;
}
var causeConnection = CausalityEvents.CauseConnection.create(topCauseToken.site, site);
var causeConnectionStack = CausalityEvents.CauseConnectionStack.create(new ImmutableStackTrace(Arrays.copyOfRange(stackTrace, nSkip, stackTrace.length - topCauseToken.stackDepth)));
directEdges.put(new Graph.DirectEdge(null, causeConnection), Boolean.TRUE);
directEdges.put(new Graph.DirectEdge(causeConnection, causeConnectionStack), Boolean.TRUE);
registerConjunctiveEdge(cause, causeConnectionStack, consequence);
return;
}
}
if (cause == consequence) {
return;
}
/*if (cause == null && !consequence.root()) {
System.err.println("Unknown root!");
}*/
directEdges.put(new Graph.DirectEdge(cause, consequence), Boolean.TRUE);
}

Expand Down Expand Up @@ -275,6 +342,18 @@ protected void forEachEvent(Consumer<CausalityEvent> callback) {

@Override
protected Graph createCausalityGraph(PointsToAnalysis bb) {
System.err.println("#Connections: " + connections.size());
System.err.println("#Paths: " + connections.values().stream().mapToInt(Map::size).sum());
int i = 0;
for (var entry : connections.entrySet()) {
System.err.println("--- Connection " + i + ": #Paths: " + entry.getValue().size() + " ---");
i++;
for (var path : entry.getValue().keySet()) {
System.err.println("-");
System.err.println(path);
}
}

Graph g = new Graph();

var directEdges = this.directEdges.keySet();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,9 @@ private static <T1, T2> EventFactory2<T1, T2> factory(BiFunction<T1, T2, Causali
public static final EventFactory<AnnotatedElement> ReflectionRegistration = factory(ReflectionRegistration::new);
public static final EventFactory<AnnotatedElement> ReflectionObjectInHeap = factory(ReflectionObjectInHeap::new);
public static final EventFactory<Object> DeferredTask = factory(DeferredTask::new);
public static final EventFactory2<StackTraceElement, StackTraceElement> CauseConnection = factory(CauseConnection::new);
public static final EventFactory<ImmutableStackTrace> CauseConnectionStack = factory(CauseConnectionStack::new);

public static final CausalityEvent AutomaticFeatureRegistration = new RootEvent(EventKinds.AutomaticFeatureRegistration);
public static final CausalityEvent UserEnabledFeatureRegistration = new RootEvent(EventKinds.UserRequestedFeatureRegistration);
public static final CausalityEvent InitialRegistration = new RootEvent(EventKinds.InitialRegistrations);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.oracle.graal.pointsto.reports.causality.events;

public final class CauseConnection extends CausalityEvent {
public final StackTraceElement from;
public final StackTraceElement to;

CauseConnection(StackTraceElement from, StackTraceElement to) {
this.from = from;
this.to = to;
}

@Override
public boolean essential() {
return false;
}

@Override
public EventKinds typeDescriptor() {
return EventKinds.CauseConnection;
}

@Override
public String toString() {
return from + ";" + to + typeDescriptor().suffix;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.oracle.graal.pointsto.reports.causality.events;

public final class CauseConnectionStack extends CausalityEvent {
public final ImmutableStackTrace stackTrace;

CauseConnectionStack(ImmutableStackTrace stackTrace) {
this.stackTrace = stackTrace;
}

@Override
public boolean essential() {
return false;
}

@Override
public EventKinds typeDescriptor() {
return EventKinds.CauseConnectionStack;
}

@Override
public String toString() {
return stackTrace.toString() + typeDescriptor().suffix;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ public enum EventKinds {

DeferredTask("Deferred Task"),

CauseConnection("Cause Connection"),
CauseConnectionStack("Cause Connection Stack"),

AutomaticFeatureRegistration("Automatic Feature Registration"),
UserRequestedFeatureRegistration("User-Requested Feature Registration"),
InitialRegistrations("Initial Registrations"),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.oracle.graal.pointsto.reports.causality.events;

import java.util.Arrays;

public record ImmutableStackTrace(StackTraceElement[] stackTrace) {
@Override
public boolean equals(Object obj) {
return obj instanceof ImmutableStackTrace other && Arrays.equals(stackTrace, other.stackTrace);
}

@Override
public int hashCode() {
return Arrays.hashCode(stackTrace);
}

@Override
public String toString() {
StringBuilder sb = new StringBuilder();
for (StackTraceElement element : stackTrace) {
sb.append(element).append(";");
}
return sb.toString();
}
}

0 comments on commit 0119420

Please sign in to comment.