In perl.git, the branch blead has been updated

<https://perl5.git.perl.org/perl.git/commitdiff/e55ec392015ba0c575cf495206c3121d1989561b?hp=d8c930858e7fb01bcab7473e573e007d2fb9ab12>

- Log -----------------------------------------------------------------
commit e55ec392015ba0c575cf495206c3121d1989561b
Author: Paul "LeoNerd" Evans <[email protected]>
Date:   Wed Sep 18 16:18:10 2019 +0100

    Document the various stacks in perlguts.pod

-----------------------------------------------------------------------

Summary of changes:
 pod/perlguts.pod | 236 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 235 insertions(+), 1 deletion(-)

diff --git a/pod/perlguts.pod b/pod/perlguts.pod
index fb6701df4d..f70d64137b 100644
--- a/pod/perlguts.pod
+++ b/pod/perlguts.pod
@@ -883,7 +883,7 @@ dynamic scopes: there can be multiple sets of mortal 
references hanging
 around at the same time, with different death dates.  Internally, the
 actual determinant for when mortal xV references are destroyed depends
 on two macros, SAVETMPS and FREETMPS.  See L<perlcall> and L<perlxs>
-for more details on these macros.
+and L</Temporaries Stack> below for more details on these macros.
 
 Mortal references are mainly used for xVs that are placed on perl's
 main stack.  The stack is problematic for reference tracking, because it
@@ -3215,6 +3215,240 @@ I<oldop> is the previous OP optimized, whose C<op_next> 
points to I<o>.
 
 C<B::Generate> directly supports the creation of custom ops by name.
 
+=head1 Stacks
+
+Descriptions above occasionally refer to "the stack", but there are in fact
+many stack-like data structures within the perl interpreter. When otherwise
+unqualified, "the stack" usually refers to the value stack.
+
+The various stacks have different purposes, and operate in slightly different
+ways. Their differences are noted below.
+
+=head2 Value Stack
+
+This stack stores the values that regular perl code is operating on, usually
+intermediate values of expressions within a statement. The stack itself is
+formed of an array of SV pointers.
+
+The base of this stack is pointed to by the interpreter variable
+C<PL_stack_base>, of type C<SV **>.
+
+The head of the stack is C<PL_stack_sp>, and points to the most
+recently-pushed item.
+
+Items are pushed to the stack by using the C<PUSHs()> macro or its variants
+described above; C<XPUSHs()>, C<mPUSHs()>, C<mXPUSHs()> and the typed
+versions. Note carefully that the non-C<X> versions of these macros do not
+check the size of the stack and assume it to be big enough. These must be
+paired with a suitable check of the stack's size, such as the C<EXTEND> macro
+to ensure it is large enough. For example
+
+    EXTEND(SP, 4);
+    mPUSHi(10);
+    mPUSHi(20);
+    mPUSHi(30);
+    mPUSHi(40);
+
+This is slightly more performant than making four separate checks in four
+separate C<mXPUSHi()> calls.
+
+As a further performance optimisation, the various C<PUSH> macros all operate
+using a local variable C<SP>, rather than the interpreter-global variable
+C<PL_stack_sp>. This variable is declared by the C<dSP> macro - though it is
+normally implied by XSUBs and similar so it is rare you have to consider it
+directly. Once declared, the C<PUSH> macros will operate only on this local
+variable, so before invoking any other perl core functions you must use the
+C<PUTBACK> macro to return the value from the local C<SP> variable back to
+the interpreter variable. Similarly, after calling a perl core function which
+may have had reason to move the stack or push/pop values to it, you must use
+the C<SPAGAIN> macro which refreshes the local C<SP> value back from the
+interpreter one.
+
+Items are popped from the stack by using the C<POPs> macro or its typed
+versions, There is also a macro C<TOPs> that inspects the topmost item without
+removing it.
+
+Note specifically that SV pointers on the value stack do not contribute to the
+overall reference count of the xVs being referred to. If newly-created xVs are
+being pushed to the stack you must arrange for them to be destroyed at a
+suitable time; usually by using one of the C<mPUSH*> macros or C<sv_2mortal()>
+to mortalise the xV.
+
+=head2 Mark Stack
+
+The value stack stores individual perl scalar values as temporaries between
+expressions. Some perl expressions operate on entire lists; for that purpose
+we need to know where on the stack each list begins. This is the purpose of the
+mark stack.
+
+The mark stack stores integers as I32 values, which are the height of the
+value stack at the time before the list began; thus the mark itself actually
+points to the value stack entry one before the list. The list itself starts at
+C<mark + 1>.
+
+The base of this stack is pointed to by the interpreter variable
+C<PL_markstack>, of type C<I32 *>.
+
+The head of the stack is C<PL_markstack_ptr>, and points to the most
+recently-pushed item.
+
+Items are pushed to the stack by using the C<PUSHMARK()> macro. Even though
+the stack itself stores (value) stack indices as integers, the C<PUSHMARK>
+macro should be given a stack pointer directly; it will calculate the index
+offset by comparing to the C<PL_stack_sp> variable. Thus almost always the
+code to perform this is
+
+    PUSHMARK(SP);
+
+Items are popped from the stack by the C<POPMARK> macro. There is also a macro
+C<TOPMARK> that inspects the topmost item without removing it. These macros
+return I32 index values directly. There is also the C<dMARK> macro which
+declares a new SV double-pointer variable, called C<mark>, which points at the
+marked stack slot; this is the usual macro that C code will use when operating
+on lists given on the stack.
+
+As noted above, the C<mark> variable itself will point at the most recently
+pushed value on the value stack before the list begins, and so the list itself
+starts at C<mark + 1>. The values of the list may be iterated by code such as
+
+    for(SV **svp = mark + 1; svp <= PL_stack_sp; svp++) {
+      SV *item = *svp;
+      ...
+    }
+
+Note specifically in the case that the list is already empty, C<mark> will
+equal C<PL_stack_sp>.
+
+Because the C<mark> variable is converted to a pointer on the value stack,
+extra care must be taken if C<EXTEND> or any of the C<XPUSH> macros are
+invoked within the function, because the stack may need to be moved to
+extend it and so the existing pointer will now be invalid. If this may be a
+problem, a possible solution is to track the mark offset as an integer and
+track the mark itself later on after the stack had been moved.
+
+    I32 markoff = POPMARK;
+
+    ...
+
+    SP **mark = PL_stack_base + markoff;
+
+=head2 Temporaries Stack
+
+As noted above, xV references on the main value stack do not contribute to the
+reference count of an xV, and so another mechanism is used to track when
+temporary values which live on the stack must be released. This is the job of
+the temporaries stack.
+
+The temporaries stack stores pointers to xVs whose reference counts will be
+decremented soon.
+
+The base of this stack is pointed to by the interpreter variable
+C<PL_tmps_stack>, of type C<SV **>.
+
+The head of the stack is indexed by C<PL_tmps_ix>, an integer which stores the
+index in the array of the most recently-pushed item.
+
+There is no public API to directly push items to the temporaries stack. 
Instead,
+the API function C<sv_2mortal()> is used to mortalize an xV, adding its
+address to the temporaries stack.
+
+Likewise, there is no public API to read values from the temporaries stack.
+Instead. the macros C<SAVETMPS> and C<FREETPMS> are used. The C<SAVETMPS>
+macro establishes the base levels of the temporaries stack, by capturing the
+current value of C<PL_tmps_ix> into C<PL_tmps_floor> and saving the previous
+value to the save stack. Thereafter, whenever C<FREETMPS> is invoked all of
+the temporaries that have been pushed since that level are reclaimed.
+
+While it is common to see these two macros in pairs within an C<ENTER>/
+C<LEAVE> pair, it is not necessary to match them. It is permitted to invoke
+C<FREETMPS> multiple times since the most recent C<SAVETMPS>; for example in a
+loop iterating over elements of a list. While you can invoke C<SAVETMPS>
+multiple times within a scope pair, it is unlikely to be useful. Subsequent
+invocations will move the temporaries floor further up, thus effectively
+trapping the existing temporaries to only be released at the end of the scope.
+
+=head2 Save Stack
+
+The save stack is used by perl to implement the C<local> keyword and other
+similar behaviours; any cleanup operations that need to be performed when
+leaving the current scope. Items pushed to this stack generally capture the
+current value of some internal variable or state, which will be restored when
+the scope is unwound due to leaving, C<return>, C<die>, C<goto> or other
+reasons.
+
+Whereas other perl internal stacks store individual items all of the same type
+(usually SV pointers or integers), the items pushed to the save stack are
+formed of many different types, having multiple fields to them. For example,
+the C<SAVEt_INT> type needs to store both the address of the C<int> variable
+to restore, and the value to restore it to. This information could have been
+stored using fields of a C<struct>, but would have to be large enough to store
+three pointers in the largest case, which would waste a lot of space in most
+of the smaller cases.
+
+Instead, the stack stores information in a variable-length encoding of C<ANY>
+structures. The final value pushed is stored in the C<UV> field which encodes
+the kind of item held by the preceeding items; the count and types of which
+will depend on what kind of item is being stored. The kind field is pushed
+last because that will be the first field to be popped when unwinding items
+from the stack.
+
+The base of this stack is pointed to by the interpreter variable
+C<PL_savestack>, of type C<ANY *>.
+
+The head of the stack is indexed by C<PL_savestack_ix>, an integer which
+stores the index in the array at which the next item should be pushed. (Note
+that this is different to most other stacks, which reference the most
+recently-pushed item).
+
+Items are pushed to the save stack by using the various C<SAVE...()> macros.
+Many of these macros take a variable and store both its address and current
+value on the save stack, ensuring that value gets restored on scope exit.
+
+    SAVEI8(i8)
+    SAVEI16(i16)
+    SAVEI32(i32)
+    SAVEINT(i)
+    ...
+
+There are also a variety of other special-purpose macros which save particular
+types or values of interest. C<SAVETMPS> has already been mentioned above.
+Others include C<SAVEFREEPV> which arranges for a PV (i.e. a string buffer) to
+be freed, or C<SAVEDESTRUCTOR> which arranges for a given function pointer to
+be invoked on scope exit. A full list of such macros can be found in
+F<scope.h>.
+
+There is no public API for popping individual values or items from the save
+stack. Instead, via the scope stack, the C<ENTER> and C<LEAVE> pair form a way
+to start and stop nested scopes. Leaving a nested scope via C<LEAVE> will
+restore all of the saved values that had been pushed since the most recent
+C<ENTER>.
+
+=head2 Scope Stack
+
+As with the mark stack to the value stack, the scope stack forms a pair with
+the save stack. The scope stack stores the height of the scope stack at which
+nested scopes begin, and allows the save stack to be unwound back to that
+point when the scope is left.
+
+When perl is built with debugging enabled, there is a second part to this
+stack storing human-readable string names describing the type of stack
+context. Each push operation saves the name as well as the height of the save
+stack, and each pop operation checks the topmost name with what is expected,
+causing an assertion failure if the name does not match.
+
+The base of this stack is pointed to by the interpreter variable
+C<PL_scopestack>, of type C<I32 *>. If enabled, the scope stack names are
+stored in a separate array pointed to by C<PL_scopestack_name>, of type
+C<const char **>.
+
+The head of the stack is indexed by C<PL_scopestack_ix>, an integer which
+stores the index of the array or arrays at which the next item should be
+pushed. (Note that this is different to most other stacks, which reference the
+most recently-pushed item).
+
+Values are pushed to the scope stack using the C<ENTER> macro, which begins a
+new nested scope. Any items pushed to the save stack are then restored at the
+next nested invocation of the C<LEAVE> macro.
 
 =head1 Dynamic Scope and the Context Stack
 

-- 
Perl5 Master Repository

Reply via email to