Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Molaro <lupus@oddwiz.org>2006-01-24 14:37:10 +0300
committerPaolo Molaro <lupus@oddwiz.org>2006-01-24 14:37:10 +0300
commitd58dfa185af1d48fb93efdef1d046762f214f0a7 (patch)
treef851d10caf20d342811d58d624fcdcbd92fe4151 /libgc/darwin_stop_world.c
parent3be1eb27881d243559d4ab0baf7b538334c7e1b3 (diff)
Tue Jan 24 12:34:06 CET 2006 Paolo Molaro <lupus@ximian.com>
* *: update from upstream changes. svn path=/trunk/mono/; revision=55979
Diffstat (limited to 'libgc/darwin_stop_world.c')
-rw-r--r--libgc/darwin_stop_world.c124
1 files changed, 109 insertions, 15 deletions
diff --git a/libgc/darwin_stop_world.c b/libgc/darwin_stop_world.c
index 60acd83c6bd..692b18db4db 100644
--- a/libgc/darwin_stop_world.c
+++ b/libgc/darwin_stop_world.c
@@ -12,23 +12,33 @@
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
+#ifdef POWERPC
+# if CPP_WORDSZ == 32
+# define PPC_RED_ZONE_SIZE 224
+# elif CPP_WORDSZ == 64
+# define PPC_RED_ZONE_SIZE 320
+# endif
+#endif
-/* Not 64-bit clean. Wait until Apple defines their 64-bit ABI */
typedef struct StackFrame {
- unsigned int savedSP;
- unsigned int savedCR;
- unsigned int savedLR;
- unsigned int reserved[2];
- unsigned int savedRTOC;
+ unsigned long savedSP;
+ unsigned long savedCR;
+ unsigned long savedLR;
+ unsigned long reserved[2];
+ unsigned long savedRTOC;
} StackFrame;
-
-unsigned int FindTopOfStack(unsigned int stack_start) {
+unsigned long FindTopOfStack(unsigned int 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("ldz %0,0(r1)" : "=r" (frame));
+# endif
+# endif
} else {
frame = (StackFrame *)stack_start;
}
@@ -37,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;
@@ -53,9 +63,88 @@ 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;
+ ppc_thread_state_t state;
+ mach_msg_type_number_t thread_state_count = MACHINE_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,
+ MACHINE_THREAD_STATE,
+ (natural_t*)&state,
+ &thread_state_count);
+ if(r != KERN_SUCCESS) ABORT("thread_get_state failed");
+
+ 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);
+ } /* 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() */
+
void GC_push_all_stacks() {
int i;
kern_return_t r;
@@ -75,8 +164,12 @@ void GC_push_all_stacks() {
lo = GC_approx_sp();
hi = (ptr_t)FindTopOfStack(0);
} else {
-# ifdef POWERPC
+# if defined(POWERPC)
+# if CPP_WORDSZ == 32
ppc_thread_state_t info;
+# else
+ ppc_thread_state64_t info;
+# endif
mach_msg_type_number_t outCount = THREAD_STATE_MAX;
r = thread_get_state(thread, MACHINE_THREAD_STATE,
(natural_t *)&info, &outCount);
@@ -156,6 +249,7 @@ void GC_push_all_stacks() {
} /* for(p=GC_threads[i]...) */
vm_deallocate(current_task(), (vm_address_t)act_list, sizeof(thread_t) * listcount);
}
+#endif /* !DARWIN_DONT_PARSE_STACK */
static mach_port_t GC_mach_handler_thread;
static int GC_use_mach_handler_thread = 0;
@@ -326,6 +420,8 @@ void GC_start_world()
kern_return_t kern_result;
thread_act_array_t act_list;
mach_msg_type_number_t listcount;
+ struct thread_basic_info info;
+ mach_msg_type_number_t outCount = THREAD_INFO_MAX;
# if DEBUG_THREADS
GC_printf0("World starting\n");
@@ -352,8 +448,6 @@ void GC_start_world()
# endif
continue;
}
- struct thread_basic_info info;
- mach_msg_type_number_t outCount = THREAD_INFO_MAX;
kern_result = thread_info(thread, THREAD_BASIC_INFO,
(thread_info_t)&info, &outCount);
if(kern_result != KERN_SUCCESS) continue;