From 935f69d9a19c4a4c2f76a5e71ba1f45824aed707 Mon Sep 17 00:00:00 2001 From: rtoy <rtoy> Date: Wed, 10 Sep 2008 13:46:43 +0000 Subject: [PATCH] Change how we handle function end breakpoints for non-x86. We don't disable GC before calling HANDLE-BREAKPOINT. We save the real LRA object to the Lisp stack, before calling HANDLE-BREAKPOINT. Afterwards, we load the LRA from the stack. Thus, if GC happened, the stack value will have changed appropriately, and we return to the correct place. compiler/ppc/parms.lisp: compiler/sparc/parms.lisp: o Don't need lisp::*gc-inhibit* to be a static symbol anymore so remove it. lisp/breakpoint.c: o Implement above idea in handle_function_end_breakpoint. o Add comments on the values of REAL_LRA_SLOT and friends. o Clean up compute_offsets for the x86 case which doesn't handle ppc or sparc anymore. --- compiler/ppc/parms.lisp | 5 +-- compiler/sparc/parms.lisp | 5 +-- lisp/breakpoint.c | 89 ++++++++++++++++++--------------------- 3 files changed, 45 insertions(+), 54 deletions(-) diff --git a/compiler/ppc/parms.lisp b/compiler/ppc/parms.lisp index e8e81e72e..18fa7c582 100644 --- a/compiler/ppc/parms.lisp +++ b/compiler/ppc/parms.lisp @@ -7,7 +7,7 @@ ;;; Scott Fahlman or slisp-group@cs.cmu.edu. ;;; (ext:file-comment - "$Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/compiler/ppc/parms.lisp,v 1.17 2008/09/05 22:03:12 rtoy Exp $") + "$Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/compiler/ppc/parms.lisp,v 1.18 2008/09/10 13:46:42 rtoy Exp $") ;;; ;;; ********************************************************************** ;;; @@ -270,10 +270,9 @@ :key-and-value :key-or-value - lisp::*gc-inhibit* - ;; Spare symbols. Rename these when you need to add some static ;; symbols and don't want to do a cross-compile. + sparc-9 spare-8 spare-7 spare-6 diff --git a/compiler/sparc/parms.lisp b/compiler/sparc/parms.lisp index 875666ea0..4d0ea6d33 100644 --- a/compiler/sparc/parms.lisp +++ b/compiler/sparc/parms.lisp @@ -5,7 +5,7 @@ ;;; Carnegie Mellon University, and has been placed in the public domain. ;;; (ext:file-comment - "$Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/compiler/sparc/parms.lisp,v 1.55 2008/09/05 22:03:12 rtoy Exp $") + "$Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/compiler/sparc/parms.lisp,v 1.56 2008/09/10 13:46:42 rtoy Exp $") ;;; ;;; ********************************************************************** ;;; @@ -329,11 +329,10 @@ :key-and-value :key-or-value - lisp::*gc-inhibit* - ;; Some spare static symbols. Useful for adding another static ;; symbol without having to do a cross-compile. Just rename one ;; of these to the desired name. + sparc-9 spare-8 spare-7 spare-6 diff --git a/lisp/breakpoint.c b/lisp/breakpoint.c index d742b9807..153b10407 100644 --- a/lisp/breakpoint.c +++ b/lisp/breakpoint.c @@ -1,6 +1,6 @@ /* - $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/breakpoint.c,v 1.24 2008/09/05 22:03:12 rtoy Exp $ + $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/breakpoint.c,v 1.25 2008/09/10 13:46:43 rtoy Exp $ This code was written as part of the CMU Common Lisp project at Carnegie Mellon University, and has been placed in the public domain. @@ -24,8 +24,12 @@ #endif /* - * See MAKE-BOGUS-LRA in code/debug-int.lisp for these values. (We - * really should generate these from the Lisp code.) + * See MAKE-BOGUS-LRA in code/debug-int.lisp for these values. + * + * Note: In debug-int.lisp, real-lra-slot and known-return-p-slot are + * offsets from the start of the code object. But in the C code here, + * it is the offset from the constants vector in the code object. The + * difference between the two is vm:code-constants-offset. */ #define REAL_LRA_SLOT 0 #ifndef i386 @@ -200,29 +204,7 @@ compute_offset(os_context_t * scp, lispobj code, boolean function_end) int offset = pc - code_start; if (offset >= codeptr->code_size) { - if (function_end) { -#if defined(sparc) || (defined(DARWIN) && defined(__ppc__)) - /* - * We're in a function end breakpoint. Compute the - * offset from the (known) breakpoint location and the - * beginning of the breakpoint guts. (See *-assem.S.) - * - * Then make the offset negative so the caller knows - * that the offset is not from the code object. - */ - extern char function_end_breakpoint_trap; - extern char function_end_breakpoint_guts; - - offset = - &function_end_breakpoint_trap - - &function_end_breakpoint_guts; - return make_fixnum(-offset); -#else - return 0; -#endif - } else { - return 0; - } + return 0; } else { return make_fixnum(offset); } @@ -280,7 +262,8 @@ handle_function_end_breakpoint(int signal, int subcode, os_context_t * scp) lispobj code, lra; struct code *codeptr; int offset; - + int known_return_p; + fake_foreign_function_call(scp); code = find_code(scp); @@ -311,7 +294,8 @@ handle_function_end_breakpoint(int signal, int subcode, os_context_t * scp) * Some magic here. pc points to the trap instruction. The * offset gives us where the function_end_breakpoint_guts * begins. But we need to back up some more to get to the - * code-component object. The magic 2 below is + * code-component object. See MAKE-BOGUS-LRA in + * debug-int.lisp */ code = pc - fixnum_value(offset); code -= sizeof(struct code) + BOGUS_LRA_CONSTANTS * sizeof(lispobj); @@ -326,32 +310,41 @@ handle_function_end_breakpoint(int signal, int subcode, os_context_t * scp) #endif } - /* - * Breakpoint handling done, so get the real LRA where we're - * supposed to return to so we can return there. - */ lra = codeptr->constants[REAL_LRA_SLOT]; -#ifdef reg_CODE - /* - * With the known-return convention, we definitely do NOT want to - * mangle the CODE register because it isn't pointing to the bogus - * LRA but to the actual routine. - */ - if (codeptr->constants[KNOWN_RETURN_P_SLOT] == NIL) - SC_REG(scp, reg_CODE) = lra; -#endif + + known_return_p = codeptr->constants[KNOWN_RETURN_P_SLOT] != NIL; { - lispobj saved_gc_inhibit; + lispobj *args = current_control_stack_pointer; + + /* + * Because HANDLE_BREAKPOINT can GC, the LRA could move, and + * we need to know where it went so we can return to the + * correct place. We do this by saving the LRA on the Lisp + * stack. If GC moves the LRA, the stack entry will get + * updated appropriately too. + */ + current_control_stack_pointer += 1; + args[0] = lra; -#ifdef GC_INHIBIT - saved_gc_inhibit = SymbolValue(GC_INHIBIT); - SetSymbolValue(GC_INHIBIT, T); -#endif funcall3(SymbolFunction(HANDLE_BREAKPOINT), offset, code, alloc_sap(scp)); -#ifdef GC_INHIBIT - SetSymbolValue(GC_INHIBIT, saved_gc_inhibit); + /* + * Breakpoint handling done. Get the (possibly changed) LRA + * value off the stack so we know where to return to. + */ + lra = args[0]; + current_control_stack_pointer -= 1; + +#ifdef reg_CODE + /* + * With the known-return convention, we definitely do NOT want + * to mangle the CODE register because it isn't pointing to + * the bogus LRA but to the actual routine. + */ + if (!known_return_p) { + SC_REG(scp, reg_CODE) = lra; + } #endif } -- GitLab