Revision: 1123
Author: [email protected]
Date: Mon Mar  8 01:48:27 2010
Log: Move sub info handling to a new function load_sub_info_callback().
http://code.google.com/p/perl-devel-nytprof/source/detail?r=1123

Modified:
 /trunk/NYTProf.xs

=======================================
--- /trunk/NYTProf.xs   Mon Mar  8 01:48:22 2010
+++ /trunk/NYTProf.xs   Mon Mar  8 01:48:27 2010
@@ -3507,6 +3507,8 @@
     int statement_discount;
     int total_stmts_discounted;
     AV *fid_srclines_av;
+    AV *fid_fileinfo_av;
+    HV *sub_subinfo_hv;
 } Loader_state;

 static void
@@ -3555,6 +3557,70 @@
         logwarn("Fid %2u:%u: %s\n", file_num, line_num, SvPV_nolen(src));
     }
 }
+
+static void
+load_sub_info_callback(Loader_state *state, ...)
+{
+    dTHXa(state->interp);
+    va_list args;
+    unsigned int fid;
+    unsigned int first_line;
+    unsigned int last_line;
+    SV *subname_sv;
+    int skip_subinfo_store = 0;
+    STRLEN subname_len;
+    char *subname_pv;
+    AV *av;
+    SV *sv;
+
+    va_start(args, state);
+
+    fid = va_arg(args, unsigned int);
+    first_line = va_arg(args, unsigned int);
+    last_line = va_arg(args, unsigned int);
+    subname_sv = va_arg(args, SV *);
+
+    va_end(args);
+
+    normalize_eval_seqn(aTHX_ subname_sv);
+
+    subname_pv = SvPV(subname_sv, subname_len);
+    if (trace_level >= 2)
+        logwarn("Sub %s fid %u lines %u..%u\n",
+                subname_pv, fid, first_line, last_line);
+
+    av = lookup_subinfo_av(aTHX_ subname_sv, state->sub_subinfo_hv);
+    if (SvOK(*av_fetch(av, NYTP_SIi_FID, 1))) {
+        /* We've already seen this subroutine name.
+         * Should only happen for anon subs in string evals so we warn
+         * for other cases.
+         */
+        if (!instr(subname_pv, "__ANON__[(eval"))
+            logwarn("Sub %s already defined!\n", subname_pv);
+
+        /* We could always discard the fid+first_line+last_line here,
+         * because we already have them stored, but for consistency
+         * (and for the stability of the tests) we'll prefer the lowest fid
+         */
+        if (fid > SvUV(*av_fetch(av, NYTP_SIi_FID, 1)))
+            skip_subinfo_store = 1;
+
+        /* Finally, note that the fileinfo NYTP_FIDi_SUBS_DEFINED hash,
+         * updated below, does get an entry for the sub *from each fid*
+         * (ie string eval) that defines the subroutine.
+         */
+    }
+    if (!skip_subinfo_store) {
+        sv_setuv(*av_fetch(av, NYTP_SIi_FID,        1), fid);
+        sv_setuv(*av_fetch(av, NYTP_SIi_FIRST_LINE, 1), first_line);
+        sv_setuv(*av_fetch(av, NYTP_SIi_LAST_LINE,  1), last_line);
+    }
+
+    /* add sub to NYTP_FIDi_SUBS_DEFINED hash */
+    sv = SvRV(*av_fetch(state->fid_fileinfo_av, fid, 1));
+    sv = SvRV(*av_fetch((AV *)sv, NYTP_FIDi_SUBS_DEFINED, 1));
+ (void)hv_store((HV *)sv, subname_pv, (I32)subname_len, newRV_inc((SV*)av), 0);
+}

 /**
  * Process a profile output file and return the results in a hash like
@@ -3583,11 +3649,9 @@
     HV* profile_modes = newHV();
     HV *live_pids_hv = newHV();
     HV *attr_hv = newHV();
-    AV* fid_fileinfo_av = newAV();
     AV* fid_line_time_av = newAV();
     AV* fid_block_time_av = NULL;
     AV* fid_sub_time_av = NULL;
-    HV* sub_subinfo_hv = newHV();
     SV *tmp_str1_sv = newSVpvn("",0);
     SV *tmp_str2_sv = newSVpvn("",0);
HV *file_info_stash = gv_stashpv("Devel::NYTProf::FileInfo", GV_ADDWARN);
@@ -3615,8 +3679,10 @@
     state.interp = my_perl;
 #endif
     state.fid_srclines_av = newAV();
-
-    av_extend(fid_fileinfo_av, 64);               /* grow them up front. */
+    state.fid_fileinfo_av = newAV();
+    state.sub_subinfo_hv = newHV();
+
+ av_extend(state.fid_fileinfo_av, 64); /* grow them up front. */
     av_extend(state.fid_srclines_av, 64);
     av_extend(fid_line_time_av, 64);

@@ -3742,7 +3808,7 @@

                 seconds  = (NV)ticks / ticks_per_sec;

-                fid_info_rvav = *av_fetch(fid_fileinfo_av, file_num, 1);
+ fid_info_rvav = *av_fetch(state.fid_fileinfo_av, file_num, 1);
                 if (!SvROK(fid_info_rvav)) {    /* should never happen */
                     if (!SvOK(fid_info_rvav)) { /* only warn once */
                         logwarn("Fid %u used but not defined\n", file_num);
@@ -3750,7 +3816,7 @@
                     }
                 }
                 else {
- eval_outer_fid(aTHX_ fid_fileinfo_av, file_num, 1, &eval_file_num, &eval_line_num); + eval_outer_fid(aTHX_ state.fid_fileinfo_av, file_num, 1, &eval_file_num, &eval_line_num);
                 }

                 if (eval_file_num) {              /* fid is an eval */
@@ -3856,9 +3922,9 @@
                 rv = newRV_noinc((SV*)av);
                 sv_bless(rv, file_info_stash);

-                svp = av_fetch(fid_fileinfo_av, file_num, 1);
+                svp = av_fetch(state.fid_fileinfo_av, file_num, 1);
if (SvOK(*svp)) { /* should never happen, perhaps file is corrupt */ - AV *old_av = (AV *)SvRV(*av_fetch(fid_fileinfo_av, file_num, 1)); + AV *old_av = (AV *)SvRV(*av_fetch(state.fid_fileinfo_av, file_num, 1));
                     SV *old_name = *av_fetch(old_av, 0, 1);
                     logwarn("Fid %d redefined from %s to %s\n", file_num,
                         SvPV_nolen(old_name), SvPV_nolen(filename_sv));
@@ -3869,7 +3935,7 @@
                 if (eval_file_num) {
                     SV *has_evals;
/* this eval fid refers to the fid that contained the eval */ - SV *eval_fi = *av_fetch(fid_fileinfo_av, eval_file_num, 1); + SV *eval_fi = *av_fetch(state.fid_fileinfo_av, eval_file_num, 1);
                     if (!SvROK(eval_fi)) { /* should never happen */
logwarn("Eval '%s' (fid %d) has unknown invoking fid %d\n", SvPV_nolen(filename_sv), file_num, eval_file_num);
@@ -3932,15 +3998,10 @@

             case NYTP_TAG_SUB_INFO:
             {
-                AV *av;
-                SV *sv;
                 unsigned int fid        = read_int(in);
                 SV *subname_sv = read_str(aTHX_ in, tmp_str1_sv);
                 unsigned int first_line = read_int(in);
                 unsigned int last_line  = read_int(in);
-                int skip_subinfo_store = 0;
-                STRLEN subname_len;
-                char *subname_pv;
                 int extra_items = read_int(in);

                 while (extra_items-- > 0)
@@ -3962,45 +4023,8 @@
                     break;
                 }

-                normalize_eval_seqn(aTHX_ subname_sv);
-
-                subname_pv = SvPV(subname_sv, subname_len);
-                if (trace_level >= 2)
-                    logwarn("Sub %s fid %u lines %u..%u\n",
-                        subname_pv, fid, first_line, last_line);
-
-                av = lookup_subinfo_av(aTHX_ subname_sv, sub_subinfo_hv);
-                if (SvOK(*av_fetch(av, NYTP_SIi_FID, 1))) {
-                    /* We've already seen this subroutine name.
- * Should only happen for anon subs in string evals so we warn
-                     * for other cases.
-                     */
-                    if (!instr(subname_pv, "__ANON__[(eval"))
-                        logwarn("Sub %s already defined!\n", subname_pv);
-
- /* We could always discard the fid+first_line+last_line here, - * because we already have them stored, but for consistency - * (and for the stability of the tests) we'll prefer the lowest fid
-                     */
-                    if (fid > SvUV(*av_fetch(av, NYTP_SIi_FID, 1)))
-                        skip_subinfo_store = 1;
-
- /* Finally, note that the fileinfo NYTP_FIDi_SUBS_DEFINED hash, - * updated below, does get an entry for the sub *from each fid*
-                     * (ie string eval) that defines the subroutine.
-                     */
-                }
-                if (!skip_subinfo_store) {
-                    sv_setuv(*av_fetch(av, NYTP_SIi_FID,        1), fid);
- sv_setuv(*av_fetch(av, NYTP_SIi_FIRST_LINE, 1), first_line); - sv_setuv(*av_fetch(av, NYTP_SIi_LAST_LINE, 1), last_line);
-                }
-
-                /* add sub to NYTP_FIDi_SUBS_DEFINED hash */
-                sv = SvRV(*av_fetch(fid_fileinfo_av, fid, 1));
-                sv = SvRV(*av_fetch((AV *)sv, NYTP_FIDi_SUBS_DEFINED, 1));
- (void)hv_store((HV *)sv, subname_pv, (I32)subname_len, newRV_inc((SV*)av), 0);
-
+                load_sub_info_callback(&state, fid, first_line, last_line,
+                                       subname_sv);
                 break;
             }

@@ -4057,7 +4081,7 @@
SvPV_nolen(called_subname_sv), SvPV_nolen(caller_subname_sv), fid, line,
                         count, incl_time, excl_time);

- subinfo_av = lookup_subinfo_av(aTHX_ called_subname_sv, sub_subinfo_hv); + subinfo_av = lookup_subinfo_av(aTHX_ called_subname_sv, state.sub_subinfo_hv);

/* { caller_fid => { caller_line => [ count, incl_time, ... ] } } */
                 sv = *av_fetch(subinfo_av, NYTP_SIi_CALLED_BY, 1);
@@ -4108,7 +4132,7 @@

/* add sub call to NYTP_FIDi_SUBS_CALLED hash of fid making the call */
                     /* => { line => { subname => [ ... ] } } */
-                    fi = SvRV(*av_fetch(fid_fileinfo_av, fid, 1));
+                    fi = SvRV(*av_fetch(state.fid_fileinfo_av, fid, 1));
                     fi = *av_fetch((AV *)fi, NYTP_FIDi_SUBS_CALLED, 1);
                     fi = *hv_fetch((HV*)SvRV(fi), text, len, 1);
                     if (!SvROK(fi))               /* autoviv */
@@ -4318,12 +4342,12 @@
     if (cb) {
         SvREFCNT_dec(profile_modes);
         SvREFCNT_dec(attr_hv);
-        SvREFCNT_dec(fid_fileinfo_av);
+        SvREFCNT_dec(state.fid_fileinfo_av);
         SvREFCNT_dec(state.fid_srclines_av);
         SvREFCNT_dec(fid_line_time_av);
         SvREFCNT_dec(fid_block_time_av);
         SvREFCNT_dec(fid_sub_time_av);
-        SvREFCNT_dec(sub_subinfo_hv);
+        SvREFCNT_dec(state.sub_subinfo_hv);

         return newHV(); /* dummy */
     }
@@ -4355,7 +4379,8 @@

     profile_hv = newHV();
(void)hv_stores(profile_hv, "attribute", newRV_noinc((SV*)attr_hv)); - (void)hv_stores(profile_hv, "fid_fileinfo", newRV_noinc((SV*)fid_fileinfo_av));
+    (void)hv_stores(profile_hv, "fid_fileinfo",
+                    newRV_noinc((SV*)state.fid_fileinfo_av));
     (void)hv_stores(profile_hv, "fid_srclines",
             newRV_noinc((SV*)state.fid_srclines_av));
(void)hv_stores(profile_hv, "fid_line_time", newRV_noinc((SV*)fid_line_time_av));
@@ -4368,7 +4393,8 @@
(void)hv_stores(profile_hv, "fid_sub_time", newRV_noinc((SV*)fid_sub_time_av));
         (void)hv_stores(profile_modes, "fid_sub_time", newSVpvs("sub"));
     }
- (void)hv_stores(profile_hv, "sub_subinfo", newRV_noinc((SV*)sub_subinfo_hv));
+    (void)hv_stores(profile_hv, "sub_subinfo",
+                    newRV_noinc((SV*)state.sub_subinfo_hv));
(void)hv_stores(profile_hv, "profile_modes", newRV_noinc((SV*)profile_modes));
     return profile_hv;
 }

--
You've received this message because you are subscribed to
the Devel::NYTProf Development User group.

Group hosted at:  http://groups.google.com/group/develnytprof-dev
Project hosted at:  http://perl-devel-nytprof.googlecode.com
CPAN distribution:  http://search.cpan.org/dist/Devel-NYTProf

To post, email:  [email protected]
To unsubscribe, email:  [email protected]

Reply via email to