X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=boehm-gc%2Fdarwin_stop_world.c;h=719b1b02d35ee474f7e4b0d9242c410fa59dc559;hb=f4d4d18fe0ff271bfcc74d3303dd44f5bf668bb9;hp=2fad9474716bf9983da10b0e7c20b2e2db1d25c9;hpb=acccd380933dd5679854ee5bfce3014d202991d4;p=pf3gnuchains%2Fgcc-fork.git diff --git a/boehm-gc/darwin_stop_world.c b/boehm-gc/darwin_stop_world.c index 2fad9474716..719b1b02d35 100644 --- a/boehm-gc/darwin_stop_world.c +++ b/boehm-gc/darwin_stop_world.c @@ -10,11 +10,15 @@ be allocated, is called the red zone. This area as shown in Figure 3-2 may be used for any purpose as long as a new stack frame does not need to be added to the stack." - + Page 50: "If a leaf procedure's red zone usage would exceed 224 bytes, then it must set up a stack frame just like routines that call other routines." */ -#define PPC_RED_ZONE_SIZE 224 +#if defined(__ppc__) +# define PPC_RED_ZONE_SIZE 224 +#elif defined(__ppc64__) +# define PPC_RED_ZONE_SIZE 320 +#endif typedef struct StackFrame { unsigned long savedSP; @@ -24,12 +28,17 @@ typedef struct StackFrame { unsigned long savedRTOC; } StackFrame; - -unsigned int FindTopOfStack(unsigned int stack_start) { +unsigned long FindTopOfStack(unsigned long stack_start) { StackFrame *frame; if (stack_start == 0) { - __asm__ volatile("lwz %0,0(r1)" : "=r" (frame)); +# ifdef POWERPC +# if CPP_WORDSZ == 32 + __asm__ volatile("lwz %0,0(r1)" : "=r" (frame)); +# else + __asm__ volatile("ld %0,0(r1)" : "=r" (frame)); +# endif +# endif } else { frame = (StackFrame *)stack_start; } @@ -38,7 +47,7 @@ unsigned int FindTopOfStack(unsigned int stack_start) { /* GC_printf1("FindTopOfStack start at sp = %p\n", frame); */ # endif do { - if (frame->savedSP == NULL) break; + if (frame->savedSP == 0) break; /* if there are no more stack frames, stop */ frame = (StackFrame*)frame->savedSP; @@ -54,9 +63,125 @@ unsigned int FindTopOfStack(unsigned int stack_start) { /* GC_printf1("FindTopOfStack finish at sp = %p\n", frame); */ # endif - return (unsigned int)frame; + return (unsigned long)frame; } +#ifdef DARWIN_DONT_PARSE_STACK +void GC_push_all_stacks() { + int i; + kern_return_t r; + GC_thread p; + pthread_t me; + ptr_t lo, hi; + GC_THREAD_STATE_T state; + mach_msg_type_number_t thread_state_count = GC_MACH_THREAD_STATE_COUNT; + + me = pthread_self(); + if (!GC_thr_initialized) GC_thr_init(); + + for(i=0;inext) { + if(p -> flags & FINISHED) continue; + if(pthread_equal(p->id,me)) { + lo = GC_approx_sp(); + } else { + /* Get the thread state (registers, etc) */ + r = thread_get_state(p->stop_info.mach_thread, GC_MACH_THREAD_STATE, + (natural_t*)&state, &thread_state_count); + if(r != KERN_SUCCESS) ABORT("thread_get_state failed"); + +#if defined(I386) + lo = (void*)state . THREAD_FLD (esp); + + GC_push_one(state . THREAD_FLD (eax)); + GC_push_one(state . THREAD_FLD (ebx)); + GC_push_one(state . THREAD_FLD (ecx)); + GC_push_one(state . THREAD_FLD (edx)); + GC_push_one(state . THREAD_FLD (edi)); + GC_push_one(state . THREAD_FLD (esi)); + GC_push_one(state . THREAD_FLD (ebp)); + +#elif defined(X86_64) + lo = (void*)state . THREAD_FLD (rsp); + + GC_push_one(state . THREAD_FLD (rax)); + GC_push_one(state . THREAD_FLD (rbx)); + GC_push_one(state . THREAD_FLD (rcx)); + GC_push_one(state . THREAD_FLD (rdx)); + GC_push_one(state . THREAD_FLD (rdi)); + GC_push_one(state . THREAD_FLD (rsi)); + GC_push_one(state . THREAD_FLD (rbp)); + GC_push_one(state . THREAD_FLD (rsp)); + GC_push_one(state . THREAD_FLD (r8)); + GC_push_one(state . THREAD_FLD (r9)); + GC_push_one(state . THREAD_FLD (r10)); + GC_push_one(state . THREAD_FLD (r11)); + GC_push_one(state . THREAD_FLD (r12)); + GC_push_one(state . THREAD_FLD (r13)); + GC_push_one(state . THREAD_FLD (r14)); + GC_push_one(state . THREAD_FLD (r15)); + GC_push_one(state . THREAD_FLD (rip)); + GC_push_one(state . THREAD_FLD (rflags)); + GC_push_one(state . THREAD_FLD (cs)); + GC_push_one(state . THREAD_FLD (fs)); + GC_push_one(state . THREAD_FLD (gs)); + +#elif defined(POWERPC) + lo = (void*)(state . THREAD_FLD (r1) - PPC_RED_ZONE_SIZE); + + GC_push_one(state . THREAD_FLD (r0)); + GC_push_one(state . THREAD_FLD (r2)); + GC_push_one(state . THREAD_FLD (r3)); + GC_push_one(state . THREAD_FLD (r4)); + GC_push_one(state . THREAD_FLD (r5)); + GC_push_one(state . THREAD_FLD (r6)); + GC_push_one(state . THREAD_FLD (r7)); + GC_push_one(state . THREAD_FLD (r8)); + GC_push_one(state . THREAD_FLD (r9)); + GC_push_one(state . THREAD_FLD (r10)); + GC_push_one(state . THREAD_FLD (r11)); + GC_push_one(state . THREAD_FLD (r12)); + GC_push_one(state . THREAD_FLD (r13)); + GC_push_one(state . THREAD_FLD (r14)); + GC_push_one(state . THREAD_FLD (r15)); + GC_push_one(state . THREAD_FLD (r16)); + GC_push_one(state . THREAD_FLD (r17)); + GC_push_one(state . THREAD_FLD (r18)); + GC_push_one(state . THREAD_FLD (r19)); + GC_push_one(state . THREAD_FLD (r20)); + GC_push_one(state . THREAD_FLD (r21)); + GC_push_one(state . THREAD_FLD (r22)); + GC_push_one(state . THREAD_FLD (r23)); + GC_push_one(state . THREAD_FLD (r24)); + GC_push_one(state . THREAD_FLD (r25)); + GC_push_one(state . THREAD_FLD (r26)); + GC_push_one(state . THREAD_FLD (r27)); + GC_push_one(state . THREAD_FLD (r28)); + GC_push_one(state . THREAD_FLD (r29)); + GC_push_one(state . THREAD_FLD (r30)); + GC_push_one(state . THREAD_FLD (r31)); +#else +# error FIXME for non-x86 || ppc architectures +#endif + } /* p != me */ + if(p->flags & MAIN_THREAD) + hi = GC_stackbottom; + else + hi = p->stack_end; +#if DEBUG_THREADS + GC_printf3("Darwin: Stack for thread 0x%lx = [%lx,%lx)\n", + (unsigned long) p -> id, + (unsigned long) lo, + (unsigned long) hi + ); +#endif + GC_push_all_stack(lo,hi); + } /* for(p=GC_threads[i]...) */ + } /* for(i=0;i