misc cleanup/perf enhancement
authorbrian <brian@brianweb.net>
Fri, 28 May 2004 16:30:37 +0000 (16:30 +0000)
committerbrian <brian@brianweb.net>
Fri, 28 May 2004 16:30:37 +0000 (16:30 +0000)
darcs-hash:20040528163037-24bed-23360ae3f5754c0141e50bc9fb04765a9bb8ead4.gz

src/org/ibex/classgen/CPGen.java
src/org/ibex/classgen/ClassGen.java
src/org/ibex/classgen/FieldRef.java
src/org/ibex/classgen/MethodGen.java
src/org/ibex/classgen/MethodRef.java

index e22fd9e..6b3db97 100644 (file)
@@ -71,6 +71,18 @@ class CPGen {
         public int hashCode() { return ~s.hashCode(); }
     }
         
+    static class NameAndTypeKey {
+        String name;
+        String type;
+        NameAndTypeKey(String name, String type) { this.name = name; this.type = type; }
+        public boolean equals(Object o_) {
+            if(!(o_ instanceof NameAndTypeKey)) return false;
+            NameAndTypeKey o = (NameAndTypeKey) o_;
+            return o.name.equals(name) && o.type.equals(type);
+        }
+        public int hashCode() { return name.hashCode() ^ type.hashCode(); }
+    }
+    
     /*
      * Methods
      */
@@ -90,7 +102,7 @@ class CPGen {
         return e.getIndex();
     }
     
-    public final Ent addNameAndType(String name, String descriptor) { return add(new ClassGen.NameAndType(name,descriptor)); }
+    public final Ent addNameAndType(String name, String descriptor) { return add(new NameAndTypeKey(name,descriptor)); }
     public final Ent addUtf8(String s) { return add(new Utf8Key(s)); }
     
     public final Ent add(Object o) {
@@ -127,19 +139,19 @@ class CPGen {
             Utf8Ent ue = new Utf8Ent();
             ue.s = ((Utf8Key)o).s;
             ent = ue;
-        } else if(o instanceof ClassGen.NameAndType) {
+        } else if(o instanceof NameAndTypeKey) {
             CPRefEnt ce = new CPRefEnt(12);
-            ClassGen.NameAndType key = (ClassGen.NameAndType) o;
+            NameAndTypeKey key = (NameAndTypeKey) o;
             ce.e1 = addUtf8(key.name);
             ce.e2 = addUtf8(key.type);
             ent = ce;
-        } else if(o instanceof ClassGen.FieldMethodRef) {
-            ClassGen.FieldMethodRef key = (ClassGen.FieldMethodRef) o;
-            int tag = o instanceof FieldRef ? 9 : o instanceof MethodRef ? 10 : o instanceof ClassGen.InterfaceMethodRef ? 11 : 0;
+        } else if(o instanceof ClassGen.FieldOrMethodRef) {
+            ClassGen.FieldOrMethodRef key = (ClassGen.FieldOrMethodRef) o;
+            int tag = o instanceof FieldRef ? 9 : o instanceof MethodRef ? 10 : o instanceof MethodRef.I ? 11 : 0;
             if(tag == 0) throw new Error("should never happen");
             CPRefEnt ce = new CPRefEnt(tag);
             ce.e1 = add(key.klass);
-            ce.e2 = add(key.nameAndType);
+            ce.e2 = addNameAndType(key.name,key.descriptor);
             ent = ce;
         } else {
             throw new IllegalArgumentException("Unknown type passed to add");
index de32d3c..997678c 100644 (file)
@@ -105,33 +105,19 @@ public class ClassGen implements CGConst {
         public Exn(String s) { super(s); }
     }
     
-    public static class NameAndType {
-        String name;
-        String type;
-        NameAndType(String name, String type) { this.name = name; this.type = type; }
-        public boolean equals(Object o_) {
-            if(!(o_ instanceof NameAndType)) return false;
-            NameAndType o = (NameAndType) o_;
-            return o.name.equals(name) && o.type.equals(type);
-        }
-        public int hashCode() { return name.hashCode() ^ type.hashCode(); }
-    }
-    
-    public static abstract class FieldMethodRef {
+    public static abstract class FieldOrMethodRef {
         Type.Object klass;
-        NameAndType nameAndType;
-        FieldMethodRef(Type.Object klass, NameAndType nameAndType) { this.klass = klass; this.nameAndType = nameAndType; }
+        String name;
+        String descriptor;
+        
+        FieldOrMethodRef(Type.Object klass, String name, String descriptor) { this.klass = klass; this.name = name; this.descriptor = descriptor; }
+        FieldOrMethodRef(FieldOrMethodRef o) { this.klass = o.klass; this.name = o.name; this.descriptor = o.descriptor; }
         public boolean equals(Object o_) {
-            if(!(o_ instanceof FieldMethodRef)) return false;
-            FieldMethodRef o = (FieldMethodRef) o_;
-            return o.klass.equals(klass) && o.nameAndType.equals(nameAndType);
+            if(!(o_ instanceof FieldOrMethodRef)) return false;
+            FieldOrMethodRef o = (FieldOrMethodRef) o_;
+            return o.klass.equals(klass) && o.name.equals(name) && o.descriptor.equals(descriptor);
         }
-        public int hashCode() { return klass.hashCode() ^ nameAndType.hashCode(); }
-    }
-    
-    public static class InterfaceMethodRef extends FieldMethodRef {
-        public InterfaceMethodRef(MethodRef r) { super(r.klass,r.nameAndType); }
-        public InterfaceMethodRef(Type.Object c, NameAndType t) { super(c,t); }
+        public int hashCode() { return klass.hashCode() ^ name.hashCode() ^ descriptor.hashCode(); }
     }
     
     static class AttrGen {
index f77ad93..6c2d8cf 100644 (file)
@@ -1,6 +1,6 @@
 package org.ibex.classgen;
 
-public class FieldRef extends ClassGen.FieldMethodRef {
-    public FieldRef  (Type.Object c, ClassGen.NameAndType t) { super(c,t); }
-    public FieldRef(Type.Object c, String name, Type t) { super(c,new ClassGen.NameAndType(name,t.getDescriptor())); }
+public class FieldRef extends ClassGen.FieldOrMethodRef {
+    public FieldRef(Type.Object c, String name, Type t) { super(c,name,t.getDescriptor()); }
+    public FieldRef(String s, String name, Type t) { this(new Type.Object(s),name,t); }
 }
index 68aebd2..c49957b 100644 (file)
@@ -113,74 +113,84 @@ public class MethodGen implements CGConst {
     
     
     public final void set(int pos, byte op, boolean b) { set(pos,op,b?1:0); }
-    public final void set(int pos, byte op, int n) {
-        if(op == LDC) {
-            switch(n) {
-                case -1: set(pos,ICONST_M1); return;
-                case 0:  set(pos,ICONST_0);  return;
-                case 1:  set(pos,ICONST_1);  return;
-                case 2:  set(pos,ICONST_2);  return; 
-                case 3:  set(pos,ICONST_3);  return;
-                case 4:  set(pos,ICONST_4);  return;
-                case 5:  set(pos,ICONST_5);  return;
-            }
-            Object arg;
-            if(n >= -128 && n <= 127) { op = BIPUSH; arg = N(n); } 
-            else if(n >= -32767 && n <= 32767) { op = SIPUSH; arg = N(n); }
-            else { arg = cp.add(N(n)); }
-            this.op[pos] = op;
-            this.arg[pos] = arg;
-        } else {
-            set(pos,op,N(n));
-        }
-    }
     
-    public void set(int pos, byte op, Object arg) {
-        switch(op) {
+    // This MUST handle x{LOAD,STORE} and LDC with an int arg WITHOUT falling back to set(int,byte,Object)
+    public final void set(int pos, byte op, int n) {
+        Object arg = null;
+        OUTER: switch(op) {
+            case LDC:
+                switch(n) {
+                    case -1: op = ICONST_M1; break OUTER;
+                    case 0:  op = ICONST_0;  break OUTER;
+                    case 1:  op = ICONST_1;  break OUTER;
+                    case 2:  op = ICONST_2;  break OUTER; 
+                    case 3:  op = ICONST_3;  break OUTER;
+                    case 4:  op = ICONST_4;  break OUTER;
+                    case 5:  op = ICONST_5;  break OUTER;
+                }
+                if(n >= -128 && n <= 127) { op = BIPUSH; arg = N(n); } 
+                else if(n >= -32767 && n <= 32767) { op = SIPUSH; arg = N(n); }
+                else { arg = cp.add(N(n)); }
+                break;
             case ILOAD: case ISTORE: case LLOAD: case LSTORE: case FLOAD:
             case FSTORE: case DLOAD: case DSTORE: case ALOAD: case ASTORE:
-            {
-                int iarg = ((Integer)arg).intValue();
-                if(iarg >= 0 && iarg <= 3) {
+                if(n >= 0 && n <= 3) {
                     byte base = 0;
                     switch(op) {
-                        case ILOAD:  base = ILOAD_0; break;
+                        case ILOAD:  base = ILOAD_0;  break;
                         case ISTORE: base = ISTORE_0; break;
-                        case LLOAD:  base = LLOAD_0; break;
+                        case LLOAD:  base = LLOAD_0;  break;
                         case LSTORE: base = LSTORE_0; break; 
-                        case FLOAD:  base = FLOAD_0; break;
+                        case FLOAD:  base = FLOAD_0;  break;
                         case FSTORE: base = FSTORE_0; break;
-                        case DLOAD:  base = DLOAD_0; break;
+                        case DLOAD:  base = DLOAD_0;  break;
                         case DSTORE: base = DSTORE_0; break;
-                        case ALOAD:  base = ALOAD_0; break;
+                        case ALOAD:  base = ALOAD_0;  break;
                         case ASTORE: base = ASTORE_0; break;
                     }
-                    op = (byte)((base&0xff) + iarg);
+                    op = (byte)((base&0xff) + n);
                 } else {
-                    if(iarg >= maxLocals) maxLocals = iarg + 1;
+                    if(n >= maxLocals) maxLocals = n + 1;
+                    arg = N(n);
                 }
                 break;
-            }
+            default:
+                set(pos,op,N(n));
+                return;
+        }            
+        this.op[pos] = op;
+        this.arg[pos] = arg;
+    }
+    
+    public final void set(int pos, byte op, Object arg) {
+        switch(op) {
+            case ILOAD: case ISTORE: case LLOAD: case LSTORE: case FLOAD:
+            case FSTORE: case DLOAD: case DSTORE: case ALOAD: case ASTORE:
+                // set(int,byte,int) always handles these ops itself
+                set(pos,op,((Integer)arg).intValue());
+                return;
             case LDC:
+                // set(int,byte,int) always handles these opts itself
                 if(arg instanceof Integer) { set(pos,op,((Integer)arg).intValue()); return; }
                 if(arg instanceof Boolean) { set(pos,op,((Boolean)arg).booleanValue()); return; }
+                
                 if(arg instanceof Long) {
                     long l = ((Long)arg).longValue();
-                    if(l == 0L) { set(pos,LCONST_0); return; }
-                    if(l == 1L) { set(pos,LCONST_1); return; }
+                    if(l == 0L) { this.op[pos] = LCONST_0; return; }
+                    if(l == 1L) { this.op[pos] = LCONST_1; return; }
                 }
                 
                 if(arg instanceof Long || arg instanceof Double) op = LDC2_W;
-                // fall through
-            default: {
-                int opdata = OP_DATA[op&0xff];
-                if((opdata&OP_CPENT_FLAG) != 0 && !(arg instanceof CPGen.Ent))
-                    arg = cp.add(arg);
-                else if((opdata&OP_VALID_FLAG) == 0)
-                    throw new IllegalArgumentException("unknown bytecode");
                 break;
-            }
+            case INVOKEINTERFACE:
+                if(arg instanceof MethodRef) arg = new MethodRef.I((MethodRef)arg);
+                break;
         }
+        int opdata = OP_DATA[op&0xff];
+        if((opdata&OP_CPENT_FLAG) != 0 && !(arg instanceof CPGen.Ent))
+            arg = cp.add(arg);
+        else if((opdata&OP_VALID_FLAG) == 0)
+            throw new IllegalArgumentException("unknown bytecode");
         this.op[pos] = op;
         this.arg[pos] = arg;
     }
@@ -197,7 +207,7 @@ public class MethodGen implements CGConst {
         public int size() { return targets.length; }
         
         public int getTarget(int pos) { return ((Integer)targets[pos]).intValue(); }
-        public int getDefaultTarget() { return ((Integer)defaultTarget).intValue(); }
+        public int getDefaultTarget() { return ((Integer)defaultTarget).intValue(); }        
     }
     
     public static class TSI extends SI {
@@ -340,7 +350,7 @@ public class MethodGen implements CGConst {
                 case TABLESWITCH:
                 case LOOKUPSWITCH: {
                     SI si = (SI) arg[i];
-                    p++; // opcpde itself
+                    p++; // opcode itself
                     p = (p + 3) & ~3; // padding
                     p += 4; // default
                     if(op == TABLESWITCH) p += 4 + 4 + si.size() * 4; // lo, hi, targets
@@ -403,6 +413,8 @@ public class MethodGen implements CGConst {
                     }
                     break;
                 }
+                case WIDE:
+                    throw new Error("WIDE instruction not yet supported");
                     
                 default:
                     if((opdata & OP_BRANCH_FLAG) != 0) {
@@ -414,7 +426,7 @@ public class MethodGen implements CGConst {
                         if(argLength == 1) o.writeByte(v);
                         else if(argLength == 2) o.writeShort(v);
                         else throw new Error("should never happen");
-                    } else if(argLength == -1) {
+                    } else if(argLength == 7) {
                         throw new Error("should never happen - variable length instruction not explicitly handled");
                     } else {
                         int iarg  = ((Integer)arg).intValue();
index cb546bd..c866adc 100644 (file)
@@ -1,16 +1,13 @@
 package org.ibex.classgen;
 
-public class MethodRef extends ClassGen.FieldMethodRef {
-    public MethodRef(Type.Object c, ClassGen.NameAndType t) { super(c,t); }
-    public MethodRef(Type.Object c, String name, String descriptor) {
-        this(c,new ClassGen.NameAndType(name,descriptor));
-    }
+public class MethodRef extends ClassGen.FieldOrMethodRef {
     public MethodRef(Type.Object c, String name, Type ret, Type[] args) {
-        this(c,name,getDescriptor(ret,args));
+        super(c,name,getDescriptor(ret,args));
     }
     public MethodRef(String s, String name, Type ret, Type[] args) {
         this(new Type.Object(s),name,ret,args);
     }
+    MethodRef(MethodRef i) { super(i); }
     
     static String getDescriptor(Type ret, Type[] args) {
         StringBuffer sb = new StringBuffer(args.length*4);
@@ -20,5 +17,10 @@ public class MethodRef extends ClassGen.FieldMethodRef {
         sb.append(ret.getDescriptor());
         return sb.toString();
     }
+    
+    public static class I extends MethodRef {
+        public I(Type.Object c, String name, Type ret, Type[] args) { super(c,name,ret,args); }
+        public I(String s, String name, Type ret, Type[] args) { super(s,name,ret,args); }
+        I(MethodRef m) { super(m); }
+    }
 }
-