[vmkit-commits] [vmkit] r199010 - Transparent trampoline for the stack (important for libunwind)
Gael Thomas
gael.thomas at lip6.fr
Sat Jan 11 07:22:13 PST 2014
Author: gthomas
Date: Sat Jan 11 09:22:13 2014
New Revision: 199010
URL: http://llvm.org/viewvc/llvm-project?rev=199010&view=rev
Log:
Transparent trampoline for the stack (important for libunwind)
Modified:
vmkit/branches/mcjit/include/j3/j3arch-dep.h
vmkit/branches/mcjit/include/j3/j3thread.h
vmkit/branches/mcjit/include/j3/j3trampoline.h
vmkit/branches/mcjit/include/vmkit/allocator.h
vmkit/branches/mcjit/lib/j3/vm/j3.cc
vmkit/branches/mcjit/lib/j3/vm/j3arch-dep.s
vmkit/branches/mcjit/lib/j3/vm/j3trampoline.cc
vmkit/branches/mcjit/lib/vmkit/allocator.cc
vmkit/branches/mcjit/lib/vmkit/thread.cc
Modified: vmkit/branches/mcjit/include/j3/j3arch-dep.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/include/j3/j3arch-dep.h?rev=199010&r1=199009&r2=199010&view=diff
==============================================================================
--- vmkit/branches/mcjit/include/j3/j3arch-dep.h (original)
+++ vmkit/branches/mcjit/include/j3/j3arch-dep.h Sat Jan 11 09:22:13 2014
@@ -1,6 +1,13 @@
#ifndef _J3_ARCH_DEP_H_
#define _J3_ARCH_DEP_H_
-#define TRAMPOLINE_SAVE_ZONE (8*16 + 6*8 + 2*8)
+namespace j3 {
+ class J3Method;
+
+ class J3TrampolineArg {
+ uint64_t savee[8*2 + 6 + 2];
+ /* xmm0 - xmm7 + %rdi/%rsi/%rdx/%rcx/%r8/%r9 + %rbp, %rsp */
+ };
+}
#endif
Modified: vmkit/branches/mcjit/include/j3/j3thread.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/include/j3/j3thread.h?rev=199010&r1=199009&r2=199010&view=diff
==============================================================================
--- vmkit/branches/mcjit/include/j3/j3thread.h (original)
+++ vmkit/branches/mcjit/include/j3/j3thread.h Sat Jan 11 09:22:13 2014
@@ -17,7 +17,6 @@ namespace j3 {
class J3Thread : public vmkit::Thread {
friend class J3Monitor;
friend class J3CodeGen;
- friend class J3Trampoline;
static const uint32_t gepInterfaceMethodIndex = 1;
uint32_t _interfaceMethodIndex;
@@ -28,7 +27,9 @@ namespace j3 {
J3LocalReferences _localReferences;
J3ObjectHandle* _pendingException;
J3ObjectHandle _javaThread;
- char _trampolineSaveZone[TRAMPOLINE_SAVE_ZONE];
+ public:
+ J3TrampolineArg _trampolineArg;
+ private:
virtual void run();
static void doRun();
Modified: vmkit/branches/mcjit/include/j3/j3trampoline.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/include/j3/j3trampoline.h?rev=199010&r1=199009&r2=199010&view=diff
==============================================================================
--- vmkit/branches/mcjit/include/j3/j3trampoline.h (original)
+++ vmkit/branches/mcjit/include/j3/j3trampoline.h Sat Jan 11 09:22:13 2014
@@ -3,13 +3,10 @@
#include <stdint.h>
-extern "C" uintptr_t trampoline_mask;
-extern "C" uintptr_t trampoline_offset;
extern "C" char trampoline_generic;
extern "C" char trampoline_generic_method;
extern "C" char trampoline_generic_resolver;
extern "C" char trampoline_generic_end;
-extern "C" char trampoline_save;
extern "C" void trampoline_restart(void* ptr, void* saveZone);
namespace vmkit {
@@ -21,9 +18,9 @@ namespace j3 {
class J3Object;
class J3Trampoline {
- static void* interfaceTrampoline(J3Object* obj);
- static void* staticTrampoline(J3Object* obj, J3Method* ref);
- static void* virtualTrampoline(J3Object* obj, J3Method* ref);
+ static void interfaceTrampoline(J3Object* obj);
+ static void staticTrampoline(J3Object* obj, J3Method* ref);
+ static void virtualTrampoline(J3Object* obj, J3Method* ref);
static void* buildTrampoline(vmkit::BumpAllocator* allocator, J3Method* method, void* tra);
public:
Modified: vmkit/branches/mcjit/include/vmkit/allocator.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/include/vmkit/allocator.h?rev=199010&r1=199009&r2=199010&view=diff
==============================================================================
--- vmkit/branches/mcjit/include/vmkit/allocator.h (original)
+++ vmkit/branches/mcjit/include/vmkit/allocator.h Sat Jan 11 09:22:13 2014
@@ -119,29 +119,26 @@ namespace vmkit {
class ThreadAllocator {
static const uint32_t refill = 128;
- static ThreadAllocator* _allocator;
+ static pthread_mutex_t mutex;
+ static uintptr_t baseStack;
+ static uintptr_t topStack;
+ static uintptr_t _magic;
+ static std::vector<void*>* spaces;
+ static std::vector<void*>* freeThreads;
- pthread_mutex_t mutex;
- std::vector<void*> spaces;
- std::vector<void*> freeThreads;
- uintptr_t baseStack;
- uintptr_t topStack;
-
- ThreadAllocator(uintptr_t minThreadStruct, uintptr_t minFullSize);
public:
static void initialize(uintptr_t minThreadStruct, uintptr_t minFullSize);
- static ThreadAllocator* allocator() { return _allocator; }
- void* allocate();
- void release(void* thread);
+ static void* allocate();
+ static void release(void* thread);
- void* alternateStackAddr(void* thread);
- size_t alternateStackSize(void* thread);
+ static void* alternateStackAddr(void* thread);
+ static size_t alternateStackSize(void* thread);
- void* stackAddr(void* thread);
- size_t stackSize(void* thread);
+ static void* stackAddr(void* thread);
+ static size_t stackSize(void* thread);
- uintptr_t magic() { return -topStack; }
+ static uintptr_t magic() { return _magic; }
};
} // end namespace vmkit
Modified: vmkit/branches/mcjit/lib/j3/vm/j3.cc
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/lib/j3/vm/j3.cc?rev=199010&r1=199009&r2=199010&view=diff
==============================================================================
--- vmkit/branches/mcjit/lib/j3/vm/j3.cc (original)
+++ vmkit/branches/mcjit/lib/j3/vm/j3.cc Sat Jan 11 09:22:13 2014
@@ -70,7 +70,6 @@ void J3::start(int argc, char** argv) {
_options.process(argc, argv);
vmkit::ThreadAllocator::initialize(sizeof(J3Thread), options()->stackSize);
- J3Trampoline::initialize(vmkit::Thread::getThreadMask());
J3Thread* thread = new J3ThreadBootstrap(this);
Modified: vmkit/branches/mcjit/lib/j3/vm/j3arch-dep.s
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/lib/j3/vm/j3arch-dep.s?rev=199010&r1=199009&r2=199010&view=diff
==============================================================================
--- vmkit/branches/mcjit/lib/j3/vm/j3arch-dep.s (original)
+++ vmkit/branches/mcjit/lib/j3/vm/j3arch-dep.s Sat Jan 11 09:22:13 2014
@@ -1,44 +1,27 @@
.section __DATA,__data
- .globl _trampoline_mask, _trampoline_offset
+ .globl _trampoline_offset, __ZN5vmkit15ThreadAllocator6_magicE
.globl _trampoline_generic, _trampoline_generic_method, _trampoline_generic_resolver, _trampoline_generic_end
-_trampoline_mask:
- .quad 0
-_trampoline_offset:
- .quad 0
-
_trampoline_generic:
- .byte 0x48, 0xb8 /* mov _trampoline_save, %rax (absolute adressing, what is the mnemonic?) */
- .quad _trampoline_save
+ movabsq $_trampoline_save, %rax /* absolute to avoid any problem of relocation */
callq *%rax
- mov %rsp, 184(%rax)
- .byte 0x48, 0xbe /* mov _trampoline_generic_method, %rsi */
+ .byte 0x48, 0xbe /* movabsq _trampoline_generic_method, %rsi (i.e., replace second arg) */
_trampoline_generic_method:
.quad 0
- .byte 0x48, 0xb8 /* mov _trampoline_generic_resolver, %rax */
+ .byte 0x48, 0xb8 /* movabsq _trampoline_generic_resolver, %rax */
_trampoline_generic_resolver:
.quad 0
jmpq *%rax
_trampoline_generic_end:
.section __TEXT,__text,regular,pure_instructions
- .globl _trampoline_save, _trampoline_restart
+ .globl _trampoline_restart
.align 4
- /* compute the adress of the save zone area */
- /* and return the adress in %rax */
-_trampoline_get_save_zone:
- push %rbx
- mov %rsp, %rax
- movq _trampoline_mask(%rip), %rbx
- and %rbx, %rax
- movq _trampoline_offset(%rip), %rbx
- add %rbx, %rax
- pop %rbx
- ret
-
_trampoline_save:
- call _trampoline_get_save_zone
+ mov %rsp, %rax
+ and __ZN5vmkit15ThreadAllocator6_magicE(%rip), %rax
+ add _trampoline_offset(%rip), %rax
mov %xmm0, 0(%rax)
mov %xmm1, 16(%rax)
@@ -55,11 +38,14 @@ _trampoline_save:
mov %r8, 160(%rax)
mov %r9, 168(%rax)
mov %rbp, 176(%rax)
-
+ mov %rsp, 184(%rax)
+ addq $8, 184(%rax) /* my own call :) */
+
ret
- /* %rdi contains the function */
- /* %rsi contains the save zone area */
+ /* void trampoline_restart(void* ptr, void* saveZone); */
+ /* %rsi: saveZone */
+ /* %rdi: pointer to function */
_trampoline_restart:
mov %rdi, %rax
Modified: vmkit/branches/mcjit/lib/j3/vm/j3trampoline.cc
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/lib/j3/vm/j3trampoline.cc?rev=199010&r1=199009&r2=199010&view=diff
==============================================================================
--- vmkit/branches/mcjit/lib/j3/vm/j3trampoline.cc (original)
+++ vmkit/branches/mcjit/lib/j3/vm/j3trampoline.cc Sat Jan 11 09:22:13 2014
@@ -8,8 +8,10 @@
using namespace j3;
-void* J3Trampoline::interfaceTrampoline(J3Object* obj) {
- J3::internalError("implement me it");
+extern "C" uintptr_t trampoline_offset = (uint64_t)&((J3Thread*)0)->_trampolineArg;
+
+void J3Trampoline::interfaceTrampoline(J3Object* obj) {
+ J3TrampolineArg arg = J3Thread::get()->_trampolineArg;
J3ObjectHandle* prev = J3Thread::get()->tell();
J3ObjectHandle* handle = J3Thread::get()->push(obj);
J3ObjectType* type = obj->vt()->type()->asObjectType();
@@ -30,20 +32,17 @@ void* J3Trampoline::interfaceTrampoline(
J3Thread::get()->restore(prev);
- return res;
+ trampoline_restart(res, &arg);
}
-void* J3Trampoline::staticTrampoline(J3Object* obj, J3Method* target) {
- char saveZone[TRAMPOLINE_SAVE_ZONE];
- memcpy(saveZone, J3Thread::get()->_trampolineSaveZone, TRAMPOLINE_SAVE_ZONE);
+void J3Trampoline::staticTrampoline(J3Object* obj, J3Method* target) {
+ J3TrampolineArg arg = J3Thread::get()->_trampolineArg;
target->ensureCompiled(0);
- //return target->fnPtr();
- trampoline_restart(target->fnPtr(), saveZone);
- return 0;
+ trampoline_restart(target->fnPtr(), &arg);
}
-void* J3Trampoline::virtualTrampoline(J3Object* obj, J3Method* target) {
- J3::internalError("implement me vt");
+void J3Trampoline::virtualTrampoline(J3Object* obj, J3Method* target) {
+ J3TrampolineArg arg = J3Thread::get()->_trampolineArg;
J3ObjectHandle* prev = J3Thread::get()->tell();
J3ObjectHandle* handle = J3Thread::get()->push(obj);
J3ObjectType* cl = handle->vt()->type()->asObjectType();
@@ -55,7 +54,7 @@ void* J3Trampoline::virtualTrampoline(J3
J3Thread::get()->restore(prev);
- return res;
+ trampoline_restart(res, &arg);
}
void* J3Trampoline::buildTrampoline(vmkit::BumpAllocator* allocator, J3Method* m, void* tra) {
@@ -82,9 +81,3 @@ void* J3Trampoline::buildInterfaceTrampo
return buildTrampoline(allocator, 0, (void*)interfaceTrampoline);
}
-void J3Trampoline::initialize(uintptr_t mask) {
- J3Thread* thread = J3Thread::get();
- trampoline_mask = mask;
- trampoline_offset = (uintptr_t)&thread->_trampolineSaveZone - (uintptr_t)thread;
-}
-
Modified: vmkit/branches/mcjit/lib/vmkit/allocator.cc
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/lib/vmkit/allocator.cc?rev=199010&r1=199009&r2=199010&view=diff
==============================================================================
--- vmkit/branches/mcjit/lib/vmkit/allocator.cc (original)
+++ vmkit/branches/mcjit/lib/vmkit/allocator.cc Sat Jan 11 09:22:13 2014
@@ -8,7 +8,12 @@
using namespace vmkit;
-ThreadAllocator* ThreadAllocator::_allocator = 0;
+pthread_mutex_t ThreadAllocator::mutex;
+uintptr_t ThreadAllocator::baseStack = 0;
+uintptr_t ThreadAllocator::topStack = 0;
+uintptr_t ThreadAllocator::_magic = 0;
+std::vector<void*>* ThreadAllocator::spaces = 0;
+std::vector<void*>* ThreadAllocator::freeThreads = 0;
void* BumpAllocator::operator new(size_t n) {
return (void*)((uintptr_t)map(bucketSize) + sizeof(BumpAllocatorNode));
@@ -89,10 +94,15 @@ void PermanentObject::operator delete[](
Thread::get()->vm()->internalError("should not happen");
}
-ThreadAllocator::ThreadAllocator(uintptr_t minThreadStruct, uintptr_t minFullSize) {
+void ThreadAllocator::initialize(uintptr_t minThreadStruct, uintptr_t minFullSize) {
+ if(spaces)
+ VMKit::internalError("thread allocation system is already initialized");
+ spaces = new std::vector<void*>();
+ freeThreads = new std::vector<void*>();
+
pthread_mutex_init(&mutex, 0);
- spaces.reserve(1);
- freeThreads.reserve(refill);
+ spaces->reserve(1);
+ freeThreads->reserve(refill);
minThreadStruct = ((minThreadStruct - 1) & -PAGE_SIZE) + PAGE_SIZE;
baseStack = minThreadStruct + PAGE_SIZE;
@@ -102,19 +112,12 @@ ThreadAllocator::ThreadAllocator(uintptr
minFullSize = min;
topStack = 1L << (__builtin_clzl(0) - __builtin_clzl(minFullSize-1));
-}
-
-void ThreadAllocator::initialize(uintptr_t minThreadStruct, uintptr_t minFullSize) {
- if(_allocator) {
- fprintf(stderr, "Never try to modify the thread structure layout dynamically\n");
- abort();
- }
- _allocator = new ThreadAllocator(minThreadStruct, minFullSize);
+ _magic = -topStack;
}
void* ThreadAllocator::allocate() {
pthread_mutex_lock(&mutex);
- if(!freeThreads.size()) {
+ if(!freeThreads->size()) {
void* space = mmap(0, topStack*refill, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
if(space == MAP_FAILED) {
@@ -122,27 +125,27 @@ void* ThreadAllocator::allocate() {
abort();
}
- spaces.push_back(space);
+ spaces->push_back(space);
uintptr_t base = (((uintptr_t)space - 1) & -topStack) + topStack;
uint32_t n = (base == (uintptr_t)space) ? refill : (refill - 1);
for(uint32_t i=0; i<n; i++) {
mprotect((void*)(base + baseStack), PROT_NONE, PAGE_SIZE);
- freeThreads.push_back((void*)base);
+ freeThreads->push_back((void*)base);
base += topStack;
}
}
- void* res = freeThreads.back();
- freeThreads.pop_back();
+ void* res = freeThreads->back();
+ freeThreads->pop_back();
pthread_mutex_unlock(&mutex);
return res;
}
void ThreadAllocator::release(void* thread) {
pthread_mutex_lock(&mutex);
- freeThreads.push_back(thread);
+ freeThreads->push_back(thread);
pthread_mutex_unlock(&mutex);
}
Modified: vmkit/branches/mcjit/lib/vmkit/thread.cc
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/lib/vmkit/thread.cc?rev=199010&r1=199009&r2=199010&view=diff
==============================================================================
--- vmkit/branches/mcjit/lib/vmkit/thread.cc (original)
+++ vmkit/branches/mcjit/lib/vmkit/thread.cc Sat Jan 11 09:22:13 2014
@@ -13,11 +13,11 @@ void Thread::sigsegvHandler(int n, sigin
}
void* Thread::operator new(size_t n) {
- return ThreadAllocator::allocator()->allocate();
+ return ThreadAllocator::allocate();
}
void Thread::operator delete(void* p) {
- ThreadAllocator::allocator()->release(p);
+ ThreadAllocator::release(p);
}
Thread* Thread::get() {
@@ -29,7 +29,7 @@ Thread* Thread::get(void* ptr) {
}
uintptr_t Thread::getThreadMask() {
- return ThreadAllocator::allocator()->magic();
+ return ThreadAllocator::magic();
}
void Thread::registerSignalInternal(int n, sa_action_t handler, bool altStack) {
@@ -58,9 +58,9 @@ void* Thread::doRun(void* _thread) {
// Set the alternate stack as the second page of the thread's
// stack.
stack_t st;
- st.ss_sp = ThreadAllocator::allocator()->alternateStackAddr(thread);
+ st.ss_sp = ThreadAllocator::alternateStackAddr(thread);
st.ss_flags = 0;
- st.ss_size = ThreadAllocator::allocator()->alternateStackSize(thread);
+ st.ss_size = ThreadAllocator::alternateStackSize(thread);
sigaltstack(&st, NULL);
thread->registerSignalInternal(SIGSEGV, sigsegvHandler, 1);
@@ -74,7 +74,7 @@ void Thread::start() {
pthread_attr_t attr;
pthread_attr_init(&attr);
- pthread_attr_setstack(&attr, ThreadAllocator::allocator()->stackAddr(this), ThreadAllocator::allocator()->stackSize(this));
+ pthread_attr_setstack(&attr, ThreadAllocator::stackAddr(this), ThreadAllocator::stackSize(this));
pthread_create(&_tid, &attr, doRun, this);
More information about the vmkit-commits
mailing list