From: Juho S. <js...@us...> - 2007-06-05 11:42:58
|
Update of /cvsroot/sbcl/sbcl/src/compiler In directory sc8-pr-cvs8.sourceforge.net:/tmp/cvs-serv28203/src/compiler Modified Files: gtn.lisp ir1tran-lambda.lisp ir2tran.lisp Log Message: 1.0.6.24: a more sophisticated UNWIND-TO-FRAME-AND-CALL for x86 and x86-64 * Implement three new VOPs: ** UNWIND-TO-FRAME-AND-CALL constructs a fake catch block for a given frame pointer, runs all unwinds for that block, sets the frame pointer to the new value, and calls a given function. ** BIND-SENTINEL (stores a marker on the binding stack, used to determine how far the binding stack needs to be unwound during a U-T-F-A-C). ** UNBIND-SENTINEL (pops one of these markers from the stack). * Modify IR2 to use these VOPs when converting suitable functions. * Modify the IR1 translation in maybe-insert-debug-catch to only ensure that tail recursion doesn't happen (needed to match the BIND-SENTINELs with UNBIND-SENTINELs). * Use these to implement SB-DEBUG:UNWIND-TO-FRAME-AND-CALL: ** Grovel the binding stack, uwp block chain and the catch block chain for the values needed to reconstruct the dynamic state. ** Call SB-VM:U-T-F-A-C. * The new implementation should be substantially the same as the old one (minor difference in handling of functions with special variables in the lambda list). Some tests added to verify this. * New implementation is somewhat faster at runtime (a simple function call overhead benchmark on (DEBUG 2) improved from 3.4s to 2.9s), and significantly faster at compiling (generally around 15-30% improvement with (DEBUG 2)). * Other platforms still use the old implementation that instruments the code with a CATCH during IR1 translation. * Based on an earlier hack by Alastair Bridgewater. Index: gtn.lisp =================================================================== RCS file: /cvsroot/sbcl/sbcl/src/compiler/gtn.lisp,v retrieving revision 1.17 retrieving revision 1.18 diff -u -d -r1.17 -r1.18 --- gtn.lisp 14 Jul 2005 18:56:59 -0000 1.17 +++ gtn.lisp 5 Jun 2007 11:42:54 -0000 1.18 @@ -108,11 +108,14 @@ ;;; -- It appears to be more efficient to use the standard convention, ;;; since there are no non-TR local calls that could benefit from ;;; a non-standard convention. +;;; -- We're compiling with RETURN-FROM-FRAME instrumentation, which +;;; only works (on x86 and x86-64) for the standard convention. (defun use-standard-returns (tails) (declare (type tail-set tails)) (let ((funs (tail-set-funs tails))) (or (and (find-if #'xep-p funs) (find-if #'has-full-call-use funs)) + (some (lambda (fun) (policy fun (>= insert-debug-catch 2))) funs) (block punt (dolist (fun funs t) (dolist (ref (leaf-refs fun)) Index: ir1tran-lambda.lisp =================================================================== RCS file: /cvsroot/sbcl/sbcl/src/compiler/ir1tran-lambda.lisp,v retrieving revision 1.36 retrieving revision 1.37 diff -u -d -r1.36 -r1.37 --- ir1tran-lambda.lisp 13 Feb 2007 07:40:38 -0000 1.36 +++ ir1tran-lambda.lisp 5 Jun 2007 11:42:54 -0000 1.37 @@ -932,6 +932,14 @@ res)))) (defun wrap-forms-in-debug-catch (forms) + #!+unwind-to-frame-and-call-vop + `((multiple-value-prog1 + (progn + ,@forms) + ;; Just ensure that there won't be any tail-calls, IR2 magic will + ;; handle the rest. + (values))) + #!-unwind-to-frame-and-call-vop `( ;; Normally, we'll return from this block with the below RETURN-FROM. (block return-value-tag Index: ir2tran.lisp =================================================================== RCS file: /cvsroot/sbcl/sbcl/src/compiler/ir2tran.lisp,v retrieving revision 1.66 retrieving revision 1.67 diff -u -d -r1.66 -r1.67 --- ir2tran.lisp 6 Oct 2006 10:54:13 -0000 1.66 +++ ir2tran.lisp 5 Jun 2007 11:42:54 -0000 1.67 @@ -1179,6 +1179,11 @@ (ir2-physenv-return-pc-pass env) (ir2-physenv-return-pc env)) + #!+unwind-to-frame-and-call-vop + (when (and (policy fun (>= insert-debug-catch 2)) + (lambda-return fun)) + (vop sb!vm::bind-sentinel node block)) + (let ((lab (gen-label))) (setf (ir2-physenv-environment-start env) lab) (vop note-environment-start node block lab))) @@ -1204,6 +1209,9 @@ (old-fp (ir2-physenv-old-fp env)) (return-pc (ir2-physenv-return-pc env)) (returns (tail-set-info (lambda-tail-set fun)))) + #!+unwind-to-frame-and-call-vop + (when (policy fun (>= insert-debug-catch 2)) + (vop sb!vm::unbind-sentinel node block)) (cond ((and (eq (return-info-kind returns) :fixed) (not (xep-p fun))) |