X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=doc%2Finternals%2Fspecials.texinfo;h=4c2b4deb2cdc4bf2aee9d42bda1f1f9cbb6ba2af;hb=7cd7b23c6930e88e2185d76524dc56b789193d51;hp=036851e0d17bf6000b5d3a6d21a26cb6cb3b4105;hpb=af4d83b57531e98d455f31980ef6359465d3d5a7;p=sbcl.git diff --git a/doc/internals/specials.texinfo b/doc/internals/specials.texinfo index 036851e..4c2b4de 100644 --- a/doc/internals/specials.texinfo +++ b/doc/internals/specials.texinfo @@ -3,8 +3,8 @@ @chapter Specials @menu -* Overview:: -* Binding and unbinding:: +* Overview:: +* Binding and unbinding:: @end menu @node Overview @@ -27,8 +27,9 @@ value locally in a thread. @section Binding and unbinding Binding goes like this: the binding stack pointer (bsp) is bumped, old -value and symbol are stored at bsp - 1, new value is stored in -symbol's value slot or the tls. +value and symbol are stored at bsp - 1, new value is stored in symbol's +value slot or the tls. On multithreaded builds, @code{TLS-INDEX} is +stored on the binding stack in place of the symbol. Unbinding: the symbol's value is restored from bsp - 1, value and symbol at bsp - 1 are set to zero, and finally bsp is decremented. @@ -52,4 +53,25 @@ garbage pointer. Furthermore, @code{BIND} must always write the value to the binding stack first and the symbol second because the symbol being non-zero -means validity to @code{UNBIND-TO-HERE}. +means validity to @code{UNBIND-TO-HERE}. For similar reasons +@code{UNBIND} also zeroes the symbol first. But if it is interrupted +by a signal that does an async unwind then @code{UNBIND-TO-HERE} can +be triggered when the symbol is zeroed but the value is not. In this +case @code{UNBIND-TO-HERE} must zero out the value to avoid leaving +garbage around that may wreck the ship on the next @code{BIND}. + +In other words, the invariant is that the binding stack above bsp only +contains zeros. This makes @code{BIND} safe in face of gc triggered at +any point during its execution. + +On platforms with the @code{UNWIND-TO-FRAME-AND-CALL-VOP} feature, it's +possible to restart frames in the debugger, unwinding the binding stack. +To know how much to unwind, @code{BIND-SENTINEL} in the beginning of a +function puts the current frame pointer on the binding stack with +@code{UNBOUND-MARKER-WIDETAG} instead of the symbol/tls-index. +@code{UNBIND-SENTINEL} removes it before returning. The debugger then +search for @code{UNBOUND-MARKER-WIDETAG} with the value being equal to +the desired frame, and calls @code{UNBIND-TO-HERE}. Consequently, +@code{UNBIND-TO-HERE} treats @code{UNBOUND-MARKER-WIDETAG} the same way +as zeros. +