Revision: 1228
Author: [email protected]
Date: Fri May 21 08:49:19 2010
Log: Push the call to finish_profile() onto the END of PL_endav at END
time, rather
than INIT time. This makes it even more likely to be called last.
http://code.google.com/p/perl-devel-nytprof/source/detail?r=1228
Modified:
/trunk/NYTProf.xs
=======================================
--- /trunk/NYTProf.xs Thu May 20 15:37:04 2010
+++ /trunk/NYTProf.xs Fri May 21 08:49:19 2010
@@ -334,6 +334,7 @@
static UV cumulative_subr_seqn = 0;
static int main_runtime_used = 0;
static SV *DB_INIT_cv;
+static SV *DB_END_cv;
static SV *DB_fin_cv;
static unsigned int ticks_per_sec = 0; /* 0 forces error if not
set */
@@ -2379,7 +2380,8 @@
|| !is_profiling
/* don't profile calls to non-existant import() methods */
/* or our DB::_INIT as that makes tests perl version sensitive */
- || (op_type==OP_ENTERSUB && (sub_sv == &PL_sv_yes || sub_sv ==
DB_INIT_cv || sub_sv == DB_fin_cv))
+ || (op_type==OP_ENTERSUB && (sub_sv == &PL_sv_yes || sub_sv ==
DB_INIT_cv
+ || sub_sv == DB_END_cv || sub_sv ==
DB_fin_cv))
/* don't profile other kinds of goto */
|| (op_type==OP_GOTO &&
( !(SvROK(sub_sv) && SvTYPE(SvRV(sub_sv)) == SVt_PVCV)
@@ -2594,7 +2596,7 @@
STRLEN len;
char *p = SvPV(subr_entry->called_subnam_sv, len);
- if(memEQs(p, len, "_INIT")) {
+ if(*p == '_' && (memEQs(p, len, "_INIT") || memEQs(p,
len, "_END"))) {
subr_entry->already_counted++;
goto skip_sub_profile;
}
@@ -2802,6 +2804,7 @@
last_pid = getpid();
ticks_per_sec = (profile_usecputime) ? PL_clocktick : CLOCKS_PER_TICK;
DB_INIT_cv = (SV*)GvCV(gv_fetchpv("DB::_INIT", FALSE,
SVt_PVCV));
+ DB_END_cv = (SV*)GvCV(gv_fetchpv("DB::_END", FALSE,
SVt_PVCV));
DB_fin_cv = (SV*)GvCV(gv_fetchpv("DB::finish_profile", FALSE,
SVt_PVCV));
if (opt_use_db_sub) {
@@ -2926,10 +2929,11 @@
if (!PL_endav) PL_endav = newAV();
if (profile_start == NYTP_START_BEGIN) {
enable_profile(aTHX_ NULL);
- }
- /* else handled by _INIT */
- /* defer some init until INIT phase */
- av_push(PL_initav, SvREFCNT_inc(get_cv("DB::_INIT", GV_ADDWARN)));
+ } else {
+ /* handled by _INIT */
+ av_push(PL_initav, SvREFCNT_inc(get_cv("DB::_INIT", GV_ADDWARN)));
+ }
+ av_push(PL_endav, SvREFCNT_inc(get_cv("DB::_END", GV_ADDWARN)));
/* seed first run time */
if (profile_usecputime) {
@@ -4930,13 +4934,21 @@
av_unshift(PL_endav, 1); /* we want to be first */
av_store(PL_endav, 0, SvREFCNT_inc(enable_profile_sv));
}
+ if (trace_level >= 2)
+ logwarn("~ INIT done\n");
+
+void
+_END()
+ CODE:
/* we want to END { finish_profile() } but we want it to be the last
END
- * block run so we don't push it into PL_endav until INIT phase.
- * so it's likely to be the last thing run.
+ * block run so we don't push it into PL_endav until END phase has
started,
+ * so it's likely to be the last thing run. Do this once, else we
could end
+ * up in an infinite loop arms race with something else trying the same
+ * strategy.
*/
av_push(PL_endav, (SV *)get_cv("DB::finish_profile", GV_ADDWARN));
if (trace_level >= 2)
- logwarn("~ INIT done\n");
+ logwarn("~ END done\n");
--
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]