X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=libgc%2Fdarwin_stop_world.c;h=d3b94feb258c402830b94e3d3a200251073f41df;hb=a3ed5ef01f233106f82c7b3c709473f54f1dad49;hp=3c2d8cfa655d44bb725e80733aa5cd662abea67b;hpb=c4a3b30460c7ea1a1fb3c97cfc8478555714af2f;p=mono.git diff --git a/libgc/darwin_stop_world.c b/libgc/darwin_stop_world.c index 3c2d8cfa655..d3b94feb258 100644 --- a/libgc/darwin_stop_world.c +++ b/libgc/darwin_stop_world.c @@ -75,12 +75,17 @@ void GC_push_all_stacks() { ptr_t lo, 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; #else # error FIXME for non-x86 || ppc architectures -#endif mach_msg_type_number_t thread_state_count = MACHINE_THREAD_STATE_COUNT; +#endif me = pthread_self(); if (!GC_thr_initialized) GC_thr_init(); @@ -94,12 +99,23 @@ void GC_push_all_stacks() { /* Get the thread state (registers, etc) */ r = thread_get_state( p->stop_info.mach_thread, - MACHINE_THREAD_STATE, + GC_MACH_THREAD_STATE_FLAVOR, (natural_t*)&state, &thread_state_count); if(r != KERN_SUCCESS) ABORT("thread_get_state failed"); #if defined(I386) +#if defined(_STRUCT_X86_EXCEPTION_STATE32) + lo = state.__esp; + + GC_push_one(state.__eax); + GC_push_one(state.__ebx); + GC_push_one(state.__ecx); + GC_push_one(state.__edx); + GC_push_one(state.__edi); + GC_push_one(state.__esi); + GC_push_one(state.__ebp); +#else lo = state.esp; GC_push_one(state.eax); @@ -109,7 +125,43 @@ void GC_push_all_stacks() { GC_push_one(state.edi); GC_push_one(state.esi); GC_push_one(state.ebp); +#endif #elif defined(POWERPC) +#if defined(_STRUCT_PPC_EXCEPTION_STATE) + lo = (void*)(state.__r1 - PPC_RED_ZONE_SIZE); + + GC_push_one(state.__r0); + GC_push_one(state.__r2); + GC_push_one(state.__r3); + GC_push_one(state.__r4); + GC_push_one(state.__r5); + GC_push_one(state.__r6); + GC_push_one(state.__r7); + 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); + GC_push_one(state.__r16); + GC_push_one(state.__r17); + GC_push_one(state.__r18); + GC_push_one(state.__r19); + GC_push_one(state.__r20); + GC_push_one(state.__r21); + GC_push_one(state.__r22); + GC_push_one(state.__r23); + GC_push_one(state.__r24); + GC_push_one(state.__r25); + GC_push_one(state.__r26); + GC_push_one(state.__r27); + GC_push_one(state.__r28); + GC_push_one(state.__r29); + GC_push_one(state.__r30); + GC_push_one(state.__r31); +#else lo = (void*)(state.r1 - PPC_RED_ZONE_SIZE); GC_push_one(state.r0); @@ -143,6 +195,27 @@ void GC_push_all_stacks() { GC_push_one(state.r29); 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 @@ -193,10 +266,46 @@ void GC_push_all_stacks() { ppc_thread_state64_t info; # endif mach_msg_type_number_t outCount = THREAD_STATE_MAX; - r = thread_get_state(thread, MACHINE_THREAD_STATE, + r = thread_get_state(thread, GC_MACH_THREAD_STATE_FLAVOR, (natural_t *)&info, &outCount); if(r != KERN_SUCCESS) continue; +#if defined(_STRUCT_PPC_EXCEPTION_STATE) + lo = (void*)(info.__r1 - PPC_RED_ZONE_SIZE); + hi = (ptr_t)FindTopOfStack(info.__r1); + + GC_push_one(info.__r0); + GC_push_one(info.__r2); + GC_push_one(info.__r3); + GC_push_one(info.__r4); + GC_push_one(info.__r5); + GC_push_one(info.__r6); + GC_push_one(info.__r7); + GC_push_one(info.__r8); + GC_push_one(info.__r9); + GC_push_one(info.__r10); + GC_push_one(info.__r11); + GC_push_one(info.__r12); + GC_push_one(info.__r13); + GC_push_one(info.__r14); + GC_push_one(info.__r15); + GC_push_one(info.__r16); + GC_push_one(info.__r17); + GC_push_one(info.__r18); + GC_push_one(info.__r19); + GC_push_one(info.__r20); + GC_push_one(info.__r21); + GC_push_one(info.__r22); + GC_push_one(info.__r23); + GC_push_one(info.__r24); + GC_push_one(info.__r25); + GC_push_one(info.__r26); + GC_push_one(info.__r27); + GC_push_one(info.__r28); + GC_push_one(info.__r29); + GC_push_one(info.__r30); + GC_push_one(info.__r31); +#else lo = (void*)(info.r1 - PPC_RED_ZONE_SIZE); hi = (ptr_t)FindTopOfStack(info.r1); @@ -231,15 +340,36 @@ void GC_push_all_stacks() { GC_push_one(info.r29); GC_push_one(info.r30); GC_push_one(info.r31); -# else +#endif +# elif defined(I386) /* !POWERPC */ /* FIXME: Remove after testing: */ WARN("This is completely untested and likely will not work\n", 0); i386_thread_state_t info; mach_msg_type_number_t outCount = THREAD_STATE_MAX; - r = thread_get_state(thread, MACHINE_THREAD_STATE, + r = thread_get_state(thread, GC_MACH_THREAD_STATE_FLAVOR, (natural_t *)&info, &outCount); if(r != KERN_SUCCESS) continue; +#if defined(_STRUCT_X86_EXCEPTION_STATE32) + lo = (void*)info.__esp; + hi = (ptr_t)FindTopOfStack(info.__esp); + + GC_push_one(info.__eax); + GC_push_one(info.__ebx); + GC_push_one(info.__ecx); + GC_push_one(info.__edx); + GC_push_one(info.__edi); + GC_push_one(info.__esi); + GC_push_one(info.__ebp); + /* GC_push_one(info.__esp); */ + GC_push_one(info.__ss); + GC_push_one(info.__eip); + GC_push_one(info.__cs); + GC_push_one(info.__ds); + GC_push_one(info.__es); + GC_push_one(info.__fs); + GC_push_one(info.__gs); +#else lo = (void*)info.esp; hi = (ptr_t)FindTopOfStack(info.esp); @@ -249,7 +379,7 @@ void GC_push_all_stacks() { GC_push_one(info.edx); GC_push_one(info.edi); GC_push_one(info.esi); - /* GC_push_one(info.ebp); */ + GC_push_one(info.ebp); /* GC_push_one(info.esp); */ GC_push_one(info.ss); GC_push_one(info.eip); @@ -258,7 +388,35 @@ void GC_push_all_stacks() { GC_push_one(info.es); GC_push_one(info.fs); GC_push_one(info.gs); -# endif /* !POWERPC */ +#endif +# 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", @@ -278,13 +436,14 @@ void GC_push_all_stacks() { static mach_port_t GC_mach_handler_thread; static int GC_use_mach_handler_thread = 0; -static struct GC_mach_thread GC_mach_threads[THREAD_TABLE_SZ]; +#define SUSPEND_THREADS_SIZE 2048 +static struct GC_mach_thread GC_mach_threads[SUSPEND_THREADS_SIZE]; static int GC_mach_threads_count; void GC_stop_init() { int i; - for (i = 0; i < THREAD_TABLE_SZ; i++) { + for (i = 0; i < SUSPEND_THREADS_SIZE; i++) { GC_mach_threads[i].thread = 0; GC_mach_threads[i].already_suspended = 0; } @@ -411,24 +570,31 @@ void GC_stop_world() prev_list = NULL; prevcount = 0; do { - int result; + int result; kern_result = task_threads(my_task, &act_list, &listcount); - result = GC_suspend_thread_list(act_list, listcount, - prev_list, prevcount); - changes = result; - prev_list = act_list; - prevcount = listcount; - if(kern_result == KERN_SUCCESS) { - int i; + if(kern_result == KERN_SUCCESS) { + result = GC_suspend_thread_list(act_list, listcount, + prev_list, prevcount); + changes = result; - for(i = 0; i < listcount; i++) - mach_port_deallocate(my_task, act_list[i]); + if(prev_list != NULL) { + for(i = 0; i < prevcount; i++) + mach_port_deallocate(my_task, prev_list[i]); + + vm_deallocate(my_task, (vm_address_t)prev_list, sizeof(thread_t) * prevcount); + } - vm_deallocate(my_task, (vm_address_t)act_list, sizeof(thread_t) * listcount); - } + prev_list = act_list; + prevcount = listcount; + } } while (changes); - + + for(i = 0; i < listcount; i++) + mach_port_deallocate(my_task, act_list[i]); + + vm_deallocate(my_task, (vm_address_t)act_list, sizeof(thread_t) * listcount); + # ifdef MPROTECT_VDB if(GC_incremental) {