handle weak maps properly in hashMapResize, hashMapRemove, etc.; move Processor::parameterFootprint() into machine.h/machine.cpp

This commit is contained in:
Joel Dice 2007-11-20 15:24:02 -07:00
parent 6fe0c4636f
commit a017dab73a
5 changed files with 340 additions and 38 deletions

View File

@ -2476,4 +2476,293 @@ compile(MyThread* t, Compiler* compiler, object method)
return result; return result;
} }
class MyProcessor: public Processor {
public:
MyProcessor(System* s):
s(s)
{ }
virtual Thread*
makeThread(Machine* m, object javaThread, Thread* parent)
{
MyThread* t = new (s->allocate(sizeof(Thread)))
MyThread(m, javaThread, parent);
t->init();
return t;
}
virtual object
makeMethod(vm::Thread* t,
uint8_t vmFlags,
uint8_t returnCode,
uint8_t parameterCount,
uint8_t parameterFootprint,
uint16_t flags,
uint16_t offset,
object name,
object spec,
object class_,
object code)
{
object compiled
= ((flags & ACC_NATIVE) ? nativeCompiled : defaultCompiled);
return vm::makeMethod
(t, vmFlags, returnCode, parameterCount, parameterFootprint, flags,
offset, name, spec, class_, code, compiled);
}
virtual object
makeClass(vm::Thread* t,
uint16_t flags,
uint8_t vmFlags,
uint8_t arrayDimensions,
uint16_t fixedSize,
uint16_t arrayElementSize,
object objectMask,
object name,
object super,
object interfaceTable,
object virtualTable,
object fieldTable,
object methodTable,
object staticTable,
object loader,
unsigned vtableLength)
{
object c = vm::makeClass
(t, flags, vmFlags, arrayDimensions, fixedSize, arrayElementSize,
objectMask, name, super, interfaceTable, virtualTable, fieldTable,
methodTable, staticTable, loader, vtableLength, false);
for (unsigned i = 0; i < vtableLength; ++i) {
object compiled
= ((flags & ACC_NATIVE) ? nativeCompiled : defaultCompiled);
classVtable(t, c, i) = &singletonBody(t, compiled, 0);
}
return c;
}
virtual void
initClass(Thread* t, object c)
{
PROTECT(t, c);
ACQUIRE(t, t->m->classLock);
if (classVmFlags(t, c) & NeedInitFlag
and (classVmFlags(t, c) & InitFlag) == 0)
{
classVmFlags(t, c) |= InitFlag;
invoke(t, classInitializer(t, c), 0);
if (t->exception) {
t->exception = makeExceptionInInitializerError(t, t->exception);
}
classVmFlags(t, c) &= ~(NeedInitFlag | InitFlag);
}
}
virtual void
visitObjects(Thread* vmt, Heap::Visitor* v)
{
MyThread* t = static_cast<MyThread*>(vmt);
if (t == t->m->rootThread) {
visit(&defaultCompiled);
visit(&nativeCompiled);
visit(&addressTree);
}
for (Reference* r = t->reference; r; r = r->next) {
v->visit(&(r->target));
}
visitStack(t, v);
}
virtual uintptr_t
frameStart(Thread* vmt)
{
return reinterpret_cast<uintptr_t>
(::frameStart(static_cast<MyThread*>(vmt)));
}
virtual uintptr_t
frameNext(Thread*, uintptr_t frame)
{
return reinterpret_cast<uintptr_t>
(::frameNext(reinterpret_cast<void*>(frame)));
}
virtual bool
frameValid(Thread*, uintptr_t frame)
{
return ::frameValid(reinterpret_cast<void*>(frame));
}
virtual object
frameMethod(Thread*, uintptr_t frame)
{
return ::frameMethod(reinterpret_cast<void*>(frame));
}
virtual unsigned
frameIp(Thread* t, uintptr_t frame)
{
void* f = reinterpret_cast<void*>(frame);
return addressOffset(t, ::frameMethod(f), ::frameAddress(f));
}
virtual int
lineNumber(Thread* t, object method, unsigned ip)
{
if (methodFlags(t, method) & ACC_NATIVE) {
return NativeLine;
}
Compiled* code = reinterpret_cast<Compiled*>(methodCompiled(t, method));
if (compiledLineNumberCount(t, code)) {
unsigned bottom = 0;
unsigned top = compiledLineNumberCount(t, code);
for (unsigned span = top - bottom; span; span = top - bottom) {
unsigned middle = bottom + (span / 2);
NativeLineNumber* ln = compiledLineNumber(t, code, middle);
if (ip >= nativeLineNumberIp(ln)
and (middle + 1 == compiledLineNumberCount(t, code)
or ip < nativeLineNumberIp
(compiledLineNumber(t, code, middle + 1))))
{
return nativeLineNumberLine(ln);
} else if (ip < nativeLineNumberIp(ln)) {
top = middle;
} else if (ip > nativeLineNumberIp(ln)) {
bottom = middle + 1;
}
}
abort(t);
} else {
return UnknownLine;
}
}
virtual object*
makeLocalReference(Thread* vmt, object o)
{
if (o) {
MyThread* t = static_cast<MyThread*>(vmt);
Reference* r = new (t->m->system->allocate(sizeof(Reference)))
Reference(o, &(t->reference));
return &(r->target);
} else {
return 0;
}
}
virtual void
disposeLocalReference(Thread* t, object* r)
{
if (r) {
vm::dispose(t, reinterpret_cast<Reference*>(r));
}
}
virtual object
invokeArray(Thread* t, object method, object this_, object arguments)
{
assert(t, t->state == Thread::ActiveState
or t->state == Thread::ExclusiveState);
assert(t, ((methodFlags(t, method) & ACC_STATIC) == 0) xor (this_ == 0));
const char* spec = reinterpret_cast<char*>
(&byteArrayBody(t, methodSpec(t, method), 0));
unsigned size = methodParameterFootprint(t, method) + FrameFootprint;
uintptr_t array[size];
bool objectMask[size];
ArgumentList list(t, array, objectMask, this_, spec, arguments);
return ::invoke(t, method, &list);
}
virtual object
invokeList(Thread* t, object method, object this_, bool indirectObjects,
va_list arguments)
{
assert(t, t->state == Thread::ActiveState
or t->state == Thread::ExclusiveState);
assert(t, ((methodFlags(t, method) & ACC_STATIC) == 0) xor (this_ == 0));
const char* spec = reinterpret_cast<char*>
(&byteArrayBody(t, methodSpec(t, method), 0));
unsigned size = methodParameterFootprint(t, method) + FrameFootprint;
uintptr_t array[size];
bool objectMask[size];
ArgumentList list
(t, array, objectMask, this_, spec, indirectObjects, arguments);
return ::invoke(t, method, &list);
}
virtual object
invokeList(Thread* t, const char* className, const char* methodName,
const char* methodSpec, object this_, va_list arguments)
{
assert(t, t->state == Thread::ActiveState
or t->state == Thread::ExclusiveState);
unsigned size = parameterFootprint(t, methodSpec, false) + FrameFootprint;
uintptr_t array[size];
bool objectMask[size];
ArgumentList list
(t, array, objectMask, this_, methodSpec, false, arguments);
object method = resolveMethod(t, className, methodName, methodSpec);
if (LIKELY(t->exception == 0)) {
assert(t, ((methodFlags(t, method) & ACC_STATIC) == 0) xor (this_ == 0));
return ::invoke(t, method, &list);
} else {
return 0;
}
}
virtual void dispose() {
if (methodStub_) {
s->free(methodStub_);
}
if (nativeInvoker_) {
s->free(nativeInvoker_);
}
if (caller_) {
s->free(caller_);
}
s->free(this);
}
System* s;
Compiled* methodStub_;
Compiled* nativeInvoker_;
Compiled* caller_;
};
} // namespace } // namespace
namespace vm {
Processor*
makeProcessor(System* system)
{
return new (system->allocate(sizeof(MyProcessor))) MyProcessor(system);
}
} // namespace vm

View File

@ -2870,29 +2870,6 @@ class MyProcessor: public Processor {
methodTable, staticTable, loader, 0, false); methodTable, staticTable, loader, 0, false);
} }
virtual unsigned
parameterFootprint(vm::Thread* t, const char* s, bool static_)
{
unsigned footprint = 0;
for (MethodSpecIterator it(t, s); it.hasNext();) {
switch (*it.next()) {
case 'J':
case 'D':
footprint += 2;
break;
default:
++ footprint;
break;
}
}
if (not static_) {
++ footprint;
}
return footprint;
}
virtual void virtual void
initClass(vm::Thread* t, object c) initClass(vm::Thread* t, object c)
{ {

View File

@ -1212,15 +1212,12 @@ parseMethodTable(Thread* t, Stream& s, object class_, object pool)
unsigned returnCode; unsigned returnCode;
scanMethodSpec(t, specString, &parameterCount, &returnCode); scanMethodSpec(t, specString, &parameterCount, &returnCode);
unsigned parameterFootprint = t->m->processor->parameterFootprint
(t, specString, flags & ACC_STATIC);
object method = t->m->processor->makeMethod object method = t->m->processor->makeMethod
(t, (t,
0, // vm flags 0, // vm flags
returnCode, returnCode,
parameterCount, parameterCount,
parameterFootprint, parameterFootprint(t, specString, flags & ACC_STATIC),
flags, flags,
0, // offset 0, // offset
singletonObject(t, pool, name - 1), singletonObject(t, pool, name - 1),
@ -2244,6 +2241,9 @@ hashMapFindNode(Thread* t, object map, object key,
object k = tripleFirst(t, n); object k = tripleFirst(t, n);
if (weak) { if (weak) {
k = jreferenceTarget(t, k); k = jreferenceTarget(t, k);
if (k == 0) {
continue;
}
} }
if (equal(t, key, k)) { if (equal(t, key, k)) {
@ -2285,6 +2285,9 @@ hashMapResize(Thread* t, object map, uint32_t (*hash)(Thread*, object),
object k = tripleFirst(t, p); object k = tripleFirst(t, p);
if (weak) { if (weak) {
k = jreferenceTarget(t, k); k = jreferenceTarget(t, k);
if (k == 0) {
continue;
}
} }
unsigned index = hash(t, k) & (newLength - 1); unsigned index = hash(t, k) & (newLength - 1);
@ -2337,6 +2340,19 @@ hashMapInsert(Thread* t, object map, object key, object value,
set(t, array, ArrayBody + (index * BytesPerWord), n); set(t, array, ArrayBody + (index * BytesPerWord), n);
} }
object
hashMapRemoveNode(Thread* t, object map, unsigned index, object p, object n)
{
if (p) {
set(t, p, TripleThird, tripleThird(t, n));
} else {
set(t, hashMapArray(t, map), ArrayBody + (index * BytesPerWord),
tripleThird(t, n));
}
-- hashMapSize(t, map);
return n;
}
object object
hashMapRemove(Thread* t, object map, object key, hashMapRemove(Thread* t, object map, object key,
uint32_t (*hash)(Thread*, object), uint32_t (*hash)(Thread*, object),
@ -2354,17 +2370,14 @@ hashMapRemove(Thread* t, object map, object key,
object k = tripleFirst(t, n); object k = tripleFirst(t, n);
if (weak) { if (weak) {
k = jreferenceTarget(t, k); k = jreferenceTarget(t, k);
if (k == 0) {
n = tripleThird(t, hashMapRemoveNode(t, map, index, p, n));
continue;
}
} }
if (equal(t, key, k)) { if (equal(t, key, k)) {
o = tripleSecond(t, n); o = tripleSecond(t, hashMapRemoveNode(t, map, index, p, n));
if (p) {
set(t, p, TripleThird, tripleThird(t, n));
} else {
set(t, array, ArrayBody + (index * BytesPerWord),
tripleThird(t, n));
}
-- hashMapSize(t, map);
break; break;
} else { } else {
p = n; p = n;
@ -2825,6 +2838,29 @@ findInHierarchy(Thread* t, object class_, object name, object spec,
return o; return o;
} }
unsigned
parameterFootprint(Thread* t, const char* s, bool static_)
{
unsigned footprint = 0;
for (MethodSpecIterator it(t, s); it.hasNext();) {
switch (*it.next()) {
case 'J':
case 'D':
footprint += 2;
break;
default:
++ footprint;
break;
}
}
if (not static_) {
++ footprint;
}
return footprint;
}
void void
addFinalizer(Thread* t, object target, void (*finalize)(Thread*, object)) addFinalizer(Thread* t, object target, void (*finalize)(Thread*, object))
{ {

View File

@ -2062,6 +2062,9 @@ objectArrayBody(Thread* t UNUSED, object array, unsigned index)
return cast<object>(array, (2 + index) * BytesPerWord); return cast<object>(array, (2 + index) * BytesPerWord);
} }
unsigned
parameterFootprint(Thread* t, const char* s, bool static_);
void void
addFinalizer(Thread* t, object target, void (*finalize)(Thread*, object)); addFinalizer(Thread* t, object target, void (*finalize)(Thread*, object));

View File

@ -45,9 +45,6 @@ class Processor {
object loader, object loader,
unsigned vtableLength) = 0; unsigned vtableLength) = 0;
virtual unsigned
parameterFootprint(Thread* t, const char* spec, bool static_) = 0;
virtual void virtual void
initClass(Thread* t, object c) = 0; initClass(Thread* t, object c) = 0;