fix large memory leak that has been around for ever, masked by
Gurusamy Sarathy [Tue, 4 Jul 2000 04:15:59 +0000 (04:15 +0000)]
-DPURIFY (most of the arenas were never freed!)

p4raw-id: //depot/perl@6298

embedvar.h
global.sym
hv.c
intrpvar.h
perl.c
perlapi.h
sv.c

index 889b4d4..3bd98d1 100644 (file)
 #define PL_gid                 (PERL_GET_INTERP->Igid)
 #define PL_glob_index          (PERL_GET_INTERP->Iglob_index)
 #define PL_globalstash         (PERL_GET_INTERP->Iglobalstash)
+#define PL_he_arenaroot                (PERL_GET_INTERP->Ihe_arenaroot)
 #define PL_he_root             (PERL_GET_INTERP->Ihe_root)
 #define PL_hintgv              (PERL_GET_INTERP->Ihintgv)
 #define PL_hints               (PERL_GET_INTERP->Ihints)
 #define PL_widesyscalls                (PERL_GET_INTERP->Iwidesyscalls)
 #define PL_xiv_arenaroot       (PERL_GET_INTERP->Ixiv_arenaroot)
 #define PL_xiv_root            (PERL_GET_INTERP->Ixiv_root)
+#define PL_xnv_arenaroot       (PERL_GET_INTERP->Ixnv_arenaroot)
 #define PL_xnv_root            (PERL_GET_INTERP->Ixnv_root)
+#define PL_xpv_arenaroot       (PERL_GET_INTERP->Ixpv_arenaroot)
 #define PL_xpv_root            (PERL_GET_INTERP->Ixpv_root)
+#define PL_xpvav_arenaroot     (PERL_GET_INTERP->Ixpvav_arenaroot)
 #define PL_xpvav_root          (PERL_GET_INTERP->Ixpvav_root)
+#define PL_xpvbm_arenaroot     (PERL_GET_INTERP->Ixpvbm_arenaroot)
 #define PL_xpvbm_root          (PERL_GET_INTERP->Ixpvbm_root)
+#define PL_xpvcv_arenaroot     (PERL_GET_INTERP->Ixpvcv_arenaroot)
 #define PL_xpvcv_root          (PERL_GET_INTERP->Ixpvcv_root)
+#define PL_xpvhv_arenaroot     (PERL_GET_INTERP->Ixpvhv_arenaroot)
 #define PL_xpvhv_root          (PERL_GET_INTERP->Ixpvhv_root)
+#define PL_xpviv_arenaroot     (PERL_GET_INTERP->Ixpviv_arenaroot)
 #define PL_xpviv_root          (PERL_GET_INTERP->Ixpviv_root)
+#define PL_xpvlv_arenaroot     (PERL_GET_INTERP->Ixpvlv_arenaroot)
 #define PL_xpvlv_root          (PERL_GET_INTERP->Ixpvlv_root)
+#define PL_xpvmg_arenaroot     (PERL_GET_INTERP->Ixpvmg_arenaroot)
 #define PL_xpvmg_root          (PERL_GET_INTERP->Ixpvmg_root)
+#define PL_xpvnv_arenaroot     (PERL_GET_INTERP->Ixpvnv_arenaroot)
 #define PL_xpvnv_root          (PERL_GET_INTERP->Ixpvnv_root)
+#define PL_xrv_arenaroot       (PERL_GET_INTERP->Ixrv_arenaroot)
 #define PL_xrv_root            (PERL_GET_INTERP->Ixrv_root)
 #define PL_yychar              (PERL_GET_INTERP->Iyychar)
 #define PL_yydebug             (PERL_GET_INTERP->Iyydebug)
 #define PL_gid                 (vTHX->Igid)
 #define PL_glob_index          (vTHX->Iglob_index)
 #define PL_globalstash         (vTHX->Iglobalstash)
+#define PL_he_arenaroot                (vTHX->Ihe_arenaroot)
 #define PL_he_root             (vTHX->Ihe_root)
 #define PL_hintgv              (vTHX->Ihintgv)
 #define PL_hints               (vTHX->Ihints)
 #define PL_widesyscalls                (vTHX->Iwidesyscalls)
 #define PL_xiv_arenaroot       (vTHX->Ixiv_arenaroot)
 #define PL_xiv_root            (vTHX->Ixiv_root)
+#define PL_xnv_arenaroot       (vTHX->Ixnv_arenaroot)
 #define PL_xnv_root            (vTHX->Ixnv_root)
+#define PL_xpv_arenaroot       (vTHX->Ixpv_arenaroot)
 #define PL_xpv_root            (vTHX->Ixpv_root)
+#define PL_xpvav_arenaroot     (vTHX->Ixpvav_arenaroot)
 #define PL_xpvav_root          (vTHX->Ixpvav_root)
+#define PL_xpvbm_arenaroot     (vTHX->Ixpvbm_arenaroot)
 #define PL_xpvbm_root          (vTHX->Ixpvbm_root)
+#define PL_xpvcv_arenaroot     (vTHX->Ixpvcv_arenaroot)
 #define PL_xpvcv_root          (vTHX->Ixpvcv_root)
+#define PL_xpvhv_arenaroot     (vTHX->Ixpvhv_arenaroot)
 #define PL_xpvhv_root          (vTHX->Ixpvhv_root)
+#define PL_xpviv_arenaroot     (vTHX->Ixpviv_arenaroot)
 #define PL_xpviv_root          (vTHX->Ixpviv_root)
+#define PL_xpvlv_arenaroot     (vTHX->Ixpvlv_arenaroot)
 #define PL_xpvlv_root          (vTHX->Ixpvlv_root)
+#define PL_xpvmg_arenaroot     (vTHX->Ixpvmg_arenaroot)
 #define PL_xpvmg_root          (vTHX->Ixpvmg_root)
+#define PL_xpvnv_arenaroot     (vTHX->Ixpvnv_arenaroot)
 #define PL_xpvnv_root          (vTHX->Ixpvnv_root)
+#define PL_xrv_arenaroot       (vTHX->Ixrv_arenaroot)
 #define PL_xrv_root            (vTHX->Ixrv_root)
 #define PL_yychar              (vTHX->Iyychar)
 #define PL_yydebug             (vTHX->Iyydebug)
 #define PL_gid                 (aTHXo->interp.Igid)
 #define PL_glob_index          (aTHXo->interp.Iglob_index)
 #define PL_globalstash         (aTHXo->interp.Iglobalstash)
+#define PL_he_arenaroot                (aTHXo->interp.Ihe_arenaroot)
 #define PL_he_root             (aTHXo->interp.Ihe_root)
 #define PL_hintgv              (aTHXo->interp.Ihintgv)
 #define PL_hints               (aTHXo->interp.Ihints)
 #define PL_widesyscalls                (aTHXo->interp.Iwidesyscalls)
 #define PL_xiv_arenaroot       (aTHXo->interp.Ixiv_arenaroot)
 #define PL_xiv_root            (aTHXo->interp.Ixiv_root)
+#define PL_xnv_arenaroot       (aTHXo->interp.Ixnv_arenaroot)
 #define PL_xnv_root            (aTHXo->interp.Ixnv_root)
+#define PL_xpv_arenaroot       (aTHXo->interp.Ixpv_arenaroot)
 #define PL_xpv_root            (aTHXo->interp.Ixpv_root)
+#define PL_xpvav_arenaroot     (aTHXo->interp.Ixpvav_arenaroot)
 #define PL_xpvav_root          (aTHXo->interp.Ixpvav_root)
+#define PL_xpvbm_arenaroot     (aTHXo->interp.Ixpvbm_arenaroot)
 #define PL_xpvbm_root          (aTHXo->interp.Ixpvbm_root)
+#define PL_xpvcv_arenaroot     (aTHXo->interp.Ixpvcv_arenaroot)
 #define PL_xpvcv_root          (aTHXo->interp.Ixpvcv_root)
+#define PL_xpvhv_arenaroot     (aTHXo->interp.Ixpvhv_arenaroot)
 #define PL_xpvhv_root          (aTHXo->interp.Ixpvhv_root)
+#define PL_xpviv_arenaroot     (aTHXo->interp.Ixpviv_arenaroot)
 #define PL_xpviv_root          (aTHXo->interp.Ixpviv_root)
+#define PL_xpvlv_arenaroot     (aTHXo->interp.Ixpvlv_arenaroot)
 #define PL_xpvlv_root          (aTHXo->interp.Ixpvlv_root)
+#define PL_xpvmg_arenaroot     (aTHXo->interp.Ixpvmg_arenaroot)
 #define PL_xpvmg_root          (aTHXo->interp.Ixpvmg_root)
+#define PL_xpvnv_arenaroot     (aTHXo->interp.Ixpvnv_arenaroot)
 #define PL_xpvnv_root          (aTHXo->interp.Ixpvnv_root)
+#define PL_xrv_arenaroot       (aTHXo->interp.Ixrv_arenaroot)
 #define PL_xrv_root            (aTHXo->interp.Ixrv_root)
 #define PL_yychar              (aTHXo->interp.Iyychar)
 #define PL_yydebug             (aTHXo->interp.Iyydebug)
 #define PL_Igid                        PL_gid
 #define PL_Iglob_index         PL_glob_index
 #define PL_Iglobalstash                PL_globalstash
+#define PL_Ihe_arenaroot       PL_he_arenaroot
 #define PL_Ihe_root            PL_he_root
 #define PL_Ihintgv             PL_hintgv
 #define PL_Ihints              PL_hints
 #define PL_Iwidesyscalls       PL_widesyscalls
 #define PL_Ixiv_arenaroot      PL_xiv_arenaroot
 #define PL_Ixiv_root           PL_xiv_root
+#define PL_Ixnv_arenaroot      PL_xnv_arenaroot
 #define PL_Ixnv_root           PL_xnv_root
+#define PL_Ixpv_arenaroot      PL_xpv_arenaroot
 #define PL_Ixpv_root           PL_xpv_root
+#define PL_Ixpvav_arenaroot    PL_xpvav_arenaroot
 #define PL_Ixpvav_root         PL_xpvav_root
+#define PL_Ixpvbm_arenaroot    PL_xpvbm_arenaroot
 #define PL_Ixpvbm_root         PL_xpvbm_root
+#define PL_Ixpvcv_arenaroot    PL_xpvcv_arenaroot
 #define PL_Ixpvcv_root         PL_xpvcv_root
+#define PL_Ixpvhv_arenaroot    PL_xpvhv_arenaroot
 #define PL_Ixpvhv_root         PL_xpvhv_root
+#define PL_Ixpviv_arenaroot    PL_xpviv_arenaroot
 #define PL_Ixpviv_root         PL_xpviv_root
+#define PL_Ixpvlv_arenaroot    PL_xpvlv_arenaroot
 #define PL_Ixpvlv_root         PL_xpvlv_root
+#define PL_Ixpvmg_arenaroot    PL_xpvmg_arenaroot
 #define PL_Ixpvmg_root         PL_xpvmg_root
+#define PL_Ixpvnv_arenaroot    PL_xpvnv_arenaroot
 #define PL_Ixpvnv_root         PL_xpvnv_root
+#define PL_Ixrv_arenaroot      PL_xrv_arenaroot
 #define PL_Ixrv_root           PL_xrv_root
 #define PL_Iyychar             PL_yychar
 #define PL_Iyydebug            PL_yydebug
index 796f851..ec6180b 100644 (file)
@@ -336,6 +336,7 @@ Perl_save_destructor_x
 Perl_save_freesv
 Perl_save_freepv
 Perl_save_generic_svref
+Perl_save_generic_pvref
 Perl_save_gp
 Perl_save_hash
 Perl_save_helem
diff --git a/hv.c b/hv.c
index 44d37e3..6a07615 100644 (file)
--- a/hv.c
+++ b/hv.c
@@ -42,9 +42,14 @@ S_more_he(pTHX)
 {
     register HE* he;
     register HE* heend;
-    New(54, PL_he_root, 1008/sizeof(HE), HE);
-    he = PL_he_root;
+    XPV *ptr;
+    New(54, ptr, 1008/sizeof(XPV), XPV);
+    ptr->xpv_pv = (char*)PL_he_arenaroot;
+    PL_he_arenaroot = ptr;
+
+    he = (HE*)ptr;
     heend = &he[1008 / sizeof(HE) - 1];
+    PL_he_root = ++he;
     while (he < heend) {
         HeNEXT(he) = (HE*)(he + 1);
         he++;
index 8ed93f8..9d513f7 100644 (file)
@@ -245,19 +245,31 @@ PERLVARI(Ish_path,        char *, SH_PATH)/* full path of shell */
 PERLVAR(Isighandlerp,  Sighandler_t)
 
 PERLVAR(Ixiv_arenaroot,        XPV*)           /* list of allocated xiv areas */
-PERLVAR(Ixiv_root,     IV *)           /* free xiv list--shared by interpreters */
-PERLVAR(Ixnv_root,     NV *)           /* free xnv list--shared by interpreters */
-PERLVAR(Ixrv_root,     XRV *)          /* free xrv list--shared by interpreters */
-PERLVAR(Ixpv_root,     XPV *)          /* free xpv list--shared by interpreters */
-PERLVAR(Ixpviv_root,   XPVIV *)        /* free xpviv list--shared by interpreters */
-PERLVAR(Ixpvnv_root,   XPVNV *)        /* free xpvnv list--shared by interpreters */
-PERLVAR(Ixpvcv_root,   XPVCV *)        /* free xpvcv list--shared by interpreters */
-PERLVAR(Ixpvav_root,   XPVAV *)        /* free xpvav list--shared by interpreters */
-PERLVAR(Ixpvhv_root,   XPVHV *)        /* free xpvhv list--shared by interpreters */
-PERLVAR(Ixpvmg_root,   XPVMG *)        /* free xpvmg list--shared by interpreters */
-PERLVAR(Ixpvlv_root,   XPVLV *)        /* free xpvlv list--shared by interpreters */
-PERLVAR(Ixpvbm_root,   XPVBM *)        /* free xpvbm list--shared by interpreters */
-PERLVAR(Ihe_root,      HE *)           /* free he list--shared by interpreters */
+PERLVAR(Ixiv_root,     IV *)           /* free xiv list */
+PERLVAR(Ixnv_arenaroot,        XPV*)           /* list of allocated xnv areas */
+PERLVAR(Ixnv_root,     NV *)           /* free xnv list */
+PERLVAR(Ixrv_arenaroot,        XPV*)           /* list of allocated xrv areas */
+PERLVAR(Ixrv_root,     XRV *)          /* free xrv list */
+PERLVAR(Ixpv_arenaroot,        XPV*)           /* list of allocated xpv areas */
+PERLVAR(Ixpv_root,     XPV *)          /* free xpv list */
+PERLVAR(Ixpviv_arenaroot,XPVIV*)       /* list of allocated xpviv areas */
+PERLVAR(Ixpviv_root,   XPVIV *)        /* free xpviv list */
+PERLVAR(Ixpvnv_arenaroot,XPVNV*)       /* list of allocated xpvnv areas */
+PERLVAR(Ixpvnv_root,   XPVNV *)        /* free xpvnv list */
+PERLVAR(Ixpvcv_arenaroot,XPVCV*)       /* list of allocated xpvcv areas */
+PERLVAR(Ixpvcv_root,   XPVCV *)        /* free xpvcv list */
+PERLVAR(Ixpvav_arenaroot,XPVAV*)       /* list of allocated xpvav areas */
+PERLVAR(Ixpvav_root,   XPVAV *)        /* free xpvav list */
+PERLVAR(Ixpvhv_arenaroot,XPVHV*)       /* list of allocated xpvhv areas */
+PERLVAR(Ixpvhv_root,   XPVHV *)        /* free xpvhv list */
+PERLVAR(Ixpvmg_arenaroot,XPVMG*)       /* list of allocated xpvmg areas */
+PERLVAR(Ixpvmg_root,   XPVMG *)        /* free xpvmg list */
+PERLVAR(Ixpvlv_arenaroot,XPVLV*)       /* list of allocated xpvlv areas */
+PERLVAR(Ixpvlv_root,   XPVLV *)        /* free xpvlv list */
+PERLVAR(Ixpvbm_arenaroot,XPVBM*)       /* list of allocated xpvbm areas */
+PERLVAR(Ixpvbm_root,   XPVBM *)        /* free xpvbm list */
+PERLVAR(Ihe_arenaroot, XPV*)           /* list of allocated he areas */
+PERLVAR(Ihe_root,      HE *)           /* free he list */
 PERLVAR(Inice_chunk,   char *)         /* a nice chunk of memory to reuse */
 PERLVAR(Inice_chunk_size,      U32)    /* how nice the chunk of memory is */
 
diff --git a/perl.c b/perl.c
index eb454b9..33ca540 100644 (file)
--- a/perl.c
+++ b/perl.c
@@ -706,9 +706,6 @@ perl_destruct(pTHXx)
     if (PL_sv_count != 0 && ckWARN_d(WARN_INTERNAL))
        Perl_warner(aTHX_ WARN_INTERNAL,"Scalars leaked: %ld\n", (long)PL_sv_count);
 
-    sv_free_arenas();
-
-    /* No SVs have survived, need to clean out */
     Safefree(PL_origfilename);
     Safefree(PL_reg_start_tmp);
     if (PL_reg_curpm)
@@ -739,6 +736,8 @@ perl_destruct(pTHXx)
     PL_thrsv = Nullsv;
 #endif /* USE_THREADS */
 
+    sv_free_arenas();
+
     /* As the absolutely last thing, free the non-arena SV for mess() */
 
     if (PL_mess_sv) {
index 634634c..de0e7cc 100644 (file)
--- a/perlapi.h
+++ b/perlapi.h
@@ -246,6 +246,8 @@ START_EXTERN_C
 #define PL_glob_index          (*Perl_Iglob_index_ptr(aTHXo))
 #undef  PL_globalstash
 #define PL_globalstash         (*Perl_Iglobalstash_ptr(aTHXo))
+#undef  PL_he_arenaroot
+#define PL_he_arenaroot                (*Perl_Ihe_arenaroot_ptr(aTHXo))
 #undef  PL_he_root
 #define PL_he_root             (*Perl_Ihe_root_ptr(aTHXo))
 #undef  PL_hintgv
@@ -568,26 +570,48 @@ START_EXTERN_C
 #define PL_xiv_arenaroot       (*Perl_Ixiv_arenaroot_ptr(aTHXo))
 #undef  PL_xiv_root
 #define PL_xiv_root            (*Perl_Ixiv_root_ptr(aTHXo))
+#undef  PL_xnv_arenaroot
+#define PL_xnv_arenaroot       (*Perl_Ixnv_arenaroot_ptr(aTHXo))
 #undef  PL_xnv_root
 #define PL_xnv_root            (*Perl_Ixnv_root_ptr(aTHXo))
+#undef  PL_xpv_arenaroot
+#define PL_xpv_arenaroot       (*Perl_Ixpv_arenaroot_ptr(aTHXo))
 #undef  PL_xpv_root
 #define PL_xpv_root            (*Perl_Ixpv_root_ptr(aTHXo))
+#undef  PL_xpvav_arenaroot
+#define PL_xpvav_arenaroot     (*Perl_Ixpvav_arenaroot_ptr(aTHXo))
 #undef  PL_xpvav_root
 #define PL_xpvav_root          (*Perl_Ixpvav_root_ptr(aTHXo))
+#undef  PL_xpvbm_arenaroot
+#define PL_xpvbm_arenaroot     (*Perl_Ixpvbm_arenaroot_ptr(aTHXo))
 #undef  PL_xpvbm_root
 #define PL_xpvbm_root          (*Perl_Ixpvbm_root_ptr(aTHXo))
+#undef  PL_xpvcv_arenaroot
+#define PL_xpvcv_arenaroot     (*Perl_Ixpvcv_arenaroot_ptr(aTHXo))
 #undef  PL_xpvcv_root
 #define PL_xpvcv_root          (*Perl_Ixpvcv_root_ptr(aTHXo))
+#undef  PL_xpvhv_arenaroot
+#define PL_xpvhv_arenaroot     (*Perl_Ixpvhv_arenaroot_ptr(aTHXo))
 #undef  PL_xpvhv_root
 #define PL_xpvhv_root          (*Perl_Ixpvhv_root_ptr(aTHXo))
+#undef  PL_xpviv_arenaroot
+#define PL_xpviv_arenaroot     (*Perl_Ixpviv_arenaroot_ptr(aTHXo))
 #undef  PL_xpviv_root
 #define PL_xpviv_root          (*Perl_Ixpviv_root_ptr(aTHXo))
+#undef  PL_xpvlv_arenaroot
+#define PL_xpvlv_arenaroot     (*Perl_Ixpvlv_arenaroot_ptr(aTHXo))
 #undef  PL_xpvlv_root
 #define PL_xpvlv_root          (*Perl_Ixpvlv_root_ptr(aTHXo))
+#undef  PL_xpvmg_arenaroot
+#define PL_xpvmg_arenaroot     (*Perl_Ixpvmg_arenaroot_ptr(aTHXo))
 #undef  PL_xpvmg_root
 #define PL_xpvmg_root          (*Perl_Ixpvmg_root_ptr(aTHXo))
+#undef  PL_xpvnv_arenaroot
+#define PL_xpvnv_arenaroot     (*Perl_Ixpvnv_arenaroot_ptr(aTHXo))
 #undef  PL_xpvnv_root
 #define PL_xpvnv_root          (*Perl_Ixpvnv_root_ptr(aTHXo))
+#undef  PL_xrv_arenaroot
+#define PL_xrv_arenaroot       (*Perl_Ixrv_arenaroot_ptr(aTHXo))
 #undef  PL_xrv_root
 #define PL_xrv_root            (*Perl_Ixrv_root_ptr(aTHXo))
 #undef  PL_yychar
diff --git a/sv.c b/sv.c
index 3254cfb..df2dce6 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -194,6 +194,7 @@ Perl_sv_free_arenas(pTHX)
 {
     SV* sva;
     SV* svanext;
+    XPV *arena, *arenanext;
 
     /* Free arenas here, but be careful about fake ones.  (We assume
        contiguity of the fake ones with the corresponding real ones.) */
@@ -207,6 +208,84 @@ Perl_sv_free_arenas(pTHX)
            Safefree((void *)sva);
     }
 
+    for (arena = PL_xiv_arenaroot; arena; arena = arenanext) {
+       arenanext = (XPV*)arena->xpv_pv;
+       Safefree(arena);
+    }
+    PL_xiv_arenaroot = 0;
+
+    for (arena = PL_xnv_arenaroot; arena; arena = arenanext) {
+       arenanext = (XPV*)arena->xpv_pv;
+       Safefree(arena);
+    }
+    PL_xnv_arenaroot = 0;
+
+    for (arena = PL_xrv_arenaroot; arena; arena = arenanext) {
+       arenanext = (XPV*)arena->xpv_pv;
+       Safefree(arena);
+    }
+    PL_xrv_arenaroot = 0;
+
+    for (arena = PL_xpv_arenaroot; arena; arena = arenanext) {
+       arenanext = (XPV*)arena->xpv_pv;
+       Safefree(arena);
+    }
+    PL_xpv_arenaroot = 0;
+
+    for (arena = (XPV*)PL_xpviv_arenaroot; arena; arena = arenanext) {
+       arenanext = (XPV*)arena->xpv_pv;
+       Safefree(arena);
+    }
+    PL_xpviv_arenaroot = 0;
+
+    for (arena = (XPV*)PL_xpvnv_arenaroot; arena; arena = arenanext) {
+       arenanext = (XPV*)arena->xpv_pv;
+       Safefree(arena);
+    }
+    PL_xpvnv_arenaroot = 0;
+
+    for (arena = (XPV*)PL_xpvcv_arenaroot; arena; arena = arenanext) {
+       arenanext = (XPV*)arena->xpv_pv;
+       Safefree(arena);
+    }
+    PL_xpvcv_arenaroot = 0;
+
+    for (arena = (XPV*)PL_xpvav_arenaroot; arena; arena = arenanext) {
+       arenanext = (XPV*)arena->xpv_pv;
+       Safefree(arena);
+    }
+    PL_xpvav_arenaroot = 0;
+
+    for (arena = (XPV*)PL_xpvhv_arenaroot; arena; arena = arenanext) {
+       arenanext = (XPV*)arena->xpv_pv;
+       Safefree(arena);
+    }
+    PL_xpvhv_arenaroot = 0;
+
+    for (arena = (XPV*)PL_xpvmg_arenaroot; arena; arena = arenanext) {
+       arenanext = (XPV*)arena->xpv_pv;
+       Safefree(arena);
+    }
+    PL_xpvmg_arenaroot = 0;
+
+    for (arena = (XPV*)PL_xpvlv_arenaroot; arena; arena = arenanext) {
+       arenanext = (XPV*)arena->xpv_pv;
+       Safefree(arena);
+    }
+    PL_xpvlv_arenaroot = 0;
+
+    for (arena = (XPV*)PL_xpvbm_arenaroot; arena; arena = arenanext) {
+       arenanext = (XPV*)arena->xpv_pv;
+       Safefree(arena);
+    }
+    PL_xpvbm_arenaroot = 0;
+
+    for (arena = (XPV*)PL_he_arenaroot; arena; arena = arenanext) {
+       arenanext = (XPV*)arena->xpv_pv;
+       Safefree(arena);
+    }
+    PL_he_arenaroot = 0;
+
     if (PL_nice_chunk)
        Safefree(PL_nice_chunk);
     PL_nice_chunk = Nullch;
@@ -300,7 +379,12 @@ S_more_xnv(pTHX)
 {
     register NV* xnv;
     register NV* xnvend;
-    New(711, xnv, 1008/sizeof(NV), NV);
+    XPV *ptr;
+    New(711, ptr, 1008/sizeof(XPV), XPV);
+    ptr->xpv_pv = (char*)PL_xnv_arenaroot;
+    PL_xnv_arenaroot = ptr;
+
+    xnv = (NV*) ptr;
     xnvend = &xnv[1008 / sizeof(NV) - 1];
     xnv += (sizeof(XPVIV) - 1) / sizeof(NV) + 1; /* fudge by sizeof XPVIV */
     PL_xnv_root = xnv;
@@ -338,9 +422,15 @@ S_more_xrv(pTHX)
 {
     register XRV* xrv;
     register XRV* xrvend;
-    New(712, PL_xrv_root, 1008/sizeof(XRV), XRV);
-    xrv = PL_xrv_root;
+    XPV *ptr;
+    New(712, ptr, 1008/sizeof(XPV), XPV);
+    ptr->xpv_pv = (char*)PL_xrv_arenaroot;
+    PL_xrv_arenaroot = ptr;
+
+    xrv = (XRV*) ptr;
     xrvend = &xrv[1008 / sizeof(XRV) - 1];
+    xrv += (sizeof(XPV) - 1) / sizeof(XRV) + 1;
+    PL_xrv_root = xrv;
     while (xrv < xrvend) {
        xrv->xrv_rv = (SV*)(xrv + 1);
        xrv++;
@@ -375,9 +465,12 @@ S_more_xpv(pTHX)
 {
     register XPV* xpv;
     register XPV* xpvend;
-    New(713, PL_xpv_root, 1008/sizeof(XPV), XPV);
-    xpv = PL_xpv_root;
+    New(713, xpv, 1008/sizeof(XPV), XPV);
+    xpv->xpv_pv = (char*)PL_xpv_arenaroot;
+    PL_xpv_arenaroot = xpv;
+
     xpvend = &xpv[1008 / sizeof(XPV) - 1];
+    PL_xpv_root = ++xpv;
     while (xpv < xpvend) {
        xpv->xpv_pv = (char*)(xpv + 1);
        xpv++;
@@ -407,15 +500,17 @@ S_del_xpviv(pTHX_ XPVIV *p)
     UNLOCK_SV_MUTEX;
 }
 
-
 STATIC void
 S_more_xpviv(pTHX)
 {
     register XPVIV* xpviv;
     register XPVIV* xpvivend;
-    New(714, PL_xpviv_root, 1008/sizeof(XPVIV), XPVIV);
-    xpviv = PL_xpviv_root;
+    New(714, xpviv, 1008/sizeof(XPVIV), XPVIV);
+    xpviv->xpv_pv = (char*)PL_xpviv_arenaroot;
+    PL_xpviv_arenaroot = xpviv;
+
     xpvivend = &xpviv[1008 / sizeof(XPVIV) - 1];
+    PL_xpviv_root = ++xpviv;
     while (xpviv < xpvivend) {
        xpviv->xpv_pv = (char*)(xpviv + 1);
        xpviv++;
@@ -423,7 +518,6 @@ S_more_xpviv(pTHX)
     xpviv->xpv_pv = 0;
 }
 
-
 STATIC XPVNV*
 S_new_xpvnv(pTHX)
 {
@@ -446,15 +540,17 @@ S_del_xpvnv(pTHX_ XPVNV *p)
     UNLOCK_SV_MUTEX;
 }
 
-
 STATIC void
 S_more_xpvnv(pTHX)
 {
     register XPVNV* xpvnv;
     register XPVNV* xpvnvend;
-    New(715, PL_xpvnv_root, 1008/sizeof(XPVNV), XPVNV);
-    xpvnv = PL_xpvnv_root;
+    New(715, xpvnv, 1008/sizeof(XPVNV), XPVNV);
+    xpvnv->xpv_pv = (char*)PL_xpvnv_arenaroot;
+    PL_xpvnv_arenaroot = xpvnv;
+
     xpvnvend = &xpvnv[1008 / sizeof(XPVNV) - 1];
+    PL_xpvnv_root = ++xpvnv;
     while (xpvnv < xpvnvend) {
        xpvnv->xpv_pv = (char*)(xpvnv + 1);
        xpvnv++;
@@ -462,8 +558,6 @@ S_more_xpvnv(pTHX)
     xpvnv->xpv_pv = 0;
 }
 
-
-
 STATIC XPVCV*
 S_new_xpvcv(pTHX)
 {
@@ -486,15 +580,17 @@ S_del_xpvcv(pTHX_ XPVCV *p)
     UNLOCK_SV_MUTEX;
 }
 
-
 STATIC void
 S_more_xpvcv(pTHX)
 {
     register XPVCV* xpvcv;
     register XPVCV* xpvcvend;
-    New(716, PL_xpvcv_root, 1008/sizeof(XPVCV), XPVCV);
-    xpvcv = PL_xpvcv_root;
+    New(716, xpvcv, 1008/sizeof(XPVCV), XPVCV);
+    xpvcv->xpv_pv = (char*)PL_xpvcv_arenaroot;
+    PL_xpvcv_arenaroot = xpvcv;
+
     xpvcvend = &xpvcv[1008 / sizeof(XPVCV) - 1];
+    PL_xpvcv_root = ++xpvcv;
     while (xpvcv < xpvcvend) {
        xpvcv->xpv_pv = (char*)(xpvcv + 1);
        xpvcv++;
@@ -502,8 +598,6 @@ S_more_xpvcv(pTHX)
     xpvcv->xpv_pv = 0;
 }
 
-
-
 STATIC XPVAV*
 S_new_xpvav(pTHX)
 {
@@ -526,15 +620,17 @@ S_del_xpvav(pTHX_ XPVAV *p)
     UNLOCK_SV_MUTEX;
 }
 
-
 STATIC void
 S_more_xpvav(pTHX)
 {
     register XPVAV* xpvav;
     register XPVAV* xpvavend;
-    New(717, PL_xpvav_root, 1008/sizeof(XPVAV), XPVAV);
-    xpvav = PL_xpvav_root;
+    New(717, xpvav, 1008/sizeof(XPVAV), XPVAV);
+    xpvav->xav_array = (char*)PL_xpvav_arenaroot;
+    PL_xpvav_arenaroot = xpvav;
+
     xpvavend = &xpvav[1008 / sizeof(XPVAV) - 1];
+    PL_xpvav_root = ++xpvav;
     while (xpvav < xpvavend) {
        xpvav->xav_array = (char*)(xpvav + 1);
        xpvav++;
@@ -542,8 +638,6 @@ S_more_xpvav(pTHX)
     xpvav->xav_array = 0;
 }
 
-
-
 STATIC XPVHV*
 S_new_xpvhv(pTHX)
 {
@@ -566,15 +660,17 @@ S_del_xpvhv(pTHX_ XPVHV *p)
     UNLOCK_SV_MUTEX;
 }
 
-
 STATIC void
 S_more_xpvhv(pTHX)
 {
     register XPVHV* xpvhv;
     register XPVHV* xpvhvend;
-    New(718, PL_xpvhv_root, 1008/sizeof(XPVHV), XPVHV);
-    xpvhv = PL_xpvhv_root;
+    New(718, xpvhv, 1008/sizeof(XPVHV), XPVHV);
+    xpvhv->xhv_array = (char*)PL_xpvhv_arenaroot;
+    PL_xpvhv_arenaroot = xpvhv;
+
     xpvhvend = &xpvhv[1008 / sizeof(XPVHV) - 1];
+    PL_xpvhv_root = ++xpvhv;
     while (xpvhv < xpvhvend) {
        xpvhv->xhv_array = (char*)(xpvhv + 1);
        xpvhv++;
@@ -582,7 +678,6 @@ S_more_xpvhv(pTHX)
     xpvhv->xhv_array = 0;
 }
 
-
 STATIC XPVMG*
 S_new_xpvmg(pTHX)
 {
@@ -605,15 +700,17 @@ S_del_xpvmg(pTHX_ XPVMG *p)
     UNLOCK_SV_MUTEX;
 }
 
-
 STATIC void
 S_more_xpvmg(pTHX)
 {
     register XPVMG* xpvmg;
     register XPVMG* xpvmgend;
-    New(719, PL_xpvmg_root, 1008/sizeof(XPVMG), XPVMG);
-    xpvmg = PL_xpvmg_root;
+    New(719, xpvmg, 1008/sizeof(XPVMG), XPVMG);
+    xpvmg->xpv_pv = (char*)PL_xpvmg_arenaroot;
+    PL_xpvmg_arenaroot = xpvmg;
+
     xpvmgend = &xpvmg[1008 / sizeof(XPVMG) - 1];
+    PL_xpvmg_root = ++xpvmg;
     while (xpvmg < xpvmgend) {
        xpvmg->xpv_pv = (char*)(xpvmg + 1);
        xpvmg++;
@@ -621,8 +718,6 @@ S_more_xpvmg(pTHX)
     xpvmg->xpv_pv = 0;
 }
 
-
-
 STATIC XPVLV*
 S_new_xpvlv(pTHX)
 {
@@ -645,15 +740,17 @@ S_del_xpvlv(pTHX_ XPVLV *p)
     UNLOCK_SV_MUTEX;
 }
 
-
 STATIC void
 S_more_xpvlv(pTHX)
 {
     register XPVLV* xpvlv;
     register XPVLV* xpvlvend;
-    New(720, PL_xpvlv_root, 1008/sizeof(XPVLV), XPVLV);
-    xpvlv = PL_xpvlv_root;
+    New(720, xpvlv, 1008/sizeof(XPVLV), XPVLV);
+    xpvlv->xpv_pv = (char*)PL_xpvlv_arenaroot;
+    PL_xpvlv_arenaroot = xpvlv;
+
     xpvlvend = &xpvlv[1008 / sizeof(XPVLV) - 1];
+    PL_xpvlv_root = ++xpvlv;
     while (xpvlv < xpvlvend) {
        xpvlv->xpv_pv = (char*)(xpvlv + 1);
        xpvlv++;
@@ -661,7 +758,6 @@ S_more_xpvlv(pTHX)
     xpvlv->xpv_pv = 0;
 }
 
-
 STATIC XPVBM*
 S_new_xpvbm(pTHX)
 {
@@ -684,15 +780,17 @@ S_del_xpvbm(pTHX_ XPVBM *p)
     UNLOCK_SV_MUTEX;
 }
 
-
 STATIC void
 S_more_xpvbm(pTHX)
 {
     register XPVBM* xpvbm;
     register XPVBM* xpvbmend;
-    New(721, PL_xpvbm_root, 1008/sizeof(XPVBM), XPVBM);
-    xpvbm = PL_xpvbm_root;
+    New(721, xpvbm, 1008/sizeof(XPVBM), XPVBM);
+    xpvbm->xpv_pv = (char*)PL_xpvbm_arenaroot;
+    PL_xpvbm_arenaroot = xpvbm;
+
     xpvbmend = &xpvbm[1008 / sizeof(XPVBM) - 1];
+    PL_xpvbm_root = ++xpvbm;
     while (xpvbm < xpvbmend) {
        xpvbm->xpv_pv = (char*)(xpvbm + 1);
        xpvbm++;
@@ -7436,17 +7534,29 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags,
     /* arena roots */
     PL_xiv_arenaroot   = NULL;
     PL_xiv_root                = NULL;
+    PL_xnv_arenaroot   = NULL;
     PL_xnv_root                = NULL;
+    PL_xrv_arenaroot   = NULL;
     PL_xrv_root                = NULL;
+    PL_xpv_arenaroot   = NULL;
     PL_xpv_root                = NULL;
+    PL_xpviv_arenaroot = NULL;
     PL_xpviv_root      = NULL;
+    PL_xpvnv_arenaroot = NULL;
     PL_xpvnv_root      = NULL;
+    PL_xpvcv_arenaroot = NULL;
     PL_xpvcv_root      = NULL;
+    PL_xpvav_arenaroot = NULL;
     PL_xpvav_root      = NULL;
+    PL_xpvhv_arenaroot = NULL;
     PL_xpvhv_root      = NULL;
+    PL_xpvmg_arenaroot = NULL;
     PL_xpvmg_root      = NULL;
+    PL_xpvlv_arenaroot = NULL;
     PL_xpvlv_root      = NULL;
+    PL_xpvbm_arenaroot = NULL;
     PL_xpvbm_root      = NULL;
+    PL_he_arenaroot    = NULL;
     PL_he_root         = NULL;
     PL_nice_chunk      = NULL;
     PL_nice_chunk_size = 0;