Permalink
Browse files

1. Moved Detector from kilim.analysis to kilim.mirrors to avoid inter…

…-package

   recursive calling.  That accounts for many of the changes in kilim.analysis.

2. Removed Field/MemberMirror because the weaver doesn't need access to fields.

3. Created two parallel hierarchies as a first step towards runtime weaving:
   Cached{Class,Method}Mirror  to represent class files supplied to the weaver
   that are not in the classpath (or loaded by the context classloader)
   and Runtime{Class,Method}Mirror for those that are. This commit has not
   tested the Cached*Mirror functionality.
  • Loading branch information...
1 parent 91e35b3 commit 52596c331e30285031f59dc82bb6063883b47ed6 @kilim committed May 3, 2011
@@ -4,6 +4,8 @@
import java.io.IOException;
import java.util.HashMap;
+import kilim.mirrors.Detector;
+
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.MethodNode;
@@ -36,6 +36,7 @@
import java.util.Stack;
import kilim.KilimException;
+import kilim.mirrors.Detector;
import org.objectweb.asm.Label;
import org.objectweb.asm.tree.AbstractInsnNode;
@@ -6,6 +6,7 @@
package kilim.analysis;
import kilim.*;
+import kilim.mirrors.Detector;
import java.io.IOException;
import java.io.InputStream;
@@ -6,6 +6,7 @@
package kilim.analysis;
import kilim.*;
+import kilim.mirrors.Detector;
import static kilim.Constants.*;
import java.io.IOException;
import java.io.InputStream;
@@ -27,7 +28,7 @@
* CPS transformed file if needed
*/
public class ClassWeaver {
- ClassFlow classFlow;
+ public ClassFlow classFlow;
List<ClassInfo> classInfoList = new LinkedList<ClassInfo>();
static HashSet<String> stateClasses = new HashSet<String>();
@@ -37,27 +38,25 @@ public ClassWeaver(byte[] data) {
public ClassWeaver(byte[] data, Detector detector) {
classFlow = new ClassFlow(data, detector);
- weave();
}
public ClassWeaver(InputStream is, Detector detector) throws IOException {
classFlow = new ClassFlow(is, detector);
- weave();
}
public ClassWeaver(String className, Detector detector) throws IOException {
classFlow = new ClassFlow(className, detector);
- weave();
}
- private void weave() throws KilimException {
+ public void weave() throws KilimException {
classFlow.analyze(false);
if (needsWeaving() && classFlow.isPausable()) {
ClassWriter cw = new ClassWriter(false);
accept(cw);
addClassInfo(new ClassInfo(classFlow.getClassName(), cw.toByteArray()));
}
}
+
private void accept(final ClassVisitor cv) {
ClassFlow cf = classFlow;
@@ -1,205 +0,0 @@
-/* Copyright (c) 2006, Sriram Srinivasan
- *
- * You may distribute this software under the terms of the license
- * specified in the file "License"
- */
-package kilim.analysis;
-import static kilim.Constants.D_OBJECT;
-
-import java.util.ArrayList;
-
-import kilim.Constants;
-import kilim.NotPausable;
-import kilim.Pausable;
-import kilim.mirrors.ClassMirror;
-import kilim.mirrors.ClassMirrorNotFoundException;
-import kilim.mirrors.MethodMirror;
-import kilim.mirrors.Mirrors;
-/**
- * Utility class to check if a method has been marked pausable
- *
- */
-public class Detector {
- public static final int METHOD_NOT_FOUND = 0;
- public static final int PAUSABLE_METHOD_FOUND = 1;
- public static final int METHOD_NOT_PAUSABLE = 2;
-
- // Note that we don't have the kilim package itself in the following list.
- static final String[] STANDARD_DONT_CHECK_LIST = {
- "java.", "javax." };
-
- public static final Detector DEFAULT = new Detector(Mirrors.getRuntimeMirrors());
-
- private final Mirrors mirrors;
-
- public Detector(Mirrors mirrors) {
- this.mirrors = mirrors;
-
- NOT_PAUSABLE = mirrors.mirror(NotPausable.class);
- PAUSABLE = mirrors.mirror(Pausable.class);
- OBJECT = mirrors.mirror(Object.class);
-
- }
-
- ClassMirror NOT_PAUSABLE, PAUSABLE, OBJECT;
-
- public boolean isPausable(String className, String methodName,
- String desc) {
- return getPausableStatus(className, methodName, desc) == PAUSABLE_METHOD_FOUND;
- }
-
- /**
- * @return one of METHOD_NOT_FOUND, PAUSABLE_METHOD_FOUND, METHOD_NOT_PAUSABLE
- */
-
- public int getPausableStatus(String className, String methodName,
- String desc)
- {
- int ret = METHOD_NOT_FOUND;
- if (methodName.endsWith("init>")) {
- return METHOD_NOT_PAUSABLE; // constructors are not pausable.
- }
- className = className.replace('/', '.');
- try {
- ClassMirror cl = mirrors.classForName(className);
- MethodMirror m = findMethod(cl, methodName, desc);
- if (m != null) {
- for (ClassMirror c: m.getExceptionTypes()) {
- if (NOT_PAUSABLE.isAssignableFrom(c)) {
- return METHOD_NOT_PAUSABLE;
- }
- if (PAUSABLE.isAssignableFrom(c)) {
- return PAUSABLE_METHOD_FOUND;
- }
- }
- return METHOD_NOT_PAUSABLE;
- }
- } catch (ClassMirrorNotFoundException ignore) {
-
- } catch (VerifyError ve) {
- return AsmDetector.getPausableStatus(className, methodName, desc, this);
- }
- return ret;
- }
-
- private MethodMirror findMethod(ClassMirror cl, String methodName, String desc) {
- if (cl == null) return null;
- MethodMirror m = findMethodInHierarchy(cl, methodName, desc);
- if (m == null) {
- cl = mirrors.mirror(Object.class);
- for (MethodMirror om : cl.getDeclaredMethods()) {
- if (om.getName().equals(methodName) && om.getMethodDescriptor().equals(desc)) {
- return om;
- }
- }
- }
- return m;
- }
-
- private MethodMirror findMethodInHierarchy(ClassMirror cl, String methodName,
- String desc) {
- if (cl == null) return null;
-
- for (MethodMirror om : cl.getDeclaredMethods()) {
- if (om.getName().equals(methodName) && om.getMethodDescriptor().equals(desc)) {
- if (om.isBridge()) continue;
- return om;
- }
- }
-
- if (OBJECT.equals(cl))
- return null;
-
- MethodMirror m = findMethodInHierarchy(cl.getSuperclass(), methodName, desc);
- if (m != null)
- return m;
- for (ClassMirror ifcl : cl.getInterfaces()) {
- m = findMethodInHierarchy(ifcl, methodName, desc);
- if (m != null)
- return m;
- }
- return null;
- }
-
- public static String D_FIBER_ = Constants.D_FIBER + ")";
-
- @SuppressWarnings("unused")
- private static String statusToStr(int st) {
- switch (st) {
- case METHOD_NOT_FOUND : return "not found";
- case PAUSABLE_METHOD_FOUND : return "pausable";
- case METHOD_NOT_PAUSABLE : return "not pausable";
- default: throw new AssertionError("Unknown status");
- }
- }
-
-
- static private final ThreadLocal<Detector> DETECTOR = new ThreadLocal<Detector>();
-
- static Detector getDetector() {
- Detector d = DETECTOR.get();
- if (d == null) return Detector.DEFAULT;
- return d;
-}
-
- static Detector setDetector(Detector d) {
- Detector res = DETECTOR.get();
- DETECTOR.set(d);
- return res;
- }
-
- public String commonSuperType(String oa, String ob) throws ClassMirrorNotFoundException {
- String a = toClassName(oa);
- String b = toClassName(ob);
-
- try {
- ClassMirror ca = mirrors.classForName(a);
- ClassMirror cb = mirrors.classForName(b);
- if (ca.isAssignableFrom(cb)) return oa;
- if (cb.isAssignableFrom(ca)) return ob;
- if (ca.isInterface() && cb.isInterface()) {
- return D_OBJECT; // This is what the java bytecode verifier does
- }
- } catch (ClassMirrorNotFoundException e) {
- // try to see if the below works...
- }
-
- ArrayList<String> sca = getSuperClasses(a);
- ArrayList<String> scb = getSuperClasses(b);
- int lasta = sca.size()-1;
- int lastb = scb.size()-1;
- do {
- if (sca.get(lasta).equals(scb.get(lastb))) {
- lasta--;
- lastb--;
- } else {
- break;
- }
- } while (lasta >= 0 && lastb >= 0);
- return toDesc(sca.get(lasta+1));
- }
-
-
- public ArrayList<String> getSuperClasses(String cc) throws ClassMirrorNotFoundException {
- ClassMirror c = mirrors.classForName(cc);
- ArrayList<String> ret = new ArrayList<String>(3);
- while (c != null) {
- ret.add(c.getName());
- c = c.getSuperclass();
- }
- return ret;
-
- }
-
- private static String toDesc(String name) {
- return (name.equals(JAVA_LANG_OBJECT)) ?
- D_OBJECT : "L" + name.replace('.', '/') + ';';
- }
-
- private static String toClassName(String s) {
- return s.replace('/','.').substring(1,s.length()-1);
- }
-
- static String JAVA_LANG_OBJECT = "java.lang.Object";
-
-}
@@ -23,6 +23,7 @@
import java.util.PriorityQueue;
import kilim.KilimException;
+import kilim.mirrors.Detector;
import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.Attribute;
Oops, something went wrong.

0 comments on commit 52596c3

Please sign in to comment.