From ab9c6bbaaa409e815a1c9696885c9621b429aed6 Mon Sep 17 00:00:00 2001 From: Alastair Bridgewater Date: Fri, 6 Aug 2010 18:48:19 +0000 Subject: [PATCH] 1.0.41.12: gc: Unify gencgc and cheneygc interrupt-context scavenging. * Both gencgc and cheneygc had separate copies of scavenge_interrupt_contexts which had drifted out of sync over time. * Resynchronized both versions and moved the result into gc-common.c, which should prevent further desynchronization. --- src/runtime/cheneygc.c | 126 --------------------------------------- src/runtime/gc-common.c | 149 +++++++++++++++++++++++++++++++++++++++++++++++ src/runtime/gencgc.c | 140 -------------------------------------------- version.lisp-expr | 2 +- 4 files changed, 150 insertions(+), 267 deletions(-) diff --git a/src/runtime/cheneygc.c b/src/runtime/cheneygc.c index 403c31a..10b4d4a 100644 --- a/src/runtime/cheneygc.c +++ b/src/runtime/cheneygc.c @@ -283,132 +283,6 @@ scavenge_newspace(void) /* printf("done with newspace\n"); */ } -/* scavenging interrupt contexts */ - -static int boxed_registers[] = BOXED_REGISTERS; - -static void -scavenge_interrupt_context(os_context_t *context) -{ - int i; -#ifdef reg_LIP - unsigned long lip; - unsigned long lip_offset; - int lip_register_pair; -#endif - unsigned long pc_code_offset; -#ifdef ARCH_HAS_LINK_REGISTER - unsigned long lr_code_offset; -#endif -#ifdef ARCH_HAS_NPC_REGISTER - unsigned long npc_code_offset; -#endif -#ifdef DEBUG_SCAVENGE_VERBOSE - fprintf(stderr, "Scavenging interrupt context at 0x%x\n",context); -#endif - /* Find the LIP's register pair and calculate its offset */ - /* before we scavenge the context. */ -#ifdef reg_LIP - lip = *os_context_register_addr(context, reg_LIP); - /* 0x7FFFFFFF on 32-bit platforms; - 0x7FFFFFFFFFFFFFFF on 64-bit platforms */ - lip_offset = (((unsigned long)1) << (N_WORD_BITS - 1)) - 1; - lip_register_pair = -1; - for (i = 0; i < (int)(sizeof(boxed_registers) / sizeof(int)); i++) { - unsigned long reg; - unsigned long offset; - int index; - - index = boxed_registers[i]; - reg = *os_context_register_addr(context, index); - /* would be using PTR if not for integer length issues */ - if ((reg & ~((1L<interrupt_contexts[i]; - scavenge_interrupt_context(context); - } -} - - /* debugging code */ void diff --git a/src/runtime/gc-common.c b/src/runtime/gc-common.c index a9f69b6..c99afb7 100644 --- a/src/runtime/gc-common.c +++ b/src/runtime/gc-common.c @@ -2545,3 +2545,152 @@ scrub_control_stack(void) } while (((unsigned long)++sp) & (BYTES_ZERO_BEFORE_END - 1)); #endif } + +#if !defined(LISP_FEATURE_X86) && !defined(LISP_FEATURE_X86_64) + +/* scavenging interrupt contexts */ + +static int boxed_registers[] = BOXED_REGISTERS; + +static void +scavenge_interrupt_context(os_context_t *context) +{ + int i; + +#ifdef reg_LIP + unsigned long lip; + unsigned long lip_offset; + int lip_register_pair; +#endif + unsigned long pc_code_offset; + +#ifdef ARCH_HAS_LINK_REGISTER + unsigned long lr_code_offset; +#endif +#ifdef ARCH_HAS_NPC_REGISTER + unsigned long npc_code_offset; +#endif +#ifdef DEBUG_SCAVENGE_VERBOSE + fprintf(stderr, "Scavenging interrupt context at 0x%x\n",context); +#endif + +#ifdef reg_LIP + /* Find the LIP's register pair and calculate its offset */ + /* before we scavenge the context. */ + + /* + * I (RLT) think this is trying to find the boxed register that is + * closest to the LIP address, without going past it. Usually, it's + * reg_CODE or reg_LRA. But sometimes, nothing can be found. + */ + lip = *os_context_register_addr(context, reg_LIP); + /* 0x7FFFFFFF on 32-bit platforms; + 0x7FFFFFFFFFFFFFFF on 64-bit platforms */ + lip_offset = (((unsigned long)1) << (N_WORD_BITS - 1)) - 1; + lip_register_pair = -1; + for (i = 0; i < (int)(sizeof(boxed_registers) / sizeof(int)); i++) { + unsigned long reg; + unsigned long offset; + int index; + + index = boxed_registers[i]; + reg = *os_context_register_addr(context, index); + /* would be using PTR if not for integer length issues */ + if ((reg & ~((1L<uc_mcontext.gregs[2]. But gregs[2] is REG_nPC. Is + * that what we really want? My guess is that that is not what we + * want, so if lip_register_pair is -1, we don't touch reg_LIP at + * all. But maybe it doesn't really matter if LIP is trashed? + */ + if (lip_register_pair >= 0) { + *os_context_register_addr(context, reg_LIP) = + *os_context_register_addr(context, lip_register_pair) + + lip_offset; + } +#endif /* reg_LIP */ + + /* Fix the PC if it was in from space */ + if (from_space_p(*os_context_pc_addr(context))) + *os_context_pc_addr(context) = + *os_context_register_addr(context, reg_CODE) + pc_code_offset; + +#ifdef ARCH_HAS_LINK_REGISTER + /* Fix the LR ditto; important if we're being called from + * an assembly routine that expects to return using blr, otherwise + * harmless */ + if (from_space_p(*os_context_lr_addr(context))) + *os_context_lr_addr(context) = + *os_context_register_addr(context, reg_CODE) + lr_code_offset; +#endif + +#ifdef ARCH_HAS_NPC_REGISTER + if (from_space_p(*os_context_npc_addr(context))) + *os_context_npc_addr(context) = + *os_context_register_addr(context, reg_CODE) + npc_code_offset; +#endif /* ARCH_HAS_NPC_REGISTER */ +} + +void scavenge_interrupt_contexts(struct thread *th) +{ + int i, index; + os_context_t *context; + + index = fixnum_value(SymbolValue(FREE_INTERRUPT_CONTEXT_INDEX,th)); + +#ifdef DEBUG_SCAVENGE_VERBOSE + fprintf(stderr, "%d interrupt contexts to scan\n",index); +#endif + + for (i = 0; i < index; i++) { + context = th->interrupt_contexts[i]; + scavenge_interrupt_context(context); + } +} +#endif /* x86oid targets */ diff --git a/src/runtime/gencgc.c b/src/runtime/gencgc.c index be171ba..910b913 100644 --- a/src/runtime/gencgc.c +++ b/src/runtime/gencgc.c @@ -3822,7 +3822,6 @@ write_protect_generation_pages(generation_index_t generation) } #if !defined(LISP_FEATURE_X86) && !defined(LISP_FEATURE_X86_64) - static void scavenge_control_stack(struct thread *th) { @@ -3836,145 +3835,6 @@ scavenge_control_stack(struct thread *th) control_stack_size = current_control_stack_pointer - control_stack; scavenge(control_stack, control_stack_size); } - -/* Scavenging Interrupt Contexts */ - -static int boxed_registers[] = BOXED_REGISTERS; - -static void -scavenge_interrupt_context(os_context_t * context) -{ - int i; - -#ifdef reg_LIP - unsigned long lip; - unsigned long lip_offset; - int lip_register_pair; -#endif - unsigned long pc_code_offset; - -#ifdef ARCH_HAS_LINK_REGISTER - unsigned long lr_code_offset; -#endif -#ifdef ARCH_HAS_NPC_REGISTER - unsigned long npc_code_offset; -#endif - -#ifdef reg_LIP - /* Find the LIP's register pair and calculate it's offset */ - /* before we scavenge the context. */ - - /* - * I (RLT) think this is trying to find the boxed register that is - * closest to the LIP address, without going past it. Usually, it's - * reg_CODE or reg_LRA. But sometimes, nothing can be found. - */ - lip = *os_context_register_addr(context, reg_LIP); - lip_offset = 0x7FFFFFFF; - lip_register_pair = -1; - for (i = 0; i < (sizeof(boxed_registers) / sizeof(int)); i++) { - unsigned long reg; - long offset; - int index; - - index = boxed_registers[i]; - reg = *os_context_register_addr(context, index); - if ((reg & ~((1L<uc_mcontext.gregs[2]. But gregs[2] is REG_nPC. Is - * that what we really want? My guess is that that is not what we - * want, so if lip_register_pair is -1, we don't touch reg_LIP at - * all. But maybe it doesn't really matter if LIP is trashed? - */ - if (lip_register_pair >= 0) { - *os_context_register_addr(context, reg_LIP) = - *os_context_register_addr(context, lip_register_pair) - + lip_offset; - } -#endif /* reg_LIP */ - - /* Fix the PC if it was in from space */ - if (from_space_p(*os_context_pc_addr(context))) - *os_context_pc_addr(context) = - *os_context_register_addr(context, reg_CODE) + pc_code_offset; - -#ifdef ARCH_HAS_LINK_REGISTER - /* Fix the LR ditto; important if we're being called from - * an assembly routine that expects to return using blr, otherwise - * harmless */ - if (from_space_p(*os_context_lr_addr(context))) - *os_context_lr_addr(context) = - *os_context_register_addr(context, reg_CODE) + lr_code_offset; -#endif - -#ifdef ARCH_HAS_NPC_REGISTER - if (from_space_p(*os_context_npc_addr(context))) - *os_context_npc_addr(context) = - *os_context_register_addr(context, reg_CODE) + npc_code_offset; -#endif /* ARCH_HAS_NPC_REGISTER */ -} - -void -scavenge_interrupt_contexts(struct thread *th) -{ - int i, index; - os_context_t *context; - - index = fixnum_value(SymbolValue(FREE_INTERRUPT_CONTEXT_INDEX,th)); - -#if defined(DEBUG_PRINT_CONTEXT_INDEX) - printf("Number of active contexts: %d\n", index); -#endif - - for (i = 0; i < index; i++) { - context = th->interrupt_contexts[i]; - scavenge_interrupt_context(context); - } -} - #endif #if defined(LISP_FEATURE_SB_THREAD) && (defined(LISP_FEATURE_X86) || defined(LISP_FEATURE_X86_64)) diff --git a/version.lisp-expr b/version.lisp-expr index 2bca10b..340b910 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.11" +"1.0.41.12" -- 1.7.10.4