From 117011b62a025fc320e1a48b0ea4dd52ceab4204 Mon Sep 17 00:00:00 2001 From: circlespainter Date: Mon, 15 Jun 2015 18:12:09 +0200 Subject: [PATCH] Different attempt to fix #93 and to remove extra entries --- .../instrument/SuspendablesScanner.java | 113 +++++++----------- 1 file changed, 41 insertions(+), 72 deletions(-) diff --git a/quasar-core/src/main/java/co/paralleluniverse/fibers/instrument/SuspendablesScanner.java b/quasar-core/src/main/java/co/paralleluniverse/fibers/instrument/SuspendablesScanner.java index 53ba6d6d02..301055acd4 100644 --- a/quasar-core/src/main/java/co/paralleluniverse/fibers/instrument/SuspendablesScanner.java +++ b/quasar-core/src/main/java/co/paralleluniverse/fibers/instrument/SuspendablesScanner.java @@ -511,34 +511,13 @@ private void walkGraph() { while (!q.isEmpty()) { final MethodNode m = q.poll(); - if (m.inProject) { - followBridges(q, getClassNode(m), m); + if (m.inProject) followSupers(q, getClassNode(m), m); - } followNonOverriddenSubs(q, getClassNode(m), m); followCallers(q, m); } } - private void followBridges(Queue q, ClassNode cls, MethodNode method) { - log("followBridges " + method + " " + cls, Project.MSG_DEBUG); - if (cls == null) - return; - - if (method.suspendType == SuspendableType.NON_SUSPENDABLE) - return; - final List bridges = cls.getMethodWithDifferentReturn(method.name); - for (String m1 : bridges) { - if (!method.name.equals(m1)) { - MethodNode m = getOrCreateMethodNode(cls.name + '.' + m1); - if (m.suspendType != SuspendableType.SUSPENDABLE && m.suspendType != SuspendableType.SUSPENDABLE_SUPER) { - m.setSuspendType(SuspendableType.SUSPENDABLE_SUPER); - q.add(m); - } - } - } - } - private boolean followSupers(Queue q, ClassNode cls, MethodNode method) { log("followSupers " + method + " " + cls, Project.MSG_DEBUG); if (cls == null) @@ -549,14 +528,20 @@ private boolean followSupers(Queue q, ClassNode cls, MethodNode meth boolean foundMethod = false; - if (cls.hasMethod(method.name) && method.classNode != cls) { - final MethodNode m1 = methods.get((cls.name + '.' + method.name).intern()); - if (m1 != null && m1.suspendType == SuspendableType.NON_SUSPENDABLE) + String clsMethodDesc = cls.findMethodBySignature(method.nameAndSignature); + if (clsMethodDesc != null && method.classNode != cls) { + final MethodNode m1 = methods.get((cls.name + '.' + method.nameAndSignature).intern()); + if (m1 != null && m1.suspendType == SuspendableType.NON_SUSPENDABLE) // Already explored, not suspendable return false; - if (m1 == null || m1.suspendType == null) { - log("Found parent of suspendable method: " + method.owner + '.' + method.name + " in " + cls.name + if (m1 == null || m1.suspendType == null) { // Not explored before, found first here + log("Found parent " + clsMethodDesc + " of suspendable method: " + method.owner + '.' + method.nameAndDesc + " in " + cls.name + (cls.inProject ? "" : " NOT IN PROJECT"), cls.inProject ? Project.MSG_VERBOSE : Project.MSG_WARN); + foundMethod = true; + + MethodNode m = getOrCreateMethodNode(cls.name + '.' + clsMethodDesc); + m.setSuspendType(SuspendableType.SUSPENDABLE_SUPER); + q.add(m); } } @@ -566,18 +551,10 @@ private boolean followSupers(Queue q, ClassNode cls, MethodNode meth methodInParent |= followSupers(q, fill(s), method); if (!foundMethod && methodInParent) - log("Found parent of suspendable method in a parent of: " + method.owner + '.' + method.name + " in " + cls.name + log("Found parent of suspendable method in a parent of: " + method.owner + '.' + method.nameAndDesc + " in " + cls.name + (cls.inProject ? "" : " NOT IN PROJECT"), cls.inProject ? Project.MSG_VERBOSE : Project.MSG_WARN); - final boolean res = foundMethod | methodInParent; - if (res) { - MethodNode m = getOrCreateMethodNode(cls.name + '.' + method.name); - if (m.suspendType != SuspendableType.SUSPENDABLE && m.suspendType != SuspendableType.SUSPENDABLE_SUPER) { - m.setSuspendType(SuspendableType.SUSPENDABLE_SUPER); - q.add(m); - } - } - return res; + return foundMethod | methodInParent; } private void followNonOverriddenSubs(Queue q, ClassNode cls, MethodNode method) { @@ -590,8 +567,8 @@ private void followNonOverriddenSubs(Queue q, ClassNode cls, MethodN if (cls.subs != null) { for (ClassNode s : cls.subs) { - if (s != null && !s.hasMethod(method.name) && s.inProject) { - MethodNode sm = getOrCreateMethodNode(s.name + '.' + method.name); + if (s != null && s.findMethodBySignature(method.nameAndSignature) == null && s.inProject) { + MethodNode sm = getOrCreateMethodNode(s.name + '.' + method.nameAndDesc); sm.inProject = true; sm.refersToSuper = true; if (sm.inProject && sm.suspendType == null) { @@ -629,7 +606,7 @@ else if (method.suspendType == SuspendableType.SUSPENDABLE_SUPER && !method.refe } private static String output(MethodNode method) { - return method.owner.replace('/', '.') + '.' + method.name; + return method.owner.replace('/', '.') + '.' + method.nameAndDesc; } private static void outputResults(String outputFile, boolean append, Collection results) throws Exception { @@ -639,16 +616,21 @@ private static void outputResults(String outputFile, boolean append, Collection< } } - private MethodNode getOrCreateMethodNode(String methodName) { - methodName = methodName.intern(); - MethodNode entry = methods.get(methodName); + private MethodNode getOrCreateMethodNode(String fullMethodDesc) { + fullMethodDesc = fullMethodDesc.intern(); + final String fullMethodSignature = getSignature(fullMethodDesc); + MethodNode entry = methods.get(fullMethodSignature); if (entry == null) { - entry = new MethodNode(getClassName(methodName), getMethodWithDesc(methodName)); - methods.put(methodName, entry); + entry = new MethodNode(getClassName(fullMethodSignature), getMethod(fullMethodSignature), getMethod(fullMethodDesc)); + methods.put(fullMethodSignature, entry); } return entry; } + private static String getSignature(String methodName) { + return methodName.substring(0, methodName.lastIndexOf(')') + 1).intern(); + } + private ClassNode getOrCreateClassNode(String className) { className = className.intern(); ClassNode node = classes.get(className); @@ -722,22 +704,12 @@ void setMethods(Collection ms) { methods[i] = methods[i].intern(); } - boolean hasMethod(String method) { + String findMethodBySignature(String nameAndSignature) { for (String m : methods) { - if (method.equals(m)) - return true; + if (m.startsWith(nameAndSignature)) + return m; } - return false; - } - - List getMethodWithDifferentReturn(String method) { - method = getMethodWithoutReturn(method); - List ms = new ArrayList<>(); - for (String m : methods) { - if (m.startsWith(method)) - ms.add(m); - } - return ms; + return null; } @Override @@ -758,7 +730,7 @@ private void addSub(ClassNode cn) { private static class MethodNode { String owner; ClassNode classNode; - final String name; // methodname+desc + final String nameAndSignature; // methodname+signature //int acc; boolean inProject; boolean known; @@ -767,10 +739,12 @@ private static class MethodNode { boolean setBySuper; private MethodNode[] callers; private int numCallers; + private final String nameAndDesc; - public MethodNode(String owner, String nameAndDesc) { + public MethodNode(String owner, String nameAndSignature, String nameAndDesc) { this.owner = owner.intern(); - this.name = nameAndDesc.intern(); + this.nameAndSignature = nameAndSignature.intern(); + this.nameAndDesc = nameAndDesc.intern(); } public void addCaller(MethodNode caller) { @@ -813,7 +787,7 @@ public void remove() { @Override public String toString() { - return "MethodNode{" + owner + '.' + name + " inProject: " + inProject + " suspendType: " + suspendType + '}'; + return "MethodNode{" + owner + '.' + nameAndDesc + " inProject: " + inProject + " suspendType: " + suspendType + '}'; } public void setSuspendType(SuspendableType suspendType) { @@ -826,17 +800,12 @@ public void setSuspendType(SuspendableType suspendType) { } } - private static String getClassName(String fullMethodWithDesc) { - return fullMethodWithDesc.substring(0, fullMethodWithDesc.lastIndexOf('.')); - } - - private static String getMethodWithDesc(String fullMethodWithDesc) { - return fullMethodWithDesc.substring(fullMethodWithDesc.lastIndexOf('.') + 1); + private static String getClassName(String fullMethod) { + return fullMethod.substring(0, fullMethod.lastIndexOf('.')); } - private static String getMethodWithoutReturn(String fullMethodWithDesc) { - String m = getMethodWithDesc(fullMethodWithDesc); - return m.substring(0, m.lastIndexOf(')') + 1); + private static String getMethod(String fullMethod) { + return fullMethod.substring(fullMethod.lastIndexOf('.') + 1); } private static boolean isReflectInvocation(String className, String methodName) {