cache array class lookups in element class; misc. bugfixes

This commit is contained in:
Joel Dice 2010-09-25 15:54:01 -06:00
parent a2cc95d196
commit 268d2de175
5 changed files with 98 additions and 68 deletions

View File

@ -13,4 +13,5 @@ package avian;
public class ClassAddendum extends Addendum {
public volatile Class class_;
public Object[] signers;
public volatile Class arrayClass;
}

View File

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

View File

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

View File

@ -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<uint8_t*>(&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)
{

View File

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