Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PATCH] improve docs about mortal in perlguts #13996

Closed
p5pRT opened this issue Jul 22, 2014 · 15 comments
Closed

[PATCH] improve docs about mortal in perlguts #13996

p5pRT opened this issue Jul 22, 2014 · 15 comments

Comments

@p5pRT
Copy link

p5pRT commented Jul 22, 2014

Migrated from rt.perl.org#122368 (status was 'resolved')

Searchable as RT122368$

@p5pRT
Copy link
Author

p5pRT commented Jul 22, 2014

From @bulk88

Created by @bulk88

Unsmoked. See attached patch.

Perl Info

Flags:
    category=docs
    severity=low

Site configuration information for perl 5.21.2:

Configured by Owner at Fri Jul 11 00:44:08 2014.

Summary of my perl5 (revision 5 version 21 subversion 2) configuration:
  Derived from: ecafd7654a8d1bc705e8fe0cd3c89044374db045
  Ancestor: 6e9f2f2d7d7f6ae8cf72ada5a8bf7781fba14273
  Platform:
    osname=MSWin32, osvers=5.1, archname=MSWin32-x86-multi-thread
    uname=''
    config_args='undef'
    hint=recommended, useposix=true, d_sigaction=undef
    useithreads=define, usemultiplicity=define
    use64bitint=undef, use64bitall=undef, uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='cl', ccflags ='-nologo -GF -W3 -Od -MD -Zi -DDEBUGGING -DWIN32 
-D_CONSOLE -DNO_STRICT  -DPERL_TEXTMODE_SCRIPTS 
-DPERL_HASH_FUNC_ONE_AT_A_TIME -DPERL_IMPLICIT_CONTEXT 
-DPERL_IMPLICIT_SYS -DUSE_PERLIO -D_USE_32BIT_TIME_T',
    optimize='-Od -MD -Zi -DDEBUGGING',
    cppflags='-DWIN32'
    ccversion='13.10.6030', gccversion='', gccosandvers=''
    intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
    d_longlong=undef, longlongsize=8, d_longdbl=define, longdblsize=8
    ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='__int64', 
lseeksize=8
    alignbytes=8, prototype=define
  Linker and Libraries:
    ld='link', ldflags ='-nologo -nodefaultlib -debug  
-libpath:"c:\perl521\lib\CORE"  -machine:x86'
    libpth="C:\Program Files\Microsoft Visual Studio .NET 2003\VC7\lib"
    libs=oldnames.lib kernel32.lib user32.lib gdi32.lib winspool.lib  
comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib  
netapi32.lib uuid.lib ws2_32.lib mpr.lib winmm.lib  version.lib 
odbc32.lib odbccp32.lib comctl32.lib msvcrt.lib
    perllibs=oldnames.lib kernel32.lib user32.lib gdi32.lib 
winspool.lib  comdlg32.lib advapi32.lib shell32.lib ole32.lib 
oleaut32.lib  netapi32.lib uuid.lib ws2_32.lib mpr.lib winmm.lib  
version.lib odbc32.lib odbccp32.lib comctl32.lib msvcrt.lib
    libc=msvcrt.lib, so=dll, useshrplib=true, libperl=perl521.lib
    gnulibc_version=''
  Dynamic Linking:
    dlsrc=dl_win32.xs, dlext=dll, d_dlsymun=undef, ccdlflags=' '
    cccdlflags=' ', lddlflags='-dll -nologo -nodefaultlib -debug  
-libpath:"c:\perl521\lib\CORE"  -machine:x86'

Locally applied patches:
    uncommitted-changes
    22eb0703e4f1ca0305ca22390770b019a4b0ec4c
    ab36ae0a3ee81e650c6775a6e779fd961d14a2df


@INC for perl 5.21.2:
    C:/perl521/site/lib
    C:/perl521/lib
    .


Environment for perl 5.21.2:
    HOME (unset)
    LANG (unset)
    LANGUAGE (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=C:\perl521\bin;C:\Program Files\Microsoft Visual Studio .NET 
2003\Common7\IDE;C:\Program Files\Microsoft Visual Studio .NET 
2003\VC7\BIN;C:\Program Files\Microsoft Visual Studio .NET 
2003\Common7\Tools;C:\Program Files\Microsoft Visual Studio .NET 
2003\Common7\Tools\bin\prerelease;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\system32\wbem;
    PERL_BADLANG (unset)
    SHELL (unset)


@p5pRT
Copy link
Author

p5pRT commented Jul 22, 2014

From @bulk88

0001-improve-docs-about-mortal-in-perlguts.patch
From 543c0e688ee3c5a452b9203e04eee8a0f448ecfa Mon Sep 17 00:00:00 2001
From: Daniel Dragan <bulk88@hotmail.com>
Date: Tue, 22 Jul 2014 11:33:06 -0400
Subject: [PATCH] improve docs about mortal in perlguts

---
 pod/perlguts.pod |   16 +++++++++++++---
 1 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/pod/perlguts.pod b/pod/perlguts.pod
index 105e817..b8d2d77 100644
--- a/pod/perlguts.pod
+++ b/pod/perlguts.pod
@@ -787,7 +787,11 @@ manipulated with the following macros:
 
     int SvREFCNT(SV* sv);
     SV* SvREFCNT_inc(SV* sv);
+    SV* SvREFCNT_inc_NN(SV* sv);
+    void SvREFCNT_inc_void(SV* sv);
+    /* see perlapi for other variants */
     void SvREFCNT_dec(SV* sv);
+    void SvREFCNT_dec_NN(SV* sv);
 
 However, there is one other function which manipulates the reference
 count of its argument.  The C<newRV_inc> function, you will recall,
@@ -822,13 +826,16 @@ See L<perlcall> and L<perlxs> for more details on these macros.
 
 "Mortalization" then is at its simplest a deferred C<SvREFCNT_dec>.
 However, if you mortalize a variable twice, the reference count will
-later be decremented twice.
+later be decremented twice.  Mortal can be thought of as attached a SV to
+the current scope of the Perl stack (but not putting the SV on the Perl stack),
+and the SV will be freeded if nothing else wants it, when the scope is left.
+Mortal is similar to a C++ smart pointer.
 
 "Mortal" SVs are mainly used for SVs that are placed on perl's stack.
 For example an SV which is created just to pass a number to a called sub
 is made mortal to have it cleaned up automatically when it's popped off
 the stack.  Similarly, results returned by XSUBs (which are pushed on the
-stack) are often made mortal.
+stack) are often made mortal; the few exceptions are listed further down.
 
 To create a mortal variable, use the functions:
 
@@ -858,7 +865,10 @@ as deferred C<SvREFCNT_dec> should help to minimize such problems.
 For example if you are passing an SV which you I<know> has a high enough REFCNT
 to survive its use on the stack you need not do any mortalization.
 If you are not sure then doing an C<SvREFCNT_inc> and C<sv_2mortal>, or
-making a C<sv_mortalcopy> is safer.
+making a C<sv_mortalcopy> is safer.  A real example would be getting a SV * from
+C<get_sv>. In that case, the SV is owned by the package namespace.  If you just
+mortal the package SV, you will probably free the SV in the glob, causing a perl
+panic or crash.
 
 The mortal routines are not just for SVs; AVs and HVs can be
 made mortal by passing their address (type-casted to C<SV*>) to the
-- 
1.7.9.msysgit.0

@p5pRT
Copy link
Author

p5pRT commented Jul 22, 2014

From @tonycoz

On Tue Jul 22 08​:35​:48 2014, bulk88 wrote​:

Unsmoked. See attached patch.

"Mortalization" then is at its simplest a deferred C<SvREFCNT_dec>.
However, if you mortalize a variable twice, the reference count will
-later be decremented twice.
+later be decremented twice. Mortal can be thought of as attached a SV to

Should probably be "Mortalization can be thought of attaching an SV to ..."[1]

+the current scope of the Perl stack (but not putting the SV on the Perl stack),
+and the SV will be freeded if nothing else wants it, when the scope is left.
+Mortal is similar to a C++ smart pointer.

There's a enough differences that this comparison might be confusing. Anyone else?

Tony

[1] I pronounce SV as ess-vee, so "an" instead of "a", perlguts uses "a SV" once, "an SV" several times

@p5pRT
Copy link
Author

p5pRT commented Jul 22, 2014

The RT System itself - Status changed from 'new' to 'open'

@p5pRT
Copy link
Author

p5pRT commented Jul 23, 2014

From @Tux

Tony Cook via RT schreef op 2014-07-23 01​:37​:

On Tue Jul 22 08​:35​:48 2014, bulk88 wrote​:

Unsmoked. See attached patch.

"Mortalization" then is at its simplest a deferred C<SvREFCNT_dec>.
However, if you mortalize a variable twice, the reference count will
-later be decremented twice.
+later be decremented twice. Mortal can be thought of as attached a SV
to

Should probably be "Mortalization can be thought of attaching an SV to
..."[1]

+the current scope of the Perl stack (but not putting the SV on the
Perl stack),
+and the SV will be freeded if nothing else wants it, when the scope is
left.

freeded?

+Mortal is similar to a C++ smart pointer.

There's a enough differences that this comparison might be confusing.
Anyone else?

Tony

[1] I pronounce SV as ess-vee, so "an" instead of "a", perlguts uses
"a SV" once, "an SV" several times

---
via perlbug​: queue​: perl5 status​: new
https://rt-archive.perl.org/perl5/Ticket/Display.html?id=122368

@p5pRT
Copy link
Author

p5pRT commented Jul 23, 2014

From @iabyn

On Tue, Jul 22, 2014 at 08​:35​:48AM -0700, bulk88 wrote​:

-later be decremented twice.
+later be decremented twice. Mortal can be thought of as attached a SV to
+the current scope of the Perl stack (but not putting the SV on the Perl stack),
+and the SV will be freeded if nothing else wants it, when the scope is left.

I'm not particularly keen on this phrasing and am not sure what it's
trying to say. The "Perl stack" (i.e. PL_stack_sp) doesn't really have a
scope as such. Tmps are freed based on the scope of the tmps stack, and is
triggered by a call to FREETMPS, which is done in many places, often only
marginally connected to PL_stack_sp. Its possible for the Perl_stack
frame to be popped and no temps freed and vice versa.

--
"Do not dabble in paradox, Edward, it puts you in danger of fortuitous wit."
  -- Lady Croom, "Arcadia"

@p5pRT
Copy link
Author

p5pRT commented Apr 28, 2015

From @bulk88

On Tue Jul 22 16​:37​:37 2014, tonyc wrote​:

On Tue Jul 22 08​:35​:48 2014, bulk88 wrote​:

Unsmoked. See attached patch.

"Mortalization" then is at its simplest a deferred C<SvREFCNT_dec>.
However, if you mortalize a variable twice, the reference count will
-later be decremented twice.
+later be decremented twice. Mortal can be thought of as attached a
SV to

Should probably be "Mortalization can be thought of attaching an SV to
..."[1]

+the current scope of the Perl stack (but not putting the SV on the
Perl stack),
+and the SV will be freeded if nothing else wants it, when the scope
is left.
+Mortal is similar to a C++ smart pointer.

There's a enough differences that this comparison might be confusing.
Anyone else?

Tony

[1] I pronounce SV as ess-vee, so "an" instead of "a", perlguts uses
"a SV" once, "an SV" several times

-freeded fixed,
-analogy to "perl stack" removed and replaced with another analogy
-a replace with an
-example expanded of when it is safe to return an SV on perl stack without sv_2mortal

--
bulk88 ~ bulk88 at hotmail.com

@p5pRT
Copy link
Author

p5pRT commented Apr 28, 2015

From @bulk88

0001-improve-docs-about-mortal-in-perlguts.patch
From 761d128f341c67af9d00072fdfc77d9d19f63a9c Mon Sep 17 00:00:00 2001
From: Daniel Dragan <bulk88@hotmail.com>
Date: Tue, 28 Apr 2015 13:10:10 -0400
Subject: [PATCH] improve docs about mortal in perlguts

---
 pod/perlguts.pod | 19 ++++++++++++++++---
 1 file changed, 16 insertions(+), 3 deletions(-)

diff --git a/pod/perlguts.pod b/pod/perlguts.pod
index 9761bad..be72d9d 100644
--- a/pod/perlguts.pod
+++ b/pod/perlguts.pod
@@ -805,7 +805,11 @@ manipulated with the following macros:
 
     int SvREFCNT(SV* sv);
     SV* SvREFCNT_inc(SV* sv);
+    SV* SvREFCNT_inc_NN(SV* sv);
+    void SvREFCNT_inc_void(SV* sv);
+    /* see perlapi for other variants */
     void SvREFCNT_dec(SV* sv);
+    void SvREFCNT_dec_NN(SV* sv);
 
 However, there is one other function which manipulates the reference
 count of its argument.  The C<newRV_inc> function, you will recall,
@@ -840,13 +844,18 @@ See L<perlcall> and L<perlxs> for more details on these macros.
 
 "Mortalization" then is at its simplest a deferred C<SvREFCNT_dec>.
 However, if you mortalize a variable twice, the reference count will
-later be decremented twice.
+later be decremented twice.  Mortalization can be thought of attaching an SV to
+the current scope, or current executing statement of Perl code, and upon the
+change to the next Perl language scope (C<}>), or next Perl language statement
+(C<;>), or XS synthesis of those 2 Perl langauge concepts, the SV will be
+freed if nothing else wanted to retain the SV.  Mortal is similar to a C++
+smart pointer.
 
 "Mortal" SVs are mainly used for SVs that are placed on perl's stack.
 For example an SV which is created just to pass a number to a called sub
 is made mortal to have it cleaned up automatically when it's popped off
 the stack.  Similarly, results returned by XSUBs (which are pushed on the
-stack) are often made mortal.
+stack) are often made mortal; the few exceptions are listed further down.
 
 To create a mortal variable, use the functions:
 
@@ -876,7 +885,11 @@ as deferred C<SvREFCNT_dec> should help to minimize such problems.
 For example if you are passing an SV which you I<know> has a high enough REFCNT
 to survive its use on the stack you need not do any mortalization.
 If you are not sure then doing an C<SvREFCNT_inc> and C<sv_2mortal>, or
-making a C<sv_mortalcopy> is safer.
+making a C<sv_mortalcopy> is safer.  A real example would be getting an SV *
+from C<get_sv>.  In that case, the SV is owned by the package namespace.  If
+you just C<sv_2mortal> the package SV, you will probably free the SV in the
+glob, causing a perl panic or crash.  If you C<SvREFCNT_inc> and then
+C<sv_2mortal> the package SV, that is safe, but inefficient.
 
 The mortal routines are not just for SVs; AVs and HVs can be
 made mortal by passing their address (type-casted to C<SV*>) to the
-- 
1.8.0.msysgit.0

@p5pRT
Copy link
Author

p5pRT commented May 27, 2015

From @tonycoz

On Tue Apr 28 12​:35​:10 2015, bulk88 wrote​:
"Mortalization" then is at its simplest a deferred C<SvREFCNT_dec>.
However, if you mortalize a variable twice, the reference count will
-later be decremented twice.
+later be decremented twice. Mortalization can be thought of attaching an SV to
+the current scope, or current executing statement of Perl code, and upon the
+change to the next Perl language scope (C<}>), or next Perl language statement
+(C<;>), or XS synthesis of those 2 Perl langauge concepts, the SV will be
+freed if nothing else wanted to retain the SV. Mortal is similar to a C++
+smart pointer.

It might be better to just say that FREETMPS is called in those places.

Tony

@p5pRT
Copy link
Author

p5pRT commented Aug 9, 2015

From @bulk88

On Wed May 27 00​:03​:09 2015, tonyc wrote​:

On Tue Apr 28 12​:35​:10 2015, bulk88 wrote​:
"Mortalization" then is at its simplest a deferred C<SvREFCNT_dec>.
However, if you mortalize a variable twice, the reference count will
-later be decremented twice.
+later be decremented twice. Mortalization can be thought of
attaching an SV to
+the current scope, or current executing statement of Perl code, and
upon the
+change to the next Perl language scope (C<}>), or next Perl language
statement
+(C<;>), or XS synthesis of those 2 Perl langauge concepts, the SV
will be
+freed if nothing else wanted to retain the SV. Mortal is similar to
a C++
+smart pointer.

It might be better to just say that FREETMPS is called in those
places.

Tony

I think saying only "calls FREETMPS" is unhelpful. FREETMPS is another macro. Documenting any 2 macros as being the opposites of each other, doesn't say what they are, or when to use them. I want to connect the mortal concept of XS code to something in PP code, that a XS newbie will understand, since all XS programmers come from PP programmers (I hope).

--
bulk88 ~ bulk88 at hotmail.com

@p5pRT
Copy link
Author

p5pRT commented Sep 9, 2015

From @bulk88

On Sat Aug 08 22​:24​:55 2015, bulk88 wrote​:

On Wed May 27 00​:03​:09 2015, tonyc wrote​:

On Tue Apr 28 12​:35​:10 2015, bulk88 wrote​:
"Mortalization" then is at its simplest a deferred C<SvREFCNT_dec>.
However, if you mortalize a variable twice, the reference count will
-later be decremented twice.
+later be decremented twice. Mortalization can be thought of
attaching an SV to
+the current scope, or current executing statement of Perl code, and
upon the
+change to the next Perl language scope (C<}>), or next Perl language
statement
+(C<;>), or XS synthesis of those 2 Perl langauge concepts, the SV
will be
+freed if nothing else wanted to retain the SV. Mortal is similar to
a C++
+smart pointer.

It might be better to just say that FREETMPS is called in those
places.

Tony

I think saying only "calls FREETMPS" is unhelpful. FREETMPS is another
macro. Documenting any 2 macros as being the opposites of each other,
doesn't say what they are, or when to use them. I want to connect the
mortal concept of XS code to something in PP code, that a XS newbie
will understand, since all XS programmers come from PP programmers (I
hope).

Bump.

--
bulk88 ~ bulk88 at hotmail.com

@p5pRT
Copy link
Author

p5pRT commented Sep 10, 2015

From @tonycoz

On Tue Apr 28 12​:35​:10 2015, bulk88 wrote​:

On Tue Jul 22 16​:37​:37 2014, tonyc wrote​:

On Tue Jul 22 08​:35​:48 2014, bulk88 wrote​:

Unsmoked. See attached patch.

"Mortalization" then is at its simplest a deferred C<SvREFCNT_dec>.
However, if you mortalize a variable twice, the reference count will
-later be decremented twice.
+later be decremented twice. Mortal can be thought of as attached a
SV to

Should probably be "Mortalization can be thought of attaching an SV
to
..."[1]

+the current scope of the Perl stack (but not putting the SV on the
Perl stack),
+and the SV will be freeded if nothing else wants it, when the scope
is left.
+Mortal is similar to a C++ smart pointer.

There's a enough differences that this comparison might be confusing.
Anyone else?

Tony

[1] I pronounce SV as ess-vee, so "an" instead of "a", perlguts uses
"a SV" once, "an SV" several times

-freeded fixed,
-analogy to "perl stack" removed and replaced with another analogy
-a replace with an
-example expanded of when it is safe to return an SV on perl stack
without sv_2mortal

+the current scope, or current executing statement of Perl code, and upon the
+change to the next Perl language scope (C<}>), or next Perl language statement
+(C<;>), or XS synthesis of those 2 Perl langauge concepts, the SV will be
+freed if nothing else wanted to retain the SV. Mortal is similar to a C++
+smart pointer.

s/langauge/language/

"or XS synthesis of those 2 Perl langauge concepts"

This is kind of vague to me.

@​@​ -876,7 +885,11 @​@​ as deferred C<SvREFCNT_dec> should help to minimize such problems.
For example if you are passing an SV which you I<know> has a high enough REFCNT
to survive its use on the stack you need not do any mortalization.
If you are not sure then doing an C<SvREFCNT_inc> and C<sv_2mortal>, or
-making a C<sv_mortalcopy> is safer.
+making a C<sv_mortalcopy> is safer. A real example would be getting an SV *
+from C<get_sv>. In that case, the SV is owned by the package namespace. If
+you just C<sv_2mortal> the package SV, you will probably free the SV in the
+glob, causing a perl panic or crash. If you C<SvREFCNT_inc> and then
+C<sv_2mortal> the package SV, that is safe, but inefficient.

I tend to think of this in terms of "ownership" of the reference - did I create the reference*? If so I can mortalize it.

I don't own a reference from get_sv() and no longer own a reference I've stored in a HV, AV or GV.

Expressing that clearly and concisely might be hard though.

Again, other opinions desired.

Tony

* in this the "reference" being an increment of the reference count of some SV, including the starting count on a new SV

@p5pRT
Copy link
Author

p5pRT commented Nov 11, 2017

From zefram@fysh.org

I have heavily revised that doc section in commit
3d2ba98. This should satisfy the aims
of this ticket.

-zefram

@p5pRT
Copy link
Author

p5pRT commented Nov 15, 2017

From @xsawyerx

On Sat, 11 Nov 2017 04​:25​:57 -0800, zefram@​fysh.org wrote​:

I have heavily revised that doc section in commit
3d2ba98. This should satisfy the aims
of this ticket.

Bulk, I will be resolving this issue within 7 days unless you object.

Thank you.

@p5pRT p5pRT closed this as completed Dec 4, 2017
@p5pRT
Copy link
Author

p5pRT commented Dec 4, 2017

@xsawyerx - Status changed from 'open' to 'resolved'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant