From 6793d7dd32d1fa48d2ee395e240e1b7ff857912e Mon Sep 17 00:00:00 2001 From: Alastair Bridgewater Date: Sat, 7 Aug 2010 13:46:26 +0000 Subject: [PATCH] 1.0.41.21: runtime: Current stack and frame pointers are per-thread data. * Add slots to the thread structure on threaded targets to hold the control stack and frame pointers. * Add some macros to thread.h to grab the correct variable or slot on all builds, and use them everywhere required. * Conditional-compile out the old global variables for this on threaded targets (I probably messed this up). --- src/compiler/generic/objdef.lisp | 8 ++++++++ src/runtime/alloc.c | 8 ++++---- src/runtime/backtrace.c | 4 ++-- src/runtime/funcall.c | 22 +++++++++++++++------- src/runtime/gc-common.c | 2 +- src/runtime/gencgc.c | 7 ++----- src/runtime/globals.c | 6 ++++++ src/runtime/globals.h | 6 ++++++ src/runtime/interrupt.c | 20 ++++++++++---------- src/runtime/monitor.c | 6 ++++-- src/runtime/purify.c | 6 +++--- src/runtime/thread.c | 5 +++-- src/runtime/thread.h | 10 ++++++++++ src/runtime/x86-64-arch.c | 2 +- src/runtime/x86-arch.c | 2 +- version.lisp-expr | 2 +- 16 files changed, 77 insertions(+), 39 deletions(-) diff --git a/src/compiler/generic/objdef.lisp b/src/compiler/generic/objdef.lisp index 0d23165..ccad11b 100644 --- a/src/compiler/generic/objdef.lisp +++ b/src/compiler/generic/objdef.lisp @@ -420,6 +420,14 @@ ;; the runtime, but it's clearly a per-thread value. #!+sb-thread (foreign-function-call-active :c-type "boolean") + ;; Same as above for the location of the current control stack frame. + #!+(and sb-thread (not (or x86 x86-64))) + (control-frame-pointer :c-type "lispobj *") + ;; Same as above for the location of the current control stack + ;; pointer. This is also used on threaded x86oids to allow LDB to + ;; print an approximation of the CSP as needed. + #!+(and sb-thread) + (control-stack-pointer :c-type "lispobj *") ;; KLUDGE: On alpha, until STEPPING we have been lucky and the 32 ;; bit slots came in pairs. However the C compiler will align ;; interrupt_contexts on a double word boundary. This logic should diff --git a/src/runtime/alloc.c b/src/runtime/alloc.c index eeb827f..58c1798 100644 --- a/src/runtime/alloc.c +++ b/src/runtime/alloc.c @@ -73,13 +73,13 @@ pa_alloc(int bytes, int page_type_flag) #ifdef LISP_FEATURE_STACK_GROWS_DOWNWARD_NOT_UPWARD #error "!C_STACK_IS_CONTROL_STACK and STACK_GROWS_DOWNWARD_NOT_UPWARD is not supported" #endif - *current_control_stack_pointer = (lispobj) result; - current_control_stack_pointer += 1; + *access_control_stack_pointer(th) = (lispobj) result; + access_control_stack_pointer(th) += 1; #endif do_pending_interrupt(); #ifndef LISP_FEATURE_C_STACK_IS_CONTROL_STACK - current_control_stack_pointer -= 1; - result = (lispobj *) *current_control_stack_pointer; + access_control_stack_pointer(th) -= 1; + result = (lispobj *) *access_control_stack_pointer(th); #endif } return result; diff --git a/src/runtime/backtrace.c b/src/runtime/backtrace.c index 996357e..a9fde5d 100644 --- a/src/runtime/backtrace.c +++ b/src/runtime/backtrace.c @@ -110,13 +110,13 @@ cs_valid_pointer_p(struct call_frame *pointer) { struct thread *thread=arch_os_get_current_thread(); return (((char *) thread->control_stack_start <= (char *) pointer) && - ((char *) pointer < (char *) current_control_stack_pointer)); + ((char *) pointer < (char *) access_control_stack_pointer(thread))); } static void call_info_from_lisp_state(struct call_info *info) { - info->frame = (struct call_frame *)current_control_frame_pointer; + info->frame = (struct call_frame *)access_control_frame_pointer(arch_os_get_current_thread()); info->interrupted = 0; info->code = NULL; info->lra = 0; diff --git a/src/runtime/funcall.c b/src/runtime/funcall.c index 91f5513..c3724eb 100644 --- a/src/runtime/funcall.c +++ b/src/runtime/funcall.c @@ -85,7 +85,9 @@ funcall3(lispobj function, lispobj arg0, lispobj arg1, lispobj arg2) lispobj funcall0(lispobj function) { - lispobj *args = current_control_stack_pointer; + lispobj **stack_pointer + = &access_control_stack_pointer(arch_os_get_current_thread()); + lispobj *args = *stack_pointer; return safe_call_into_lisp(function, args, 0); } @@ -93,9 +95,11 @@ funcall0(lispobj function) lispobj funcall1(lispobj function, lispobj arg0) { - lispobj *args = current_control_stack_pointer; + lispobj **stack_pointer + = &access_control_stack_pointer(arch_os_get_current_thread()); + lispobj *args = *stack_pointer; - current_control_stack_pointer += 1; + *stack_pointer += 1; args[0] = arg0; return safe_call_into_lisp(function, args, 1); @@ -104,9 +108,11 @@ funcall1(lispobj function, lispobj arg0) lispobj funcall2(lispobj function, lispobj arg0, lispobj arg1) { - lispobj *args = current_control_stack_pointer; + lispobj **stack_pointer + = &access_control_stack_pointer(arch_os_get_current_thread()); + lispobj *args = *stack_pointer; - current_control_stack_pointer += 2; + *stack_pointer += 2; args[0] = arg0; args[1] = arg1; @@ -116,9 +122,11 @@ funcall2(lispobj function, lispobj arg0, lispobj arg1) lispobj funcall3(lispobj function, lispobj arg0, lispobj arg1, lispobj arg2) { - lispobj *args = current_control_stack_pointer; + lispobj **stack_pointer + = &access_control_stack_pointer(arch_os_get_current_thread()); + lispobj *args = *stack_pointer; - current_control_stack_pointer += 3; + *stack_pointer += 3; args[0] = arg0; args[1] = arg1; args[2] = arg2; diff --git a/src/runtime/gc-common.c b/src/runtime/gc-common.c index cc76f5c..95b5c3b 100644 --- a/src/runtime/gc-common.c +++ b/src/runtime/gc-common.c @@ -2514,7 +2514,7 @@ scrub_control_stack(void) #ifdef LISP_FEATURE_C_STACK_IS_CONTROL_STACK sp = (lispobj *)&sp - 1; #else - sp = current_control_stack_pointer; + sp = access_control_stack_pointer(th); #endif scrub: if ((((os_vm_address_t)sp < (hard_guard_page_address + os_vm_page_size)) && diff --git a/src/runtime/gencgc.c b/src/runtime/gencgc.c index 74b818e..f3c3aab 100644 --- a/src/runtime/gencgc.c +++ b/src/runtime/gencgc.c @@ -3833,14 +3833,11 @@ write_protect_generation_pages(generation_index_t generation) static void scavenge_control_stack(struct thread *th) { - unsigned long control_stack_size; - - /* This is going to be a big problem when we try to port threads - * to PPC... CLH */ lispobj *control_stack = (lispobj *)(th->control_stack_start); + unsigned long control_stack_size = + access_control_stack_pointer(th) - control_stack; - control_stack_size = current_control_stack_pointer - control_stack; scavenge(control_stack, control_stack_size); } #endif diff --git a/src/runtime/globals.c b/src/runtime/globals.c index 9eec708..5c0cd1d 100644 --- a/src/runtime/globals.c +++ b/src/runtime/globals.c @@ -26,8 +26,12 @@ int foreign_function_call_active; #endif +#if !defined(LISP_FEATURE_SB_THREAD) && !defined(LISP_FEATURE_C_STACK_IS_CONTROL_STACK) lispobj *current_control_stack_pointer; +#endif +#if defined(LISP_FEATURE_X86) || defined(LISP_FEATURE_X86_64) || !defined(LISP_FEATURE_SB_THREAD) lispobj *current_control_frame_pointer; +#endif #if !defined(BINDING_STACK_POINTER) && !defined(LISP_FEATURE_SB_THREAD) lispobj *current_binding_stack_pointer; #endif @@ -56,7 +60,9 @@ void globals_init(void) { /* Space, stack, and free pointer vars are initialized by * validate() and coreparse(). */ +#if defined(LISP_FEATURE_X86) || defined(LISP_FEATURE_X86_64) || !defined(LISP_FEATURE_SB_THREAD) current_control_frame_pointer = (lispobj *)0; +#endif #ifndef LISP_FEATURE_GENCGC /* no GC trigger yet */ diff --git a/src/runtime/globals.h b/src/runtime/globals.h index 7d424a8..e807eee 100644 --- a/src/runtime/globals.h +++ b/src/runtime/globals.h @@ -47,8 +47,12 @@ extern char **ENVIRON; extern pthread_key_t specials; #endif +#if !defined(LISP_FEATURE_SB_THREAD) && !defined(LISP_FEATURE_C_STACK_IS_CONTROL_STACK) extern lispobj *current_control_stack_pointer; +#endif +#if defined(LISP_FEATURE_X86) || defined(LISP_FEATURE_X86_64) || !defined(LISP_FEATURE_SB_THREAD) extern lispobj *current_control_frame_pointer; +#endif #if !defined(LISP_FEATURE_X86) && !defined(LISP_FEATURE_X86_64) && !defined(LISP_FEATURE_SB_THREAD) extern lispobj *current_binding_stack_pointer; #endif @@ -118,7 +122,9 @@ extern void globals_init(void); EXTERN(foreign_function_call_active, 4) #endif +#if !defined(LISP_FEATURE_SB_THREAD) && !defined(LISP_FEATURE_C_STACK_IS_CONTROL_STACK) EXTERN(current_control_stack_pointer, POINTERSIZE) +#endif EXTERN(current_control_frame_pointer, POINTERSIZE) # if !defined(LISP_FEATURE_X86) && !defined(LISP_FEATURE_X86_64) EXTERN(current_binding_stack_pointer, POINTERSIZE) diff --git a/src/runtime/interrupt.c b/src/runtime/interrupt.c index 5f057aa..ea0880f 100644 --- a/src/runtime/interrupt.c +++ b/src/runtime/interrupt.c @@ -609,23 +609,23 @@ build_fake_control_stack_frames(struct thread *th,os_context_t *context) /* Build a fake stack frame or frames */ - current_control_frame_pointer = + access_control_frame_pointer(th) = (lispobj *)(unsigned long) (*os_context_register_addr(context, reg_CSP)); if ((lispobj *)(unsigned long) (*os_context_register_addr(context, reg_CFP)) - == current_control_frame_pointer) { + == access_control_frame_pointer(th)) { /* There is a small window during call where the callee's * frame isn't built yet. */ if (lowtag_of(*os_context_register_addr(context, reg_CODE)) == FUN_POINTER_LOWTAG) { /* We have called, but not built the new frame, so * build it for them. */ - current_control_frame_pointer[0] = + access_control_frame_pointer(th)[0] = *os_context_register_addr(context, reg_OCFP); - current_control_frame_pointer[1] = + access_control_frame_pointer(th)[1] = *os_context_register_addr(context, reg_LRA); - current_control_frame_pointer += 8; + access_control_frame_pointer(th) += 8; /* Build our frame on top of it. */ oldcont = (lispobj)(*os_context_register_addr(context, reg_CFP)); } @@ -644,11 +644,11 @@ build_fake_control_stack_frames(struct thread *th,os_context_t *context) oldcont = (lispobj)(*os_context_register_addr(context, reg_CFP)); } - current_control_stack_pointer = current_control_frame_pointer + 8; + access_control_stack_pointer(th) = access_control_frame_pointer(th) + 8; - current_control_frame_pointer[0] = oldcont; - current_control_frame_pointer[1] = NIL; - current_control_frame_pointer[2] = + access_control_frame_pointer(th)[0] = oldcont; + access_control_frame_pointer(th)[1] = NIL; + access_control_frame_pointer(th)[2] = (lispobj)(*os_context_register_addr(context, reg_CODE)); #endif } @@ -1475,7 +1475,7 @@ arrange_return_to_lisp_function(os_context_t *context, lispobj function) *os_context_register_addr(context,reg_LIP) = (os_context_register_t)(unsigned long)code; *os_context_register_addr(context,reg_CFP) = - (os_context_register_t)(unsigned long)current_control_frame_pointer; + (os_context_register_t)(unsigned long)access_control_frame_pointer(th); #endif #ifdef ARCH_HAS_NPC_REGISTER *os_context_npc_addr(context) = diff --git a/src/runtime/monitor.c b/src/runtime/monitor.c index 193f4c1..1f13630 100644 --- a/src/runtime/monitor.c +++ b/src/runtime/monitor.c @@ -190,8 +190,10 @@ regs_cmd(char **ptr) { struct thread *thread=arch_os_get_current_thread(); - printf("CSP\t=\t0x%08lx ", (unsigned long)current_control_stack_pointer); - printf("CFP\t=\t0x%08lx ", (unsigned long)current_control_frame_pointer); + printf("CSP\t=\t0x%08lx ", (unsigned long)access_control_stack_pointer(thread)); +#if !defined(LISP_FEATURE_X86) && !defined(LISP_FEATURE_X86_64) + printf("CFP\t=\t0x%08lx ", (unsigned long)access_control_frame_pointer(thread)); +#endif #ifdef reg_BSP printf("BSP\t=\t0x%08lx\n", (unsigned long)get_binding_stack_pointer(thread)); diff --git a/src/runtime/purify.c b/src/runtime/purify.c index eeedda4..90c4669 100644 --- a/src/runtime/purify.c +++ b/src/runtime/purify.c @@ -954,7 +954,7 @@ purify(lispobj static_roots, lispobj read_only_roots) fflush(stdout); #endif pscav((lispobj *)all_threads->control_stack_start, - current_control_stack_pointer - + access_control_stack_pointer(all_threads) - all_threads->control_stack_start, 0); @@ -1030,10 +1030,10 @@ purify(lispobj static_roots, lispobj read_only_roots) (os_vm_size_t) dynamic_space_size); /* Zero the stack. */ - os_zero((os_vm_address_t) current_control_stack_pointer, + os_zero((os_vm_address_t) access_control_stack_pointer(all_threads), (os_vm_size_t) ((all_threads->control_stack_end - - current_control_stack_pointer) * sizeof(lispobj))); + access_control_stack_pointer(all_threads)) * sizeof(lispobj))); /* It helps to update the heap free pointers so that free_heap can * verify after it's done. */ diff --git a/src/runtime/thread.c b/src/runtime/thread.c index 60821ee..8e3f7fd 100644 --- a/src/runtime/thread.c +++ b/src/runtime/thread.c @@ -469,8 +469,6 @@ create_thread_struct(lispobj initial_function) { #if defined(LISP_FEATURE_X86) || defined (LISP_FEATURE_X86_64) SetSymbolValue(ALIEN_STACK,(lispobj)th->alien_stack_pointer,th); SetSymbolValue(PSEUDO_ATOMIC_BITS,(lispobj)th->pseudo_atomic_bits,th); -#else - current_control_stack_pointer=th->control_stack_start; #endif #endif bind_variable(CURRENT_CATCH_BLOCK,make_fixnum(0),th); @@ -487,6 +485,9 @@ create_thread_struct(lispobj initial_function) { #ifdef LISP_FEATURE_SB_THREAD bind_variable(STOP_FOR_GC_PENDING,NIL,th); #endif +#ifndef LISP_FEATURE_C_STACK_IS_CONTROL_STACK + access_control_stack_pointer(th)=th->control_stack_start; +#endif th->interrupt_data = (struct interrupt_data *) os_validate(0,(sizeof (struct interrupt_data))); diff --git a/src/runtime/thread.h b/src/runtime/thread.h index fa4b7bc..e1765d7 100644 --- a/src/runtime/thread.h +++ b/src/runtime/thread.h @@ -177,6 +177,12 @@ StaticSymbolFunction(lispobj sym) ((thread)->binding_stack_pointer) #define set_binding_stack_pointer(thread,value) \ ((thread)->binding_stack_pointer = (lispobj *)(value)) +#define access_control_stack_pointer(thread) \ + ((thread)->control_stack_pointer) +# if !defined(LISP_FEATURE_X86) && !defined(LISP_FEATURE_X86_64) +#define access_control_frame_pointer(thread) \ + ((thread)->control_frame_pointer) +# endif #elif defined(LISP_FEATURE_X86) || defined(LISP_FEATURE_X86_64) #define get_binding_stack_pointer(thread) \ SymbolValue(BINDING_STACK_POINTER, thread) @@ -187,6 +193,10 @@ StaticSymbolFunction(lispobj sym) (current_binding_stack_pointer) #define set_binding_stack_pointer(thread,value) \ (current_binding_stack_pointer = (lispobj *)(value)) +#define access_control_stack_pointer(thread) \ + (current_control_stack_pointer) +#define access_control_frame_pointer(thread) \ + (current_control_frame_pointer) #endif #if defined(LISP_FEATURE_SB_THREAD) && defined(LISP_FEATURE_GCC_TLS) diff --git a/src/runtime/x86-64-arch.c b/src/runtime/x86-64-arch.c index 0612ce9..bc25a9e 100644 --- a/src/runtime/x86-64-arch.c +++ b/src/runtime/x86-64-arch.c @@ -276,7 +276,7 @@ sigtrap_handler(int signal, siginfo_t *info, os_context_t *context) /* This is just for info in case the monitor wants to print an * approximation. */ - current_control_stack_pointer = + access_control_stack_pointer(arch_os_get_current_thread()) = (lispobj *)*os_context_sp_addr(context); /* On entry %eip points just after the INT3 byte and aims at the diff --git a/src/runtime/x86-arch.c b/src/runtime/x86-arch.c index b000e0f..cbb6fb4 100644 --- a/src/runtime/x86-arch.c +++ b/src/runtime/x86-arch.c @@ -287,7 +287,7 @@ sigtrap_handler(int signal, siginfo_t *info, os_context_t *context) /* This is just for info in case the monitor wants to print an * approximation. */ - current_control_stack_pointer = + access_control_stack_pointer(arch_os_get_current_thread()) = (lispobj *)*os_context_sp_addr(context); #ifdef LISP_FEATURE_SUNOS diff --git a/version.lisp-expr b/version.lisp-expr index ceec0e9..6854cea 100644 --- a/version.lisp-expr +++ b/version.lisp-expr @@ -17,4 +17,4 @@ ;;; checkins which aren't released. (And occasionally for internal ;;; versions, especially for internal versions off the main CVS ;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".) -"1.0.41.20" +"1.0.41.21" -- 1.7.10.4