mirror of
https://github.com/corda/corda.git
synced 2024-12-29 09:18:58 +00:00
snapshot (broken)
This commit is contained in:
parent
f698d347ac
commit
bb16d8e62b
@ -5,9 +5,7 @@ public class TestExceptions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static void moreDangerous() {
|
private static void moreDangerous() {
|
||||||
// synchronized (TestExceptions.class) {
|
evenMoreDangerous();
|
||||||
evenMoreDangerous();
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void dangerous() {
|
private static void dangerous() {
|
||||||
|
66
src/heap.cpp
66
src/heap.cpp
@ -483,12 +483,6 @@ class Segment {
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* add(void* p, unsigned size) {
|
|
||||||
void* target = allocate(size);
|
|
||||||
memcpy(target, p, size * BytesPerWord);
|
|
||||||
return target;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ensure(unsigned minimum) {
|
void ensure(unsigned minimum) {
|
||||||
if (remaining() < minimum) {
|
if (remaining() < minimum) {
|
||||||
assert(context, rear->position);
|
assert(context, rear->position);
|
||||||
@ -713,40 +707,48 @@ bitset(Context* c, object o)
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline object
|
inline object
|
||||||
copyTo(Context* c, Segment* s, object o, unsigned size)
|
copyTo(Context* c, Segment* s, object o)
|
||||||
{
|
{
|
||||||
if (s->remaining() < size) {
|
class Allocator: public Heap::Allocator {
|
||||||
s->ensure(size);
|
public:
|
||||||
|
Allocator(Segment* s): s(s) { }
|
||||||
|
|
||||||
if (Verbose) {
|
virtual void* allocate(unsigned size) {
|
||||||
if (s == &(c->gen2)) {
|
if (s->remaining() < size) {
|
||||||
fprintf(stderr, "grow gen2 to %d bytes\n",
|
s->ensure(size);
|
||||||
c->gen2.capacity() * BytesPerWord);
|
|
||||||
} else if (s == &(c->nextGen1)) {
|
if (Verbose) {
|
||||||
fprintf(stderr, "grow nextGen1 to %d bytes\n",
|
if (s == &(c->gen2)) {
|
||||||
c->nextGen1.capacity() * BytesPerWord);
|
fprintf(stderr, "grow gen2 to %d bytes\n",
|
||||||
} else if (s == &(c->nextGen2)) {
|
c->gen2.capacity() * BytesPerWord);
|
||||||
fprintf(stderr, "grow nextGen2 to %d bytes\n",
|
} else if (s == &(c->nextGen1)) {
|
||||||
c->nextGen2.capacity() * BytesPerWord);
|
fprintf(stderr, "grow nextGen1 to %d bytes\n",
|
||||||
} else {
|
c->nextGen1.capacity() * BytesPerWord);
|
||||||
abort(c);
|
} else if (s == &(c->nextGen2)) {
|
||||||
|
fprintf(stderr, "grow nextGen2 to %d bytes\n",
|
||||||
|
c->nextGen2.capacity() * BytesPerWord);
|
||||||
|
} else {
|
||||||
|
abort(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return static_cast<object>(s->add(o, size));
|
return s->allocate(size);
|
||||||
|
}
|
||||||
|
} allocator(s);
|
||||||
|
|
||||||
|
c->client->copy(o, &allocator);
|
||||||
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
object
|
object
|
||||||
copy2(Context* c, object o)
|
copy2(Context* c, object o)
|
||||||
{
|
{
|
||||||
unsigned size = c->client->sizeInWords(o);
|
|
||||||
|
|
||||||
if (c->gen2.contains(o)) {
|
if (c->gen2.contains(o)) {
|
||||||
assert(c, c->mode == MajorCollection
|
assert(c, c->mode == MajorCollection
|
||||||
or c->mode == Gen2Collection);
|
or c->mode == Gen2Collection);
|
||||||
|
|
||||||
return copyTo(c, &(c->nextGen2), o, size);
|
return copyTo(c, &(c->nextGen2), o);
|
||||||
} else if (c->gen1.contains(o)) {
|
} else if (c->gen1.contains(o)) {
|
||||||
unsigned age = c->ageMap.get(o);
|
unsigned age = c->ageMap.get(o);
|
||||||
if (age == TenureThreshold) {
|
if (age == TenureThreshold) {
|
||||||
@ -758,7 +760,7 @@ copy2(Context* c, object o)
|
|||||||
c->gen2Base = c->gen2.position();
|
c->gen2Base = c->gen2.position();
|
||||||
}
|
}
|
||||||
|
|
||||||
return copyTo(c, &(c->gen2), o, size);
|
return copyTo(c, &(c->gen2), o);
|
||||||
} else {
|
} else {
|
||||||
if (Verbose) {
|
if (Verbose) {
|
||||||
fprintf(stderr, "overflow collection\n");
|
fprintf(stderr, "overflow collection\n");
|
||||||
@ -766,13 +768,13 @@ copy2(Context* c, object o)
|
|||||||
|
|
||||||
c->mode = OverflowCollection;
|
c->mode = OverflowCollection;
|
||||||
initNextGen2(c);
|
initNextGen2(c);
|
||||||
return copyTo(c, &(c->nextGen2), o, size);
|
return copyTo(c, &(c->nextGen2), o);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return copyTo(c, &(c->nextGen2), o, size);
|
return copyTo(c, &(c->nextGen2), o);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
o = copyTo(c, &(c->nextGen1), o, size);
|
o = copyTo(c, &(c->nextGen1), o);
|
||||||
c->nextAgeMap.setOnly(o, age + 1);
|
c->nextAgeMap.setOnly(o, age + 1);
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
@ -780,7 +782,7 @@ copy2(Context* c, object o)
|
|||||||
assert(c, not c->nextGen1.contains(o));
|
assert(c, not c->nextGen1.contains(o));
|
||||||
assert(c, not c->nextGen2.contains(o));
|
assert(c, not c->nextGen2.contains(o));
|
||||||
|
|
||||||
o = copyTo(c, &(c->nextGen1), o, size);
|
o = copyTo(c, &(c->nextGen1), o);
|
||||||
|
|
||||||
c->nextAgeMap.clear(o);
|
c->nextAgeMap.clear(o);
|
||||||
|
|
||||||
|
@ -24,11 +24,18 @@ class Heap {
|
|||||||
virtual bool visit(unsigned) = 0;
|
virtual bool visit(unsigned) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class Allocator {
|
||||||
|
public:
|
||||||
|
virtual ~Allocator() { }
|
||||||
|
virtual void* allocate(unsigned sizeInWords) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
class Client {
|
class Client {
|
||||||
public:
|
public:
|
||||||
virtual ~Client() { }
|
virtual ~Client() { }
|
||||||
virtual void visitRoots(Visitor*) = 0;
|
virtual void visitRoots(Visitor*) = 0;
|
||||||
virtual unsigned sizeInWords(void*) = 0;
|
virtual unsigned sizeInWords(void*) = 0;
|
||||||
|
virtual void copy(void*, Allocator*) = 0;
|
||||||
virtual void walk(void*, Walker*) = 0;
|
virtual void walk(void*, Walker*) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
98
src/system.h
98
src/system.h
@ -18,15 +18,101 @@ class System {
|
|||||||
class Monitor {
|
class Monitor {
|
||||||
public:
|
public:
|
||||||
virtual ~Monitor() { }
|
virtual ~Monitor() { }
|
||||||
virtual bool tryAcquire(void* id) = 0;
|
virtual bool tryAcquire(void* context) = 0;
|
||||||
virtual void acquire(void* id) = 0;
|
virtual void acquire(void* context) = 0;
|
||||||
virtual void release(void* id) = 0;
|
virtual void release(void* context) = 0;
|
||||||
virtual void wait(void* id, int64_t time) = 0;
|
virtual void wait(void* context, int64_t time) = 0;
|
||||||
virtual void notify(void* id) = 0;
|
virtual void notify(void* context) = 0;
|
||||||
virtual void notifyAll(void* id) = 0;
|
virtual void notifyAll(void* context) = 0;
|
||||||
virtual void dispose() = 0;
|
virtual void dispose() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ReadWriteLock {
|
||||||
|
public:
|
||||||
|
ReadWriteLock(System* s): s(s), m(0), readers(0), writer(0) {
|
||||||
|
if (not s->success(s->make(&m))) {
|
||||||
|
s->abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
~ReadWriteLock() {
|
||||||
|
if (readers or writer) {
|
||||||
|
s->abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
m->dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool tryAcquireRead(void* context) {
|
||||||
|
bool result;
|
||||||
|
m->acquire(context);
|
||||||
|
if (writer) {
|
||||||
|
result = false;
|
||||||
|
} else {
|
||||||
|
result = true;
|
||||||
|
++ readers;
|
||||||
|
}
|
||||||
|
m->release(context);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void acquireRead(void* context) {
|
||||||
|
m->acquire(context);
|
||||||
|
while (writer) {
|
||||||
|
m->wait(context, 0);
|
||||||
|
}
|
||||||
|
++ readers;
|
||||||
|
m->release(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
void releaseRead(void* context) {
|
||||||
|
m->acquire(context);
|
||||||
|
if (-- readers == 0) {
|
||||||
|
m->notify(context);
|
||||||
|
}
|
||||||
|
m->release(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool tryAcquireWrite(void* context) {
|
||||||
|
bool result;
|
||||||
|
m->acquire(context);
|
||||||
|
if (readers or writer) {
|
||||||
|
result = false;
|
||||||
|
} else {
|
||||||
|
result = true;
|
||||||
|
writer = context;
|
||||||
|
}
|
||||||
|
m->release(context);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void acquireWrite(void* context) {
|
||||||
|
m->acquire(context);
|
||||||
|
while (readers or writer) {
|
||||||
|
m->wait(context, 0);
|
||||||
|
}
|
||||||
|
writer = context;
|
||||||
|
m->release(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
void releaseWrite(void* context) {
|
||||||
|
if (writer != context) {
|
||||||
|
s->abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
m->acquire(context);
|
||||||
|
writer = 0;
|
||||||
|
m->notifyAll(context);
|
||||||
|
m->release(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
System* s;
|
||||||
|
Monitor* m;
|
||||||
|
unsigned readers;
|
||||||
|
void* writer;
|
||||||
|
};
|
||||||
|
|
||||||
class Library {
|
class Library {
|
||||||
public:
|
public:
|
||||||
virtual ~Library() { }
|
virtual ~Library() { }
|
||||||
|
321
src/vm.cpp
321
src/vm.cpp
@ -11,14 +11,26 @@
|
|||||||
Thread::Protector MAKE_NAME(protector_) (thread, &name);
|
Thread::Protector MAKE_NAME(protector_) (thread, &name);
|
||||||
|
|
||||||
#define ACQUIRE(t, x) MonitorResource MAKE_NAME(monitorResource_) (t, x)
|
#define ACQUIRE(t, x) MonitorResource MAKE_NAME(monitorResource_) (t, x)
|
||||||
|
|
||||||
#define ACQUIRE_RAW(t, x) RawMonitorResource MAKE_NAME(monitorResource_) (t, x)
|
#define ACQUIRE_RAW(t, x) RawMonitorResource MAKE_NAME(monitorResource_) (t, x)
|
||||||
|
|
||||||
|
#define ACQUIRE_READ(t, x) ReadResource MAKE_NAME(readResource_) (t, x)
|
||||||
|
|
||||||
|
#define ACQUIRE_WRITE(t, x) WriteResource MAKE_NAME(writeResource_) (t, x)
|
||||||
|
|
||||||
|
#define ENTER(t, state) StateResource MAKE_NAME(stateResource_) (t, state)
|
||||||
|
|
||||||
using namespace vm;
|
using namespace vm;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
static const bool Verbose = false;
|
const bool Verbose = false;
|
||||||
static const bool Debug = false;
|
const bool Debug = false;
|
||||||
|
|
||||||
|
const uintptr_t HashTakenMark = 1;
|
||||||
|
const uintptr_t ExtendedMark = 2;
|
||||||
|
const uintptr_t MonitorFlag
|
||||||
|
= static_cast<uintptr_t>(1) << ((BytesPerWord * 8) - 1);
|
||||||
|
|
||||||
class Thread;
|
class Thread;
|
||||||
|
|
||||||
@ -73,10 +85,12 @@ class Machine {
|
|||||||
System::Monitor* stateLock;
|
System::Monitor* stateLock;
|
||||||
System::Monitor* heapLock;
|
System::Monitor* heapLock;
|
||||||
System::Monitor* classLock;
|
System::Monitor* classLock;
|
||||||
|
System::ReadWriteLock monitorMapLock;
|
||||||
System::Library* libraries;
|
System::Library* libraries;
|
||||||
object classMap;
|
object classMap;
|
||||||
object bootstrapClassMap;
|
object bootstrapClassMap;
|
||||||
object builtinMap;
|
object builtinMap;
|
||||||
|
object monitorMap;
|
||||||
object types;
|
object types;
|
||||||
bool unsafe;
|
bool unsafe;
|
||||||
JNIEnvVTable jniEnvVTable;
|
JNIEnvVTable jniEnvVTable;
|
||||||
@ -168,13 +182,57 @@ objectClass(Thread*, object o)
|
|||||||
|
|
||||||
void enter(Thread* t, Thread::State state);
|
void enter(Thread* t, Thread::State state);
|
||||||
|
|
||||||
|
class StateResource {
|
||||||
|
public:
|
||||||
|
StateResource(Thread* t, Thread::State state): t(t), oldState(t->state) {
|
||||||
|
enter(t, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
~StateResource() { enter(t, oldState); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
Thread* t;
|
||||||
|
Thread::State oldState;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ReadResource {
|
||||||
|
public:
|
||||||
|
ReadResource(Thread* t, System::ReadWriteLock& lock): t(t), lock(lock) {
|
||||||
|
if (not lock.tryAcquireRead(t)) {
|
||||||
|
ENTER(t, Thread::IdleState);
|
||||||
|
lock.acquireRead(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
~ReadResource() { lock.releaseRead(t); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
Thread* t;
|
||||||
|
System::ReadWriteLock& lock;
|
||||||
|
};
|
||||||
|
|
||||||
|
class WriteResource {
|
||||||
|
public:
|
||||||
|
WriteResource(Thread* t, System::ReadWriteLock& lock): t(t), lock(lock) {
|
||||||
|
if (not lock.tryAcquireWrite(t)) {
|
||||||
|
ENTER(t, Thread::IdleState);
|
||||||
|
lock.acquireWrite(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
~WriteResource() { lock.releaseWrite(t); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
Thread* t;
|
||||||
|
System::ReadWriteLock& lock;
|
||||||
|
};
|
||||||
|
|
||||||
class MonitorResource {
|
class MonitorResource {
|
||||||
public:
|
public:
|
||||||
MonitorResource(Thread* t, System::Monitor* m): t(t), m(m) {
|
MonitorResource(Thread* t, System::Monitor* m): t(t), m(m) {
|
||||||
if (not m->tryAcquire(t)) {
|
if (not m->tryAcquire(t)) {
|
||||||
enter(t, Thread::IdleState);
|
ENTER(t, Thread::IdleState);
|
||||||
m->acquire(t);
|
m->acquire(t);
|
||||||
enter(t, Thread::ActiveState);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -224,6 +282,105 @@ hash(const int8_t* s, unsigned length)
|
|||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
objectExtended(Thread*, object o)
|
||||||
|
{
|
||||||
|
return (cast<uintptr_t>(o, 0) & (~PointerMask)) == ExtendedMark;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uintptr_t&
|
||||||
|
extendedWord(Thread* t, object o, unsigned baseSize)
|
||||||
|
{
|
||||||
|
assert(t, objectExtended(t, o));
|
||||||
|
return cast<uintptr_t>(o, baseSize * BytesPerWord);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned
|
||||||
|
baseSize(Thread* t, object o, object class_)
|
||||||
|
{
|
||||||
|
return divide(classFixedSize(t, class_), BytesPerWord)
|
||||||
|
+ divide(classArrayElementSize(t, class_)
|
||||||
|
* cast<uint32_t>(o, classFixedSize(t, class_) - 4),
|
||||||
|
BytesPerWord);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline unsigned
|
||||||
|
baseSize(Thread* t, object o)
|
||||||
|
{
|
||||||
|
return baseSize(t, o, objectClass(t, o));
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned
|
||||||
|
extendedSize(Thread* t, object o, unsigned baseSize)
|
||||||
|
{
|
||||||
|
unsigned n = baseSize;
|
||||||
|
|
||||||
|
if (objectExtended(t, o)) {
|
||||||
|
if (extendedWord(t, o, n) & MonitorFlag) {
|
||||||
|
n += BytesPerWord;
|
||||||
|
}
|
||||||
|
n += BytesPerWord;
|
||||||
|
}
|
||||||
|
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline unsigned
|
||||||
|
extendedSize(Thread* t, object o)
|
||||||
|
{
|
||||||
|
return extendedSize(t, o, baseSize(t, o));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
monitorAttached(Thread* t, object o, unsigned baseSize)
|
||||||
|
{
|
||||||
|
return objectExtended(t, o)
|
||||||
|
and (extendedWord(t, o, baseSize) & MonitorFlag);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline System::Monitor*&
|
||||||
|
attachedMonitor(Thread* t, object o, unsigned baseSize)
|
||||||
|
{
|
||||||
|
assert(t, monitorAttached(t, o, baseSize));
|
||||||
|
return cast<System::Monitor*>(o, (baseSize + 1) * BytesPerWord);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
hashTaken(Thread*, object o)
|
||||||
|
{
|
||||||
|
return (cast<uintptr_t>(o, 0) & (~PointerMask)) == HashTakenMark;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void
|
||||||
|
markHashTaken(Thread* t, object o)
|
||||||
|
{
|
||||||
|
assert(t, not objectExtended(t, o));
|
||||||
|
cast<uintptr_t>(o, 0) |= HashTakenMark;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint32_t
|
||||||
|
takeHash(Thread*, object o)
|
||||||
|
{
|
||||||
|
return reinterpret_cast<uintptr_t>(o) / BytesPerWord;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint32_t
|
||||||
|
objectHash(Thread* t, object o)
|
||||||
|
{
|
||||||
|
if (objectExtended(t, o)) {
|
||||||
|
return extendedWord(t, o, baseSize(t, o)) & PointerMask;
|
||||||
|
} else {
|
||||||
|
markHashTaken(t, o);
|
||||||
|
return takeHash(t, o);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
objectEqual(Thread*, object a, object b)
|
||||||
|
{
|
||||||
|
return a == b;
|
||||||
|
}
|
||||||
|
|
||||||
inline uint32_t
|
inline uint32_t
|
||||||
byteArrayHash(Thread* t, object array)
|
byteArrayHash(Thread* t, object array)
|
||||||
{
|
{
|
||||||
@ -479,6 +636,7 @@ collect(Machine* m, Heap::CollectionType type)
|
|||||||
v->visit(&(m->classMap));
|
v->visit(&(m->classMap));
|
||||||
v->visit(&(m->bootstrapClassMap));
|
v->visit(&(m->bootstrapClassMap));
|
||||||
v->visit(&(m->builtinMap));
|
v->visit(&(m->builtinMap));
|
||||||
|
v->visit(&(m->monitorMap));
|
||||||
v->visit(&(m->types));
|
v->visit(&(m->types));
|
||||||
|
|
||||||
for (Thread* t = m->rootThread; t; t = t->next) {
|
for (Thread* t = m->rootThread; t; t = t->next) {
|
||||||
@ -486,16 +644,64 @@ collect(Machine* m, Heap::CollectionType type)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual unsigned sizeInWords(void* p) {
|
virtual unsigned sizeInWords(object o) {
|
||||||
Thread* t = m->rootThread;
|
Thread* t = m->rootThread;
|
||||||
|
|
||||||
p = m->heap->follow(mask(p));
|
o = m->heap->follow(mask(o));
|
||||||
object class_ = m->heap->follow(objectClass(t, p));
|
|
||||||
|
|
||||||
return divide(classFixedSize(t, class_), BytesPerWord)
|
return extendedSize
|
||||||
+ divide(classArrayElementSize(t, class_)
|
(t, o, baseSize(t, o, m->heap->follow(objectClass(t, o))));
|
||||||
* cast<uint32_t>(p, classFixedSize(t, class_) - 4),
|
}
|
||||||
BytesPerWord);
|
|
||||||
|
virtual void copy(object o, Heap::Allocator* allocator) {
|
||||||
|
Thread* t = m->rootThread;
|
||||||
|
|
||||||
|
o = m->heap->follow(mask(o));
|
||||||
|
|
||||||
|
unsigned base = baseSize(t, o, m->heap->follow(objectClass(t, o)));
|
||||||
|
unsigned copyCount = base;
|
||||||
|
unsigned allocateCount = base;
|
||||||
|
|
||||||
|
System::Monitor* monitor = 0;
|
||||||
|
|
||||||
|
if (objectExtended(t, o)) {
|
||||||
|
copyCount += BytesPerWord;
|
||||||
|
allocateCount += BytesPerWord;
|
||||||
|
|
||||||
|
if (extendedWord(t, o, base) & MonitorFlag) {
|
||||||
|
copyCount += BytesPerWord;
|
||||||
|
allocateCount += BytesPerWord;
|
||||||
|
} else {
|
||||||
|
monitor = gcHashMapRemove
|
||||||
|
(t, m->monitorMap, o, gcObjectHash, gcObjectEqual);
|
||||||
|
|
||||||
|
if (monitor) {
|
||||||
|
allocateCount += BytesPerWord;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (hashTaken(t, o)) {
|
||||||
|
allocateCount += BytesPerWord;
|
||||||
|
|
||||||
|
monitor = gcHashMapRemove
|
||||||
|
(t, m->monitorMap, o, gcObjectHash, gcObjectEqual);
|
||||||
|
|
||||||
|
if (monitor) {
|
||||||
|
allocateCount += BytesPerWord;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object dst = allocator->allocate(allocateCount);
|
||||||
|
memcpy(o, dst, copyCount * BytesPerWord);
|
||||||
|
|
||||||
|
if (hashTaken(t, o)) {
|
||||||
|
extendedWord(t, dst, base) = takeHash(t, o);
|
||||||
|
cast<uintptr_t>(dst, 0) &= PointerMask;
|
||||||
|
cast<uintptr_t>(dst, 0) |= ExtendedMark;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (monitor) {
|
||||||
|
attachedMonitor(t, dst, base) = monitor;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void walk(void* p, Heap::Walker* w) {
|
virtual void walk(void* p, Heap::Walker* w) {
|
||||||
@ -755,15 +961,41 @@ make(Thread* t, object class_)
|
|||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned
|
System::Monitor*
|
||||||
objectSize(Thread* t, object o)
|
mappedMonitor(Thread* t, object o)
|
||||||
{
|
{
|
||||||
object class_ = objectClass(t, o);
|
PROTECT(t, o);
|
||||||
|
|
||||||
return divide(classFixedSize(t, class_), BytesPerWord)
|
System::Monitor* m = 0;
|
||||||
+ divide(classArrayElementSize(t, class_)
|
{ ACQUIRE_READ(t, t->vm->monitorMapLock);
|
||||||
* cast<uint32_t>(o, classFixedSize(t, class_) - 4),
|
object p = hashMapFind(t, t->vm->monitorMap, o, objectHash, objectEqual);
|
||||||
BytesPerWord);
|
if (p) {
|
||||||
|
m = static_cast<System::Monitor*>(pointerValue(t, p));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m == 0) {
|
||||||
|
System::Status s = t->vm->system->make(&m);
|
||||||
|
expect(t, t->vm->system->success(s));
|
||||||
|
|
||||||
|
object pointer = makePointer(t, m);
|
||||||
|
PROTECT(t, pointer);
|
||||||
|
|
||||||
|
ACQUIRE_WRITE(t, t->vm->monitorMapLock);
|
||||||
|
|
||||||
|
hashMapInsert(t, t->vm->monitorMap, o, pointer, objectHash);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline System::Monitor*
|
||||||
|
objectMonitor(Thread* t, object o)
|
||||||
|
{
|
||||||
|
unsigned base = baseSize(t, o);
|
||||||
|
if (monitorAttached(t, o, base)) {
|
||||||
|
return attachedMonitor(t, o, base);
|
||||||
|
} else {
|
||||||
|
return mappedMonitor(t, o);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object
|
object
|
||||||
@ -1985,9 +2217,9 @@ updateBootstrapClass(Thread* t, object bootstrapClass, object class_)
|
|||||||
PROTECT(t, bootstrapClass);
|
PROTECT(t, bootstrapClass);
|
||||||
PROTECT(t, class_);
|
PROTECT(t, class_);
|
||||||
|
|
||||||
enter(t, Thread::ExclusiveState);
|
ENTER(t, Thread::ExclusiveState);
|
||||||
|
|
||||||
memcpy(bootstrapClass, class_, objectSize(t, class_) * BytesPerWord);
|
memcpy(bootstrapClass, class_, extendedSize(t, class_) * BytesPerWord);
|
||||||
|
|
||||||
object fieldTable = classFieldTable(t, class_);
|
object fieldTable = classFieldTable(t, class_);
|
||||||
if (fieldTable) {
|
if (fieldTable) {
|
||||||
@ -2002,8 +2234,6 @@ updateBootstrapClass(Thread* t, object bootstrapClass, object class_)
|
|||||||
set(t, methodClass(t, arrayBody(t, methodTable, i)), bootstrapClass);
|
set(t, methodClass(t, arrayBody(t, methodTable, i)), bootstrapClass);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enter(t, Thread::ActiveState);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
object
|
object
|
||||||
@ -2369,7 +2599,7 @@ GetStringUTFLength(JNIEnv* e, jstring s)
|
|||||||
{
|
{
|
||||||
Thread* t = static_cast<Thread*>(e);
|
Thread* t = static_cast<Thread*>(e);
|
||||||
|
|
||||||
enter(t, Thread::ActiveState);
|
ENTER(t, Thread::ActiveState);
|
||||||
|
|
||||||
jsize length = 0;
|
jsize length = 0;
|
||||||
if (LIKELY(s)) {
|
if (LIKELY(s)) {
|
||||||
@ -2378,8 +2608,6 @@ GetStringUTFLength(JNIEnv* e, jstring s)
|
|||||||
t->exception = makeNullPointerException(t);
|
t->exception = makeNullPointerException(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
enter(t, Thread::IdleState);
|
|
||||||
|
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2388,7 +2616,7 @@ GetStringUTFChars(JNIEnv* e, jstring s, jboolean* isCopy)
|
|||||||
{
|
{
|
||||||
Thread* t = static_cast<Thread*>(e);
|
Thread* t = static_cast<Thread*>(e);
|
||||||
|
|
||||||
enter(t, Thread::ActiveState);
|
ENTER(t, Thread::ActiveState);
|
||||||
|
|
||||||
char* chars = 0;
|
char* chars = 0;
|
||||||
if (LIKELY(s)) {
|
if (LIKELY(s)) {
|
||||||
@ -2403,8 +2631,6 @@ GetStringUTFChars(JNIEnv* e, jstring s, jboolean* isCopy)
|
|||||||
t->exception = makeNullPointerException(t);
|
t->exception = makeNullPointerException(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
enter(t, Thread::IdleState);
|
|
||||||
|
|
||||||
if (isCopy) *isCopy = true;
|
if (isCopy) *isCopy = true;
|
||||||
return chars;
|
return chars;
|
||||||
}
|
}
|
||||||
@ -2428,10 +2654,12 @@ Machine::Machine(System* system, Heap* heap, ClassFinder* classFinder):
|
|||||||
stateLock(0),
|
stateLock(0),
|
||||||
heapLock(0),
|
heapLock(0),
|
||||||
classLock(0),
|
classLock(0),
|
||||||
|
monitorMapLock(system),
|
||||||
libraries(0),
|
libraries(0),
|
||||||
classMap(0),
|
classMap(0),
|
||||||
bootstrapClassMap(0),
|
bootstrapClassMap(0),
|
||||||
builtinMap(0),
|
builtinMap(0),
|
||||||
|
monitorMap(0),
|
||||||
types(0),
|
types(0),
|
||||||
unsafe(false)
|
unsafe(false)
|
||||||
{
|
{
|
||||||
@ -2505,6 +2733,7 @@ Thread::Thread(Machine* m):
|
|||||||
|
|
||||||
m->classMap = makeHashMap(this, 0, 0);
|
m->classMap = makeHashMap(this, 0, 0);
|
||||||
m->builtinMap = makeHashMap(this, 0, 0);
|
m->builtinMap = makeHashMap(this, 0, 0);
|
||||||
|
m->monitorMap = makeHashMap(this, 0, 0);
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
const char* key;
|
const char* key;
|
||||||
@ -3635,25 +3864,25 @@ run(Thread* t)
|
|||||||
push(t, makeLong(t, longValue(t, a) ^ longValue(t, b)));
|
push(t, makeLong(t, longValue(t, a) ^ longValue(t, b)));
|
||||||
} goto loop;
|
} goto loop;
|
||||||
|
|
||||||
// case monitorenter: {
|
case monitorenter: {
|
||||||
// object o = pop(t);
|
object o = pop(t);
|
||||||
// if (LIKELY(o)) {
|
if (LIKELY(o)) {
|
||||||
// objectMonitor(t, o)->acquire(t);
|
objectMonitor(t, o)->acquire(t);
|
||||||
// } else {
|
} else {
|
||||||
// exception = makeNullPointerException(t);
|
exception = makeNullPointerException(t);
|
||||||
// goto throw_;
|
goto throw_;
|
||||||
// }
|
}
|
||||||
// } goto loop;
|
} goto loop;
|
||||||
|
|
||||||
// case monitorexit: {
|
case monitorexit: {
|
||||||
// object o = pop(t);
|
object o = pop(t);
|
||||||
// if (LIKELY(o)) {
|
if (LIKELY(o)) {
|
||||||
// objectMonitor(t, o)->release(t);
|
objectMonitor(t, o)->release(t);
|
||||||
// } else {
|
} else {
|
||||||
// exception = makeNullPointerException(t);
|
exception = makeNullPointerException(t);
|
||||||
// goto throw_;
|
goto throw_;
|
||||||
// }
|
}
|
||||||
// } goto loop;
|
} goto loop;
|
||||||
|
|
||||||
case new_: {
|
case new_: {
|
||||||
uint8_t index1 = codeBody(t, code, ip++);
|
uint8_t index1 = codeBody(t, code, ip++);
|
||||||
|
Loading…
Reference in New Issue
Block a user