+#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;i<THREAD_TABLE_SZ;i++) {
+ for(p=GC_threads[i];p!=0;p=p->next) {
+ 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<THREAD_TABLE_SZ...) */
+}
+
+#else /* !DARWIN_DONT_PARSE_STACK; Use FindTopOfStack() */
+