From 6c8fb599f516aa0003cb83c38d974a95385d77bf Mon Sep 17 00:00:00 2001 From: brian Date: Fri, 28 May 2004 16:30:37 +0000 Subject: [PATCH] misc cleanup/perf enhancement darcs-hash:20040528163037-24bed-23360ae3f5754c0141e50bc9fb04765a9bb8ead4.gz --- src/org/ibex/classgen/CPGen.java | 26 ++++++--- src/org/ibex/classgen/ClassGen.java | 34 ++++------- src/org/ibex/classgen/FieldRef.java | 6 +- src/org/ibex/classgen/MethodGen.java | 106 +++++++++++++++++++--------------- src/org/ibex/classgen/MethodRef.java | 16 ++--- 5 files changed, 100 insertions(+), 88 deletions(-) diff --git a/src/org/ibex/classgen/CPGen.java b/src/org/ibex/classgen/CPGen.java index e22fd9e..6b3db97 100644 --- a/src/org/ibex/classgen/CPGen.java +++ b/src/org/ibex/classgen/CPGen.java @@ -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"); diff --git a/src/org/ibex/classgen/ClassGen.java b/src/org/ibex/classgen/ClassGen.java index de32d3c..997678c 100644 --- a/src/org/ibex/classgen/ClassGen.java +++ b/src/org/ibex/classgen/ClassGen.java @@ -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 { diff --git a/src/org/ibex/classgen/FieldRef.java b/src/org/ibex/classgen/FieldRef.java index f77ad93..6c2d8cf 100644 --- a/src/org/ibex/classgen/FieldRef.java +++ b/src/org/ibex/classgen/FieldRef.java @@ -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); } } diff --git a/src/org/ibex/classgen/MethodGen.java b/src/org/ibex/classgen/MethodGen.java index 68aebd2..c49957b 100644 --- a/src/org/ibex/classgen/MethodGen.java +++ b/src/org/ibex/classgen/MethodGen.java @@ -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(); diff --git a/src/org/ibex/classgen/MethodRef.java b/src/org/ibex/classgen/MethodRef.java index cb546bd..c866adc 100644 --- a/src/org/ibex/classgen/MethodRef.java +++ b/src/org/ibex/classgen/MethodRef.java @@ -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); } + } } - -- 1.7.10.4