Extend newSVpvn_flags() to also call sv_2mortal() if SVs_TEMP is set in
[p5sagit/p5-mst-13.2.git] / mro.c
diff --git a/mro.c b/mro.c
index ed40bdd..9c57b79 100644 (file)
--- a/mro.c
+++ b/mro.c
@@ -313,12 +313,13 @@ S_mro_get_linear_isa_c3(pTHX_ HV* stash, I32 level)
                 SV** seq_ptr = AvARRAY(seq) + 1;
                 while(seq_items--) {
                     SV* const seqitem = *seq_ptr++;
-                    HE* const he = hv_fetch_ent(tails, seqitem, 0, 0);
-                    if(!he) {
-                        (void)hv_store_ent(tails, seqitem, newSViv(1), 0);
-                    }
-                    else {
+                   /* LVALUE fetch will create a new undefined SV if necessary
+                    */
+                    HE* const he = hv_fetch_ent(tails, seqitem, 1, 0);
+                    if(he) {
                         SV* const val = HeVAL(he);
+                       /* This will increment undef to 1, which is what we
+                          want for a newly created entry.  */
                         sv_inc(val);
                     }
                 }
@@ -517,8 +518,9 @@ Perl_mro_isa_changed_in(pTHX_ HV* stash)
     if(isarev) {
         hv_iterinit(isarev);
         while((iter = hv_iternext(isarev))) {
-            SV* const revkey = hv_iterkeysv(iter);
-            HV* revstash = gv_stashsv(revkey, 0);
+           I32 len;
+            const char* const revkey = hv_iterkey(iter, &len);
+            HV* revstash = gv_stashpvn(revkey, len, 0);
             struct mro_meta* revmeta;
 
             if(!revstash) continue;
@@ -549,12 +551,16 @@ Perl_mro_isa_changed_in(pTHX_ HV* stash)
         SV* const sv = *svp++;
         HV* mroisarev;
 
-        HE *he = hv_fetch_ent(PL_isarev, sv, 0, 0);
-        if(!he) {
-            he = hv_store_ent(PL_isarev, sv, (SV*)newHV(), 0);
-        }
+        HE *he = hv_fetch_ent(PL_isarev, sv, TRUE, 0);
+
+       /* That fetch should not fail.  But if it had to create a new SV for
+          us, then will need to upgrade it to an HV (which sv_upgrade() can
+          now do for us. */
+
         mroisarev = (HV*)HeVAL(he);
 
+       SvUPGRADE((SV*)mroisarev, SVt_PVHV);
+
        /* This hash only ever contains PL_sv_yes. Storing it over itself is
           almost as cheap as calling hv_exists, so on aggregate we expect to
           save time by not making two calls to the common HV code for the
@@ -633,8 +639,9 @@ Perl_mro_method_changed_in(pTHX_ HV *stash)
 
         hv_iterinit(isarev);
         while((iter = hv_iternext(isarev))) {
-            SV* const revkey = hv_iterkeysv(iter);
-            HV* const revstash = gv_stashsv(revkey, 0);
+           I32 len;
+            const char* const revkey = hv_iterkey(iter, &len);
+            HV* const revstash = gv_stashpvn(revkey, len, 0);
             struct mro_meta* mrometa;
 
             if(!revstash) continue;
@@ -1042,7 +1049,7 @@ XS(XS_mro_nextcan)
     /* beyond here is just for cache misses, so perf isn't as critical */
 
     stashname_len = subname - fq_subname - 2;
-    stashname = sv_2mortal(newSVpvn(fq_subname, stashname_len));
+    stashname = newSVpvn_flags(fq_subname, stashname_len, SVs_TEMP);
 
     linear_av = mro_get_linear_isa_c3(selfstash, 0); /* has ourselves at the top of the list */