Browse Source

fixed JASSIST-150

git-svn-id: http://anonsvn.jboss.org/repos/javassist/trunk@611 30ef5769-5b8d-40dd-aea6-55b5d6557bb3
tags/rel_3_17_1_ga
chiba 12 years ago
parent
commit
0564d29d85

+ 8
- 4
src/main/javassist/ClassPool.java View File

@@ -331,17 +331,21 @@ public class ClassPool {
}

/**
* Records a name that never exists.
* Records a class name that never exists.
* For example, a package name can be recorded by this method.
* This would improve execution performance
* since <code>get()</code> does not search the class path at all
* since <code>get()</code> quickly throw an exception
* without searching the class path at all
* if the given name is an invalid name recorded by this method.
* Note that searching the class path takes relatively long time.
*
* @param name a class name (separeted by dot).
* <p>The current implementation of this method performs nothing.
*
* @param name an invalid class name (separeted by dots).
* @deprecated
*/
public void recordInvalidClassName(String name) {
source.recordInvalidClassName(name);
// source.recordInvalidClassName(name);
}

/**

+ 0
- 16
src/main/javassist/ClassPoolTail.java View File

@@ -178,11 +178,9 @@ final class JarClassPath implements ClassPath {

final class ClassPoolTail {
protected ClassPathList pathList;
private Hashtable packages; // should be synchronized.

public ClassPoolTail() {
pathList = null;
packages = new Hashtable();
}

public String toString() {
@@ -269,14 +267,6 @@ final class ClassPoolTail {
return new DirClassPath(pathname);
}

/**
* You can record "System" so that java.lang.System can be quickly
* found although "System" is not a package name.
*/
public void recordInvalidClassName(String name) {
packages.put(name, name);
}

/**
* This method does not close the output stream.
*/
@@ -325,9 +315,6 @@ final class ClassPoolTail {
InputStream openClassfile(String classname)
throws NotFoundException
{
if (packages.get(classname) != null)
return null; // not found

ClassPathList list = pathList;
InputStream ins = null;
NotFoundException error = null;
@@ -361,9 +348,6 @@ final class ClassPoolTail {
* @return null if the class file could not be found.
*/
public URL find(String classname) {
if (packages.get(classname) != null)
return null;

ClassPathList list = pathList;
URL url = null;
while (list != null) {

+ 0
- 2
src/main/javassist/compiler/MemberCodeGen.java View File

@@ -504,7 +504,6 @@ public class MemberCodeGen extends CodeGen {
exprType = CLASS;
arrayDim = 0;
className = nfe.getField(); // JVM-internal
resolver.recordPackage(className);
isStatic = true;
}

@@ -1078,7 +1077,6 @@ public class MemberCodeGen extends CodeGen {
Symbol fname = (Symbol)e.oprand2();
String cname = nfe.getField();
f = resolver.lookupFieldByJvmName2(cname, fname, expr);
resolver.recordPackage(cname);
resultStatic = true;
return f;
}

+ 42
- 32
src/main/javassist/compiler/MemberResolver.java View File

@@ -16,6 +16,8 @@

package javassist.compiler;

import java.util.Hashtable;
import java.util.WeakHashMap;
import java.util.List;
import java.util.Iterator;
import javassist.*;
@@ -37,22 +39,6 @@ public class MemberResolver implements TokenId {
throw new CompileError("fatal");
}

/**
* @param jvmClassName a class name. Not a package name.
*/
public void recordPackage(String jvmClassName) {
String classname = jvmToJavaName(jvmClassName);
for (;;) {
int i = classname.lastIndexOf('.');
if (i > 0) {
classname = classname.substring(0, i);
classPool.recordInvalidClassName(classname);
}
else
break;
}
}

public static class Method {
public CtClass declaring;
public MethodInfo info;
@@ -276,6 +262,7 @@ public class MemberResolver implements TokenId {
* Only used by fieldAccess() in MemberCodeGen and TypeChecker.
*
* @param jvmClassName a JVM class name. e.g. java/lang/String
* @see #lookupClass(String, boolean)
*/
public CtField lookupFieldByJvmName2(String jvmClassName, Symbol fieldSym,
ASTree expr) throws NoFieldException
@@ -406,12 +393,44 @@ public class MemberResolver implements TokenId {
public CtClass lookupClass(String name, boolean notCheckInner)
throws CompileError
{
Hashtable cache = getInvalidNames();
Object found = cache.get(name);
if (found == INVALID)
throw new CompileError("no such class: " + name);
else if (found != null)
return (CtClass)found;

CtClass cc = null;
try {
return lookupClass0(name, notCheckInner);
cc = lookupClass0(name, notCheckInner);
}
catch (NotFoundException e) {
return searchImports(name);
cc = searchImports(name);
}

cache.put(name, cc);
return cc;
}

private static final String INVALID = "<invalid>";
private static WeakHashMap invalidNamesMap = new WeakHashMap();
private Hashtable invalidNames = null;

private Hashtable getInvalidNames() {
Hashtable ht = invalidNames;
if (ht == null) {
synchronized (MemberResolver.class) {
ht = (Hashtable)invalidNamesMap.get(classPool);
if (ht == null) {
ht = new Hashtable();
invalidNamesMap.put(classPool, ht);
}
}

invalidNames = ht;
}

return ht;
}

private CtClass searchImports(String orgName)
@@ -423,28 +442,19 @@ public class MemberResolver implements TokenId {
String pac = (String)it.next();
String fqName = pac + '.' + orgName;
try {
CtClass cc = classPool.get(fqName);
// if the class is found,
classPool.recordInvalidClassName(orgName);
return cc;
return classPool.get(fqName);
}
catch (NotFoundException e) {
classPool.recordInvalidClassName(fqName);
try {
if (pac.endsWith("." + orgName)) {
CtClass cc = classPool.get(pac);
// if the class is found,
classPool.recordInvalidClassName(orgName);
return cc;
}
}
catch (NotFoundException e2) {
classPool.recordInvalidClassName(pac);
if (pac.endsWith("." + orgName))
return classPool.get(pac);
}
catch (NotFoundException e2) {}
}
}
}

getInvalidNames().put(orgName, INVALID);
throw new CompileError("no such class: " + orgName);
}


+ 68
- 0
src/test/Jassist150.java View File

@@ -0,0 +1,68 @@
import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.NotFoundException;

public class Jassist150 {

public static final String BASE_PATH="./";
public static final String JAVASSIST_JAR=BASE_PATH+"javassist.jar";
public static final String CLASSES_FOLDER=BASE_PATH+"build/classes";
public static final String TEST_CLASSES_FOLDER=BASE_PATH+"build/test-classes";

public static class Inner1 {
public static int get() {
return 0;
}
}

public static void implTestClassTailCache() throws NotFoundException, CannotCompileException {
ClassPool pool = new ClassPool(true);
for(int paths=0; paths<50; paths++) {
pool.appendClassPath(JAVASSIST_JAR);
pool.appendClassPath(CLASSES_FOLDER);
pool.appendClassPath(TEST_CLASSES_FOLDER);
}
CtClass cc = pool.get("Jassist150$Inner1");
CtMethod ccGet = cc.getDeclaredMethod("get");
String code1 = "{ int n1 = Integer.valueOf(1); " +
" int n2 = Integer.valueOf(2); " +
" int n3 = Integer.valueOf(3); " +
" int n4 = Integer.valueOf(4); " +
" int n5 = Integer.valueOf(5); " +
" return n1+n2+n3+n4+n5; }";
String code2 = "{ int n1 = java.lang.Integer.valueOf(1); " +
" int n2 = java.lang.Integer.valueOf(2); " +
" int n3 = java.lang.Integer.valueOf(3); " +
" int n4 = java.lang.Integer.valueOf(4); " +
" int n5 = java.lang.Integer.valueOf(5); " +
" return n1+n2+n3+n4+n5; }";
String code3 = "{ int n1 = java.lang.Integer#valueOf(1); " +
" int n2 = java.lang.Integer#valueOf(2); " +
" int n3 = java.lang.Integer#valueOf(3); " +
" int n4 = java.lang.Integer#valueOf(4); " +
" int n5 = java.lang.Integer#valueOf(5); " +
" return n1+n2+n3+n4+n5; }";
loop(cc, ccGet, code1);
}

public static void loop(CtClass cc, CtMethod ccGet, String code) throws CannotCompileException {
long startTime = System.currentTimeMillis();
for(int replace=0; replace<1000; replace++) {
ccGet.setBody(code);
}
long endTime = System.currentTimeMillis();
System.out.println("Test: Time (ms) "+(endTime-startTime));
}

public static void main(String[] args) {
for (int loop = 0; loop < 5; loop++) {
try {
implTestClassTailCache();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}

+ 59
- 0
src/test/javassist/JvstTest4.java View File

@@ -598,4 +598,63 @@ public class JvstTest4 extends JvstTestRoot {
Object obj = cl.newInstance();
assertEquals(packageName, obj.getClass().getPackage().getName());
}

public static final String BASE_PATH="../";
public static final String JAVASSIST_JAR=BASE_PATH+"javassist.jar";
public static final String CLASSES_FOLDER=BASE_PATH+"build/classes";
public static final String TEST_CLASSES_FOLDER=BASE_PATH+"build/test-classes";

public static class Inner1 {
public static int get() {
return 0;
}
}

public void testJIRA150() throws Exception {
ClassPool pool = new ClassPool(true);
for(int paths=0; paths<50; paths++) {
pool.appendClassPath(JAVASSIST_JAR);
pool.appendClassPath(CLASSES_FOLDER);
pool.appendClassPath(TEST_CLASSES_FOLDER);
}
CtClass cc = pool.get("Jassist150$Inner1");
CtMethod ccGet = cc.getDeclaredMethod("get");
long startTime = System.currentTimeMillis();
for(int replace=0; replace<1000; replace++) {
ccGet.setBody(
"{ int n1 = java.lang.Integer#valueOf(1); " +
" int n2 = java.lang.Integer#valueOf(2); " +
" int n3 = java.lang.Integer#valueOf(3); " +
" int n4 = java.lang.Integer#valueOf(4); " +
" int n5 = java.lang.Integer#valueOf(5); " +
" return n1+n2+n3+n4+n5; }");
}
long endTime = System.currentTimeMillis();
for(int replace=0; replace<1000; replace++) {
ccGet.setBody(
"{ int n1 = java.lang.Integer.valueOf(1); " +
" int n2 = java.lang.Integer.valueOf(2); " +
" int n3 = java.lang.Integer.valueOf(3); " +
" int n4 = java.lang.Integer.valueOf(4); " +
" int n5 = java.lang.Integer.valueOf(5); " +
" return n1+n2+n3+n4+n5; }");
}
long endTime2 = System.currentTimeMillis();
for(int replace=0; replace<1000; replace++) {
ccGet.setBody(
"{ int n1 = Integer.valueOf(1); " +
" int n2 = Integer.valueOf(2); " +
" int n3 = Integer.valueOf(3); " +
" int n4 = Integer.valueOf(4); " +
" int n5 = Integer.valueOf(5); " +
" return n1+n2+n3+n4+n5; }");
}
long endTime3 = System.currentTimeMillis();
long t1 = endTime - startTime;
long t2 = endTime2 - endTime;
long t3 = endTime3 - endTime2;
System.out.println("JIRA150: " + t1 + ", " + t2 + ", " + t3);
assertTrue(t2 < t1 * 2);
assertTrue(t3 < t1 * 2);
}
}

Loading…
Cancel
Save