Change 14284 by jhi@alpha on 2002/01/15 15:55:53

        Integrate perlio;
        
        (reintroduce #14251) Slab allocator for ops
         - moved the statics to intrpvar.h
         - implemented Slab_Free()
         - uses PerlMemShared (for now) if distinction exists.
        
        Slab allocator submit after resolve -ay to keep it!
        
        Hand merge of non slab allocator stuff
        
        const-ness fix in savepv's passing of NULL
        
        Typo in #else branch of PL_SLAB_ALLOC
        
        Integrate rest of mainline
        
        Regen embed enable slab for PERL_IMPLICIT_SYS
        
        Correct name of PL_OP_SLAB_ALLOC
        
        Correct slab allocator for case where sizeof(IV) > sizeof(IV *)
        e.g. -Duse64bitint on a 32-bit platform.
        Now uses I32 for use-count and is more careful with its casts.

Affected files ...

.... //depot/perl/cop.h#62 integrate
.... //depot/perl/embed.fnc#9 integrate
.... //depot/perl/embed.h#330 integrate
.... //depot/perl/embedvar.h#138 integrate
.... //depot/perl/global.sym#202 integrate
.... //depot/perl/intrpvar.h#100 integrate
.... //depot/perl/op.c#478 integrate
.... //depot/perl/op.h#104 integrate
.... //depot/perl/perl.c#405 integrate
.... //depot/perl/perl.h#436 integrate
.... //depot/perl/perlapi.c#128 integrate
.... //depot/perl/perlapi.h#60 integrate
.... //depot/perl/perlio.h#38 integrate
.... //depot/perl/pod/perlapi.pod#127 integrate
.... //depot/perl/pod/perlintern.pod#16 integrate
.... //depot/perl/proto.h#372 integrate
.... //depot/perl/scope.c#89 integrate
.... //depot/perl/scope.h#51 integrate
.... //depot/perl/sv.c#510 integrate
.... //depot/perl/toke.c#411 integrate
.... //depot/perl/util.c#316 integrate
.... //depot/perl/win32/config_H.vc#114 integrate
.... //depot/perl/win32/config_h.PL#26 integrate
.... //depot/perl/win32/perlhost.h#49 integrate
.... //depot/perl/win32/perllib.c#51 integrate
.... //depot/perl/win32/vmem.h#8 integrate
.... //depot/perl/win32/win32.c#187 integrate
.... //depot/perl/win32/win32.h#98 integrate

Differences ...

==== //depot/perl/cop.h#62 (text) ====
Index: perl/cop.h
--- perl/cop.h.~1~      Tue Jan 15 09:00:05 2002
+++ perl/cop.h  Tue Jan 15 09:00:05 2002
@@ -30,13 +30,13 @@
 #  define CopFILE(c)           ((c)->cop_file)
 #  define CopFILEGV(c)         (CopFILE(c) \
                                 ? gv_fetchfile(CopFILE(c)) : Nullgv)
-#  define CopFILE_set(c,pv)    ((c)->cop_file = savepv(pv))
+#  define CopFILE_set(c,pv)    ((c)->cop_file = savesharedpv(pv))
 #  define CopFILESV(c)         (CopFILE(c) \
                                 ? GvSV(gv_fetchfile(CopFILE(c))) : Nullsv)
 #  define CopFILEAV(c)         (CopFILE(c) \
                                 ? GvAV(gv_fetchfile(CopFILE(c))) : Nullav)
 #  define CopSTASHPV(c)                ((c)->cop_stashpv)
-#  define CopSTASHPV_set(c,pv) ((c)->cop_stashpv = ((pv) ? savepv(pv) : Nullch))
+#  define CopSTASHPV_set(c,pv) ((c)->cop_stashpv = savesharedpv(pv))
 #  define CopSTASH(c)          (CopSTASHPV(c) \
                                 ? gv_stashpv(CopSTASHPV(c),GV_ADD) : Nullhv)
 #  define CopSTASH_set(c,hv)   CopSTASHPV_set(c, (hv) ? HvNAME(hv) : Nullch)
@@ -44,6 +44,8 @@
                                 && (CopSTASHPV(c) == HvNAME(hv)        \
                                     || (CopSTASHPV(c) && HvNAME(hv)    \
                                         && strEQ(CopSTASHPV(c), HvNAME(hv)))))
+#  define CopSTASH_free(c)     PerlMemShared_free(CopSTASHPV(c))      
+#  define CopFILE_free(c)      (PerlMemShared_free(CopFILE(c)),(CopFILE(c) = Nullch)) 
+     
 #else
 #  define CopFILEGV(c)         ((c)->cop_filegv)
 #  define CopFILEGV_set(c,gv)  ((c)->cop_filegv = (GV*)SvREFCNT_inc(gv))
@@ -57,6 +59,9 @@
    /* cop_stash is not refcounted */
 #  define CopSTASHPV_set(c,pv) CopSTASH_set((c), gv_stashpv(pv,GV_ADD))
 #  define CopSTASH_eq(c,hv)    (CopSTASH(c) == (hv))
+#  define CopSTASH_free(c)     
+#  define CopFILE_free(c)      (SvREFCNT_dec(CopFILEGV(c)),(CopFILEGV(c) = Nullgv))
+
 #endif /* USE_ITHREADS */
 
 #define CopSTASH_ne(c,hv)      (!CopSTASH_eq(c,hv))

==== //depot/perl/embed.fnc#9 (text) ====
Index: perl/embed.fnc
--- perl/embed.fnc.~1~  Tue Jan 15 09:00:05 2002
+++ perl/embed.fnc      Tue Jan 15 09:00:05 2002
@@ -613,6 +613,7 @@
 p      |I32    |same_dirent    |char* a|char* b
 #endif
 Apd    |char*  |savepv         |const char* sv
+Apd    |char*  |savesharedpv   |const char* sv
 Apd    |char*  |savepvn        |const char* sv|I32 len
 Ap     |void   |savestack_grow
 Ap     |void   |save_aelem     |AV* av|I32 idx|SV **sptr
@@ -628,6 +629,7 @@
 Ap     |void   |save_freepv    |char* pv
 Ap     |void   |save_generic_svref|SV** sptr
 Ap     |void   |save_generic_pvref|char** str
+Ap     |void   |save_shared_pvref|char** str
 Ap     |void   |save_gp        |GV* gv|I32 empty
 Ap     |HV*    |save_hash      |GV* gv
 Ap     |void   |save_helem     |HV* hv|SV *key|SV **sptr

==== //depot/perl/embed.h#330 (text+w) ====
Index: perl/embed.h
--- perl/embed.h.~1~    Tue Jan 15 09:00:05 2002
+++ perl/embed.h        Tue Jan 15 09:00:05 2002
@@ -578,6 +578,7 @@
 #define same_dirent            Perl_same_dirent
 #endif
 #define savepv                 Perl_savepv
+#define savesharedpv           Perl_savesharedpv
 #define savepvn                        Perl_savepvn
 #define savestack_grow         Perl_savestack_grow
 #define save_aelem             Perl_save_aelem
@@ -593,6 +594,7 @@
 #define save_freepv            Perl_save_freepv
 #define save_generic_svref     Perl_save_generic_svref
 #define save_generic_pvref     Perl_save_generic_pvref
+#define save_shared_pvref      Perl_save_shared_pvref
 #define save_gp                        Perl_save_gp
 #define save_hash              Perl_save_hash
 #define save_helem             Perl_save_helem
@@ -2127,6 +2129,7 @@
 #define same_dirent(a,b)       Perl_same_dirent(aTHX_ a,b)
 #endif
 #define savepv(a)              Perl_savepv(aTHX_ a)
+#define savesharedpv(a)                Perl_savesharedpv(aTHX_ a)
 #define savepvn(a,b)           Perl_savepvn(aTHX_ a,b)
 #define savestack_grow()       Perl_savestack_grow(aTHX)
 #define save_aelem(a,b,c)      Perl_save_aelem(aTHX_ a,b,c)
@@ -2142,6 +2145,7 @@
 #define save_freepv(a)         Perl_save_freepv(aTHX_ a)
 #define save_generic_svref(a)  Perl_save_generic_svref(aTHX_ a)
 #define save_generic_pvref(a)  Perl_save_generic_pvref(aTHX_ a)
+#define save_shared_pvref(a)   Perl_save_shared_pvref(aTHX_ a)
 #define save_gp(a,b)           Perl_save_gp(aTHX_ a,b)
 #define save_hash(a)           Perl_save_hash(aTHX_ a)
 #define save_helem(a,b,c)      Perl_save_helem(aTHX_ a,b,c)

==== //depot/perl/embedvar.h#138 (text+w) ====
Index: perl/embedvar.h
--- perl/embedvar.h.~1~ Tue Jan 15 09:00:05 2002
+++ perl/embedvar.h     Tue Jan 15 09:00:05 2002
@@ -183,6 +183,9 @@
 #define PL_Mem                 (PERL_GET_INTERP->IMem)
 #define PL_MemParse            (PERL_GET_INTERP->IMemParse)
 #define PL_MemShared           (PERL_GET_INTERP->IMemShared)
+#define PL_OpPtr               (PERL_GET_INTERP->IOpPtr)
+#define PL_OpSlab              (PERL_GET_INTERP->IOpSlab)
+#define PL_OpSpace             (PERL_GET_INTERP->IOpSpace)
 #define PL_Proc                        (PERL_GET_INTERP->IProc)
 #define PL_Sock                        (PERL_GET_INTERP->ISock)
 #define PL_StdIO               (PERL_GET_INTERP->IStdIO)
@@ -478,6 +481,9 @@
 #define PL_Mem                 (vTHX->IMem)
 #define PL_MemParse            (vTHX->IMemParse)
 #define PL_MemShared           (vTHX->IMemShared)
+#define PL_OpPtr               (vTHX->IOpPtr)
+#define PL_OpSlab              (vTHX->IOpSlab)
+#define PL_OpSpace             (vTHX->IOpSpace)
 #define PL_Proc                        (vTHX->IProc)
 #define PL_Sock                        (vTHX->ISock)
 #define PL_StdIO               (vTHX->IStdIO)
@@ -776,6 +782,9 @@
 #define PL_IMem                        PL_Mem
 #define PL_IMemParse           PL_MemParse
 #define PL_IMemShared          PL_MemShared
+#define PL_IOpPtr              PL_OpPtr
+#define PL_IOpSlab             PL_OpSlab
+#define PL_IOpSpace            PL_OpSpace
 #define PL_IProc               PL_Proc
 #define PL_ISock               PL_Sock
 #define PL_IStdIO              PL_StdIO

==== //depot/perl/global.sym#202 (text+w) ====
Index: perl/global.sym
--- perl/global.sym.~1~ Tue Jan 15 09:00:05 2002
+++ perl/global.sym     Tue Jan 15 09:00:05 2002
@@ -351,6 +351,7 @@
 Perl_rsignal
 Perl_rsignal_state
 Perl_savepv
+Perl_savesharedpv
 Perl_savepvn
 Perl_savestack_grow
 Perl_save_aelem
@@ -365,6 +366,7 @@
 Perl_save_freepv
 Perl_save_generic_svref
 Perl_save_generic_pvref
+Perl_save_shared_pvref
 Perl_save_gp
 Perl_save_hash
 Perl_save_helem

==== //depot/perl/intrpvar.h#100 (text) ====
Index: perl/intrpvar.h
--- perl/intrpvar.h.~1~ Tue Jan 15 09:00:05 2002
+++ perl/intrpvar.h     Tue Jan 15 09:00:05 2002
@@ -512,6 +512,12 @@
 
 PERLVAR(Itaint_warn, bool)      /* taint warns instead of dying */
 
+#ifdef PL_OP_SLAB_ALLOC
+PERLVAR(IOpPtr,I32 **)
+PERLVARI(IOpSpace,I32,0)
+PERLVAR(IOpSlab,I32 *)
+#endif
+
 /* New variables must be added to the very end for binary compatibility.
  * XSUB.h provides wrapper functions via perlapi.h that make this
  * irrelevant, but not all code may be expected to #include XSUB.h. */

==== //depot/perl/op.c#478 (text) ====
Index: perl/op.c
--- perl/op.c.~1~       Tue Jan 15 09:00:05 2002
+++ perl/op.c   Tue Jan 15 09:00:05 2002
@@ -23,28 +23,75 @@
 
 #define CALL_PEEP(o) CALL_FPTR(PL_peepp)(aTHX_ o)
 
-/* #define PL_OP_SLAB_ALLOC */
+#if defined(PL_OP_SLAB_ALLOC)
+
+#ifndef PERL_SLAB_SIZE
+#define PERL_SLAB_SIZE 2048
+#endif
+
+#define NewOp(m,var,c,type) \
+       STMT_START { var = (type *) Slab_Alloc(m,c*sizeof(type)); } STMT_END
 
-#if defined(PL_OP_SLAB_ALLOC) && !defined(PERL_IMPLICIT_CONTEXT)
-#define SLAB_SIZE 8192
-static char    *PL_OpPtr  = NULL;      /* XXX threadead */
-static int     PL_OpSpace = 0;         /* XXX threadead */
-#define NewOp(m,var,c,type) do { if ((PL_OpSpace -= c*sizeof(type)) >= 0)     \
-                              var =  (type *)(PL_OpPtr -= c*sizeof(type));    \
-                             else                                             \
-                              var = (type *) Slab_Alloc(m,c*sizeof(type));    \
-                           } while (0)
+#define FreeOp(p) Slab_Free(p)
 
 STATIC void *
 S_Slab_Alloc(pTHX_ int m, size_t sz)
 {
- Newz(m,PL_OpPtr,SLAB_SIZE,char);
- PL_OpSpace = SLAB_SIZE - sz;
- return PL_OpPtr += PL_OpSpace;
+    /*
+     * To make incrementing use count easy PL_OpSlab is an I32 *
+     * To make inserting the link to slab PL_OpPtr is I32 **
+     * So compute size in units of sizeof(I32 *) as that is how Pl_OpPtr increments
+     * Add an overhead for pointer to slab and round up as a number of pointers
+     */
+    sz = (sz + 2*sizeof(I32 *) -1)/sizeof(I32 *);
+    if ((PL_OpSpace -= sz) < 0) {
+       PL_OpPtr = (I32 **) PerlMemShared_malloc(PERL_SLAB_SIZE*sizeof(I32*));
+       if (!PL_OpPtr) {
+           return NULL;
+       }
+       Zero(PL_OpPtr,PERL_SLAB_SIZE,I32 **);
+       /* We reserve the 0'th I32 sized chunk as a use count */
+       PL_OpSlab = (I32 *) PL_OpPtr;
+       /* Reduce size by the use count word, and by the size we need.
+        * Latter is to mimic the '-=' in the if() above
+        */
+       PL_OpSpace = PERL_SLAB_SIZE - (sizeof(I32)+sizeof(I32 **)-1)/sizeof(I32 **) - 
+sz;
+       /* Allocation pointer starts at the top.
+          Theory: because we build leaves before trunk allocating at end
+          means that at run time access is cache friendly upward
+        */
+       PL_OpPtr += PERL_SLAB_SIZE;
+    }
+    assert( PL_OpSpace >= 0 );
+    /* Move the allocation pointer down */
+    PL_OpPtr   -= sz;
+    assert( PL_OpPtr > (I32 **) PL_OpSlab );
+    *PL_OpPtr   = PL_OpSlab;   /* Note which slab it belongs to */
+    (*PL_OpSlab)++;            /* Increment use count of slab */
+    assert( PL_OpPtr+sz <= ((I32 **) PL_OpSlab + PERL_SLAB_SIZE) );
+    assert( *PL_OpSlab > 0 );
+    return (void *)(PL_OpPtr + 1);
+}
+
+STATIC void
+S_Slab_Free(pTHX_ void *op)
+{
+    I32 **ptr = (I32 **) op;
+    I32 *slab = ptr[-1];
+    assert( ptr-1 > (I32 **) slab );
+    assert( ptr < ( (I32 **) slab + PERL_SLAB_SIZE) );
+    assert( *slab > 0 );
+    if (--(*slab) == 0) {
+       PerlMemShared_free(slab);
+       if (slab == PL_OpSlab) {
+           PL_OpSpace = 0;
+       }
+    }
 }
 
 #else
 #define NewOp(m, var, c, type) Newz(m, var, c, type)
+#define FreeOp(p) Safefree(p)
 #endif
 /*
  * In the following definition, the ", Nullop" is just to make the compiler
@@ -735,14 +782,7 @@
        cop_free((COP*)o);
 
     op_clear(o);
-
-#ifdef PL_OP_SLAB_ALLOC
-    if ((char *) o == PL_OpPtr)
-     {
-     }
-#else
-    Safefree(o);
-#endif
+    FreeOp(o);
 }
 
 void
@@ -847,11 +887,7 @@
                    pmop = pmop->op_pmnext;
                }
            }
-#ifdef USE_ITHREADS
-           Safefree(PmopSTASHPV(cPMOPo));
-#else
-           /* NOTE: PMOP.op_pmstash is not refcounted */
-#endif
+           PmopSTASH_free(cPMOPo);
        }
        cPMOPo->op_pmreplroot = Nullop;
         /* we use the "SAFE" version of the PM_ macros here
@@ -882,18 +918,20 @@
 STATIC void
 S_cop_free(pTHX_ COP* cop)
 {
-    Safefree(cop->cop_label);
+    Safefree(cop->cop_label);   /* FIXME: treaddead ??? */
+    CopFILE_free(cop);
+    CopSTASH_free(cop);
+    if (! specialWARN(cop->cop_warnings))
+       SvREFCNT_dec(cop->cop_warnings);
+    if (! specialCopIO(cop->cop_io)) {
 #ifdef USE_ITHREADS
-    Safefree(CopFILE(cop));            /* XXX share in a pvtable? */
-    Safefree(CopSTASHPV(cop));         /* XXX share in a pvtable? */
+       STRLEN len;
+        char *s = SvPV(cop->cop_io,len);
+       Perl_warn(aTHX_ "io='%.*s'",(int) len,s);
 #else
-    /* NOTE: COP.cop_stash is not refcounted */
-    SvREFCNT_dec(CopFILEGV(cop));
+       SvREFCNT_dec(cop->cop_io);
 #endif
-    if (! specialWARN(cop->cop_warnings))
-       SvREFCNT_dec(cop->cop_warnings);
-    if (! specialCopIO(cop->cop_io))
-       SvREFCNT_dec(cop->cop_io);
+    }
 }
 
 void
@@ -2583,10 +2621,8 @@
     first->op_last = last->op_last;
     first->op_flags |= (last->op_flags & OPf_KIDS);
 
-#ifdef PL_OP_SLAB_ALLOC
-#else
-    Safefree(last);
-#endif
+    FreeOp(last);
+
     return (OP*)first;
 }
 
@@ -4288,6 +4324,7 @@
        LOOP *tmp;
        NewOp(1234,tmp,1,LOOP);
        Copy(loop,tmp,1,LOOP);
+       FreeOp(loop);
        loop = tmp;
     }
 #else
@@ -5141,11 +5178,7 @@
        SAVESPTR(PL_curstash);
        SAVECOPSTASH(PL_curcop);
        PL_curstash = stash;
-#ifdef USE_ITHREADS
-       CopSTASHPV(PL_curcop) = stash ? HvNAME(stash) : Nullch;
-#else
-       CopSTASH(PL_curcop) = stash;
-#endif
+       CopSTASH_set(PL_curcop,stash);
     }
 
     cv = newXS(name, const_sv_xsub, __FILE__);
@@ -6056,8 +6089,6 @@
                newSVpvn("File::Glob", 10), Nullsv, Nullsv, Nullsv);
        gv = gv_fetchpv("CORE::GLOBAL::glob", FALSE, SVt_PVCV);
        glob_gv = gv_fetchpv("File::Glob::csh_glob", FALSE, SVt_PVCV);
-       if (!glob_gv)
-           Perl_croak(aTHX_ "Can't locate File::Glob");
        GvCV(gv) = GvCV(glob_gv);
        SvREFCNT_inc((SV*)GvCV(gv));
        GvIMPORTED_CV_on(gv);

==== //depot/perl/op.h#104 (text) ====
Index: perl/op.h
--- perl/op.h.~1~       Tue Jan 15 09:00:05 2002
+++ perl/op.h   Tue Jan 15 09:00:05 2002
@@ -299,17 +299,21 @@
 #define PMf_COMPILETIME        
(PMf_MULTILINE|PMf_SINGLELINE|PMf_LOCALE|PMf_FOLD|PMf_EXTENDED)
 
 #ifdef USE_ITHREADS
+
 #  define PmopSTASHPV(o)       ((o)->op_pmstashpv)
-#  define PmopSTASHPV_set(o,pv)        ((o)->op_pmstashpv = ((pv) ? savepv(pv) : 
Nullch))
+#  define PmopSTASHPV_set(o,pv)        (PmopSTASHPV(o) = savesharedpv(pv))
 #  define PmopSTASH(o)         (PmopSTASHPV(o) \
                                 ? gv_stashpv(PmopSTASHPV(o),GV_ADD) : Nullhv)
-#  define PmopSTASH_set(o,hv)  PmopSTASHPV_set(o, (hv) ? HvNAME(hv) : Nullch)
+#  define PmopSTASH_set(o,hv)  PmopSTASHPV_set(o, ((hv) ? HvNAME(hv) : Nullch))
+#  define PmopSTASH_free(o)    PerlMemShared_free(PmopSTASHPV(o))
+
 #else
 #  define PmopSTASH(o)         ((o)->op_pmstash)
 #  define PmopSTASH_set(o,hv)  ((o)->op_pmstash = (hv))
 #  define PmopSTASHPV(o)       (PmopSTASH(o) ? HvNAME(PmopSTASH(o)) : Nullch)
    /* op_pmstash is not refcounted */
 #  define PmopSTASHPV_set(o,pv)        PmopSTASH_set((o), gv_stashpv(pv,GV_ADD))
+#  define PmopSTASH_free(o)    
 #endif
 
 struct svop {

==== //depot/perl/perl.c#405 (text) ====
Index: perl/perl.c
--- perl/perl.c.~1~     Tue Jan 15 09:00:05 2002
+++ perl/perl.c Tue Jan 15 09:00:05 2002
@@ -696,15 +696,8 @@
     if (!specialCopIO(PL_compiling.cop_io))
        SvREFCNT_dec(PL_compiling.cop_io);
     PL_compiling.cop_io = Nullsv;
-#ifdef USE_ITHREADS
-    Safefree(CopFILE(&PL_compiling));
-    CopFILE(&PL_compiling) = Nullch;
-    Safefree(CopSTASHPV(&PL_compiling));
-#else
-    SvREFCNT_dec(CopFILEGV(&PL_compiling));
-    CopFILEGV(&PL_compiling) = Nullgv;
-    /* cop_stash is not refcounted */
-#endif
+    CopFILE_free(&PL_compiling);
+    CopSTASH_free(&PL_compiling);
 
     /* Prepare to destruct main symbol table.  */
 
@@ -2717,11 +2710,7 @@
        }
     }
 
-#   ifdef USE_ITHREADS
-        Safefree(CopFILE(PL_curcop));
-#   else
-        SvREFCNT_dec(CopFILEGV(PL_curcop));
-#   endif
+    CopFILE_free(PL_curcop);
     CopFILE_set(PL_curcop, PL_origfilename);
     if (strEQ(PL_origfilename,"-"))
        scriptname = "";

==== //depot/perl/perl.h#436 (text) ====
Index: perl/perl.h
--- perl/perl.h.~1~     Tue Jan 15 09:00:05 2002
+++ perl/perl.h Tue Jan 15 09:00:05 2002
@@ -41,6 +41,15 @@
 /* See L<perlguts/"The Perl API"> for detailed notes on
  * PERL_IMPLICIT_CONTEXT and PERL_IMPLICIT_SYS */
 
+#ifdef PERL_IMPLICIT_SYS
+/* PERL_IMPLICIT_SYS implies PerlMemShared != PerlMem
+   so use slab allocator to avoid lots of MUTEX overhead
+ */
+#  ifndef PL_OP_SLAB_ALLOC
+#    define PL_OP_SLAB_ALLOC
+#  endif
+#endif
+
 #ifdef USE_ITHREADS
 #  if !defined(MULTIPLICITY)
 #    define MULTIPLICITY

==== //depot/perl/perlapi.c#128 (text+w) ====
==== //depot/perl/perlapi.h#60 (text+w) ====
Index: perl/perlapi.h
--- perl/perlapi.h.~1~  Tue Jan 15 09:00:05 2002
+++ perl/perlapi.h      Tue Jan 15 09:00:05 2002
@@ -103,6 +103,12 @@
 #define PL_MemParse            (*Perl_IMemParse_ptr(aTHX))
 #undef  PL_MemShared
 #define PL_MemShared           (*Perl_IMemShared_ptr(aTHX))
+#undef  PL_OpPtr
+#define PL_OpPtr               (*Perl_IOpPtr_ptr(aTHX))
+#undef  PL_OpSlab
+#define PL_OpSlab              (*Perl_IOpSlab_ptr(aTHX))
+#undef  PL_OpSpace
+#define PL_OpSpace             (*Perl_IOpSpace_ptr(aTHX))
 #undef  PL_Proc
 #define PL_Proc                        (*Perl_IProc_ptr(aTHX))
 #undef  PL_Sock

==== //depot/perl/perlio.h#38 (text) ====
Index: perl/perlio.h
--- perl/perlio.h.~1~   Tue Jan 15 09:00:05 2002
+++ perl/perlio.h       Tue Jan 15 09:00:05 2002
@@ -149,7 +149,7 @@
 #endif                         /* ifndef PERLIO_NOT_STDIO */
 #endif                         /* PERLIO_IS_STDIO */
 
-#define specialCopIO(sv) ((sv) != Nullsv)
+#define specialCopIO(sv) ((sv) == Nullsv)
 
 /* ----------- fill in things that have not got #define'd  ---------- */
 

==== //depot/perl/pod/perlapi.pod#127 (text+w) ====
==== //depot/perl/pod/perlintern.pod#16 (text+w) ====
==== //depot/perl/proto.h#372 (text+w) ====
Index: perl/proto.h
--- perl/proto.h.~1~    Tue Jan 15 09:00:05 2002
+++ perl/proto.h        Tue Jan 15 09:00:05 2002
@@ -641,6 +641,7 @@
 PERL_CALLCONV I32      Perl_same_dirent(pTHX_ char* a, char* b);
 #endif
 PERL_CALLCONV char*    Perl_savepv(pTHX_ const char* sv);
+PERL_CALLCONV char*    Perl_savesharedpv(pTHX_ const char* sv);
 PERL_CALLCONV char*    Perl_savepvn(pTHX_ const char* sv, I32 len);
 PERL_CALLCONV void     Perl_savestack_grow(pTHX);
 PERL_CALLCONV void     Perl_save_aelem(pTHX_ AV* av, I32 idx, SV **sptr);
@@ -656,6 +657,7 @@
 PERL_CALLCONV void     Perl_save_freepv(pTHX_ char* pv);
 PERL_CALLCONV void     Perl_save_generic_svref(pTHX_ SV** sptr);
 PERL_CALLCONV void     Perl_save_generic_pvref(pTHX_ char** str);
+PERL_CALLCONV void     Perl_save_shared_pvref(pTHX_ char** str);
 PERL_CALLCONV void     Perl_save_gp(pTHX_ GV* gv, I32 empty);
 PERL_CALLCONV HV*      Perl_save_hash(pTHX_ GV* gv);
 PERL_CALLCONV void     Perl_save_helem(pTHX_ HV* hv, SV *key, SV **sptr);

==== //depot/perl/scope.c#89 (text) ====
Index: perl/scope.c
--- perl/scope.c.~1~    Tue Jan 15 09:00:05 2002
+++ perl/scope.c        Tue Jan 15 09:00:05 2002
@@ -254,6 +254,18 @@
     SSPUSHINT(SAVEt_GENERIC_PVREF);
 }
 
+/* Like save_generic_pvref(), but uses PerlMemShared_free() rather than Safefree().
+ * Can be used to restore a shared global char* to its prior
+ * contents, freeing new value. */
+void
+Perl_save_shared_pvref(pTHX_ char **str)
+{
+    SSCHECK(3);
+    SSPUSHPTR(str);
+    SSPUSHPTR(*str);
+    SSPUSHINT(SAVEt_SHARED_PVREF);
+}
+
 void
 Perl_save_gp(pTHX_ GV *gv, I32 empty)
 {
@@ -657,6 +669,14 @@
                *(char**)ptr = str;
            }
            break;
+       case SAVEt_SHARED_PVREF:                /* shared pv */
+           str = (char*)SSPOPPTR;
+           ptr = SSPOPPTR;
+           if (*(char**)ptr != str) {
+               PerlMemShared_free(*(char**)ptr);
+               *(char**)ptr = str;
+           }
+           break;
        case SAVEt_GENERIC_SVREF:               /* generic sv */
            value = (SV*)SSPOPPTR;
            ptr = SSPOPPTR;

==== //depot/perl/scope.h#51 (text) ====
Index: perl/scope.h
--- perl/scope.h.~1~    Tue Jan 15 09:00:05 2002
+++ perl/scope.h        Tue Jan 15 09:00:05 2002
@@ -35,6 +35,7 @@
 #define SAVEt_GENERIC_PVREF    34
 #define SAVEt_PADSV            35
 #define SAVEt_MORTALIZESV      36
+#define SAVEt_SHARED_PVREF     37
 
 #ifndef SCOPE_SAVES_SIGNAL_MASK
 #define SCOPE_SAVES_SIGNAL_MASK 0
@@ -117,6 +118,7 @@
 #define SAVECLEARSV(sv)        save_clearsv(SOFT_CAST(SV**)&(sv))
 #define SAVEGENERICSV(s)       save_generic_svref((SV**)&(s))
 #define SAVEGENERICPV(s)       save_generic_pvref((char**)&(s))
+#define SAVESHAREDPV(s)                save_shared_pvref((char**)&(s))
 #define SAVEDELETE(h,k,l) \
          save_delete(SOFT_CAST(HV*)(h), SOFT_CAST(char*)(k), (I32)(l))
 #define SAVEDESTRUCTOR(f,p) \
@@ -160,9 +162,9 @@
 
 #ifdef USE_ITHREADS
 #  define SAVECOPSTASH(c)      SAVEPPTR(CopSTASHPV(c))
-#  define SAVECOPSTASH_FREE(c) SAVEGENERICPV(CopSTASHPV(c))
+#  define SAVECOPSTASH_FREE(c) SAVESHAREDPV(CopSTASHPV(c))
 #  define SAVECOPFILE(c)       SAVEPPTR(CopFILE(c))
-#  define SAVECOPFILE_FREE(c)  SAVEGENERICPV(CopFILE(c))
+#  define SAVECOPFILE_FREE(c)  SAVESHAREDPV(CopFILE(c))
 #else
 #  define SAVECOPSTASH(c)      SAVESPTR(CopSTASH(c))
 #  define SAVECOPSTASH_FREE(c) SAVECOPSTASH(c) /* XXX not refcounted */

==== //depot/perl/sv.c#510 (text) ====
Index: perl/sv.c
--- perl/sv.c.~1~       Tue Jan 15 09:00:05 2002
+++ perl/sv.c   Tue Jan 15 09:00:05 2002
@@ -9363,8 +9363,9 @@
     /* see if it is part of the interpreter structure */
     if (v >= (void*)proto_perl && v < (void*)(proto_perl+1))
        ret = (void*)(((char*)aTHX) + (((char*)v) - (char*)proto_perl));
-    else
+    else {
        ret = v;
+    }
 
     return ret;
 }
@@ -9417,6 +9418,12 @@
            ptr = POPPTR(ss,ix);
            TOPPTR(nss,ix) = any_dup(ptr, proto_perl);
            break;
+       case SAVEt_SHARED_PVREF:                /* char* in shared space */
+           c = (char*)POPPTR(ss,ix);
+           TOPPTR(nss,ix) = savesharedpv(c);
+           ptr = POPPTR(ss,ix);
+           TOPPTR(nss,ix) = any_dup(ptr, proto_perl);
+           break;
         case SAVEt_GENERIC_SVREF:              /* generic sv */
         case SAVEt_SVREF:                      /* scalar reference */
            sv = (SV*)POPPTR(ss,ix);
@@ -9786,15 +9793,21 @@
     SvNVX(&PL_sv_yes)          = 1;
     ptr_table_store(PL_ptr_table, &proto_perl->Isv_yes, &PL_sv_yes);
 
-    /* create shared string table */
+    /* create (a non-shared!) shared string table */
     PL_strtab          = newHV();
     HvSHAREKEYS_off(PL_strtab);
     hv_ksplit(PL_strtab, 512);
     ptr_table_store(PL_ptr_table, proto_perl->Istrtab, PL_strtab);
 
-    PL_compiling               = proto_perl->Icompiling;
-    PL_compiling.cop_stashpv   = SAVEPV(PL_compiling.cop_stashpv);
-    PL_compiling.cop_file      = SAVEPV(PL_compiling.cop_file);
+    PL_compiling = proto_perl->Icompiling;
+
+    /* These two PVs will be free'd special way so must set them same way op.c does */
+    PL_compiling.cop_stashpv = savesharedpv(PL_compiling.cop_stashpv);
+    ptr_table_store(PL_ptr_table, proto_perl->Icompiling.cop_stashpv, 
+PL_compiling.cop_stashpv);
+
+    PL_compiling.cop_file    = savesharedpv(PL_compiling.cop_file);
+    ptr_table_store(PL_ptr_table, proto_perl->Icompiling.cop_file, 
+PL_compiling.cop_file);
+
     ptr_table_store(PL_ptr_table, &proto_perl->Icompiling, &PL_compiling);
     if (!specialWARN(PL_compiling.cop_warnings))
        PL_compiling.cop_warnings = sv_dup_inc(PL_compiling.cop_warnings, param);

==== //depot/perl/toke.c#411 (text) ====
Index: perl/toke.c
--- perl/toke.c.~1~     Tue Jan 15 09:00:05 2002
+++ perl/toke.c Tue Jan 15 09:00:05 2002
@@ -514,11 +514,7 @@
     ch = *t;
     *t = '\0';
     if (t - s > 0) {
-#ifdef USE_ITHREADS
-       Safefree(CopFILE(PL_curcop));
-#else
-       SvREFCNT_dec(CopFILEGV(PL_curcop));
-#endif
+       CopFILE_free(PL_curcop);
        CopFILE_set(PL_curcop, s);
     }
     *t = ch;
@@ -2184,7 +2180,7 @@
     bool bof = FALSE;
 
     /* check if there's an identifier for us to look at */
-    if (PL_pending_ident) 
+    if (PL_pending_ident)
         return S_pending_ident(aTHX);
 
     /* no identifier pending identification */
@@ -6672,12 +6668,12 @@
            (void)strcpy(d,"ARGV");
 
        /* Check whether readline() is overriden */
-       if ((gv_readline = gv_fetchpv("readline", FALSE, SVt_PVCV))
-               && GvCVu(gv_readline) && GvIMPORTED_CV(gv_readline)
+       if (((gv_readline = gv_fetchpv("readline", FALSE, SVt_PVCV))
+               && GvCVu(gv_readline) && GvIMPORTED_CV(gv_readline))
                ||
-               (gvp = (GV**)hv_fetch(PL_globalstash, "readline", 8, FALSE))
+               ((gvp = (GV**)hv_fetch(PL_globalstash, "readline", 8, FALSE))
                && (gv_readline = *gvp) != (GV*)&PL_sv_undef
-               && GvCVu(gv_readline) && GvIMPORTED_CV(gv_readline))
+               && GvCVu(gv_readline) && GvIMPORTED_CV(gv_readline)))
            readline_overriden = TRUE;
 
        /* if <$fh>, create the ops to turn the variable into a

==== //depot/perl/util.c#316 (text) ====
Index: perl/util.c
--- perl/util.c.~1~     Tue Jan 15 09:00:05 2002
+++ perl/util.c Tue Jan 15 09:00:05 2002
@@ -891,10 +891,11 @@
 char *
 Perl_savepv(pTHX_ const char *sv)
 {
-    register char *newaddr;
-
-    New(902,newaddr,strlen(sv)+1,char);
-    (void)strcpy(newaddr,sv);
+    register char *newaddr = Nullch;
+    if (sv) {
+       New(902,newaddr,strlen(sv)+1,char);
+       (void)strcpy(newaddr,sv);
+    }
     return newaddr;
 }
 
@@ -920,6 +921,27 @@
     return newaddr;
 }
 
+/*
+=for apidoc savesharedpv
+
+Copy a string to a safe spot in memory shared between threads.
+This does not use an SV.
+
+=cut
+*/
+char *
+Perl_savesharedpv(pTHX_ const char *sv)
+{
+    register char *newaddr = Nullch;
+    if (sv) {
+       newaddr = PerlMemShared_malloc(strlen(sv)+1);
+       (void)strcpy(newaddr,sv);
+    }
+    return newaddr;
+}
+
+
+
 /* the SV for Perl_form() and mess() is not kept in an arena */
 
 STATIC SV *

==== //depot/perl/win32/config_H.vc#114 (text+w) ====
Index: perl/win32/config_H.vc
--- perl/win32/config_H.vc.~1~  Tue Jan 15 09:00:05 2002
+++ perl/win32/config_H.vc      Tue Jan 15 09:00:05 2002
@@ -13,7 +13,7 @@
 /*
  * Package name      : perl5
  * Source directory  : 
- * Configuration time: Fri Jan 11 12:16:33 2002
+ * Configuration time: Mon Jan 14 15:39:13 2002
  * Configured by     : nick
  * Target system     : 
  */
@@ -733,12 +733,6 @@
  */
 /*#define I_MEMORY             /**/
 
-/* I_NDBM:
- *     This symbol, if defined, indicates that <ndbm.h> exists and should
- *     be included.
- */
-/*#define I_NDBM       /**/
-
 /* I_NET_ERRNO:
  *     This symbol, if defined, indicates that <net/errno.h> exists and 
  *     should be included.
@@ -3420,6 +3414,12 @@
 /*#define SETUID_SCRIPTS_ARE_SECURE_NOW        /**/
 /*#define DOSUID               /**/
 
+/* I_NDBM:
+ *     This symbol, if defined, indicates that <ndbm.h> exists and should
+ *     be included.
+ */
+/*#define I_NDBM       /**/
+
 /* I_STDARG:
  *     This symbol, if defined, indicates that <stdarg.h> exists and should
  *     be included.

==== //depot/perl/win32/config_h.PL#26 (text) ====
==== //depot/perl/win32/perlhost.h#49 (text) ====
Index: perl/win32/perlhost.h
--- perl/win32/perlhost.h.~1~   Tue Jan 15 09:00:05 2002
+++ perl/win32/perlhost.h       Tue Jan 15 09:00:05 2002
@@ -216,9 +216,7 @@
     static long num_hosts;
 public:
     inline  int LastHost(void) { return num_hosts == 1L; };
-#ifdef CHECK_HOST_INTERP
     struct interpreter *host_perl;
-#endif
 };
 
 long CPerlHost::num_hosts = 0L;
@@ -244,12 +242,12 @@
 
 inline CPerlHost* IPerlMemShared2Host(struct IPerlMem* piPerl)
 {
-    return STRUCT2PTR(piPerl, m_hostperlMemShared);
+    return STRUCT2RAWPTR(piPerl, m_hostperlMemShared);
 }
 
 inline CPerlHost* IPerlMemParse2Host(struct IPerlMem* piPerl)
 {
-    return STRUCT2PTR(piPerl, m_hostperlMemParse);
+    return STRUCT2RAWPTR(piPerl, m_hostperlMemParse);
 }
 
 inline CPerlHost* IPerlEnv2Host(struct IPerlEnv* piPerl)

==== //depot/perl/win32/perllib.c#51 (text) ====
==== //depot/perl/win32/vmem.h#8 (text) ====
Index: perl/win32/vmem.h
--- perl/win32/vmem.h.~1~       Tue Jan 15 09:00:05 2002
+++ perl/win32/vmem.h   Tue Jan 15 09:00:05 2002
@@ -200,15 +200,17 @@
     if (pMem) {
        PMEMORY_BLOCK_HEADER ptr = 
(PMEMORY_BLOCK_HEADER)(((char*)pMem)-sizeof(MEMORY_BLOCK_HEADER));
         if (ptr->owner != this) {
-#if 0
-           int *nowhere = NULL;
-            *nowhere = 0;
+           if (ptr->owner) {
+#if 1
+               dTHX;
+               int *nowhere = NULL;
+               Perl_warn(aTHX_ "Free to wrong pool %p not %p",this,ptr->owner);
+               *nowhere = 0;
 #else
-           if (ptr->owner) {
-               ptr->owner->Free(pMem); 
+                ptr->owner->Free(pMem);        
+#endif
            }
            return;
-#endif
         }
        GetLock();
        UnlinkBlock(ptr);

==== //depot/perl/win32/win32.c#187 (text) ====
Index: perl/win32/win32.c
--- perl/win32/win32.c.~1~      Tue Jan 15 09:00:05 2002
+++ perl/win32/win32.c  Tue Jan 15 09:00:05 2002
@@ -1759,6 +1759,7 @@
            break;
        }
     }
+    w32_poll_count = 0;
 
     /* Above or other stuff may have set a signal flag */
     if (PL_sig_pending) {
@@ -4561,6 +4562,7 @@
 #  endif
     w32_init_socktype          = 0;
     w32_timerid                 = 0;
+    w32_poll_count              = 0;
     if (my_perl == PL_curinterp) {
         /* Force C runtime signal stuff to set its console handler */
        signal(SIGINT,&win32_csighandler);
@@ -4603,6 +4605,7 @@
     Newz(1313, dst->pseudo_children, 1, child_tab);
     dst->thr_intern.Winit_socktype = 0;
     dst->timerid                 = 0;
+    dst->poll_count              = 0;
 }
 #  endif /* USE_ITHREADS */
 #endif /* HAVE_INTERP_INTERN */

==== //depot/perl/win32/win32.h#98 (text) ====
Index: perl/win32/win32.h
--- perl/win32/win32.h.~1~      Tue Jan 15 09:00:05 2002
+++ perl/win32/win32.h  Tue Jan 15 09:00:05 2002
@@ -383,11 +383,12 @@
     struct thread_intern       thr_intern;
 #endif
     UINT       timerid;
-    HANDLE     msg_event;
+    unsigned   poll_count;
 };
 
 DllExport int win32_async_check(pTHX);
 
+#define WIN32_POLL_INTERVAL 32768
 #define PERL_ASYNC_CHECK() if (w32_do_async || PL_sig_pending) win32_async_check(aTHX)
 
 #define w32_perlshell_tokens   (PL_sys_intern.perlshell_tokens)
@@ -405,7 +406,8 @@
 #define w32_pseudo_child_handles       (w32_pseudo_children->handles)
 #define w32_internal_host              (PL_sys_intern.internal_host)
 #define w32_timerid                    (PL_sys_intern.timerid)
-#define w32_do_async                   (w32_timerid != 0)
+#define w32_poll_count                 (PL_sys_intern.poll_count)
+#define w32_do_async                   (w32_poll_count++ > WIN32_POLL_INTERVAL)
 #ifdef USE_5005THREADS
 #  define w32_strerror_buffer  (thr->i.Wstrerror_buffer)
 #  define w32_getlogin_buffer  (thr->i.Wgetlogin_buffer)
End of Patch.

Reply via email to