import java.util.Hashtable;
import java.util.Iterator;
import java.util.ArrayList;
+import java.util.Enumeration;
import javassist.bytecode.Descriptor;
/**
*/
public static boolean doPruning = false;
+ private int compressCount;
+ private static final int COMPRESS_THRESHOLD = 100;
+
/* releaseUnmodifiedClassFile was introduced for avoiding a bug
of JBoss AOP. So the value should be true except for JBoss AOP.
*/
}
this.cflow = null;
+ this.compressCount = 0;
clearImportedPackages();
}
return source.toString();
}
+ /**
+ * This method is periodically invoked so that memory
+ * footprint will be minimized.
+ */
+ void compress() {
+ if (compressCount++ > COMPRESS_THRESHOLD) {
+ compressCount = 0;
+ Enumeration e = classes.elements();
+ while (e.hasMoreElements())
+ ((CtClass)e.nextElement()).compress();
+ }
+ }
+
/**
* Record a package name so that the Javassist compiler searches
* the package to resolve a class name.
public CtClass makeClass(InputStream classfile, boolean ifNotFrozen)
throws IOException, RuntimeException
{
+ compress();
classfile = new BufferedInputStream(classfile);
CtClass clazz = new CtClassType(classfile, this);
clazz.checkModify();
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
-import java.util.Enumeration;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
private int uniqueNumberSeed;
private boolean doPruning = ClassPool.doPruning;
- int getCounter;
- private static int readCounter = 0;
- private static final int READ_THRESHOLD = 100; // see getClassFile2()
- private static final int GET_THRESHOLD = 2; // see releaseClassFiles()
+ private int getCount;
+ private static final int GET_THRESHOLD = 2; // see compress()
CtClassType(String name, ClassPool cp) {
super(name);
fieldInitializers = null;
hiddenMethods = null;
uniqueNumberSeed = 0;
- getCounter = 0;
+ getCount = 0;
}
CtClassType(InputStream ins, ClassPool cp) throws IOException {
if (cfile != null)
return cfile;
- if (readCounter++ > READ_THRESHOLD) {
- releaseClassFiles();
- readCounter = 0;
- }
-
+ classPool.compress();
if (rawClassfile != null) {
try {
classfile = new ClassFile(new DataInputStream(
new ByteArrayInputStream(rawClassfile)));
rawClassfile = null;
- getCounter = GET_THRESHOLD;
+ getCount = GET_THRESHOLD;
return classfile;
}
catch (IOException e) {
}
}
- /**
+ /* Inherited from CtClass. Called by get() in ClassPool.
+ *
+ * @see javassist.CtClass#incGetCounter()
+ * @see #toBytecode(DataOutputStream)
+ */
+ final void incGetCounter() { ++getCount; }
+
+ /**
+ * Invoked from ClassPool#compress().
+ * It releases the class files that have not been recently used
+ * if they are unmodified.
+ */
+ void compress() {
+ if (getCount < GET_THRESHOLD)
+ if (!isModified() && ClassPool.releaseUnmodifiedClassFile)
+ removeClassFile();
+ else if (isFrozen() && !wasPruned)
+ saveClassFile();
+
+ getCount = 0;
+ }
+
+ /**
* Converts a ClassFile object into a byte array
* for saving memory space.
*/
- public synchronized void saveClassFile() {
+ private synchronized void saveClassFile() {
/* getMembers() and releaseClassFile() are also synchronized.
*/
if (classfile == null || hasMemberCache() != null)
catch (IOException e) {}
}
- public synchronized void releaseClassFile() {
+ private synchronized void removeClassFile() {
if (classfile != null && !isModified() && hasMemberCache() == null)
classfile = null;
}
- /* Inherited from CtClass. Called by get() in ClassPool.
- *
- * @see javassist.CtClass#incGetCounter()
- * @see #toBytecode(DataOutputStream)
- */
- void incGetCounter() { ++getCounter; }
-
- /**
- * Releases the class files
- * of the CtClasses that have not been recently used
- * if they are unmodified.
- */
- public void releaseClassFiles() {
- Enumeration e = classPool.classes.elements();
- while (e.hasMoreElements()) {
- Object obj = e.nextElement();
- if (obj instanceof CtClassType) {
- CtClassType cct = (CtClassType)obj;
- if (cct.getCounter < GET_THRESHOLD)
- if (!cct.isModified() && ClassPool.releaseUnmodifiedClassFile)
- cct.releaseClassFile();
- else if (cct.isFrozen() && !cct.wasPruned)
- cct.saveClassFile();
-
- cct.getCounter = 0;
- }
- }
- }
-
public ClassPool getClassPool() { return classPool; }
void setClassPool(ClassPool cp) { classPool = cp; }
// classfile = null;
}
- getCounter = 0;
+ getCount = 0;
wasFrozen = true;
}
catch (NotFoundException e) {