mirror of
https://github.com/corda/corda.git
synced 2024-12-28 16:58:55 +00:00
resolveClass() sketch
This commit is contained in:
parent
7904fa40a3
commit
8d7cd5482f
@ -6,7 +6,7 @@
|
|||||||
class ClassFinder {
|
class ClassFinder {
|
||||||
public:
|
public:
|
||||||
virtual ~ClassFinder() { }
|
virtual ~ClassFinder() { }
|
||||||
virtual const uint8_t* find(const char* className) = 0;
|
virtual const uint8_t* find(const char* className, unsigned* size) = 0;
|
||||||
virtual void free(const uint8_t* class_) = 0;
|
virtual void free(const uint8_t* class_) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
11
src/system.h
11
src/system.h
@ -3,8 +3,6 @@
|
|||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
#define ACQUIRE(x) System::MonitorResource MAKE_NAME(monitorResource_) (x)
|
|
||||||
|
|
||||||
class System {
|
class System {
|
||||||
public:
|
public:
|
||||||
typedef int Status;
|
typedef int Status;
|
||||||
@ -26,15 +24,6 @@ class System {
|
|||||||
virtual void dispose() = 0;
|
virtual void dispose() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MonitorResource {
|
|
||||||
public:
|
|
||||||
MonitorResource(Monitor* m): m(m) { m->acquire(); }
|
|
||||||
~MonitorResource() { m->release(); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
Monitor* m;
|
|
||||||
};
|
|
||||||
|
|
||||||
class File {
|
class File {
|
||||||
public:
|
public:
|
||||||
virtual ~File() { }
|
virtual ~File() { }
|
||||||
|
@ -109,6 +109,9 @@
|
|||||||
(type classCastException
|
(type classCastException
|
||||||
(extends runtimeException))
|
(extends runtimeException))
|
||||||
|
|
||||||
|
(type classNotFoundException
|
||||||
|
(extends runtimeException))
|
||||||
|
|
||||||
(type error
|
(type error
|
||||||
(extends throwable))
|
(extends throwable))
|
||||||
|
|
||||||
|
166
src/vm.cpp
166
src/vm.cpp
@ -1,10 +1,13 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "system.h"
|
#include "system.h"
|
||||||
#include "heap.h"
|
#include "heap.h"
|
||||||
|
#include "class_finder.h"
|
||||||
|
|
||||||
#define PROTECT(thread, name) \
|
#define PROTECT(thread, name) \
|
||||||
Thread::Protector MAKE_NAME(protector_) (thread, &name);
|
Thread::Protector MAKE_NAME(protector_) (thread, &name);
|
||||||
|
|
||||||
|
#define ACQUIRE_MONITOR(x) MonitorResource MAKE_NAME(monitorResource_) (x)
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
typedef void* object;
|
typedef void* object;
|
||||||
@ -33,12 +36,15 @@ class Machine {
|
|||||||
public:
|
public:
|
||||||
System* sys;
|
System* sys;
|
||||||
Heap* heap;
|
Heap* heap;
|
||||||
|
ClassFinder* classFinder;
|
||||||
Thread* rootThread;
|
Thread* rootThread;
|
||||||
Thread* exclusive;
|
Thread* exclusive;
|
||||||
unsigned activeCount;
|
unsigned activeCount;
|
||||||
unsigned liveCount;
|
unsigned liveCount;
|
||||||
System::Monitor* stateLock;
|
System::Monitor* stateLock;
|
||||||
System::Monitor* heapLock;
|
System::Monitor* heapLock;
|
||||||
|
System::Monitor* classLock;
|
||||||
|
object classMap;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Thread {
|
class Thread {
|
||||||
@ -86,6 +92,15 @@ class Thread {
|
|||||||
Protector* protector;
|
Protector* protector;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class MonitorResource {
|
||||||
|
public:
|
||||||
|
MonitorResource(System::Monitor* m): m(m) { m->acquire(); }
|
||||||
|
~MonitorResource() { m->release(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
System::Monitor* m;
|
||||||
|
};
|
||||||
|
|
||||||
inline void NO_RETURN
|
inline void NO_RETURN
|
||||||
abort(Thread* t)
|
abort(Thread* t)
|
||||||
{
|
{
|
||||||
@ -99,14 +114,16 @@ assert(Thread* t, bool v)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
init(Machine* m, System* sys, Heap* heap)
|
init(Machine* m, System* sys, Heap* heap, ClassFinder* classFinder)
|
||||||
{
|
{
|
||||||
memset(m, 0, sizeof(Machine));
|
memset(m, 0, sizeof(Machine));
|
||||||
m->sys = sys;
|
m->sys = sys;
|
||||||
m->heap = heap;
|
m->heap = heap;
|
||||||
|
m->classFinder = classFinder;
|
||||||
|
|
||||||
if (not sys->success(sys->make(&(m->stateLock))) or
|
if (not sys->success(sys->make(&(m->stateLock))) or
|
||||||
not sys->success(sys->make(&(m->heapLock))))
|
not sys->success(sys->make(&(m->heapLock))) or
|
||||||
|
not sys->success(sys->make(&(m->classLock))))
|
||||||
{
|
{
|
||||||
sys->abort();
|
sys->abort();
|
||||||
}
|
}
|
||||||
@ -156,16 +173,18 @@ collect(Machine* m, Heap::CollectionType type)
|
|||||||
{
|
{
|
||||||
class Iterator: public Heap::Iterator {
|
class Iterator: public Heap::Iterator {
|
||||||
public:
|
public:
|
||||||
Iterator(Machine* m): machine(m) { }
|
Iterator(Machine* m): m(m) { }
|
||||||
|
|
||||||
void iterate(Heap::Visitor* v) {
|
void iterate(Heap::Visitor* v) {
|
||||||
for (Thread* t = machine->rootThread; t; t = t->next) {
|
v->visit(&(m->classMap));
|
||||||
|
|
||||||
|
for (Thread* t = m->rootThread; t; t = t->next) {
|
||||||
::iterate(t, v);
|
::iterate(t, v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Machine* machine;
|
Machine* m;
|
||||||
} it(m);
|
} it(m);
|
||||||
|
|
||||||
m->heap->collect(type, &it);
|
m->heap->collect(type, &it);
|
||||||
@ -176,7 +195,7 @@ enter(Thread* t, Thread::State s)
|
|||||||
{
|
{
|
||||||
if (s == t->state) return;
|
if (s == t->state) return;
|
||||||
|
|
||||||
ACQUIRE(t->vm->stateLock);
|
ACQUIRE_MONITOR(t->vm->stateLock);
|
||||||
|
|
||||||
switch (s) {
|
switch (s) {
|
||||||
case Thread::ExclusiveState: {
|
case Thread::ExclusiveState: {
|
||||||
@ -278,7 +297,7 @@ maybeYieldAndMaybeCollect(Thread* t, unsigned size)
|
|||||||
abort(t);
|
abort(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
ACQUIRE(t->vm->stateLock);
|
ACQUIRE_MONITOR(t->vm->stateLock);
|
||||||
|
|
||||||
while (t->vm->exclusive) {
|
while (t->vm->exclusive) {
|
||||||
// another thread wants to enter the exclusive state, either for a
|
// another thread wants to enter the exclusive state, either for a
|
||||||
@ -403,7 +422,15 @@ makeClassCastException(Thread* t, object message)
|
|||||||
{
|
{
|
||||||
PROTECT(t, message);
|
PROTECT(t, message);
|
||||||
object trace = makeTrace(t);
|
object trace = makeTrace(t);
|
||||||
return makeArrayIndexOutOfBoundsException(t, message, trace);
|
return makeClassCastException(t, message, trace);
|
||||||
|
}
|
||||||
|
|
||||||
|
object
|
||||||
|
makeClassNotFoundException(Thread* t, object message)
|
||||||
|
{
|
||||||
|
PROTECT(t, message);
|
||||||
|
object trace = makeTrace(t);
|
||||||
|
return makeClassNotFoundException(t, message, trace);
|
||||||
}
|
}
|
||||||
|
|
||||||
object
|
object
|
||||||
@ -551,17 +578,15 @@ isSpecialMethod(Thread* t, object method, object class_)
|
|||||||
}
|
}
|
||||||
|
|
||||||
object
|
object
|
||||||
find(Thread* t, object class_, object reference,
|
find(Thread* t, object class_, object table, object reference,
|
||||||
object& (*table)(Thread*, object),
|
|
||||||
object& (*name)(Thread*, object),
|
object& (*name)(Thread*, object),
|
||||||
object& (*spec)(Thread*, object),
|
object& (*spec)(Thread*, object),
|
||||||
object (*makeError)(Thread*, object))
|
object (*makeError)(Thread*, object))
|
||||||
{
|
{
|
||||||
object a = table(t, class_);
|
|
||||||
object n = referenceName(t, reference);
|
object n = referenceName(t, reference);
|
||||||
object s = referenceSpec(t, reference);
|
object s = referenceSpec(t, reference);
|
||||||
for (unsigned i = 0; i < rawArrayLength(t, a); ++i) {
|
for (unsigned i = 0; i < rawArrayLength(t, table); ++i) {
|
||||||
object field = rawArrayBody(t, a)[i];
|
object field = rawArrayBody(t, table)[i];
|
||||||
if (strcmp(byteArrayBody(t, name(t, field)),
|
if (strcmp(byteArrayBody(t, name(t, field)),
|
||||||
byteArrayBody(t, n)) == 0 and
|
byteArrayBody(t, n)) == 0 and
|
||||||
strcmp(byteArrayBody(t, spec(t, field)),
|
strcmp(byteArrayBody(t, spec(t, field)),
|
||||||
@ -583,15 +608,120 @@ find(Thread* t, object class_, object reference,
|
|||||||
inline object
|
inline object
|
||||||
findFieldInClass(Thread* t, object class_, object reference)
|
findFieldInClass(Thread* t, object class_, object reference)
|
||||||
{
|
{
|
||||||
return find(t, class_, reference, classFieldTable, fieldName, fieldSpec,
|
return find(t, class_, classFieldTable(t, class_), reference, fieldName,
|
||||||
makeNoSuchFieldError);
|
fieldSpec, makeNoSuchFieldError);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline object
|
inline object
|
||||||
findMethodInClass(Thread* t, object class_, object reference)
|
findMethodInClass(Thread* t, object class_, object reference)
|
||||||
{
|
{
|
||||||
return find(t, class_, reference, classMethodTable, methodName, methodSpec,
|
return find(t, class_, classMethodTable(t, class_), reference, methodName,
|
||||||
makeNoSuchMethodError);
|
methodSpec, makeNoSuchMethodError);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
hash(const int8_t* s, unsigned length)
|
||||||
|
{
|
||||||
|
uint32_t h = 0;
|
||||||
|
for (unsigned i = 0; i < length; ++i) h = (h * 31) + s[i];
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
byteArrayEqual(Thread* t, object a, object b)
|
||||||
|
{
|
||||||
|
if (a == b) return true;
|
||||||
|
|
||||||
|
if (byteArrayLength(t, a) == byteArrayLength(t, b)) {
|
||||||
|
return strcmp(byteArrayBody(t, a), byteArrayBody(t, b)) == 0;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object
|
||||||
|
hashMapFind(Thread* t, object map, uint32_t hash, object key,
|
||||||
|
bool (*equal)(Thread*, object, object))
|
||||||
|
{
|
||||||
|
unsigned index = hash & (rawArrayLength(t, map) - 1);
|
||||||
|
object n = rawArrayBody(t, map)[index];
|
||||||
|
while (n) {
|
||||||
|
if (equal(t, tripleFirst(t, n), key)) {
|
||||||
|
return tripleSecond(t, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
n = tripleThird(t, n);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
object
|
||||||
|
hashMapInsert(Thread* t, object map, uint32_t hash, object key, object value)
|
||||||
|
{
|
||||||
|
unsigned index = hash & (rawArrayLength(t, map) - 1);
|
||||||
|
object n = rawArrayBody(t, map)[index];
|
||||||
|
|
||||||
|
PROTECT(t, map);
|
||||||
|
|
||||||
|
n = makeTriple(t, key, value, n);
|
||||||
|
|
||||||
|
set(t, rawArrayBody(t, map)[index], n);
|
||||||
|
}
|
||||||
|
|
||||||
|
object
|
||||||
|
resolveClass(Thread* t, object spec)
|
||||||
|
{
|
||||||
|
PROTECT(t, spec);
|
||||||
|
ACQUIRE(t, t->vm->classLock);
|
||||||
|
|
||||||
|
uint32_t h = hash(byteArrayBody(t, spec), byteArrayLength(t, spec) - 1);
|
||||||
|
object class_ = hashMapFind(t, t->vm->classMap, h, spec, byteArrayEqual);
|
||||||
|
if (class_ == 0) {
|
||||||
|
unsigned size;
|
||||||
|
const uint8_t* data = t->vm->classFinder->find
|
||||||
|
(reinterpret_cast<const char*>(byteArrayBody(t, spec)), &size);
|
||||||
|
|
||||||
|
if (data) {
|
||||||
|
class_ = parseClass(t, data, size);
|
||||||
|
|
||||||
|
PROTECT(t, class_);
|
||||||
|
hashMapInsert(t, t->vm->classMap, h, spec, class_);
|
||||||
|
} else {
|
||||||
|
object message = makeString(t, "%s", byteArrayBody(t, spec));
|
||||||
|
t->exception = makeClassNotFoundException(t, message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return class_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline object
|
||||||
|
resolveClass(Thread* t, object pool, unsigned index)
|
||||||
|
{
|
||||||
|
object o = rawArrayBody(t, pool)[index];
|
||||||
|
if (typeOf(o) == ByteArrayType) {
|
||||||
|
PROTECT(t, pool);
|
||||||
|
|
||||||
|
o = resolveClass(t, o);
|
||||||
|
if (UNLIKELY(t->exception)) return 0;
|
||||||
|
|
||||||
|
set(t, rawArrayBody(t, pool)[index], o);
|
||||||
|
}
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline object
|
||||||
|
resolveClass(Thread* t, object container, object& (*class_)(Thread*, object))
|
||||||
|
{
|
||||||
|
object o = class_(t, container);
|
||||||
|
if (typeOf(o) == ByteArrayType) {
|
||||||
|
PROTECT(t, container);
|
||||||
|
|
||||||
|
o = resolveClass(t, o);
|
||||||
|
if (UNLIKELY(t->exception)) return 0;
|
||||||
|
|
||||||
|
set(t, class_(t, container), o);
|
||||||
|
}
|
||||||
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline object
|
inline object
|
||||||
@ -602,7 +732,7 @@ resolve(Thread* t, object pool, unsigned index,
|
|||||||
if (typeOf(o) == ReferenceType) {
|
if (typeOf(o) == ReferenceType) {
|
||||||
PROTECT(t, pool);
|
PROTECT(t, pool);
|
||||||
|
|
||||||
object class_ = resolveClass(t, referenceClass(t, o));
|
object class_ = resolveClass(t, o, referenceClass);
|
||||||
if (UNLIKELY(t->exception)) return 0;
|
if (UNLIKELY(t->exception)) return 0;
|
||||||
|
|
||||||
o = find(t, class_, rawArrayBody(t, pool)[index]);
|
o = find(t, class_, rawArrayBody(t, pool)[index]);
|
||||||
|
Loading…
Reference in New Issue
Block a user