Integrate mainline
[p5sagit/p5-mst-13.2.git] / pod / perlintern.pod
index a9915d2..d6cd333 100644 (file)
@@ -11,6 +11,67 @@ format but are not marked as part of the Perl API. In other words,
 B<they are not for use in extensions>!
 
 
+=head1 CV reference counts and CvOUTSIDE
+
+=over 8
+
+=item CvWEAKOUTSIDE
+
+Each CV has a pointer, C<CvOUTSIDE()>, to its lexically enclosing
+CV (if any). Because pointers to anonymous sub prototypes are
+stored in C<&> pad slots, it is a possible to get a circular reference,
+with the parent pointing to the child and vice-versa. To avoid the
+ensuing memory leak, we do not increment the reference count of the CV
+pointed to by C<CvOUTSIDE> in the I<one specific instance> that the parent
+has a C<&> pad slot pointing back to us. In this case, we set the
+C<CvWEAKOUTSIDE> flag in the child. This allows us to determine under what
+circumstances we should decrement the refcount of the parent when freeing
+the child.
+
+There is a further complication with non-closure anonymous subs (ie those
+that do not refer to any lexicals outside that sub). In this case, the
+anonymous prototype is shared rather than being cloned. This has the
+consequence that the parent may be freed while there are still active
+children, eg
+
+    BEGIN { $a = sub { eval '$x' } }
+
+In this case, the BEGIN is freed immediately after execution since there
+are no active references to it: the anon sub prototype has
+C<CvWEAKOUTSIDE> set since it's not a closure, and $a points to the same
+CV, so it doesn't contribute to BEGIN's refcount either.  When $a is
+executed, the C<eval '$x'> causes the chain of C<CvOUTSIDE>s to be followed,
+and the freed BEGIN is accessed.
+
+To avoid this, whenever a CV and its associated pad is freed, any
+C<&> entries in the pad are explicitly removed from the pad, and if the
+refcount of the pointed-to anon sub is still positive, then that
+child's C<CvOUTSIDE> is set to point to its grandparent. This will only
+occur in the single specific case of a non-closure anon prototype
+having one or more active references (such as C<$a> above).
+
+One other thing to consider is that a CV may be merely undefined
+rather than freed, eg C<undef &foo>. In this case, its refcount may
+not have reached zero, but we still delete its pad and its C<CvROOT> etc.
+Since various children may still have their C<CvOUTSIDE> pointing at this
+undefined CV, we keep its own C<CvOUTSIDE> for the time being, so that
+the chain of lexical scopes is unbroken. For example, the following
+should print 123:
+
+    my $x = 123;
+    sub tmp { sub { eval '$x' } }
+    my $a = tmp();
+    undef &tmp;
+    print  $a->();
+
+       bool    CvWEAKOUTSIDE(CV *cv)
+
+=for hackers
+Found in file cv.h
+
+
+=back
+
 =head1 Functions in file pad.h
 
 
@@ -30,7 +91,7 @@ Found in file pad.h
 Access the SV at offset po in the saved current pad in the given
 context block structure (can be used as an lvalue).
 
-       PAD *   CX_CURPAD_SV(struct context, PADOFFSET po)
+       SV *    CX_CURPAD_SV(struct context, PADOFFSET po)
 
 =for hackers
 Found in file pad.h
@@ -113,6 +174,25 @@ Clone a padlist.
 =for hackers
 Found in file pad.h
 
+=item PAD_RESTORE_LOCAL
+
+Restore the old pad saved into the local variable opad by PAD_SAVE_LOCAL()
+
+       void    PAD_RESTORE_LOCAL(PAD *opad)
+
+=for hackers
+Found in file pad.h
+
+=item PAD_SAVE_LOCAL
+
+Save the current pad to the local variable opad, then make the
+current pad equal to npad
+
+       void    PAD_SAVE_LOCAL(PAD *opad, PAD *npad)
+
+=for hackers
+Found in file pad.h
+
 =item PAD_SAVE_SETNULLPAD
 
 Save the current pad then set it to null.
@@ -162,15 +242,6 @@ For internal use only.
 =for hackers
 Found in file pad.h
 
-=item PAD_UPDATE_CURPAD
-
-Set PL_curpad from the value of PL_comppad.
-
-       void    PAD_UPDATE_CURPAD()
-
-=for hackers
-Found in file pad.h
-
 =item SAVECLEARSV      
 
 Clear the pointed to pad value on scope exit. (ie the runtime action of 'my')
@@ -184,19 +255,11 @@ Found in file pad.h
 
 save PL_comppad and PL_curpad
 
-       void    SAVECOMPPAD()
-
-=for hackers
-Found in file pad.h
-
-=item SAVEFREEOP       
 
-Free the op on scope exit. At the same time, reset PL_curpad
 
 
 
-
-       void    SAVEFREEOP      (OP *o)
+       void    SAVECOMPPAD()
 
 =for hackers
 Found in file pad.h
@@ -205,6 +268,7 @@ Found in file pad.h
 
 Save a pad slot (used to restore after an iteration)
 
+XXX DAPM it would make more sense to make the arg a PADOFFSET
        void    SAVEPADSV       (PADOFFSET po)
 
 =for hackers
@@ -213,6 +277,27 @@ Found in file pad.h
 
 =back
 
+=head1 Functions in file pp_ctl.c
+
+
+=over 8
+
+=item find_runcv
+
+Locate the CV corresponding to the currently executing sub or eval.
+If db_seqp is non_null, skip CVs that are in the DB package and populate
+*db_seqp with the cop sequence number at the point that the DB:: code was
+entered. (allows debuggers to eval in the scope of the breakpoint rather
+than in in the scope of the debuger itself).
+
+       CV*     find_runcv(U32 *db_seqp)
+
+=for hackers
+Found in file pp_ctl.c
+
+
+=back
+
 =head1 Global Variables
 
 =over 8
@@ -350,7 +435,7 @@ but that is really the callers pad (a slot of which is allocated by
 every entersub).
 
 The CvPADLIST AV has does not have AvREAL set, so REFCNT of component items
-is managed "manual" (mostly in op.c) rather than normal av.c rules.
+is managed "manual" (mostly in pad.c) rather than normal av.c rules.
 The items in the AV are not SVs as for a normal AV, but other AVs:
 
 0'th Entry of the CvPADLIST is an AV which represents the "names" or rather
@@ -366,7 +451,10 @@ C<PL_comppad_name> is set the the the names AV.
 C<PL_comppad> is set the the frame AV for the frame CvDEPTH == 1.
 C<PL_curpad> is set the body of the frame AV (i.e. AvARRAY(PL_comppad)).
 
-Itterating over the names AV itterates over all possible pad
+During execution, C<PL_comppad> and C<PL_curpad> refer to the live
+frame of the currently executing sub.
+
+Iterating over the names AV iterates over all possible pad
 items. Pad slots that are SVs_PADTMP (targets/GVs/constants) end up having
 &PL_sv_undef "names" (see pad_alloc()).
 
@@ -387,7 +475,9 @@ same package can be detected).  SvCUR is sometimes hijacked to
 store the generation number during compilation.
 
 If SvFAKE is set on the name SV then slot in the frame AVs are
-a REFCNT'ed references to a lexical from "outside".
+a REFCNT'ed references to a lexical from "outside". In this case,
+the name SV does not have a cop_seq range, since it is in scope
+throughout.
 
 If the 'name' is '&' the the corresponding entry in frame AV
 is a CV representing a possible closure.
@@ -499,11 +589,12 @@ Found in file pad.c
 =item pad_findlex
 
 Find a named lexical anywhere in a chain of nested pads. Add fake entries
-in the inner pads if its found in an outer one.
+in the inner pads if it's found in an outer one. innercv is the CV *inside*
+the chain of outer CVs to be searched. If newoff is non-null, this is a
+run-time cloning: don't add fake entries, just find the lexical and add a
+ref to it at newoff in the current pad.
 
-If flags == FINDLEX_NOSEARCH we don't bother searching outer contexts.
-
-       PADOFFSET       pad_findlex(char* name, PADOFFSET newoff, U32 seq, CV* startcv, I32 cx_ix, I32 saweval, U32 flags)
+       PADOFFSET       pad_findlex(char* name, PADOFFSET newoff, CV* innercv)
 
 =for hackers
 Found in file pad.c
@@ -524,7 +615,8 @@ Found in file pad.c
 =item pad_fixup_inner_anons
 
 For any anon CVs in the pad, change CvOUTSIDE of that CV from
-old_cv to new_cv if necessary.
+old_cv to new_cv if necessary. Needed when a newly-compiled CV has to be
+moved to a pre-existing CV struct.
 
        void    pad_fixup_inner_anons(PADLIST *padlist, CV *old_cv, CV *new_cv)
 
@@ -560,7 +652,7 @@ can be OR'ed together:
     padnew_SAVE                save old globals
     padnew_SAVESUB     also save extra stuff for start of sub
 
-       PADLIST*        pad_new(padnew_flags flags)
+       PADLIST*        pad_new(int flags)
 
 =for hackers
 Found in file pad.c
@@ -623,9 +715,12 @@ Free the padlist associated with a CV.
 If parts of it happen to be current, we null the relevant
 PL_*pad* global vars so that we don't have any dangling references left.
 We also repoint the CvOUTSIDE of any about-to-be-orphaned
-inner subs to outercv.
+inner subs to the outer of this cv.
+
+(This function should really be called pad_free, but the name was already
+taken)
 
-       void    pad_undef(CV* cv, CV* outercv)
+       void    pad_undef(CV* cv)
 
 =for hackers
 Found in file pad.c