Change 33449 by [EMAIL PROTECTED] on 2008/03/06 14:14:52

        Arrange for newGP to know when it needs to copy the filename of the
        current COP, because that COP is likely to be freed before the GV.
        Not perfect (valgrind still spots a couple not caught) but gets most,
        and gets ext/B/t/lint.t passing.

Affected files ...

... //depot/maint-5.8/perl/gv.c#115 edit
... //depot/maint-5.8/perl/op.c#228 edit
... //depot/maint-5.8/perl/op.h#42 edit
... //depot/maint-5.8/perl/scope.h#31 edit

Differences ...

==== //depot/maint-5.8/perl/gv.c#115 (text) ====
Index: perl/gv.c
--- perl/gv.c#114~33217~        2008-02-02 14:47:50.000000000 -0800
+++ perl/gv.c   2008-03-06 06:14:52.000000000 -0800
@@ -170,16 +170,35 @@
     GP *gp;
     const char *const file
        = (PL_curcop && CopFILE(PL_curcop)) ? CopFILE(PL_curcop) : "";
-    Newxz(gp, 1, GP);
+
+#ifdef USE_ITHREADS
+    if (PL_curcop && PL_curcop->op_flags & OPf_COP_TEMP) {
+       /* The COP's CopFILE is likely to go away soon, so we can't simply point
+          to it. There is no provision to free memory at GP destruction, so we
+          cheat wholesale and store it within the same memory as is allocated
+          for the GP itself. This hack isn't needed in 5.10 and later, where
+          the char *gp_file has been replaced by a (reference counted) pointer
+          to a shared hash key.  */
+       const STRLEN len = strlen(file) +  1;
+
+       Newxc(gp, sizeof(GP) + len, char, GP);
+       Zero(gp, 1, GP);
+       gp->gp_file = (char *) gp + 1;
+       Copy(file, gp + 1, len, char);
+    } else
+#endif
+    {
+       Newxz(gp, 1, GP);
+       /* XXX Ideally this cast would be replaced with a change to const char*
+          in the struct.  */
+       gp->gp_file = (char *) file;
+    }
 
 #ifndef PERL_DONT_CREATE_GVSV
     gp->gp_sv = newSV(0);
 #endif
 
     gp->gp_line = PL_curcop ? CopLINE(PL_curcop) : 0;
-    /* XXX Ideally this cast would be replaced with a change to const char*
-       in the struct.  */
-    gp->gp_file = (char *) file;
     gp->gp_egv = gv;
     gp->gp_refcnt = 1;
 

==== //depot/maint-5.8/perl/op.c#228 (text) ====
Index: perl/op.c
--- perl/op.c#227~33214~        2008-02-02 14:01:39.000000000 -0800
+++ perl/op.c   2008-03-06 06:14:52.000000000 -0800
@@ -1404,7 +1404,8 @@
        }
     }
     else if (type != OP_GREPSTART && type != OP_ENTERSUB
-             && type != OP_LEAVESUBLV)
+             && type != OP_LEAVESUBLV && type != OP_NEXTSTATE
+            && type != OP_SETSTATE && type != OP_DBSTATE)
        o->op_flags |= OPf_REF;
     return o;
 }

==== //depot/maint-5.8/perl/op.h#42 (text) ====
Index: perl/op.h
--- perl/op.h#41~33214~ 2008-02-02 14:01:39.000000000 -0800
+++ perl/op.h   2008-03-06 06:14:52.000000000 -0800
@@ -79,6 +79,10 @@
                                /*  (Or block needs explicit scope entry.) */
 #define OPf_REF                16      /* Certified reference. */
                                /*  (Return container, not containee). */
+#define OPf_COP_TEMP   16      /* COP is likely to get freed soon.
+                                  This is only used with ithreads, but isn't a
+                                  conditional compile, else ext/B/defsubs.h
+                                  gets confused. */
 #define OPf_MOD                32      /* Will modify (lvalue). */
 #define OPf_STACKED    64      /* Some arg is arriving on the stack. */
 #define OPf_SPECIAL    128     /* Do something weird for this op: */

==== //depot/maint-5.8/perl/scope.h#31 (text) ====
Index: perl/scope.h
--- perl/scope.h#30~33204~      2008-02-02 10:16:39.000000000 -0800
+++ perl/scope.h        2008-03-06 06:14:52.000000000 -0800
@@ -204,7 +204,11 @@
 #  define SAVECOPSTASH(c)      SAVEPPTR(CopSTASHPV(c))
 #  define SAVECOPSTASH_FREE(c) SAVESHAREDPV(CopSTASHPV(c))
 #  define SAVECOPFILE(c)       SAVEPPTR(CopFILE(c))
-#  define SAVECOPFILE_FREE(c)  SAVESHAREDPV(CopFILE(c))
+#  define SAVECOPFILE_FREE(c)  STMT_START {    \
+       SAVESHAREDPV(CopFILE(c));               \
+       SAVEI8((c)->op_flags);                  \
+       (c)->op_flags |= OPf_COP_TEMP;          \
+    } STMT_END
 #else
 #  define SAVECOPSTASH(c)      SAVESPTR(CopSTASH(c))
 #  define SAVECOPSTASH_FREE(c) SAVECOPSTASH(c) /* XXX not refcounted */
End of Patch.

Reply via email to