X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=libgc%2Fdarwin_stop_world.c;h=9904a3e1d0f17cb8e63f0f0aafaf9e1919f37fd2;hb=c16b1270273e1dd7bf9870983327414dc4c1c52b;hp=20f3fc7614dde05524fd58512b962dadacf11930;hpb=eb122748b6568629025c17786f2c898a8dcb102b;p=mono.git diff --git a/libgc/darwin_stop_world.c b/libgc/darwin_stop_world.c index 20f3fc7614d..9904a3e1d0f 100644 --- a/libgc/darwin_stop_world.c +++ b/libgc/darwin_stop_world.c @@ -2,6 +2,9 @@ # if defined(GC_DARWIN_THREADS) +#include +#include "mono/utils/mono-compiler.h" + /* From "Inside Mac OS X - Mach-O Runtime Architecture" published by Apple Page 49: "The space beneath the stack pointer, where a new stack frame would normally @@ -72,13 +75,19 @@ void GC_push_all_stacks() { kern_return_t r; GC_thread p; pthread_t me; - ptr_t lo, hi; + ptr_t lo, hi, altstack_lo, altstack_hi; #if defined(POWERPC) ppc_thread_state_t state; mach_msg_type_number_t thread_state_count = PPC_THREAD_STATE_COUNT; #elif defined(I386) i386_thread_state_t state; mach_msg_type_number_t thread_state_count = i386_THREAD_STATE_COUNT; +#elif defined(ARM) + arm_thread_state_t state; + mach_msg_type_number_t thread_state_count = ARM_THREAD_STATE_COUNT; +#elif defined(X86_64) + x86_thread_state64_t state; + mach_msg_type_number_t thread_state_count = x86_THREAD_STATE64_COUNT; #else # error FIXME for non-x86 || ppc architectures mach_msg_type_number_t thread_state_count = MACHINE_THREAD_STATE_COUNT; @@ -99,10 +108,11 @@ void GC_push_all_stacks() { GC_MACH_THREAD_STATE_FLAVOR, (natural_t*)&state, &thread_state_count); - if(r != KERN_SUCCESS) ABORT("thread_get_state failed"); + if(r != KERN_SUCCESS) continue; #if defined(I386) -#if defined(_STRUCT_X86_EXCEPTION_STATE32) +#if defined (TARGET_IOS) || (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5) + lo = state.__esp; GC_push_one(state.__eax); @@ -123,8 +133,25 @@ void GC_push_all_stacks() { GC_push_one(state.esi); GC_push_one(state.ebp); #endif +#elif defined(X86_64) + lo = state.__rsp; + GC_push_one(state.__rax); + GC_push_one(state.__rbx); + GC_push_one(state.__rcx); + GC_push_one(state.__rdx); + GC_push_one(state.__rdi); + GC_push_one(state.__rsi); + GC_push_one(state.__rbp); + GC_push_one(state.__r8); + GC_push_one(state.__r9); + GC_push_one(state.__r10); + GC_push_one(state.__r11); + GC_push_one(state.__r12); + GC_push_one(state.__r13); + GC_push_one(state.__r14); + GC_push_one(state.__r15); #elif defined(POWERPC) -#if defined(_STRUCT_PPC_EXCEPTION_STATE) +#if defined(_STRUCT_PPC_EXCEPTION_STATE) && defined(__DARWIN_UNIX03) lo = (void*)(state.__r1 - PPC_RED_ZONE_SIZE); GC_push_one(state.__r0); @@ -193,6 +220,26 @@ void GC_push_all_stacks() { GC_push_one(state.r30); GC_push_one(state.r31); #endif +#elif defined(ARM) + lo = (void*)state.__sp; + + GC_push_one(state.__r[0]); + GC_push_one(state.__r[1]); + GC_push_one(state.__r[2]); + GC_push_one(state.__r[3]); + GC_push_one(state.__r[4]); + GC_push_one(state.__r[5]); + GC_push_one(state.__r[6]); + GC_push_one(state.__r[7]); + GC_push_one(state.__r[8]); + GC_push_one(state.__r[9]); + GC_push_one(state.__r[10]); + GC_push_one(state.__r[11]); + GC_push_one(state.__r[12]); + /* GC_push_one(state.__sp); */ + GC_push_one(state.__lr); + GC_push_one(state.__pc); + GC_push_one(state.__cpsr); #else # error FIXME for non-x86 || ppc architectures #endif @@ -201,6 +248,16 @@ void GC_push_all_stacks() { hi = GC_stackbottom; else hi = p->stack_end; + + if (p->altstack && lo >= p->altstack && lo <= p->altstack + p->altstack_size) { + altstack_lo = lo; + altstack_hi = p->altstack + p->altstack_size; + lo = (char*)p->stack; + hi = (char*)p->stack + p->stack_size; + } else { + altstack_lo = NULL; + } + #if DEBUG_THREADS GC_printf3("Darwin: Stack for thread 0x%lx = [%lx,%lx)\n", (unsigned long) p -> id, @@ -208,7 +265,10 @@ void GC_push_all_stacks() { (unsigned long) hi ); #endif - GC_push_all_stack(lo,hi); + if (lo) + GC_push_all_stack(lo,hi); + if (altstack_lo) + GC_push_all_stack(altstack_lo,altstack_hi); } /* for(p=GC_threads[i]...) */ } /* for(i=0;i= MAC_OS_X_VERSION_10_5) lo = (void*)info.__esp; hi = (ptr_t)FindTopOfStack(info.__esp); @@ -366,7 +426,34 @@ void GC_push_all_stacks() { GC_push_one(info.fs); GC_push_one(info.gs); #endif -# endif /* !POWERPC */ +# elif defined(ARM) /* !I386 */ + arm_thread_state_t info; + mach_msg_type_number_t outCount = THREAD_STATE_MAX; + r = thread_get_state(thread, GC_MACH_THREAD_STATE_FLAVOR, + (natural_t *)&info, &outCount); + if(r != KERN_SUCCESS) continue; + + lo = (void*)info.__sp; + hi = (ptr_t)FindTopOfStack(info.__sp); + + GC_push_one(info.__r[0]); + GC_push_one(info.__r[1]); + GC_push_one(info.__r[2]); + GC_push_one(info.__r[3]); + GC_push_one(info.__r[4]); + GC_push_one(info.__r[5]); + GC_push_one(info.__r[6]); + GC_push_one(info.__r[7]); + GC_push_one(info.__r[8]); + GC_push_one(info.__r[9]); + GC_push_one(info.__r[10]); + GC_push_one(info.__r[11]); + GC_push_one(info.__r[12]); + /* GC_push_one(info.__sp); */ + GC_push_one(info.__lr); + GC_push_one(info.__pc); + GC_push_one(info.__cpsr); +# endif /* !ARM */ } # if DEBUG_THREADS GC_printf3("Darwin: Stack for thread 0x%lx = [%lx,%lx)\n", @@ -491,6 +578,10 @@ void GC_stop_world() thread_act_array_t act_list, prev_list; mach_msg_type_number_t listcount, prevcount; + if (GC_notify_event) + GC_notify_event (GC_EVENT_PRE_STOP_WORLD); + GC_process_togglerefs (); + # if DEBUG_THREADS GC_printf1("Stopping the world from 0x%lx\n", mach_thread_self()); # endif @@ -561,6 +652,9 @@ void GC_stop_world() #endif mach_port_deallocate(my_task, my_thread); + + if (GC_notify_event) + GC_notify_event (GC_EVENT_POST_STOP_WORLD); } /* Caller holds allocation lock, and has held it continuously since */ @@ -576,6 +670,9 @@ void GC_start_world() mach_msg_type_number_t listcount; struct thread_basic_info info; mach_msg_type_number_t outCount = THREAD_INFO_MAX; + + if (GC_notify_event) + GC_notify_event (GC_EVENT_PRE_START_WORLD); # if DEBUG_THREADS GC_printf0("World starting\n"); @@ -622,6 +719,10 @@ void GC_start_world() vm_deallocate(my_task, (vm_address_t)act_list, sizeof(thread_t) * listcount); mach_port_deallocate(my_task, my_thread); + + if (GC_notify_event) + GC_notify_event (GC_EVENT_POST_START_WORLD); + # if DEBUG_THREADS GC_printf0("World started\n"); # endif