bugfixes for recent refactoring effort

This commit is contained in:
Joel Dice 2007-09-24 07:46:48 -06:00
parent 8d983c8a39
commit 1c90708abf
7 changed files with 235 additions and 219 deletions

View File

@ -32,7 +32,7 @@ src = src
classpath = classpath classpath = classpath
test = test test = test
input = $(cls)/Hello.class input = $(cls)/Threads.class
cxx = g++ cxx = g++
cc = gcc cc = gcc

View File

@ -308,11 +308,12 @@ Java_java_lang_reflect_Method_getCaller(Thread* t, jclass)
{ {
ENTER(t, Thread::ActiveState); ENTER(t, Thread::ActiveState);
FrameIterator it; t->m->processor->start(t, &it); Processor* p = t->m->processor;
t->m->processor->next(t, &it); uintptr_t frame = p->frameStart(t);
t->m->processor->next(t, &it); frame = p->frameNext(t, frame);
frame = p->frameNext(t, frame);
return makeLocalReference(t, it.method); return makeLocalReference(t, p->frameMethod(t, frame));
} }
extern "C" JNIEXPORT jobject JNICALL extern "C" JNIEXPORT jobject JNICALL
@ -321,7 +322,7 @@ Java_java_lang_reflect_Method_invoke
{ {
ENTER(t, Thread::ActiveState); ENTER(t, Thread::ActiveState);
object v = t->m->processor->invoke object v = t->m->processor->invokeArray
(t, *method, (instance ? *instance : 0), *arguments); (t, *method, (instance ? *instance : 0), *arguments);
if (t->exception) { if (t->exception) {
t->exception = makeInvocationTargetException(t, t->exception); t->exception = makeInvocationTargetException(t, t->exception);
@ -529,25 +530,27 @@ Java_java_lang_Throwable_trace(Thread* t, jclass, jint skipCount)
{ {
ENTER(t, Thread::ActiveState); ENTER(t, Thread::ActiveState);
FrameIterator it; t->m->processor->start(t, &it); Processor* p = t->m->processor;
uintptr_t frame = p->frameStart(t);
while (skipCount-- and it.valid()) { while (skipCount-- and p->frameValid(t, frame)) {
t->m->processor->next(t, &it); frame = p->frameNext(t, frame);
} }
// skip Throwable constructors // skip Throwable constructors
while (it.valid() while (p->frameValid(t, frame)
and isAssignableFrom and isAssignableFrom
(t, arrayBody(t, t->m->types, Machine::ThrowableType), (t, arrayBody(t, t->m->types, Machine::ThrowableType),
methodClass(t, it.method)) methodClass(t, p->frameMethod(t, frame)))
and strcmp(reinterpret_cast<const int8_t*>("<init>"), and strcmp(reinterpret_cast<const int8_t*>("<init>"),
&byteArrayBody(t, methodName(t, it.method), 0)) &byteArrayBody
(t, methodName(t, p->frameMethod(t, frame)), 0))
== 0) == 0)
{ {
t->m->processor->next(t, &it); frame = p->frameNext(t, frame);
} }
return makeLocalReference(t, makeTrace(t, &it)); return makeLocalReference(t, makeTrace(t, frame));
} }
extern "C" JNIEXPORT jarray JNICALL extern "C" JNIEXPORT jarray JNICALL
@ -599,8 +602,7 @@ Java_java_lang_Thread_doStart(Thread* t, jobject this_)
{ {
ENTER(t, Thread::ActiveState); ENTER(t, Thread::ActiveState);
Thread* p = new (t->m->system->allocate(sizeof(Thread))) Thread* p = t->m->processor->makeThread(t->m, *this_, t);
Thread(t->m, *this_, t);
enter(p, Thread::ActiveState); enter(p, Thread::ActiveState);

View File

@ -28,45 +28,6 @@ class Thread: public vm::Thread {
uintptr_t stack[StackSizeInWords]; uintptr_t stack[StackSizeInWords];
}; };
class MyProcessor: public Processor {
public:
MyProcessor(System* s):
s(s)
{ }
virtual vm::Thread*
makeThread(Machine* m, object javaThread, vm::Thread* parent)
{
return new (s->allocate(sizeof(Thread))) Thread(m, javaThread, parent);
}
virtual void
visitObjects(vm::Thread* t, Heap::Visitor* v);
virtual void
start(vm::Thread* t, FrameIterator* it);
virtual void
next(vm::Thread* t, FrameIterator* it);
virtual object
invokeArray(vm::Thread* t, object method, object this_, object arguments);
virtual object
invokeList(vm::Thread* t, object method, object this_, bool indirectObjects,
va_list arguments);
virtual object
invokeList(vm::Thread* t, const char* className, const char* methodName,
const char* methodSpec, object this_, va_list arguments);
virtual void dispose() {
s->free(this);
}
System* s;
};
inline void inline void
pushObject(Thread* t, object o) pushObject(Thread* t, object o)
{ {
@ -3039,127 +3000,176 @@ invoke(Thread* t, object method)
} }
} }
void class MyProcessor: public Processor {
MyProcessor::visitObjects(vm::Thread* vmt, Heap::Visitor* v) public:
{ MyProcessor(System* s):
Thread* t = static_cast<Thread*>(vmt); s(s)
{ }
v->visit(&(t->code)); virtual vm::Thread*
makeThread(Machine* m, object javaThread, vm::Thread* parent)
{
return new (s->allocate(sizeof(Thread))) Thread(m, javaThread, parent);
}
for (unsigned i = 0; i < t->sp; ++i) { virtual void
if (t->stack[i * 2] == ObjectTag) { visitObjects(vm::Thread* vmt, Heap::Visitor* v)
v->visit(t->stack + (i * 2) + 1); {
Thread* t = static_cast<Thread*>(vmt);
v->visit(&(t->code));
for (unsigned i = 0; i < t->sp; ++i) {
if (t->stack[i * 2] == ObjectTag) {
v->visit(t->stack + (i * 2) + 1);
}
} }
} }
}
void virtual uintptr_t
MyProcessor::start(vm::Thread* vmt, FrameIterator* it) frameStart(vm::Thread* vmt)
{ {
Thread* t = static_cast<Thread*>(vmt); Thread* t = static_cast<Thread*>(vmt);
int f = t->frame; if (t->frame >= 0) {
it->base = f + 1; pokeInt(t, t->frame + FrameIpOffset, t->ip);
if (it->valid()) { }
pokeInt(t, t->frame + FrameIpOffset, t->ip); return t->frame;
it->method = frameMethod(t, f);
it->ip = frameIp(t, f);
} }
}
void virtual uintptr_t
MyProcessor::next(vm::Thread* vmt, FrameIterator* it) frameNext(vm::Thread* vmt, uintptr_t frame)
{ {
Thread* t = static_cast<Thread*>(vmt); Thread* t = static_cast<Thread*>(vmt);
if (it->valid()) { assert(t, static_cast<intptr_t>(frame) >= 0);
int f = frameNext(t, it->base - 1); return ::frameNext(t, frame);
it->base = f + 1; }
if (it->valid()) {
it->method = frameMethod(t, f); virtual bool
it->ip = frameIp(t, f); frameValid(vm::Thread*, uintptr_t frame)
{
return static_cast<intptr_t>(frame) >= 0;
}
virtual object
frameMethod(vm::Thread* vmt, uintptr_t frame)
{
Thread* t = static_cast<Thread*>(vmt);
assert(t, static_cast<intptr_t>(frame) >= 0);
return ::frameMethod(t, frame);
}
virtual unsigned
frameIp(vm::Thread* vmt, uintptr_t frame)
{
Thread* t = static_cast<Thread*>(vmt);
assert(t, static_cast<intptr_t>(frame) >= 0);
return ::frameIp(t, frame);
}
virtual object*
makeLocalReference(vm::Thread* vmt, object o)
{
Thread* t = static_cast<Thread*>(vmt);
return pushReference(t, o);
}
virtual void
disposeLocalReference(vm::Thread*, object* r)
{
if (r) {
*r = 0;
} }
} }
}
object virtual object
MyProcessor::invokeArray(vm::Thread* vmt, object method, object this_, invokeArray(vm::Thread* vmt, object method, object this_, object arguments)
object arguments)
{
Thread* t = static_cast<Thread*>(vmt);
assert(t, t->state == Thread::ActiveState
or t->state == Thread::ExclusiveState);
assert(t, ((methodFlags(t, method) & ACC_STATIC) == 0) xor (this_ == 0));
if (UNLIKELY(t->sp + methodParameterFootprint(t, method) + 1
> Thread::StackSizeInWords / 2))
{ {
t->exception = makeStackOverflowError(t); Thread* t = static_cast<Thread*>(vmt);
return 0;
}
const char* spec = reinterpret_cast<char*> assert(t, t->state == Thread::ActiveState
(&byteArrayBody(t, methodSpec(t, method), 0)); or t->state == Thread::ExclusiveState);
pushArguments(t, this_, spec, arguments);
return ::invoke(t, method);
}
object
MyProcessor::invokeList(vm::Thread* vmt, object method, object this_,
bool indirectObjects, va_list arguments)
{
Thread* t = static_cast<Thread*>(vmt);
assert(t, t->state == Thread::ActiveState
or t->state == Thread::ExclusiveState);
assert(t, ((methodFlags(t, method) & ACC_STATIC) == 0) xor (this_ == 0));
if (UNLIKELY(t->sp + methodParameterFootprint(t, method) + 1
> Thread::StackSizeInWords / 2))
{
t->exception = makeStackOverflowError(t);
return 0;
}
const char* spec = reinterpret_cast<char*>
(&byteArrayBody(t, methodSpec(t, method), 0));
pushArguments(t, this_, spec, indirectObjects, arguments);
return ::invoke(t, method);
}
object
MyProcessor::invokeList(vm::Thread* vmt, const char* className,
const char* methodName, const char* methodSpec,
object this_, va_list arguments)
{
Thread* t = static_cast<Thread*>(vmt);
assert(t, t->state == Thread::ActiveState
or t->state == Thread::ExclusiveState);
if (UNLIKELY(t->sp + parameterFootprint(methodSpec) + 1
> Thread::StackSizeInWords / 2))
{
t->exception = makeStackOverflowError(t);
return 0;
}
pushArguments(t, 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)); assert(t, ((methodFlags(t, method) & ACC_STATIC) == 0) xor (this_ == 0));
if (UNLIKELY(t->sp + methodParameterFootprint(t, method) + 1
> Thread::StackSizeInWords / 2))
{
t->exception = makeStackOverflowError(t);
return 0;
}
const char* spec = reinterpret_cast<char*>
(&byteArrayBody(t, methodSpec(t, method), 0));
pushArguments(t, this_, spec, arguments);
return ::invoke(t, method); return ::invoke(t, method);
} else {
return 0;
} }
}
virtual object
invokeList(vm::Thread* vmt, object method, object this_,
bool indirectObjects,
va_list arguments)
{
Thread* t = static_cast<Thread*>(vmt);
assert(t, t->state == Thread::ActiveState
or t->state == Thread::ExclusiveState);
assert(t, ((methodFlags(t, method) & ACC_STATIC) == 0) xor (this_ == 0));
if (UNLIKELY(t->sp + methodParameterFootprint(t, method) + 1
> Thread::StackSizeInWords / 2))
{
t->exception = makeStackOverflowError(t);
return 0;
}
const char* spec = reinterpret_cast<char*>
(&byteArrayBody(t, methodSpec(t, method), 0));
pushArguments(t, this_, spec, indirectObjects, arguments);
return ::invoke(t, method);
}
virtual object
invokeList(vm::Thread* vmt, const char* className, const char* methodName,
const char* methodSpec, object this_, va_list arguments)
{
Thread* t = static_cast<Thread*>(vmt);
assert(t, t->state == Thread::ActiveState
or t->state == Thread::ExclusiveState);
if (UNLIKELY(t->sp + parameterFootprint(methodSpec) + 1
> Thread::StackSizeInWords / 2))
{
t->exception = makeStackOverflowError(t);
return 0;
}
pushArguments(t, 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);
} else {
return 0;
}
}
virtual void dispose() {
s->free(this);
}
System* s;
};
} // namespace } // namespace

View File

@ -2752,21 +2752,28 @@ run(System* system, Heap* heap, Finder* finder, Processor* processor,
} }
object object
makeTrace(Thread* t, FrameIterator* it) makeTrace(Thread* t, uintptr_t start)
{ {
Processor* p = t->m->processor;
unsigned count = 0; unsigned count = 0;
FrameIterator copy(it); for (uintptr_t frame = start;
while (copy.valid()) { p->frameValid(t, frame);
frame = p->frameNext(t, frame))
{
++ count; ++ count;
t->m->processor->next(t, &copy);
} }
object trace = makeArray(t, count, true); object trace = makeArray(t, count, true);
PROTECT(t, trace); PROTECT(t, trace);
unsigned index = 0; unsigned index = 0;
while (it->valid()) { for (uintptr_t frame = start;
object e = makeTraceElement(t, it->method, it->ip); p->frameValid(t, frame);
frame = p->frameNext(t, frame))
{
object e = makeTraceElement
(t, p->frameMethod(t, frame), p->frameIp(t, frame));
set(t, arrayBody(t, trace, index++), e); set(t, arrayBody(t, trace, index++), e);
} }

View File

@ -1423,13 +1423,12 @@ arrayBodyUnsafe(Thread*, object, unsigned);
#include "type-declarations.cpp" #include "type-declarations.cpp"
object object
makeTrace(Thread* t, FrameIterator* it); makeTrace(Thread* t, uintptr_t start);
inline object inline object
makeTrace(Thread* t) makeTrace(Thread* t)
{ {
FrameIterator it; t->m->processor->start(t, &it); return makeTrace(t, t->m->processor->frameStart(t));
return makeTrace(t, &it);
} }
inline object inline object
@ -2054,11 +2053,17 @@ int
run(System* system, Heap* heap, Finder* finder, Processor* processor, run(System* system, Heap* heap, Finder* finder, Processor* processor,
const char* className, int argc, const char** argv); const char* className, int argc, const char** argv);
jobject inline jobject
makeLocalReference(Thread* t, object o); makeLocalReference(Thread* t, object o)
{
return t->m->processor->makeLocalReference(t, o);
}
void inline void
disposeLocalReference(Thread* t, jobject r); disposeLocalReference(Thread* t, jobject r)
{
t->m->processor->disposeLocalReference(t, r);
}
} // namespace vm } // namespace vm

View File

@ -7,29 +7,6 @@
namespace vm { namespace vm {
class FrameIterator {
public:
FrameIterator():
base(0),
method(0),
ip(0)
{ }
FrameIterator(FrameIterator* it):
base(it->base),
method(it->method),
ip(it->ip)
{ }
bool valid() {
return base != 0;
}
uintptr_t base;
object method;
unsigned ip;
};
class Processor { class Processor {
public: public:
virtual ~Processor() { } virtual ~Processor() { }
@ -40,11 +17,26 @@ class Processor {
virtual void virtual void
visitObjects(Thread* t, Heap::Visitor* v) = 0; visitObjects(Thread* t, Heap::Visitor* v) = 0;
virtual void virtual uintptr_t
start(Thread* t, FrameIterator* it) = 0; frameStart(Thread* t) = 0;
virtual void virtual uintptr_t
next(Thread* t, FrameIterator* it) = 0; frameNext(Thread* t, uintptr_t frame) = 0;
virtual bool
frameValid(Thread* t, uintptr_t frame) = 0;
virtual object
frameMethod(Thread* t, uintptr_t frame) = 0;
virtual unsigned
frameIp(Thread* t, uintptr_t frame) = 0;
virtual object*
makeLocalReference(Thread* t, object o) = 0;
virtual void
disposeLocalReference(Thread* t, object* r) = 0;
virtual object virtual object
invokeArray(Thread* t, object method, object this_, object arguments) = 0; invokeArray(Thread* t, object method, object this_, object arguments) = 0;

View File

@ -17,28 +17,28 @@
obj:/lib/ld-2.3.6.so obj:/lib/ld-2.3.6.so
} }
{ # {
<insert a suppression name here> # <insert a suppression name here>
Memcheck:Param # Memcheck:Param
write(buf) # write(buf)
obj:* # obj:*
} # }
{ # {
<insert a suppression name here> # <insert a suppression name here>
Memcheck:Param # Memcheck:Param
writev(vector[...]) # writev(vector[...])
obj:* # obj:*
} # }
{ # {
<insert a suppression name here> # <insert a suppression name here>
Memcheck:Cond # Memcheck:Cond
obj:* # obj:*
} # }
{ # {
<insert a suppression name here> # <insert a suppression name here>
Memcheck:Value8 # Memcheck:Value8
obj:* # obj:*
} # }