From 61f866ce89ff3a06ac6cb2f5f7bfaa0ae3216a02 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Sun, 20 Apr 2008 10:21:32 -0600 Subject: [PATCH 01/17] do a garbage collection in compile.cpp if throwing an exception that required creating a backup heap --- src/compile.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/compile.cpp b/src/compile.cpp index 242a5f2984..d7c1e24b4f 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -4594,6 +4594,13 @@ invoke(Thread* thread, object method, ArgumentList* arguments) arguments->position, returnType); } + if (t->exception) { + if (t->backupHeap) { + collect(t, Heap::MinorCollection); + } + return 0; + } + object r; switch (returnCode) { case ByteField: From 8c450a75a10ec7fcface59506b90ee569c1ca725 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Mon, 21 Apr 2008 11:29:36 -0600 Subject: [PATCH 02/17] do all java->native class via Compiler::indirectCall to ensure we can always make an accurate stack trace --- src/compile.cpp | 80 +++++++++++++++++++++++++----------------------- src/compiler.cpp | 27 +++++++++++----- src/compiler.h | 2 ++ 3 files changed, 64 insertions(+), 45 deletions(-) diff --git a/src/compile.cpp b/src/compile.cpp index d7c1e24b4f..5702ca48d6 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -2062,7 +2062,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, case d2f: { Operand* a = frame->popLong(); - c->directCall + c->indirectCall (c->constant(reinterpret_cast(doubleToFloat)), 2, 0, a); c->release(a); @@ -2074,7 +2074,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, case d2i: { Operand* a = frame->popLong(); - c->directCall + c->indirectCall (c->constant(reinterpret_cast(doubleToInt)), 2, 0, a); c->release(a); @@ -2086,7 +2086,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, case d2l: { Operand* a = frame->popLong(); - c->directCall + c->indirectCall (c->constant(reinterpret_cast(doubleToLong)), 2, 0, a); c->release(a); @@ -2099,7 +2099,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, Operand* a = frame->popLong(); Operand* b = frame->popLong(); - c->directCall + c->indirectCall (c->constant(reinterpret_cast(addDouble)), 4, 0, a, 0, b); c->release(a); c->release(b); @@ -2113,7 +2113,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, Operand* a = frame->popLong(); Operand* b = frame->popLong(); - c->directCall + c->indirectCall (c->constant(reinterpret_cast(compareDoublesG)), 4, 0, a, 0, b); c->release(a); @@ -2128,7 +2128,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, Operand* a = frame->popLong(); Operand* b = frame->popLong(); - c->directCall + c->indirectCall (c->constant(reinterpret_cast(compareDoublesL)), 4, 0, a, 0, b); c->release(a); @@ -2151,7 +2151,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, Operand* a = frame->popLong(); Operand* b = frame->popLong(); - c->directCall + c->indirectCall (c->constant(reinterpret_cast(divideDouble)), 4, 0, a, 0, b); c->release(a); @@ -2166,7 +2166,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, Operand* a = frame->popLong(); Operand* b = frame->popLong(); - c->directCall + c->indirectCall (c->constant(reinterpret_cast(multiplyDouble)), 4, 0, a, 0, b); c->release(a); @@ -2180,8 +2180,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, case dneg: { Operand* a = frame->popLong(); - c->directCall - (c->constant(reinterpret_cast(negateDouble)), 2, 0, a); + c->indirectCall + (c->constant(reinterpret_cast(negateDouble)), 0, 2, 0, a); c->release(a); Operand* result = c->result8(); @@ -2193,8 +2193,9 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, Operand* a = frame->popLong(); Operand* b = frame->popLong(); - c->directCall - (c->constant(reinterpret_cast(moduloDouble)), 4, 0, a, 0, b); + c->indirectCall + (c->constant(reinterpret_cast(moduloDouble)), + 4, 0, a, 0, b); c->release(a); c->release(b); @@ -2207,7 +2208,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, Operand* a = frame->popLong(); Operand* b = frame->popLong(); - c->directCall + c->indirectCall (c->constant(reinterpret_cast(subtractDouble)), 4, 0, a, 0, b); c->release(a); @@ -2245,7 +2246,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, case f2d: { Operand* a = frame->popInt(); - c->directCall + c->indirectCall (c->constant(reinterpret_cast(floatToDouble)), 1, a); c->release(a); @@ -2257,8 +2258,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, case f2i: { Operand* a = frame->popInt(); - c->directCall - (c->constant(reinterpret_cast(floatToInt)), 1, a); + c->indirectCall + (c->constant(reinterpret_cast(floatToInt)), 1, a); c->release(a); Operand* result = c->result4(); @@ -2269,7 +2270,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, case f2l: { Operand* a = frame->popInt(); - c->directCall + c->indirectCall (c->constant(reinterpret_cast(floatToLong)), 1, a); c->release(a); @@ -2282,7 +2283,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, Operand* a = frame->popInt(); Operand* b = frame->popInt(); - c->directCall + c->indirectCall (c->constant(reinterpret_cast(addFloat)), 2, a, b); c->release(a); c->release(b); @@ -2296,7 +2297,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, Operand* a = frame->popInt(); Operand* b = frame->popInt(); - c->directCall + c->indirectCall (c->constant(reinterpret_cast(compareFloatsG)), 2, a, b); c->release(a); c->release(b); @@ -2310,7 +2311,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, Operand* a = frame->popInt(); Operand* b = frame->popInt(); - c->directCall + c->indirectCall (c->constant(reinterpret_cast(compareFloatsL)), 2, a, b); c->release(a); c->release(b); @@ -2336,7 +2337,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, Operand* a = frame->popInt(); Operand* b = frame->popInt(); - c->directCall + c->indirectCall (c->constant(reinterpret_cast(divideFloat)), 2, a, b); c->release(a); c->release(b); @@ -2350,7 +2351,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, Operand* a = frame->popInt(); Operand* b = frame->popInt(); - c->directCall + c->indirectCall (c->constant(reinterpret_cast(multiplyFloat)), 2, a, b); c->release(a); c->release(b); @@ -2363,7 +2364,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, case fneg: { Operand* a = frame->popInt(); - c->directCall + c->indirectCall (c->constant(reinterpret_cast(negateFloat)), 1, a); c->release(a); @@ -2376,7 +2377,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, Operand* a = frame->popInt(); Operand* b = frame->popInt(); - c->directCall + c->indirectCall (c->constant(reinterpret_cast(moduloFloat)), 2, a, b); c->release(a); c->release(b); @@ -2390,7 +2391,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, Operand* a = frame->popInt(); Operand* b = frame->popInt(); - c->directCall + c->indirectCall (c->constant(reinterpret_cast(subtractFloat)), 2, a, b); c->release(a); c->release(b); @@ -2486,7 +2487,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, case i2d: { Operand* a = frame->popInt(); - c->directCall + c->indirectCall (c->constant(reinterpret_cast(intToDouble)), 1, a); Operand* result = c->result8(); @@ -2498,7 +2499,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, case i2f: { Operand* a = frame->popInt(); - c->directCall + c->indirectCall (c->constant(reinterpret_cast(intToFloat)), 1, a); Operand* result = c->result4(); @@ -2737,7 +2738,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, Operand* classOperand = frame->append(class_); - c->directCall + c->indirectCall (c->constant(reinterpret_cast(instanceOf)), 3, c->thread(), classOperand, instance); @@ -2923,7 +2924,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, case l2d: { Operand* a = frame->popLong(); - c->directCall + c->indirectCall (c->constant(reinterpret_cast(longToDouble)), 2, 0, a); Operand* result = c->result8(); @@ -2935,7 +2936,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, case l2f: { Operand* a = frame->popLong(); - c->directCall + c->indirectCall (c->constant(reinterpret_cast(longToDouble)), 2, 0, a); Operand* result = c->result4(); @@ -3113,7 +3114,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, } assert(t, start); - c->directCall + c->indirectCall (c->constant(reinterpret_cast(lookUpAddress)), 4, key, start, c->constant(pairCount), default_); @@ -3428,9 +3429,10 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, frame->trace(0, false), 4, c->thread(), table, c->constant(fieldOffset(t, field)), value); } else { - c->directCall + c->indirectCall (c->constant(reinterpret_cast(set)), - 4, c->thread(), table, c->constant(fieldOffset(t, field)), value); + 4, c->thread(), table, c->constant(fieldOffset(t, field)), + value); } break; @@ -5006,9 +5008,11 @@ class MyProcessor: public Processor { void* oldBase = target->ip; void* oldStack = target->stack; - target->ip = ip; - target->base = base; - target->stack = stack; + if (methodForIp(t, ip)) { + target->ip = ip; + target->base = base; + target->stack = stack; + } trace = makeTrace(t, target); @@ -5147,7 +5151,7 @@ object findCallNode(MyThread* t, void* address) { if (DebugCallTable) { - fprintf(stderr, "find trace node %p\n", address); + fprintf(stderr, "find call node %p\n", address); } MyProcessor* p = processor(t); @@ -5207,7 +5211,7 @@ void insertCallNode(MyThread* t, object node) { if (DebugCallTable) { - fprintf(stderr, "insert trace node %p\n", + fprintf(stderr, "insert call node %p\n", reinterpret_cast(callNodeAddress(t, node))); } diff --git a/src/compiler.cpp b/src/compiler.cpp index ec7514292d..a64eeeea79 100644 --- a/src/compiler.cpp +++ b/src/compiler.cpp @@ -1103,13 +1103,9 @@ pushArguments(Context* c, unsigned count, va_list list) unsigned index = 0; for (unsigned i = 0; i < count; ++i) { - if (BytesPerWord == 8) { - arguments[index] = va_arg(list, MyOperand*); - if (arguments[index]) { - ++ index; - } - } else { - arguments[index++] = va_arg(list, MyOperand*); + arguments[index] = va_arg(list, MyOperand*); + if (BytesPerWord == 4 or arguments[index]) { + ++ index; } } @@ -2540,6 +2536,23 @@ class MyCompiler: public Compiler { (&c, static_cast(machineIp())); } + virtual void indirectCall + (Operand* address, unsigned argumentCount, ...) + { + va_list a; va_start(a, argumentCount); + pushArguments(&c, argumentCount, a); + va_end(a); + + appendOperation + (&c, MyOperand::mov, address, register_(&c, rax)); + call(immediate(&c, c.indirectCaller), 0); + + appendOperation + (&c, MyOperand::add, + immediate(&c, argumentFootprint(argumentCount)), + register_(&c, rsp)); + } + virtual void indirectCall (Operand* address, TraceHandler* traceHandler, unsigned argumentCount, ...) { diff --git a/src/compiler.h b/src/compiler.h index 4efa780b2d..1f95683dd6 100644 --- a/src/compiler.h +++ b/src/compiler.h @@ -65,6 +65,8 @@ class Compiler { virtual Operand* label() = 0; virtual void mark(Operand*) = 0; + virtual void indirectCall + (Operand* address, unsigned argumentCount, ...) = 0; virtual void indirectCall (Operand* address, TraceHandler* traceHandler, unsigned argumentCount, ...) = 0; From efb4e0241baee84e80c4f2a52b323d63c0933036 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Mon, 21 Apr 2008 11:31:10 -0600 Subject: [PATCH 03/17] do all java->native class via Compiler::indirectCall to ensure we can always make an accurate stack trace (part 2) --- src/compile.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compile.cpp b/src/compile.cpp index 5702ca48d6..360cf866b4 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -2181,7 +2181,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, Operand* a = frame->popLong(); c->indirectCall - (c->constant(reinterpret_cast(negateDouble)), 0, 2, 0, a); + (c->constant(reinterpret_cast(negateDouble)), 2, 0, a); c->release(a); Operand* result = c->result8(); From 819588546e58502d6e00d8d5dc081c0296d9bb3f Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Mon, 21 Apr 2008 16:30:41 -0600 Subject: [PATCH 04/17] implement a few StackTraceElement methods --- classpath/java/lang/StackTraceElement.java | 28 ++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/classpath/java/lang/StackTraceElement.java b/classpath/java/lang/StackTraceElement.java index c26db301f5..f20dc27803 100644 --- a/classpath/java/lang/StackTraceElement.java +++ b/classpath/java/lang/StackTraceElement.java @@ -27,6 +27,34 @@ public class StackTraceElement { this.line = line; } + public int hashCode() { + return class_.hashCode() ^ method.hashCode() ^ line; + } + + public boolean equals(Object o) { + if (o instanceof StackTraceElement) { + StackTraceElement e = (StackTraceElement) o; + return class_.equals(e.class_) + && method.equals(e.method) + && line == e.line; + } else { + return false; + } + } + + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append(class_).append(".").append(method); + + if (line == NativeLine) { + sb.append(" (native)"); + } else if (line >= 0) { + sb.append(" (line ").append(line).append(")"); + } + + return sb.toString(); + } + public String getClassName() { return class_; } From 24d0ea0d9b3036ce81a979cb8302d0ba25fe9fa7 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Mon, 21 Apr 2008 16:31:50 -0600 Subject: [PATCH 05/17] use StackTraceElement.toString in Throwable.printStackTrace --- classpath/java/lang/Throwable.java | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/classpath/java/lang/Throwable.java b/classpath/java/lang/Throwable.java index 5250a380af..333a156166 100644 --- a/classpath/java/lang/Throwable.java +++ b/classpath/java/lang/Throwable.java @@ -101,21 +101,7 @@ public class Throwable { StackTraceElement[] trace = resolveTrace(); for (int i = 0; i < trace.length; ++i) { - sb.append(" at ") - .append(trace[i].getClassName()) - .append(".") - .append(trace[i].getMethodName()); - - if (trace[i].isNativeMethod()) { - sb.append(" (native)"); - } else { - int line = trace[i].getLineNumber(); - if (line >= 0) { - sb.append(" (line ").append(line).append(")"); - } - } - - sb.append(nl); + sb.append(" at ").append(trace[i].toString()).append(nl); } if (cause != null) { From 864e079aca03e4d99480d5d10c67f51cceff7101 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Mon, 21 Apr 2008 16:32:33 -0600 Subject: [PATCH 06/17] don't bother defining ArrayElementSizeOf if it has no array elements --- src/type-generator.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/type-generator.cpp b/src/type-generator.cpp index 616d3458e2..231e31fb56 100644 --- a/src/type-generator.cpp +++ b/src/type-generator.cpp @@ -1793,11 +1793,14 @@ writeSizes(Output* out, Object* declarations) out->write(typeFixedSize(o)); out->write(";\n\n"); - out->write("const unsigned ArrayElementSizeOf"); - out->write(capitalize(typeName(o))); - out->write(" = "); - out->write(typeArrayElementSize(o)); - out->write(";\n\n"); + int aes = typeArrayElementSize(o); + if (aes) { + out->write("const unsigned ArrayElementSizeOf"); + out->write(capitalize(typeName(o))); + out->write(" = "); + out->write(aes); + out->write(";\n\n"); + } } break; default: break; From df5258d1d84f5337ac378b70dce7716123bea894 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Mon, 21 Apr 2008 16:36:13 -0600 Subject: [PATCH 07/17] various bugfixes concerning Thread.getStackTrace --- src/builtin.cpp | 3 ++- src/compile.cpp | 21 ++++++++++++++------- src/machine.cpp | 8 +++++++- src/machine.h | 1 + src/posix.cpp | 10 +++++++++- src/process.cpp | 6 +++++- 6 files changed, 38 insertions(+), 11 deletions(-) diff --git a/src/builtin.cpp b/src/builtin.cpp index f93e6e07ef..7a880b846c 100644 --- a/src/builtin.cpp +++ b/src/builtin.cpp @@ -53,6 +53,7 @@ enumerateThreads(Thread* t, Thread* x, object array, unsigned* index, { if (*index < limit) { set(t, array, ArrayBody + (*index * BytesPerWord), x->javaThread); + ++ (*index); if (x->peer) enumerateThreads(t, x->peer, array, index, limit); @@ -711,7 +712,7 @@ Java_java_lang_Thread_interrupt(Thread* t, jclass, jlong peer) } extern "C" JNIEXPORT jobject JNICALL -Java_java_lang_Thread_getTrace(Thread* t, jclass, jlong peer) +Java_java_lang_Thread_getStackTrace(Thread* t, jclass, jlong peer) { ENTER(t, Thread::ActiveState); diff --git a/src/compile.cpp b/src/compile.cpp index 360cf866b4..b1e3c17fd1 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -172,7 +172,7 @@ class MyStackWalker: public Processor::StackWalker { base(t->base), stack(t->stack), trace(t->trace), - nativeMethod(trace->nativeMethod), + nativeMethod(trace ? trace->nativeMethod : 0), method_(ip_ ? methodForIp(t, ip_) : 0), protector(this) { } @@ -208,7 +208,7 @@ class MyStackWalker: public Processor::StackWalker { bool next() { if (nativeMethod) { nativeMethod = 0; - } else { + } else if (stack) { stack = static_cast(base) + 1; base = *static_cast(base); ip_ = *static_cast(stack); @@ -225,6 +225,8 @@ class MyStackWalker: public Processor::StackWalker { return false; } } + } else { + return false; } return true; } @@ -4639,16 +4641,15 @@ traceSize(Thread* t) { class Counter: public Processor::StackVisitor { public: - Counter(Thread* t): t(t), count(0) { } + Counter(): count(0) { } virtual bool visit(Processor::StackWalker*) { ++ count; return true; } - Thread* t; unsigned count; - } counter(t); + } counter; t->m->processor->walkStack(t, &counter); @@ -4673,7 +4674,9 @@ class SegFaultHandler: public System::SignalHandler { ensure(t, FixedSizeOfNullPointerException + traceSize(t)); + t->tracing = true; t->exception = makeNullPointerException(t); + t->tracing = false; findUnwindTarget(t, ip, base, stack); *thread = t; @@ -5002,10 +5005,10 @@ class MyProcessor: public Processor { Visitor(MyThread* t, MyThread* target): t(t), target(target) { } virtual void visit(void* ip, void* base, void* stack) { - ensure(t, traceSize(t)); + ensure(t, traceSize(target)); void* oldIp = target->ip; - void* oldBase = target->ip; + void* oldBase = target->base; void* oldStack = target->stack; if (methodForIp(t, ip)) { @@ -5014,7 +5017,9 @@ class MyProcessor: public Processor { target->stack = stack; } + t->tracing = true; trace = makeTrace(t, target); + t->tracing = false; target->ip = oldIp; target->base = oldBase; @@ -5026,6 +5031,8 @@ class MyProcessor: public Processor { object trace; } visitor(t, target); + t->m->system->visit(t->systemThread, target->systemThread, &visitor); + if (t->backupHeap) { PROTECT(t, visitor.trace); diff --git a/src/machine.cpp b/src/machine.cpp index bea74e231d..88220c9a62 100644 --- a/src/machine.cpp +++ b/src/machine.cpp @@ -490,6 +490,7 @@ postCollect(Thread* t) if (t->backupHeap) { t->m->heap->free (t->backupHeap, t->backupHeapSizeInWords * BytesPerWord); + t->backupHeap = 0; t->backupHeapIndex = 0; t->backupHeapSizeInWords = 0; } @@ -1735,7 +1736,8 @@ Thread::Thread(Machine* m, object javaThread, Thread* parent): heap(defaultHeap), backupHeap(0), backupHeapIndex(0), - backupHeapSizeInWords(0) + backupHeapSizeInWords(0), + tracing(false) #ifdef VM_STRESS , stress(false) #endif // VM_STRESS @@ -2046,6 +2048,10 @@ allocate3(Thread* t, Allocator* allocator, Machine::AllocationType type, t->backupHeapIndex += ceiling(sizeInBytes, BytesPerWord); cast(o, 0) = 0; return o; + } else if (t->tracing) { + expect(t, t->heapIndex + ceiling(sizeInBytes, BytesPerWord) + <= Thread::HeapSizeInWords); + return allocateSmall(t, sizeInBytes); } ACQUIRE_RAW(t, t->m->stateLock); diff --git a/src/machine.h b/src/machine.h index c722155646..4077745d61 100644 --- a/src/machine.h +++ b/src/machine.h @@ -1291,6 +1291,7 @@ class Thread { uintptr_t* backupHeap; unsigned backupHeapIndex; unsigned backupHeapSizeInWords; + bool tracing; #ifdef VM_STRESS bool stress; #endif // VM_STRESS diff --git a/src/posix.cpp b/src/posix.cpp index 15d195e4b6..6b0c63739f 100644 --- a/src/posix.cpp +++ b/src/posix.cpp @@ -793,6 +793,8 @@ handleSignal(int signal, siginfo_t* info, void* context) System::Thread* t = system->visitTarget; system->visitTarget = 0; + + ACQUIRE_MONITOR(t, system->visitLock); system->visitLock->notifyAll(t); } break; @@ -830,7 +832,13 @@ handleSignal(int signal, siginfo_t* info, void* context) } else if (system->oldHandlers[index].sa_handler) { system->oldHandlers[index].sa_handler(signal); } else { - abort(); + switch (signal) { + case VisitSignal: + break; + + default: + abort(); + } } } diff --git a/src/process.cpp b/src/process.cpp index 570d832570..ecfac1f2d8 100644 --- a/src/process.cpp +++ b/src/process.cpp @@ -223,7 +223,11 @@ findLineNumber(Thread* t, object method, unsigned ip) } } - abort(t); + if (top < lineNumberTableLength(t, lnt)) { + return lineNumberLine(lineNumberTableBody(t, lnt, top)); + } else { + return UnknownLine; + } } else { return UnknownLine; } From c7d679467fbea7a64c5d0b5505a6127e85c6bd4f Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Tue, 22 Apr 2008 09:31:40 -0600 Subject: [PATCH 08/17] handle case of visiting thread when it is executing one of the transition procedures --- src/compile.cpp | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/compile.cpp b/src/compile.cpp index b1e3c17fd1..2f59212c13 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -4689,6 +4689,11 @@ class SegFaultHandler: public System::SignalHandler { Machine* m; }; +class MyProcessor; + +MyProcessor* +processor(MyThread* t); + class MyProcessor: public Processor { public: class CodeAllocator: public Allocator { @@ -5000,6 +5005,9 @@ class MyProcessor: public Processor { MyThread* t = static_cast(vmt); MyThread* target = static_cast(vmTarget); + processor(t)->getDefaultCompiled(t); + processor(t)->getNativeCompiled(t); + class Visitor: public System::ThreadVisitor { public: Visitor(MyThread* t, MyThread* target): t(t), target(target) { } @@ -5015,6 +5023,30 @@ class MyProcessor: public Processor { target->ip = ip; target->base = base; target->stack = stack; + } else { + MyProcessor* p = processor(t); + + uint8_t* default_ = reinterpret_cast + (&singletonValue(t, p->defaultCompiled, 0)); + unsigned defaultSize = singletonLength(t, p->defaultCompiled); + + uint8_t* native = reinterpret_cast + (&singletonValue(t, p->nativeCompiled, 0)); + unsigned nativeSize = singletonLength(t, p->nativeCompiled); + + if ((static_cast(ip) >= p->indirectCaller + and static_cast(ip) + < p->indirectCaller + p->indirectCallerSize) + + or (static_cast(ip) >= default_ + and static_cast(ip) < default_ + defaultSize) + + or (static_cast(ip) >= native + and static_cast(ip) < native + nativeSize)) + { + target->base = base; + target->stack = stack; + } } t->tracing = true; From 9e8e4b3de73bf436c098eb49d55829633196be5e Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Tue, 22 Apr 2008 10:21:54 -0600 Subject: [PATCH 09/17] fix stack walker to properly handle the case of a native method calling another native method --- src/compile.cpp | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/src/compile.cpp b/src/compile.cpp index 2f59212c13..ca61548ad6 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -213,22 +213,25 @@ class MyStackWalker: public Processor::StackWalker { base = *static_cast(base); ip_ = *static_cast(stack); method_ = methodForIp(t, *static_cast(stack)); - if (method_ == 0) { - if (trace and trace->stack) { - base = trace->base; - stack = static_cast(trace->stack); - ip_ = *static_cast(stack); - method_ = methodForIp(t, *static_cast(stack)); - nativeMethod = trace->nativeMethod; - trace = trace->next; - } else { - return false; - } - } } else { return false; } - return true; + + if (method_ or nativeMethod) { + return true; + } else if (trace and trace->stack) { + base = trace->base; + stack = static_cast(trace->stack); + ip_ = *static_cast(stack); + method_ = methodForIp(t, *static_cast(stack)); + nativeMethod = trace->nativeMethod; + trace = trace->next; + + expect(t, method_ or nativeMethod); + return true; + } else { + return false; + } } virtual object method() { From d072b71c396412ba5cf4cae4aea50d047234443b Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Wed, 23 Apr 2008 10:33:31 -0600 Subject: [PATCH 10/17] nth attempt to clean up MyStackWalker --- src/compile.cpp | 188 +++++++++++++++++++++++++++++++----------------- src/machine.cpp | 1 + 2 files changed, 122 insertions(+), 67 deletions(-) diff --git a/src/compile.cpp b/src/compile.cpp index ca61548ad6..7bfcb1190c 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -40,14 +40,12 @@ class MyThread: public Thread { public: CallTrace(MyThread* t): t(t), - ip(t->ip), base(t->base), stack(t->stack), nativeMethod(0), next(t->trace) { t->trace = this; - t->ip = 0; t->base = 0; t->stack = 0; } @@ -55,7 +53,6 @@ class MyThread: public Thread { ~CallTrace() { t->stack = stack; t->base = base; - t->ip = ip; t->trace = next; } @@ -152,6 +149,14 @@ methodForIp(MyThread* t, void* ip) class MyStackWalker: public Processor::StackWalker { public: + enum State { + Start, + Next, + Method, + NativeMethod, + Finish + }; + class MyProtector: public Thread::Protector { public: MyProtector(MyStackWalker* walker): @@ -160,7 +165,6 @@ class MyStackWalker: public Processor::StackWalker { virtual void visit(Heap::Visitor* v) { v->visit(&(walker->method_)); - v->visit(&(walker->nativeMethod)); } MyStackWalker* walker; @@ -168,114 +172,156 @@ class MyStackWalker: public Processor::StackWalker { MyStackWalker(MyThread* t): t(t), - ip_(t->ip ? t->ip : (t->stack ? *static_cast(t->stack) : 0)), + state(Start), + ip_(t->ip), base(t->base), stack(t->stack), trace(t->trace), - nativeMethod(trace ? trace->nativeMethod : 0), - method_(ip_ ? methodForIp(t, ip_) : 0), + method_(0), protector(this) { } MyStackWalker(MyStackWalker* w): t(w->t), + state(w->state), ip_(w->ip_), base(w->base), stack(w->stack), trace(w->trace), - nativeMethod(w->nativeMethod), method_(w->method_), protector(this) { } virtual void walk(Processor::StackVisitor* v) { - if (stack == 0) { - return; - } - - if (not v->visit(this)) { - return; - } - - for (MyStackWalker it(this); it.next();) { + for (MyStackWalker it(this); it.valid();) { MyStackWalker walker(it); if (not v->visit(&walker)) { break; } + it.next(); } } - bool next() { - if (nativeMethod) { - nativeMethod = 0; - } else if (stack) { - stack = static_cast(base) + 1; - base = *static_cast(base); - ip_ = *static_cast(stack); - method_ = methodForIp(t, *static_cast(stack)); - } else { - return false; + bool valid() { + while (true) { +// fprintf(stderr, "state: %d\n", state); + switch (state) { + case Start: + if (ip_ == 0 and stack) { + ip_ = *static_cast(stack); + } + + if (trace and trace->nativeMethod) { + method_ = trace->nativeMethod; + state = NativeMethod; + } else if (ip_) { + state = Next; + } else { + state = Finish; + } + break; + + case Next: + if (stack) { + method_ = methodForIp(t, ip_); + if (method_) { + state = Method; + } else if (trace) { + base = trace->base; + stack = static_cast(trace->stack); + ip_ = (stack ? *static_cast(stack) : 0); + + if (trace->nativeMethod) { + method_ = trace->nativeMethod; + state = NativeMethod; + } else { + trace = trace->next; + state = Next; + } + } else { + state = Finish; + } + } else { + state = Finish; + } + break; + + case Method: + case NativeMethod: + return true; + + case Finish: + return false; + + default: + abort(t); + } } + } + + void next() { + switch (state) { + case Method: + stack = static_cast(base) + 1; + ip_ = (stack ? *static_cast(stack) : 0); + base = *static_cast(base); + state = Next; + break; - if (method_ or nativeMethod) { - return true; - } else if (trace and trace->stack) { - base = trace->base; - stack = static_cast(trace->stack); - ip_ = *static_cast(stack); - method_ = methodForIp(t, *static_cast(stack)); - nativeMethod = trace->nativeMethod; + case NativeMethod: trace = trace->next; - - expect(t, method_ or nativeMethod); - return true; - } else { - return false; + state = Next; + break; + + default: + abort(t); } } virtual object method() { - if (nativeMethod) { - return nativeMethod; - } else { + switch (state) { + case Method: return method_; + + case NativeMethod: + return trace->nativeMethod; + + default: + abort(t); } } virtual int ip() { - if (nativeMethod) { - return 0; - } else { + switch (state) { + case Method: return reinterpret_cast(ip_) - reinterpret_cast (&singletonValue(t, methodCompiled(t, method_), 0)); + + case NativeMethod: + return 0; + + default: + abort(t); } } virtual unsigned count() { - class Visitor: public Processor::StackVisitor { - public: - Visitor(): count(0) { } + unsigned count = 0; - virtual bool visit(Processor::StackWalker*) { - ++ count; - return true; - } - - unsigned count; - } v; - - MyStackWalker walker(this); - walker.walk(&v); + for (MyStackWalker walker(this); walker.valid();) { + walker.next(); + ++ count; + } - return v.count; + return count; } MyThread* t; + State state; void* ip_; void* base; void* stack; MyThread::CallTrace* trace; - object nativeMethod; object method_; MyProtector protector; }; @@ -1196,9 +1242,7 @@ findUnwindTarget(MyThread* t, void** targetIp, void** targetBase, void* ip = t->ip; void* base = t->base; void** stack = static_cast(t->stack); - if (ip) { - t->ip = 0; - } else { + if (ip == 0) { ip = *stack; } @@ -4302,11 +4346,11 @@ invokeNative(MyThread* t) { if (t->trace->nativeMethod == 0) { object node = findCallNode(t, *static_cast(t->stack)); - t->trace->nativeMethod = callNodeTarget(t, node); + object target = callNodeTarget(t, node); if (callNodeVirtualCall(t, node)) { - t->trace->nativeMethod = resolveTarget - (t, t->stack, t->trace->nativeMethod); + target = resolveTarget(t, t->stack, target); } + t->trace->nativeMethod = target; } uint64_t result = 0; @@ -4671,6 +4715,10 @@ class SegFaultHandler: public System::SignalHandler { if (t->state == Thread::ActiveState) { object node = methodForIp(t, *ip); if (node) { + void* oldIp = t->ip; + void* oldBase = t->base; + void* oldStack = t->stack; + t->ip = *ip; t->base = *base; t->stack = *stack; @@ -4682,6 +4730,11 @@ class SegFaultHandler: public System::SignalHandler { t->tracing = false; findUnwindTarget(t, ip, base, stack); + + t->ip = oldIp; + t->base = oldBase; + t->stack = oldStack; + *thread = t; return true; } @@ -5047,6 +5100,7 @@ class MyProcessor: public Processor { or (static_cast(ip) >= native and static_cast(ip) < native + nativeSize)) { + target->ip = *static_cast(stack); target->base = base; target->stack = stack; } diff --git a/src/machine.cpp b/src/machine.cpp index 88220c9a62..7c596c9bf9 100644 --- a/src/machine.cpp +++ b/src/machine.cpp @@ -2832,6 +2832,7 @@ makeTrace(Thread* t, Processor::StackWalker* walker) } object e = makeTraceElement(t, walker->method(), walker->ip()); + assert(t, index < arrayLength(t, trace)); set(t, trace, ArrayBody + (index * BytesPerWord), e); ++ index; return true; From 7e1a2ea8767f2be4696c761a631f70e1d379fedf Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Wed, 23 Apr 2008 15:01:47 -0600 Subject: [PATCH 11/17] don't remove nodes from call node table, since it leads to a race condition --- src/compile.cpp | 55 ------------------------------------------------- 1 file changed, 55 deletions(-) diff --git a/src/compile.cpp b/src/compile.cpp index 7bfcb1190c..54c0ca4956 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -1184,9 +1184,6 @@ findCallNode(MyThread* t, void* address); void insertCallNode(MyThread* t, object node); -void -removeCallNode(MyThread* t, object node); - void* findExceptionHandler(Thread* t, object method, void* ip) { @@ -4130,14 +4127,6 @@ compileMethod2(MyThread* t) (t, resolveThisPointer(t, t->stack, target)), methodOffset(t, target)) = &singletonValue(t, methodCompiled(t, target), 0); } else { -#ifndef VM_STRESS - // valgrind doesn't like this, since the effect of updateCall - // below does not propagate to valgrind's interpreter: - { ACQUIRE(t, t->m->classLock); - removeCallNode(t, node); - } -#endif - Context context(t); context.c->updateCall (reinterpret_cast(callNodeAddress(t, node)), @@ -5329,50 +5318,6 @@ insertCallNode(MyThread* t, object node) set(t, p->callTable, ArrayBody + (index * BytesPerWord), node); } -void -removeCallNode(MyThread* t, object node) -{ - if (DebugCallTable) { - fprintf(stderr, "remove call node %p\n", - reinterpret_cast(callNodeAddress(t, node))); - } - - MyProcessor* p = processor(t); - PROTECT(t, node); - - object oldNode = 0; - PROTECT(t, oldNode); - - object newNode = 0; - PROTECT(t, newNode); - - intptr_t key = callNodeAddress(t, node); - unsigned index = static_cast(key) - & (arrayLength(t, p->callTable) - 1); - - for (oldNode = arrayBody(t, p->callTable, index); - oldNode; - oldNode = callNodeNext(t, oldNode)) - { - if (oldNode != node) { - newNode = makeCallNode - (t, callNodeAddress(t, oldNode), - callNodeTarget(t, oldNode), - callNodeVirtualCall(t, oldNode), - newNode); - } - } - - set(t, p->callTable, ArrayBody + (index * BytesPerWord), newNode); - - -- p->callTableSize; - - if (p->callTableSize <= arrayLength(t, p->callTable) / 3) { - p->callTable = resizeTable - (t, p->callTable, arrayLength(t, p->callTable) / 2); - } -} - object& methodTree(MyThread* t) { From f49174da28a107df02fc02ccd45e453ee1280788 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Wed, 23 Apr 2008 15:07:14 -0600 Subject: [PATCH 12/17] set the base pointer in vmNativeCall to point to the return address per convention, allowing us to safely walk the stack in Process::getStackTrace --- src/x86.S | 37 ++++++++++++++++--------------------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/src/x86.S b/src/x86.S index 4515fb5efc..830b9f08e5 100644 --- a/src/x86.S +++ b/src/x86.S @@ -17,13 +17,14 @@ .globl vmNativeCall vmNativeCall: pushq %rbp + movq %rsp,%rbp - // %rdi aka 0(%rbp): function - // %rsi aka 8(%rbp): stack - // %rdx aka 16(%rbp): stackSize - // %rcx aka 24(%rbp): gprTable - // %r8 aka 32(%rbp): sseTable - // %r9 aka 40(%rbp): returnType + // %rdi aka -48(%rbp): function + // %rsi aka -40(%rbp): stack + // %rdx aka -32(%rbp): stackSize + // %rcx aka -24(%rbp): gprTable + // %r8 aka -16(%rbp): sseTable + // %r9 aka -8(%rbp): returnType // save our argument registers so we can clobber them pushq %r9 @@ -32,8 +33,6 @@ vmNativeCall: pushq %rdx pushq %rsi pushq %rdi - - movq %rsp,%rbp // reserve space for arguments passed via memory subq %rdx,%rsp @@ -49,21 +48,21 @@ loop: movq %rcx,%rax movq %rcx,%rdx addq %rsp,%rdx - addq 8(%rbp),%rax - movq (%rax),%rax + addq -40(%rbp),%rax + movq (%rax),%rax movq %rax,(%rdx) addq $8,%rcx test: - cmpq 16(%rbp),%rcx + cmpq -32(%rbp),%rcx jb loop // do we need to load the general-purpose registers? - cmpq $0,24(%rbp) + cmpq $0,-24(%rbp) je sse // yes, we do - movq 24(%rbp),%rax + movq -24(%rbp),%rax movq 0(%rax),%rdi movq 8(%rax),%rsi movq 16(%rax),%rdx @@ -73,11 +72,11 @@ test: sse: // do we need to load the SSE registers? - cmpq $0,32(%rbp) + cmpq $0,-16(%rbp) je call // yes, we do - movq 32(%rbp),%rax + movq -16(%rbp),%rax movq 0(%rax),%xmm0 movq 8(%rax),%xmm1 movq 16(%rax),%xmm2 @@ -88,10 +87,10 @@ sse: movq 64(%rax),%xmm7 call: - call *0(%rbp) + call *-48(%rbp) // handle return value based on expected type - movq 40(%rbp),%rcx + movq -8(%rbp),%rcx void: cmpq $VOID_TYPE,%rcx @@ -109,10 +108,6 @@ copy: exit: movq %rbp,%rsp - - // pop our argument registers - addq $48,%rsp - popq %rbp ret From 1d7b00baff15f300ef72e059e10a24318970e33d Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Wed, 23 Apr 2008 16:56:02 -0600 Subject: [PATCH 13/17] backport getstatic/putstatic optimization from compiler branch --- src/compile.cpp | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/compile.cpp b/src/compile.cpp index 54c0ca4956..17ea917ca4 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -2457,10 +2457,14 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, Operand* table; if (instruction == getstatic) { - c->indirectCall - (c->constant(reinterpret_cast(tryInitClass)), - frame->trace(0, false), - 2, c->thread(), frame->append(fieldClass(t, field))); + if ((classVmFlags(t, fieldClass(t, field)) & NeedInitFlag) + and (classVmFlags(t, fieldClass(t, field)) & InitFlag) == 0) + { + c->indirectCall + (c->constant(reinterpret_cast(tryInitClass)), + frame->trace(0, false), + 2, c->thread(), frame->append(fieldClass(t, field))); + } table = frame->append(classStaticTable(t, fieldClass(t, field))); } else { @@ -3408,10 +3412,14 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, object staticTable = 0; if (instruction == putstatic) { - c->indirectCall - (c->constant(reinterpret_cast(tryInitClass)), - frame->trace(0, false), - 2, c->thread(), frame->append(fieldClass(t, field))); + if ((classVmFlags(t, fieldClass(t, field)) & NeedInitFlag) + and (classVmFlags(t, fieldClass(t, field)) & InitFlag) == 0) + { + c->indirectCall + (c->constant(reinterpret_cast(tryInitClass)), + frame->trace(0, false), + 2, c->thread(), frame->append(fieldClass(t, field))); + } staticTable = classStaticTable(t, fieldClass(t, field)); } From 18d25468fe81b2265fc080b05e7ced17b55ecf0f Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Wed, 23 Apr 2008 18:08:24 -0600 Subject: [PATCH 14/17] optimize common case of setting a single object field so we don't acquire the heap lock unnecessarily --- src/heap.cpp | 5 +++++ src/heap.h | 1 + src/machine.h | 5 ++++- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/heap.cpp b/src/heap.cpp index 4c81b0d6ef..a70f176b3e 100644 --- a/src/heap.cpp +++ b/src/heap.cpp @@ -1709,6 +1709,11 @@ class MyHeap: public Heap { } } + virtual bool needsMark(void* p, unsigned offset) { + return needsMark(p) and targetNeedsMark + (mask(*(static_cast(p) + offset))); + } + bool targetNeedsMark(void* target) { return target and not c.gen2.contains(target) diff --git a/src/heap.h b/src/heap.h index 8b4331ca1e..bf4dc5a360 100644 --- a/src/heap.h +++ b/src/heap.h @@ -62,6 +62,7 @@ class Heap: public Allocator { virtual void* allocateImmortal(Allocator* allocator, unsigned sizeInWords, bool objectMask, unsigned* totalInBytes) = 0; virtual bool needsMark(void* p) = 0; + virtual bool needsMark(void* p, unsigned offset) = 0; virtual void mark(void* p, unsigned offset, unsigned count) = 0; virtual void pad(void* p) = 0; virtual void* follow(void* p) = 0; diff --git a/src/machine.h b/src/machine.h index 4077745d61..cca8a3b564 100644 --- a/src/machine.h +++ b/src/machine.h @@ -1487,7 +1487,10 @@ mark(Thread* t, object o, unsigned offset, unsigned count) inline void mark(Thread* t, object o, unsigned offset) { - mark(t, o, offset, 1); + if (t->m->heap->needsMark(o, offset / BytesPerWord)) { + ACQUIRE_RAW(t, t->m->heapLock); + t->m->heap->mark(o, offset / BytesPerWord, 1); + } } inline void From 584e1005e3e562b9d0c8cf07132421cb89ddb8f8 Mon Sep 17 00:00:00 2001 From: Eric Scharff Date: Thu, 24 Apr 2008 11:07:20 -0600 Subject: [PATCH 15/17] Fix Mac compiler warnings for fprintf format strings --- src/common.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/common.h b/src/common.h index 0e4383fab6..a02627b5d8 100644 --- a/src/common.h +++ b/src/common.h @@ -29,11 +29,12 @@ #ifdef __i386__ # define LD "d" -# define LX "x" # define LLD "lld" #ifdef __APPLE__ # define ULD "lu" +# define LX "lx" #else +# define LX "x" # define ULD "u" #endif #elif defined __x86_64__ From 0655b553784cacb41bcdb41f9d477c1184bf6237 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Thu, 24 Apr 2008 16:06:36 -0600 Subject: [PATCH 16/17] resolve catch type for each exception handler during compilation --- src/compile.cpp | 37 ++++++++++++------------------------- 1 file changed, 12 insertions(+), 25 deletions(-) diff --git a/src/compile.cpp b/src/compile.cpp index 17ea917ca4..3844abf78e 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -1187,8 +1187,6 @@ insertCallNode(MyThread* t, object node); void* findExceptionHandler(Thread* t, object method, void* ip) { - PROTECT(t, method); - object table = codeExceptionHandlerTable(t, methodCode(t, method)); if (table) { object index = arrayBody(t, table, 0); @@ -1202,25 +1200,7 @@ findExceptionHandler(Thread* t, object method, void* ip) unsigned key = difference(ip, compiled) - 1; if (key >= start and key < end) { - object catchType = 0; - if (arrayBody(t, table, i + 1)) { - object e = t->exception; - t->exception = 0; - PROTECT(t, e); - - PROTECT(t, table); - PROTECT(t, index); - - catchType = resolveClassInObject - (t, table, ArrayBody + ((i + 1) * BytesPerWord)); - - if (catchType) { - t->exception = e; - } else { - // can't find what we're supposed to catch - move on. - continue; - } - } + object catchType = arrayBody(t, table, i + 1); if (catchType == 0 or instanceOf(t, catchType, t->exception)) { return compiled + intArrayBody(t, index, (i * 3) + 2); @@ -3648,6 +3628,8 @@ translateExceptionHandlerTable(MyThread* t, Compiler* c, object code, PROTECT(t, newIndex); object newTable = makeArray(t, length + 1, false); + PROTECT(t, newTable); + set(t, newTable, ArrayBody, newIndex); for (unsigned i = 0; i < length; ++i) { @@ -3663,10 +3645,14 @@ translateExceptionHandlerTable(MyThread* t, Compiler* c, object code, intArrayBody(t, newIndex, (i * 3) + 2) = c->machineIp(exceptionHandlerIp(oldHandler))->value(c) - start; - object type = - (exceptionHandlerCatchType(oldHandler) ? - singletonObject(t, codePool(t, code), - exceptionHandlerCatchType(oldHandler) - 1) : 0); + object type; + if (exceptionHandlerCatchType(oldHandler)) { + type = resolveClassInPool + (t, codePool(t, code), exceptionHandlerCatchType(oldHandler) - 1); + if (UNLIKELY(t->exception)) return; + } else { + type = 0; + } set(t, newTable, ArrayBody + ((i + 1) * BytesPerWord), type); } @@ -3882,6 +3868,7 @@ finish(MyThread* t, Context* context, const char* name) translateExceptionHandlerTable(t, c, methodCode(t, context->method), reinterpret_cast(start)); + if (UNLIKELY(t->exception)) return 0; translateLineNumberTable(t, c, methodCode(t, context->method), reinterpret_cast(start)); From 23572b58bdd5de01ad71c2b2919825b967e18784 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Fri, 25 Apr 2008 16:18:19 -0600 Subject: [PATCH 17/17] fix code ordering bug in MyProcessor::getStackTrace which caused the stack trace footprint calculation to be inaccurate --- src/compile.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compile.cpp b/src/compile.cpp index 3844abf78e..57b2966b1c 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -5053,8 +5053,6 @@ class MyProcessor: public Processor { Visitor(MyThread* t, MyThread* target): t(t), target(target) { } virtual void visit(void* ip, void* base, void* stack) { - ensure(t, traceSize(target)); - void* oldIp = target->ip; void* oldBase = target->base; void* oldStack = target->stack; @@ -5090,6 +5088,8 @@ class MyProcessor: public Processor { } } + ensure(t, traceSize(target)); + t->tracing = true; trace = makeTrace(t, target); t->tracing = false;