diff options
author | chiba <chiba@30ef5769-5b8d-40dd-aea6-55b5d6557bb3> | 2005-10-13 15:48:17 +0000 |
---|---|---|
committer | chiba <chiba@30ef5769-5b8d-40dd-aea6-55b5d6557bb3> | 2005-10-13 15:48:17 +0000 |
commit | 0446eb7e747fd18bfed7eaf0ab0fe3a7c96aadc7 (patch) | |
tree | 5c7f1eab0b7a0b024f16229f3a6abfe20b2531ed /src | |
parent | 3ab8846e75afa5c249f14005324113dfb33a0124 (diff) | |
download | javassist-0446eb7e747fd18bfed7eaf0ab0fe3a7c96aadc7.tar.gz javassist-0446eb7e747fd18bfed7eaf0ab0fe3a7c96aadc7.zip |
improved the performance of Bytecode and ConstPool. Added clone() to Bytecode.
git-svn-id: http://anonsvn.jboss.org/repos/javassist/trunk@211 30ef5769-5b8d-40dd-aea6-55b5d6557bb3
Diffstat (limited to 'src')
-rw-r--r-- | src/main/javassist/CtClass.java | 4 | ||||
-rw-r--r-- | src/main/javassist/bytecode/Bytecode.java | 165 | ||||
-rw-r--r-- | src/main/javassist/bytecode/ConstPool.java | 3 | ||||
-rw-r--r-- | src/main/javassist/bytecode/ExceptionTable.java | 13 | ||||
-rw-r--r-- | src/main/javassist/bytecode/LongVector.java | 80 |
5 files changed, 129 insertions, 136 deletions
diff --git a/src/main/javassist/CtClass.java b/src/main/javassist/CtClass.java index 8356c68a..6e5196e5 100644 --- a/src/main/javassist/CtClass.java +++ b/src/main/javassist/CtClass.java @@ -460,6 +460,10 @@ public abstract class CtClass { /** * Sets the modifiers. * + * <p>If the class is a nested class, this method also modifies + * the class declaring that nested class (i.e. the enclosing + * class is modified). + * * @param mod modifiers encoded by * <code>javassist.Modifier</code> * @see Modifier diff --git a/src/main/javassist/bytecode/Bytecode.java b/src/main/javassist/bytecode/Bytecode.java index 444b4355..32f9d2b2 100644 --- a/src/main/javassist/bytecode/Bytecode.java +++ b/src/main/javassist/bytecode/Bytecode.java @@ -18,6 +18,68 @@ package javassist.bytecode; import javassist.CtClass; import javassist.CtPrimitiveType; +class ByteVector implements Cloneable { + private byte[] buffer; + private int size; + + public ByteVector() { + buffer = new byte[64]; + size = 0; + } + + public Object clone() throws CloneNotSupportedException { + ByteVector bv = (ByteVector)super.clone(); + bv.buffer = (byte[])buffer.clone(); + return bv; + } + + public final int getSize() { return size; } + + public final byte[] copy() { + byte[] b = new byte[size]; + arraycopy(buffer, b, size); + return b; + } + + public int read(int offset) { + if (offset < 0 || size <= offset) + throw new ArrayIndexOutOfBoundsException(offset); + + return buffer[offset]; + } + + public void write(int offset, int value) { + if (offset < 0 || size <= offset) + throw new ArrayIndexOutOfBoundsException(offset); + + buffer[offset] = (byte)value; + } + + public void add(int code) { + addGap(1); + buffer[size - 1] = (byte)code; + } + + public void addGap(int length) { + if (size + length > buffer.length) { + int newSize = size << 1; + if (newSize < size + length) + newSize = size + length; + + byte[] newBuf = new byte[newSize]; + arraycopy(buffer, newBuf, size); + buffer = newBuf; + } + + size += length; + } + + private static void arraycopy(byte[] src, byte[] dest, int size) { + for (int i = 0; i < size; i++) + dest[i] = src[i]; + } +} + /** * A utility class for producing a bytecode sequence. * @@ -39,21 +101,16 @@ import javassist.CtPrimitiveType; * @see ConstPool * @see CodeAttribute */ -public class Bytecode implements Opcode { +public class Bytecode extends ByteVector implements Cloneable, Opcode { /** * Represents the <code>CtClass</code> file using the * constant pool table given to this <code>Bytecode</code> object. */ public static final CtClass THIS = ConstPool.THIS; - static final int bufsize = 64; ConstPool constPool; int maxStack, maxLocals; ExceptionTable tryblocks; - Bytecode next; - byte[] buffer; - int num; - private int stackDepth; /** @@ -70,7 +127,6 @@ public class Bytecode implements Opcode { * @param localvars <code>max_locals</code>. */ public Bytecode(ConstPool cp, int stacksize, int localvars) { - this(); constPool = cp; maxStack = stacksize; maxLocals = localvars; @@ -91,12 +147,20 @@ public class Bytecode implements Opcode { this(cp, 0, 0); } - /* used in add(). + /** + * Creates and returns a copy of this object. + * The constant pool object is shared between this object + * and the cloned object. */ - private Bytecode() { - buffer = new byte[bufsize]; - num = 0; - next = null; + public Object clone() { + try { + Bytecode bc = (Bytecode)super.clone(); + bc.tryblocks = (ExceptionTable)tryblocks.clone(); + return bc; + } + catch (CloneNotSupportedException cnse) { + throw new RuntimeException(cnse); + } } /** @@ -121,32 +185,14 @@ public class Bytecode implements Opcode { * Returns the length of the bytecode sequence. */ public int length() { - int len = 0; - Bytecode b = this; - while (b != null) { - len += b.num; - b = b.next; - } - - return len; - } - - private void copy(byte[] dest, int index) { - Bytecode b = this; - while (b != null) { - System.arraycopy(b.buffer, 0, dest, index, b.num); - index += b.num; - b = b.next; - } + return getSize(); } /** * Returns the produced bytecode sequence. */ public byte[] get() { - byte[] b = new byte[length()]; - copy(b, 0); - return b; + return copy(); } /** @@ -258,14 +304,7 @@ public class Bytecode implements Opcode { * that have been added so far. */ public int currentPc() { - int n = 0; - Bytecode b = this; - while (b != null) { - n += b.num; - b = b.next; - } - - return n; + return getSize(); } /** @@ -275,17 +314,7 @@ public class Bytecode implements Opcode { * @throws ArrayIndexOutOfBoundsException if offset is invalid. */ public int read(int offset) { - if (offset < 0) - return Opcode.NOP; - else if (offset < num) - return buffer[offset]; - else - try { - return next.read(offset - num); - } - catch (NullPointerException e) { - throw new ArrayIndexOutOfBoundsException(offset); - } + return super.read(offset); } /** @@ -315,15 +344,7 @@ public class Bytecode implements Opcode { * @throws ArrayIndexOutOfBoundsException if offset is invalid. */ public void write(int offset, int value) { - if (offset < num) - buffer[offset] = (byte)value; - else - try { - next.write(offset - num, value); - } - catch (NullPointerException e) { - throw new ArrayIndexOutOfBoundsException(offset); - } + super.write(offset, value); } /** @@ -348,14 +369,7 @@ public class Bytecode implements Opcode { * Appends an 8bit value to the end of the bytecode sequence. */ public void add(int code) { - if (num < bufsize) - buffer[num++] = (byte)code; - else { - if (next == null) - next = new Bytecode(); - - next.add(code); - } + super.add(code); } /** @@ -374,20 +388,7 @@ public class Bytecode implements Opcode { * @param length the gap length in byte. */ public void addGap(int length) { - if (num < bufsize) { - num += length; - if (num <= bufsize) - return; - else { - length = num - bufsize; - num = bufsize; - } - } - - if (next == null) - next = new Bytecode(); - - next.addGap(length); + super.addGap(length); } /** diff --git a/src/main/javassist/bytecode/ConstPool.java b/src/main/javassist/bytecode/ConstPool.java index 76573e1c..3a3443d1 100644 --- a/src/main/javassist/bytecode/ConstPool.java +++ b/src/main/javassist/bytecode/ConstPool.java @@ -894,8 +894,7 @@ public final class ConstPool { private void read(DataInputStream in) throws IOException { int n = in.readUnsignedShort(); - int size = (n / LongVector.SIZE + 1) * LongVector.SIZE; - items = new LongVector(size); + items = new LongVector(n); numOfItems = 0; addItem(null); // index 0 is reserved by the JVM. diff --git a/src/main/javassist/bytecode/ExceptionTable.java b/src/main/javassist/bytecode/ExceptionTable.java index 7b0a8357..f19f0ac9 100644 --- a/src/main/javassist/bytecode/ExceptionTable.java +++ b/src/main/javassist/bytecode/ExceptionTable.java @@ -38,7 +38,7 @@ class ExceptionTableEntry { /** * <code>exception_table[]</code> of <code>Code_attribute</code>. */ -public class ExceptionTable { +public class ExceptionTable implements Cloneable { private ConstPool constPool; private ArrayList entries; @@ -68,6 +68,17 @@ public class ExceptionTable { } /** + * Creates and returns a copy of this object. + * The constant pool object is shared between this object + * and the cloned object. + */ + public Object clone() throws CloneNotSupportedException { + ExceptionTable r = (ExceptionTable)super.clone(); + r.entries = new ArrayList(entries); + return r; + } + + /** * Returns <code>exception_table_length</code>, which is the number * of entries in the <code>exception_table[]</code>. */ diff --git a/src/main/javassist/bytecode/LongVector.java b/src/main/javassist/bytecode/LongVector.java index fd90045e..b1f679be 100644 --- a/src/main/javassist/bytecode/LongVector.java +++ b/src/main/javassist/bytecode/LongVector.java @@ -16,70 +16,48 @@ package javassist.bytecode; final class LongVector { - static final int SIZE = 128; - private int num; - private Object[] objects; - private LongVector next; + static final int ASIZE = 128; + static final int ABITS = 7; // ASIZE = 2^ABITS + static final int VSIZE = 8; + private Object[][] objects; + private int elements; public LongVector() { - this(SIZE); + objects = new Object[VSIZE][]; + elements = 0; } public LongVector(int initialSize) { - num = 0; - objects = new Object[initialSize]; - next = null; + int vsize = ((initialSize >> ABITS) & ~(VSIZE - 1)) + VSIZE; + objects = new Object[vsize][]; + elements = 0; } - public void addElement(Object obj) { - LongVector p = this; - while (p.next != null) - p = p.next; + public int size() { return elements; } - if (p.num < p.objects.length) - p.objects[p.num++] = obj; - else { - LongVector q = p.next = new LongVector(SIZE); - q.objects[q.num++] = obj; - } - } - - public int size() { - LongVector p = this; - int s = 0; - while (p != null) { - s += p.num; - p = p.next; - } - - return s; - } + public int capacity() { return objects.length * ASIZE; } public Object elementAt(int i) { - LongVector p = this; - while (p != null) - if (i < p.num) - return p.objects[i]; - else { - i -= p.num; - p = p.next; - } + if (i < 0 || elements <= i) + return null; - return null; + return objects[i >> ABITS][i & (ASIZE - 1)]; } -/* - public static void main(String [] args) { - LongVector v = new LongVector(4); - int i; - for (i = 0; i < 128; ++i) - v.addElement(new Integer(i)); - - System.out.println(v.size()); - for (i = 0; i < v.size(); ++i) { - System.out.print(v.elementAt(i)); - System.out.print(", "); + public void addElement(Object value) { + int nth = elements >> ABITS; + int offset = elements & (ASIZE - 1); + int len = objects.length; + if (nth >= len) { + Object[][] newObj = new Object[len + VSIZE][]; + System.arraycopy(objects, 0, newObj, 0, len); + objects = newObj; } + + if (objects[nth] == null) + objects[nth] = new Object[ASIZE]; + + objects[nth][offset] = value; + elements++; } -*/ } |