From 0446eb7e747fd18bfed7eaf0ab0fe3a7c96aadc7 Mon Sep 17 00:00:00 2001 From: chiba Date: Thu, 13 Oct 2005 15:48:17 +0000 Subject: [PATCH] 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 --- Readme.html | 3 +- src/main/javassist/CtClass.java | 4 + src/main/javassist/bytecode/Bytecode.java | 165 +++++++++--------- src/main/javassist/bytecode/ConstPool.java | 3 +- .../javassist/bytecode/ExceptionTable.java | 13 +- src/main/javassist/bytecode/LongVector.java | 80 +++------ 6 files changed, 131 insertions(+), 137 deletions(-) diff --git a/Readme.html b/Readme.html index d7219e1d..14dc8a10 100644 --- a/Readme.html +++ b/Readme.html @@ -632,7 +632,8 @@ Howard Lewis Ship, Richard Jones, Marjan Sterjev, Bruce McDonald, Mark Brennan, Vlad Skarzhevskyy, Brett Randall, Tsuyoshi Murakami, Nathan Meyers, Yoshiyuki Usui Yutaka Sunaga, Arjan van der Meer, Bruce Eckel, Guillaume Pothier, -Kumar Matcha, and all other contributors for their contributions. +Kumar Matcha, Andreas Salathe, +and all other contributors for their contributions.


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. * + *

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 * javassist.Modifier * @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 CtClass file using the * constant pool table given to this Bytecode 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 max_locals. */ 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 { /** * exception_table[] of Code_attribute. */ -public class ExceptionTable { +public class ExceptionTable implements Cloneable { private ConstPool constPool; private ArrayList entries; @@ -67,6 +67,17 @@ public class ExceptionTable { entries = list; } + /** + * 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 exception_table_length, which is the number * of entries in the exception_table[]. 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++; } -*/ } -- 2.39.5