Merge "Timing for collision detection in class merger"
diff --git a/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java b/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java
index a34f1b9..6f935ee 100644
--- a/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java
+++ b/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java
@@ -1154,7 +1154,7 @@
}
}
- private static class CollisionDetector {
+ private class CollisionDetector {
private static final int NOT_FOUND = 1 << (Integer.SIZE - 1);
@@ -1179,27 +1179,30 @@
}
boolean mayCollide() {
+ timing.begin("collision detection");
fillSeenPositions(invokes);
+ boolean result = false;
// If the type is not used in methods at all, there cannot be any conflict.
- if (seenPositions.isEmpty()) {
- return false;
- }
- for (DexMethod method : invokes) {
- Int2IntMap positionsMap = seenPositions.get(method.name);
- if (positionsMap != null) {
- int arity = method.getArity();
- int previous = positionsMap.get(arity);
- if (previous != NOT_FOUND) {
- assert previous != 0;
- int positions = computePositionsFor(method.proto, source, sourceProtoCache,
- substituions);
- if ((positions & previous) != 0) {
- return true;
+ if (!seenPositions.isEmpty()) {
+ for (DexMethod method : invokes) {
+ Int2IntMap positionsMap = seenPositions.get(method.name);
+ if (positionsMap != null) {
+ int arity = method.getArity();
+ int previous = positionsMap.get(arity);
+ if (previous != NOT_FOUND) {
+ assert previous != 0;
+ int positions =
+ computePositionsFor(method.proto, source, sourceProtoCache, substituions);
+ if ((positions & previous) != 0) {
+ result = true;
+ break;
+ }
}
}
}
}
- return false;
+ timing.end();
+ return result;
}
private void fillSeenPositions(Collection<DexMethod> invokes) {
diff --git a/src/main/java/com/android/tools/r8/utils/Timing.java b/src/main/java/com/android/tools/r8/utils/Timing.java
index ff2aa68..e8cf59b 100644
--- a/src/main/java/com/android/tools/r8/utils/Timing.java
+++ b/src/main/java/com/android/tools/r8/utils/Timing.java
@@ -13,6 +13,8 @@
// Finally a report is printed by:
// t.report();
+import java.util.LinkedHashMap;
+import java.util.Map;
import java.util.Stack;
public class Timing {
@@ -27,23 +29,28 @@
static class Node {
final String title;
- final Stack<Node> sons = new Stack<>();
- final long start_time;
- long stop_time;
+ final Map<String, Node> children = new LinkedHashMap<>();
+ long duration = 0;
+ long start_time;
Node(String title) {
this.title = title;
this.start_time = System.nanoTime();
- this.stop_time = -1;
+ }
+
+ void restart() {
+ assert start_time == -1;
+ start_time = System.nanoTime();
}
void end() {
- stop_time = System.nanoTime();
+ duration += System.nanoTime() - start_time;
+ start_time = -1;
assert duration() >= 0;
}
long duration() {
- return stop_time - start_time;
+ return duration;
}
@Override
@@ -66,15 +73,22 @@
System.out.print("- ");
}
System.out.println(toString(top));
- sons.forEach(p -> { p.report(depth + 1, top); });
+ children.values().forEach(p -> p.report(depth + 1, top));
}
}
public void begin(String title) {
- Node n = new Node(title);
- stack.peek().sons.add(n);
- stack.push(n);
+ Node parent = stack.peek();
+ Node child;
+ if (parent.children.containsKey(title)) {
+ child = parent.children.get(title);
+ child.restart();
+ } else {
+ child = new Node(title);
+ parent.children.put(title, child);
+ }
+ stack.push(child);
}
public void end() {