+#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, 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;
+#endif
+
+ 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_FLAVOR,
+ (natural_t*)&state,
+ &thread_state_count);
+ if(r != KERN_SUCCESS) continue;
+
+#if defined(I386)
+#if defined (TARGET_IOS) || (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5)
+
+ 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);
+ 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);
+#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) && defined(__DARWIN_UNIX03)
+ 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);
+ 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);
+#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
+ } /* p != me */
+ if(p->flags & MAIN_THREAD)
+ 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,
+ (unsigned long) lo,
+ (unsigned long) hi
+ );
+#endif
+ 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<THREAD_TABLE_SZ...) */
+}
+
+#else /* !DARWIN_DONT_PARSE_STACK; Use FindTopOfStack() */
+