aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorchiba <chiba@30ef5769-5b8d-40dd-aea6-55b5d6557bb3>2005-10-13 15:48:17 +0000
committerchiba <chiba@30ef5769-5b8d-40dd-aea6-55b5d6557bb3>2005-10-13 15:48:17 +0000
commit0446eb7e747fd18bfed7eaf0ab0fe3a7c96aadc7 (patch)
tree5c7f1eab0b7a0b024f16229f3a6abfe20b2531ed /src
parent3ab8846e75afa5c249f14005324113dfb33a0124 (diff)
downloadjavassist-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.java4
-rw-r--r--src/main/javassist/bytecode/Bytecode.java165
-rw-r--r--src/main/javassist/bytecode/ConstPool.java3
-rw-r--r--src/main/javassist/bytecode/ExceptionTable.java13
-rw-r--r--src/main/javassist/bytecode/LongVector.java80
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++;
}
-*/
}