mirror of
https://github.com/corda/corda.git
synced 2025-01-21 03:55:00 +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 class ClassAddendum extends Addendum {
|
||||||
public volatile Class class_;
|
public volatile Class class_;
|
||||||
public Object[] signers;
|
public Object[] signers;
|
||||||
|
public volatile Class arrayClass;
|
||||||
}
|
}
|
||||||
|
@ -15,36 +15,6 @@
|
|||||||
|
|
||||||
namespace vm {
|
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
|
object
|
||||||
getTrace(Thread* t, unsigned skipCount)
|
getTrace(Thread* t, unsigned skipCount)
|
||||||
{
|
{
|
||||||
|
@ -304,7 +304,11 @@ FindClass(Thread* t, const char* name)
|
|||||||
object n = makeByteArray(t, strlen(name) + 1);
|
object n = makeByteArray(t, strlen(name) + 1);
|
||||||
replace('.', '/', name, &byteArrayBody(t, n, 0));
|
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));
|
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;
|
unsigned i = 0;
|
||||||
for (HashMapIterator it(t, map); it.hasMore();) {
|
for (HashMapIterator it(t, map); it.hasMore();) {
|
||||||
object interface = resolveClass
|
object interface = tripleSecond(t, it.next());
|
||||||
(t, classLoader(t, class_), tripleFirst(t, it.next()));
|
|
||||||
if (UNLIKELY(t->exception)) return;
|
if (UNLIKELY(t->exception)) return;
|
||||||
|
|
||||||
set(t, interfaceTable, ArrayBody + (i * BytesPerWord), interface);
|
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);
|
object body = makeByteArray(t, length);
|
||||||
s.read(reinterpret_cast<uint8_t*>(&byteArrayBody(t, body, 0)), 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);
|
set(t, class_, ClassAddendum, addendum);
|
||||||
} else {
|
} 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
|
void
|
||||||
removeMonitor(Thread* t, object o)
|
removeMonitor(Thread* t, object o)
|
||||||
{
|
{
|
||||||
@ -2301,7 +2352,7 @@ Thread::init()
|
|||||||
if (exception == 0) {
|
if (exception == 0) {
|
||||||
setRoot(this, Machine::ArrayIndexOutOfBoundsException,
|
setRoot(this, Machine::ArrayIndexOutOfBoundsException,
|
||||||
m->classpath->makeThrowable
|
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
|
bool
|
||||||
classNeedsInit(Thread* t, object c)
|
classNeedsInit(Thread* t, object c)
|
||||||
{
|
{
|
||||||
@ -3476,7 +3500,7 @@ object
|
|||||||
makeObjectArray(Thread* t, object elementClass, unsigned count)
|
makeObjectArray(Thread* t, object elementClass, unsigned count)
|
||||||
{
|
{
|
||||||
object arrayClass = resolveObjectArrayClass
|
object arrayClass = resolveObjectArrayClass
|
||||||
(t, classLoader(t, elementClass), className(t, elementClass));
|
(t, classLoader(t, elementClass), elementClass);
|
||||||
PROTECT(t, arrayClass);
|
PROTECT(t, arrayClass);
|
||||||
|
|
||||||
object array = makeArray(t, count);
|
object array = makeArray(t, count);
|
||||||
@ -3951,6 +3975,36 @@ parseUtf8(Thread* t, const char* data, unsigned length)
|
|||||||
return ::parseUtf8(t, s, 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
|
object
|
||||||
defineClass(Thread* t, object loader, const uint8_t* buffer, unsigned length)
|
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
|
bool
|
||||||
classNeedsInit(Thread* t, object c);
|
classNeedsInit(Thread* t, object c);
|
||||||
|
|
||||||
@ -2992,7 +2989,7 @@ getJClass(Thread* t, object c)
|
|||||||
|
|
||||||
ACQUIRE(t, t->m->classLock);
|
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);
|
set(t, c, ClassAddendum, addendum);
|
||||||
}
|
}
|
||||||
@ -3048,7 +3045,8 @@ registerNative(Thread* t, object method, void* function)
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
unregisterNatives(Thread* t, object c) {
|
unregisterNatives(Thread* t, object c)
|
||||||
|
{
|
||||||
if (classMethodTable(t, c)) {
|
if (classMethodTable(t, c)) {
|
||||||
for (unsigned i = 0; i < arrayLength(t, classMethodTable(t, c)); ++i) {
|
for (unsigned i = 0; i < arrayLength(t, classMethodTable(t, c)); ++i) {
|
||||||
object method = arrayBody(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
|
object
|
||||||
defineClass(Thread* t, object loader, const uint8_t* buffer, unsigned length);
|
defineClass(Thread* t, object loader, const uint8_t* buffer, unsigned length);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user