mirror of
https://github.com/corda/corda.git
synced 2025-01-03 19:54:13 +00:00
cache array class lookups in element class; misc. bugfixes
This commit is contained in:
parent
a2cc95d196
commit
268d2de175
@ -13,4 +13,5 @@ package avian;
|
||||
public class ClassAddendum extends Addendum {
|
||||
public volatile Class class_;
|
||||
public Object[] signers;
|
||||
public volatile Class arrayClass;
|
||||
}
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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));
|
||||
}
|
||||
|
118
src/machine.cpp
118
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<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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user