Browse Source

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
tags/rel_3_17_1_ga
chiba 18 years ago
parent
commit
0446eb7e74

+ 2
- 1
Readme.html View File

@@ -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.

<p><br>


+ 4
- 0
src/main/javassist/CtClass.java View File

@@ -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

+ 83
- 82
src/main/javassist/bytecode/Bytecode.java View File

@@ -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);
}

/**

+ 1
- 2
src/main/javassist/bytecode/ConstPool.java View File

@@ -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.


+ 12
- 1
src/main/javassist/bytecode/ExceptionTable.java View File

@@ -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;

@@ -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 <code>exception_table_length</code>, which is the number
* of entries in the <code>exception_table[]</code>.

+ 29
- 51
src/main/javassist/bytecode/LongVector.java View File

@@ -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++;
}
*/
}

Loading…
Cancel
Save