From 268d2de1754a833e6287a67a73466be4d21929a8 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Sat, 25 Sep 2010 15:54:01 -0600 Subject: [PATCH] cache array class lookups in element class; misc. bugfixes --- classpath/avian/ClassAddendum.java | 1 + src/classpath-common.h | 30 -------- src/jnienv.cpp | 6 +- src/machine.cpp | 118 +++++++++++++++++++++-------- src/machine.h | 11 +-- 5 files changed, 98 insertions(+), 68 deletions(-) diff --git a/classpath/avian/ClassAddendum.java b/classpath/avian/ClassAddendum.java index c20079df6b..ce13dbe35a 100644 --- a/classpath/avian/ClassAddendum.java +++ b/classpath/avian/ClassAddendum.java @@ -13,4 +13,5 @@ package avian; public class ClassAddendum extends Addendum { public volatile Class class_; public Object[] signers; + public volatile Class arrayClass; } diff --git a/src/classpath-common.h b/src/classpath-common.h index 29d90753bb..8567b1ae77 100644 --- a/src/classpath-common.h +++ b/src/classpath-common.h @@ -15,36 +15,6 @@ namespace vm { -object -getCaller(Thread* t, unsigned target) -{ - class Visitor: public Processor::StackVisitor { - public: - Visitor(Thread* t, unsigned target): - t(t), method(0), count(0), target(target) - { } - - virtual bool visit(Processor::StackWalker* walker) { - if (count == target) { - method = walker->method(); - return false; - } else { - ++ count; - return true; - } - } - - Thread* t; - object method; - unsigned count; - unsigned target; - } v(t, target); - - t->m->processor->walkStack(t, &v); - - return v.method; -} - object getTrace(Thread* t, unsigned skipCount) { diff --git a/src/jnienv.cpp b/src/jnienv.cpp index 0b6ae9b1c1..0c4a7070da 100644 --- a/src/jnienv.cpp +++ b/src/jnienv.cpp @@ -304,7 +304,11 @@ FindClass(Thread* t, const char* name) object n = makeByteArray(t, strlen(name) + 1); replace('.', '/', name, &byteArrayBody(t, n, 0)); - object c = resolveClass(t, root(t, Machine::AppLoader), n); + object caller = getCaller(t, 0); + + object c = resolveClass + (t, caller ? classLoader(t, methodClass(t, caller)) + : root(t, Machine::AppLoader), n); return makeLocalReference(t, c == 0 ? 0 : getJClass(t, c)); } diff --git a/src/machine.cpp b/src/machine.cpp index df9cf6c510..9640760fa2 100644 --- a/src/machine.cpp +++ b/src/machine.cpp @@ -960,8 +960,7 @@ parseInterfaceTable(Thread* t, Stream& s, object class_, object pool) unsigned i = 0; for (HashMapIterator it(t, map); it.hasMore();) { - object interface = resolveClass - (t, classLoader(t, class_), tripleFirst(t, it.next())); + object interface = tripleSecond(t, it.next()); if (UNLIKELY(t->exception)) return; set(t, interfaceTable, ArrayBody + (i * BytesPerWord), interface); @@ -1630,7 +1629,7 @@ parseAttributeTable(Thread* t, Stream& s, object class_, object pool) object body = makeByteArray(t, length); s.read(reinterpret_cast(&byteArrayBody(t, body, 0)), length); - object addendum = makeClassAddendum(t, pool, body, 0, 0); + object addendum = makeClassAddendum(t, pool, body, 0, 0, 0); set(t, class_, ClassAddendum, addendum); } else { @@ -1816,6 +1815,58 @@ resolveArrayClass(Thread* t, object loader, object spec, bool throw_) } } +object +resolveObjectArrayClass(Thread* t, object loader, object elementClass) +{ + object addendum = classAddendum(t, elementClass); + if (addendum) { + object arrayClass = classAddendumArrayClass(t, addendum); + if (arrayClass) { + return arrayClass; + } + } else { + PROTECT(t, loader); + PROTECT(t, elementClass); + + ACQUIRE(t, t->m->classLock); + + object addendum = makeClassAddendum(t, 0, 0, 0, 0, 0); + + set(t, elementClass, ClassAddendum, addendum); + } + + PROTECT(t, loader); + PROTECT(t, elementClass); + + object elementSpec = className(t, elementClass); + PROTECT(t, elementSpec); + + object spec; + if (byteArrayBody(t, elementSpec, 0) == '[') { + spec = makeByteArray(t, byteArrayLength(t, elementSpec) + 1); + byteArrayBody(t, spec, 0) = '['; + memcpy(&byteArrayBody(t, spec, 1), + &byteArrayBody(t, elementSpec, 0), + byteArrayLength(t, elementSpec)); + } else { + spec = makeByteArray(t, byteArrayLength(t, elementSpec) + 3); + byteArrayBody(t, spec, 0) = '['; + byteArrayBody(t, spec, 1) = 'L'; + memcpy(&byteArrayBody(t, spec, 2), + &byteArrayBody(t, elementSpec, 0), + byteArrayLength(t, elementSpec) - 1); + byteArrayBody(t, spec, byteArrayLength(t, elementSpec) + 1) = ';'; + byteArrayBody(t, spec, byteArrayLength(t, elementSpec) + 2) = 0; + } + + object arrayClass = resolveClass(t, loader, spec); + + set(t, classAddendum(t, elementClass), ClassAddendumArrayClass, + arrayClass); + + return arrayClass; +} + void removeMonitor(Thread* t, object o) { @@ -2301,7 +2352,7 @@ Thread::init() if (exception == 0) { setRoot(this, Machine::ArrayIndexOutOfBoundsException, m->classpath->makeThrowable - (this, Machine::IndexOutOfBoundsExceptionType)); + (this, Machine::ArrayIndexOutOfBoundsExceptionType)); } } @@ -3356,33 +3407,6 @@ resolveField(Thread* t, object class_, const char* fieldName, } } -object -resolveObjectArrayClass(Thread* t, object loader, object elementSpec) -{ - PROTECT(t, loader); - PROTECT(t, elementSpec); - - object spec; - if (byteArrayBody(t, elementSpec, 0) == '[') { - spec = makeByteArray(t, byteArrayLength(t, elementSpec) + 1); - byteArrayBody(t, spec, 0) = '['; - memcpy(&byteArrayBody(t, spec, 1), - &byteArrayBody(t, elementSpec, 0), - byteArrayLength(t, elementSpec)); - } else { - spec = makeByteArray(t, byteArrayLength(t, elementSpec) + 3); - byteArrayBody(t, spec, 0) = '['; - byteArrayBody(t, spec, 1) = 'L'; - memcpy(&byteArrayBody(t, spec, 2), - &byteArrayBody(t, elementSpec, 0), - byteArrayLength(t, elementSpec) - 1); - byteArrayBody(t, spec, byteArrayLength(t, elementSpec) + 1) = ';'; - byteArrayBody(t, spec, byteArrayLength(t, elementSpec) + 2) = 0; - } - - return resolveClass(t, loader, spec); -} - bool classNeedsInit(Thread* t, object c) { @@ -3476,7 +3500,7 @@ object makeObjectArray(Thread* t, object elementClass, unsigned count) { object arrayClass = resolveObjectArrayClass - (t, classLoader(t, elementClass), className(t, elementClass)); + (t, classLoader(t, elementClass), elementClass); PROTECT(t, arrayClass); object array = makeArray(t, count); @@ -3951,6 +3975,36 @@ parseUtf8(Thread* t, const char* data, unsigned length) return ::parseUtf8(t, s, length); } +object +getCaller(Thread* t, unsigned target) +{ + class Visitor: public Processor::StackVisitor { + public: + Visitor(Thread* t, unsigned target): + t(t), method(0), count(0), target(target) + { } + + virtual bool visit(Processor::StackWalker* walker) { + if (count == target) { + method = walker->method(); + return false; + } else { + ++ count; + return true; + } + } + + Thread* t; + object method; + unsigned count; + unsigned target; + } v(t, target); + + t->m->processor->walkStack(t, &v); + + return v.method; +} + object defineClass(Thread* t, object loader, const uint8_t* buffer, unsigned length) { diff --git a/src/machine.h b/src/machine.h index 7263994b1d..772bcd864c 100644 --- a/src/machine.h +++ b/src/machine.h @@ -2178,9 +2178,6 @@ resolveField(Thread* t, object loader, const char* className, } } -object -resolveObjectArrayClass(Thread* t, object loader, object elementSpec); - bool classNeedsInit(Thread* t, object c); @@ -2992,7 +2989,7 @@ getJClass(Thread* t, object c) ACQUIRE(t, t->m->classLock); - object addendum = makeClassAddendum(t, 0, 0, 0, 0); + object addendum = makeClassAddendum(t, 0, 0, 0, 0, 0); set(t, c, ClassAddendum, addendum); } @@ -3048,7 +3045,8 @@ registerNative(Thread* t, object method, void* function) } inline void -unregisterNatives(Thread* t, object c) { +unregisterNatives(Thread* t, object c) +{ if (classMethodTable(t, c)) { for (unsigned i = 0; i < arrayLength(t, classMethodTable(t, c)); ++i) { object method = arrayBody(t, classMethodTable(t, c), i); @@ -3059,6 +3057,9 @@ unregisterNatives(Thread* t, object c) { } } +object +getCaller(Thread* t, unsigned target); + object defineClass(Thread* t, object loader, const uint8_t* buffer, unsigned length);