diff --git a/makefile b/makefile index 5b34b5051b..db883dc741 100644 --- a/makefile +++ b/makefile @@ -151,12 +151,17 @@ rdynamic = -rdynamic warnings = -Wall -Wextra -Werror -Wunused-parameter -Winit-self \ -Wno-non-virtual-dtor -common-cflags = $(warnings) -fno-rtti -fno-exceptions -fno-omit-frame-pointer \ +common-cflags = $(warnings) -fno-rtti -fno-exceptions \ "-I$(JAVA_HOME)/include" -idirafter $(src) -I$(build) $(classpath-cflags) \ -D__STDC_LIMIT_MACROS -D_JNI_IMPLEMENTATION_ -DAVIAN_VERSION=\"$(version)\" \ -DUSE_ATOMIC_OPERATIONS -DAVIAN_JAVA_HOME=\"$(javahome)\" \ -DAVIAN_EMBED_PREFIX=\"$(embed-prefix)\" +ifeq ($(use-frame-pointer),true) + common-cflags += -fno-omit-frame-pointer -DAVIAN_USE_FRAME_POINTER + asmflags += -DAVIAN_USE_FRAME_POINTER +endif + build-cflags = $(common-cflags) -fPIC -fvisibility=hidden \ "-I$(JAVA_HOME)/include/linux" -I$(src) -pthread @@ -544,6 +549,13 @@ test-extra-classes = \ $(call java-classes,$(test-extra-sources),$(test),$(test-build)) test-extra-dep = $(test-build)-extra.dep +ifeq ($(continuations),true) + continuation-tests = \ + extra.Continuations \ + extra.Coroutines \ + extra.DynamicWind +endif + class-name = $(patsubst $(1)/%.class,%,$(2)) class-names = $(foreach x,$(2),$(call class-name,$(1),$(x))) @@ -575,7 +587,8 @@ vg: build test: build $(library-path) /bin/sh $(test)/test.sh 2>/dev/null \ $(test-executable) $(mode) "$(test-flags)" \ - $(call class-names,$(test-build),$(test-classes)) + $(call class-names,$(test-build),$(test-classes)) \ + $(continuation-tests) .PHONY: tarball tarball: diff --git a/src/arch.h b/src/arch.h index 56afe1d5c3..6e6d4b24a6 100644 --- a/src/arch.h +++ b/src/arch.h @@ -22,8 +22,8 @@ #include "common.h" extern "C" void NO_RETURN -vmJump(void* address, void* stack, void* thread, uintptr_t returnLow, - uintptr_t returnHigh); +vmJump(void* address, void* frame, void* stack, void* thread, + uintptr_t returnLow, uintptr_t returnHigh); namespace vm { diff --git a/src/compile.cpp b/src/compile.cpp index f7ad3591f4..afe20a7c95 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -1992,8 +1992,8 @@ releaseLock(MyThread* t, object method, void* stack) } void -findUnwindTarget(MyThread* t, void** targetIp, void** targetStack, - object* targetContinuation) +findUnwindTarget(MyThread* t, void** targetIp, void** targetFrame, + void** targetStack, object* targetContinuation) { void* ip; void* stack; @@ -2029,6 +2029,8 @@ findUnwindTarget(MyThread* t, void** targetIp, void** targetStack, void** sp = static_cast(stackForFrame(t, stack, method)) + t->arch->frameReturnAddressSize(); + *targetFrame = static_cast + (stack) + t->arch->framePointerOffset(); *targetStack = sp; *targetContinuation = continuation; @@ -2046,6 +2048,7 @@ findUnwindTarget(MyThread* t, void** targetIp, void** targetStack, } } else { *targetIp = ip; + *targetFrame = 0; *targetStack = static_cast(stack) + t->arch->frameReturnAddressSize(); *targetContinuation = continuation; @@ -2172,13 +2175,14 @@ void NO_RETURN unwind(MyThread* t) { void* ip; + void* frame; void* stack; object continuation; - findUnwindTarget(t, &ip, &stack, &continuation); + findUnwindTarget(t, &ip, &frame, &stack, &continuation); transition(t, ip, stack, continuation, t->trace); - vmJump(ip, stack, t, 0, 0); + vmJump(ip, frame, stack, t, 0, 0); } class MyCheckpoint: public Thread::Checkpoint { @@ -6774,7 +6778,8 @@ callContinuation(MyThread* t, object continuation, object result, MyThread::TraceContext c(t, ip, stack, continuation, t->trace); - findUnwindTarget(t, &ip, &stack, &continuation); + void* frame; + findUnwindTarget(t, &ip, &frame, &stack, &continuation); } t->trace->nativeMethod = 0; @@ -6784,7 +6789,7 @@ callContinuation(MyThread* t, object continuation, object result, transition(t, ip, stack, continuation, t->trace); - vmJump(ip, stack, t, reinterpret_cast(result), 0); + vmJump(ip, 0, stack, t, reinterpret_cast(result), 0); } int8_t* @@ -6941,10 +6946,12 @@ callContinuation(MyThread* t, object continuation, object result, (t, root(t, Machine::BootLoader), "avian/Continuations", "rewind", "(Ljava/lang/Runnable;Lavian/Callback;Ljava/lang/Object;" "Ljava/lang/Throwable;)V"); - - setRoot(t, RewindMethod, method); + + PROTECT(t, method); compile(t, local::codeAllocator(t), 0, method); + + setRoot(t, RewindMethod, method); } } else { action = Call; @@ -6957,9 +6964,10 @@ callContinuation(MyThread* t, object continuation, object result, } void* ip; + void* frame; void* stack; object threadContinuation; - findUnwindTarget(t, &ip, &stack, &threadContinuation); + findUnwindTarget(t, &ip, &frame, &stack, &threadContinuation); switch (action) { case Call: { @@ -7037,7 +7045,7 @@ dynamicWind(MyThread* t, object before, object thunk, object after) object method = resolveMethod (t, root(t, Machine::BootLoader), "avian/Continuations", "wind", "(Ljava/lang/Runnable;Ljava/util/concurrent/Callable;" - "Ljava/lang/Runnable;)Lavian/Continuations$UnwindResult;"); + "Ljava/lang/Runnable;)Lavian/Continuations$UnwindResult;"); if (method) { setRoot(t, WindMethod, method); @@ -7264,7 +7272,9 @@ class SignalHandler: public System::SignalHandler { SignalHandler(Machine::Type type, Machine::Root root, unsigned fixedSize): m(0), type(type), root(root), fixedSize(fixedSize) { } - virtual bool handleSignal(void** ip, void** stack, void** thread) { + virtual bool handleSignal(void** ip, void** frame, void** stack, + void** thread) + { MyThread* t = static_cast(m->localThread->get()); if (t and t->state == Thread::ActiveState) { object node = methodForIp(t, *ip); @@ -7289,7 +7299,7 @@ class SignalHandler: public System::SignalHandler { // printTrace(t, t->exception); object continuation; - findUnwindTarget(t, ip, stack, &continuation); + findUnwindTarget(t, ip, frame, stack, &continuation); transition(t, ip, stack, continuation, t->trace); @@ -8274,7 +8284,8 @@ fixupThunks(MyThread* t, BootImage* image, uint8_t* code) void fixupVirtualThunks(MyThread* t, BootImage* image, uint8_t* code) { - for (unsigned i = 0; i < wordArrayLength(t, root(t, VirtualThunks)); i += 2) { + for (unsigned i = 0; i < wordArrayLength(t, root(t, VirtualThunks)); i += 2) + { if (wordArrayBody(t, root(t, VirtualThunks), i)) { wordArrayBody(t, root(t, VirtualThunks), i) = (wordArrayBody(t, root(t, VirtualThunks), i) - image->codeBase) diff --git a/src/machine.h b/src/machine.h index 745ada691e..e7b30539dd 100644 --- a/src/machine.h +++ b/src/machine.h @@ -1472,7 +1472,7 @@ class Thread { void* stack = this->stack; this->stack = 0; expect(t->m->system, stack); - vmJump(voidPointer(vmRun_returnAddress), stack, t, 0, 0); + vmJump(voidPointer(vmRun_returnAddress), 0, stack, t, 0, 0); } void* stack; diff --git a/src/posix.cpp b/src/posix.cpp index 8b2496ae81..de879c3496 100644 --- a/src/posix.cpp +++ b/src/posix.cpp @@ -815,7 +815,7 @@ class MySystem: public System { } class NullSignalHandler: public SignalHandler { - virtual bool handleSignal(void**, void**, void**) { return false; } + virtual bool handleSignal(void**, void**, void**, void**) { return false; } } nullHandler; SignalHandler* handlers[SignalCount]; @@ -835,6 +835,11 @@ handleSignal(int signal, siginfo_t* info, void* context) void* stack = reinterpret_cast(STACK_REGISTER(c)); void* thread = reinterpret_cast(THREAD_REGISTER(c)); void* link = reinterpret_cast(LINK_REGISTER(c)); +#ifdef FRAME_REGISTER + void* frame = reinterpret_cast(FRAME_REGISTER(c)); +#else + void* frame = 0; +#endif unsigned index; @@ -871,7 +876,8 @@ handleSignal(int signal, siginfo_t* info, void* context) abort(); } - bool jump = system->handlers[index]->handleSignal(&ip, &stack, &thread); + bool jump = system->handlers[index]->handleSignal + (&ip, &frame, &stack, &thread); if (jump) { // I'd like to use setcontext here (and get rid of the @@ -885,7 +891,7 @@ handleSignal(int signal, siginfo_t* info, void* context) sigaddset(&set, signal); sigprocmask(SIG_UNBLOCK, &set, 0); - vmJump(ip, stack, thread, 0, 0); + vmJump(ip, frame, stack, thread, 0, 0); } } break; diff --git a/src/system.h b/src/system.h index 258b04f440..4d155cfd66 100644 --- a/src/system.h +++ b/src/system.h @@ -96,7 +96,8 @@ class System { class SignalHandler { public: - virtual bool handleSignal(void** ip, void** stack, void** thread) = 0; + virtual bool handleSignal(void** ip, void** frame, void** stack, + void** thread) = 0; }; class MonitorResource { diff --git a/src/x86.S b/src/x86.S index 08e05e4aaf..72b25268fd 100644 --- a/src/x86.S +++ b/src/x86.S @@ -170,10 +170,11 @@ LOCAL(exit): .globl GLOBAL(vmJump) GLOBAL(vmJump): - movq %r9,%rax - movq 40(%rsp),%rdx - movq %rdx,%rsp - movq %r8,%rbx + movq %rdx,%rbp + movq 40(%rsp),%rax + movq 48(%rsp),%rdx + movq %r8,%rsp + movq %r9,%rbx jmp *%rcx #define VMRUN_FRAME_SIZE 80 @@ -350,10 +351,11 @@ LOCAL(exit): .globl GLOBAL(vmJump) GLOBAL(vmJump): - movq %rsi,%rsp - movq %rdx,%rbx - movq %rcx,%rax - movq %r8,%rdx + movq %rsi,%rbp + movq %rdx,%rsp + movq %rcx,%rbx + movq %r8,%rax + movq %r9,%rdx jmp *%rdi #define VMRUN_FRAME_SIZE 64 @@ -508,10 +510,11 @@ LOCAL(exit): .globl GLOBAL(vmJump) GLOBAL(vmJump): movl 4(%esp),%esi - movl 12(%esp),%ebx - movl 16(%esp),%eax - movl 20(%esp),%edx - movl 8(%esp),%esp + movl 8(%esp),%ebp + movl 16(%esp),%ebx + movl 20(%esp),%eax + movl 24(%esp),%edx + movl 12(%esp),%esp jmp *%esi #define VMRUN_FRAME_SIZE 32 diff --git a/src/x86.h b/src/x86.h index c277168ce0..ec90c7befb 100644 --- a/src/x86.h +++ b/src/x86.h @@ -32,17 +32,20 @@ # define STACK_REGISTER(context) (context->uc_mcontext->__ss.__esp) # define THREAD_REGISTER(context) (context->uc_mcontext->__ss.__ebx) # define LINK_REGISTER(context) (context->uc_mcontext->__ss.__ecx) +# define FRAME_REGISTER(context) (context->uc_mcontext->__ss.__ebp) # else # define IP_REGISTER(context) (context->uc_mcontext->ss.eip) # define STACK_REGISTER(context) (context->uc_mcontext->ss.esp) # define THREAD_REGISTER(context) (context->uc_mcontext->ss.ebx) # define LINK_REGISTER(context) (context->uc_mcontext->ss.ecx) +# define FRAME_REGISTER(context) (context->uc_mcontext->ss.ebp) # endif # else # define IP_REGISTER(context) (context->uc_mcontext.gregs[REG_EIP]) # define STACK_REGISTER(context) (context->uc_mcontext.gregs[REG_ESP]) # define THREAD_REGISTER(context) (context->uc_mcontext.gregs[REG_EBX]) # define LINK_REGISTER(context) (context->uc_mcontext.gregs[REG_ECX]) +# define FRAME_REGISTER(context) (context->uc_mcontext.gregs[REG_EBP]) # endif extern "C" uint64_t @@ -68,17 +71,20 @@ dynamicCall(void* function, uintptr_t* arguments, uint8_t*, # define STACK_REGISTER(context) (context->uc_mcontext->__ss.__rsp) # define THREAD_REGISTER(context) (context->uc_mcontext->__ss.__rbx) # define LINK_REGISTER(context) (context->uc_mcontext->__ss.__rcx) +# define FRAME_REGISTER(context) (context->uc_mcontext->__ss.__rbp) # else # define IP_REGISTER(context) (context->uc_mcontext->ss.rip) # define STACK_REGISTER(context) (context->uc_mcontext->ss.rsp) # define THREAD_REGISTER(context) (context->uc_mcontext->ss.rbx) # define LINK_REGISTER(context) (context->uc_mcontext->ss.rcx) +# define FRAME_REGISTER(context) (context->uc_mcontext->ss.rbp) # endif # else # define IP_REGISTER(context) (context->uc_mcontext.gregs[REG_RIP]) # define STACK_REGISTER(context) (context->uc_mcontext.gregs[REG_RSP]) # define THREAD_REGISTER(context) (context->uc_mcontext.gregs[REG_RBX]) # define LINK_REGISTER(context) (context->uc_mcontext.gregs[REG_RCX]) +# define FRAME_REGISTER(context) (context->uc_mcontext.gregs[REG_RBP]) # endif extern "C" uint64_t diff --git a/test/test.sh b/test/test.sh index 72d7734832..defd6af06a 100644 --- a/test/test.sh +++ b/test/test.sh @@ -14,7 +14,7 @@ echo -n "" >${log} echo for test in ${tests}; do - printf "%16s" "${test}: " + printf "%24s" "${test}: " case ${mode} in debug|debug-fast|fast|small )