Revision: 1147
Author: [email protected]
Date: Mon Mar 8 01:50:22 2010
Log: Split apart profile loading into load_profile_to_hv() and
load_profile_to_callback(), with Loader_state_merged split into
Loader_state_profiler and Loader_state_callback. This makes
load_profile_data_from_stream() totally callback agnostic.
http://code.google.com/p/perl-devel-nytprof/source/detail?r=1147
Modified:
/trunk/NYTProf.xs
=======================================
--- /trunk/NYTProf.xs Mon Mar 8 01:50:19 2010
+++ /trunk/NYTProf.xs Mon Mar 8 01:50:22 2010
@@ -355,7 +355,6 @@
static void write_src_of_files(pTHX);
static void write_sub_line_ranges(pTHX);
static void write_sub_callers(pTHX);
-static HV *load_profile_data_from_stream(SV* cb);
static AV *store_profile_line_entry(pTHX_ SV *rvav, unsigned int line_num,
NV time, int count, unsigned int fid);
@@ -3502,7 +3501,7 @@
typedef void (*loader_callback)(Loader_state_base *cb_data, const
nytp_tax_index tag, ...);
-typedef struct loader_state {
+typedef struct loader_state_callback {
Loader_state_base base_state;
#ifdef MULTIPLICITY
PerlInterpreter *interp;
@@ -3511,7 +3510,13 @@
SV *cb_args[11]; /* must be large enough for the largest callback
argument list */
SV *tag_names[nytp_tag_max];
SV *input_chunk_seqn_sv;
-
+} Loader_state_callback;
+
+typedef struct loader_state_profiler {
+ Loader_state_base base_state;
+#ifdef MULTIPLICITY
+ PerlInterpreter *interp;
+#endif
unsigned int last_file_num;
unsigned int last_line_num;
int statement_discount;
@@ -3532,12 +3537,12 @@
NV profiler_start_time;
NV profiler_end_time;
NV profiler_duration;
-} Loader_state_merged;
+} Loader_state_profiler;
static void
load_discount_callback(Loader_state_base *cb_data, const nytp_tax_index
tag, ...)
{
- Loader_state_merged *state = (Loader_state_merged *)cb_data;
+ Loader_state_profiler *state = (Loader_state_profiler *)cb_data;
if (trace_level >= 4)
logwarn("discounting next statement after %u:%d\n",
@@ -3552,7 +3557,7 @@
static void
load_time_callback(Loader_state_base *cb_data, const nytp_tax_index
tag, ...)
{
- Loader_state_merged *state = (Loader_state_merged *)cb_data;
+ Loader_state_profiler *state = (Loader_state_profiler *)cb_data;
dTHXa(state->interp);
va_list args;
char trace_note[80] = "";
@@ -3636,7 +3641,7 @@
static void
load_new_fid_callback(Loader_state_base *cb_data, const nytp_tax_index
tag, ...)
{
- Loader_state_merged *state = (Loader_state_merged *)cb_data;
+ Loader_state_profiler *state = (Loader_state_profiler *)cb_data;
dTHXa(state->interp);
va_list args;
AV *av;
@@ -3733,7 +3738,7 @@
static void
load_src_line_callback(Loader_state_base *cb_data, const nytp_tax_index
tag, ...)
{
- Loader_state_merged *state = (Loader_state_merged *)cb_data;
+ Loader_state_profiler *state = (Loader_state_profiler *)cb_data;
dTHXa(state->interp);
va_list args;
unsigned int file_num;
@@ -3768,7 +3773,7 @@
static void
load_sub_info_callback(Loader_state_base *cb_data, const nytp_tax_index
tag, ...)
{
- Loader_state_merged *state = (Loader_state_merged *)cb_data;
+ Loader_state_profiler *state = (Loader_state_profiler *)cb_data;
dTHXa(state->interp);
va_list args;
unsigned int fid;
@@ -3833,7 +3838,7 @@
static void
load_sub_callers_callback(Loader_state_base *cb_data, const nytp_tax_index
tag, ...)
{
- Loader_state_merged *state = (Loader_state_merged *)cb_data;
+ Loader_state_profiler *state = (Loader_state_profiler *)cb_data;
dTHXa(state->interp);
va_list args;
unsigned int fid;
@@ -3957,7 +3962,7 @@
static void
load_pid_start_callback(Loader_state_base *cb_data, const nytp_tax_index
tag, ...)
{
- Loader_state_merged *state = (Loader_state_merged *)cb_data;
+ Loader_state_profiler *state = (Loader_state_profiler *)cb_data;
dTHXa(state->interp);
va_list args;
unsigned int pid;
@@ -3989,7 +3994,7 @@
static void
load_pid_end_callback(Loader_state_base *cb_data, const nytp_tax_index
tag, ...)
{
- Loader_state_merged *state = (Loader_state_merged *)cb_data;
+ Loader_state_profiler *state = (Loader_state_profiler *)cb_data;
dTHXa(state->interp);
va_list args;
unsigned int pid;
@@ -4025,7 +4030,7 @@
static void
load_attribute_callback(Loader_state_base *cb_data, const nytp_tax_index
tag, ...)
{
- Loader_state_merged *state = (Loader_state_merged *)cb_data;
+ Loader_state_profiler *state = (Loader_state_profiler *)cb_data;
dTHXa(state->interp);
va_list args;
char *key;
@@ -4082,7 +4087,7 @@
static void
load_perl_callback(Loader_state_base *cb_data, nytp_tax_index tag, ...)
{
- Loader_state_merged *state = (Loader_state_merged *)cb_data;
+ Loader_state_callback *state = (Loader_state_callback *)cb_data;
dTHXa(state->interp);
dSP;
va_list args;
@@ -4233,47 +4238,19 @@
* which is an reference to an array containing the [calls,time]
* data for each line of the string eval.
*/
-static HV*
-load_profile_data_from_stream(SV *cb)
+static void
+load_profile_data_from_stream(loader_callback *callbacks,
+ Loader_state_base *state)
{
dTHX;
int file_major, file_minor;
- HV *profile_hv;
- HV* profile_modes = newHV();
SV *tmp_str1_sv = newSVpvn("",0);
SV *tmp_str2_sv = newSVpvn("",0);
size_t buffer_len = MAXPATHLEN * 2;
char *buffer = (char *)safemalloc(buffer_len);
- loader_callback *callbacks;
- Loader_state_merged merged_state;
- Loader_state_base *const state = (Loader_state_base *) &merged_state;
-
- Zero(&merged_state, 1, Loader_state_merged);
- merged_state.total_stmts_duration = 0.0;
- merged_state.profiler_start_time = 0.0;
- merged_state.profiler_start_time = 0.0;
- merged_state.profiler_end_time = 0.0;
- merged_state.profiler_duration = 0.0;
-#ifdef MULTIPLICITY
- merged_state.interp = my_perl;
-#endif
- merged_state.fid_line_time_av = newAV();
- merged_state.fid_srclines_av = newAV();
- merged_state.fid_fileinfo_av = newAV();
- merged_state.sub_subinfo_hv = newHV();
- merged_state.live_pids_hv = newHV();
- merged_state.attr_hv = newHV();
- merged_state.file_info_stash = gv_stashpv("Devel::NYTProf::FileInfo",
GV_ADDWARN);
- /* These will be split out into a different state structure later. */
- merged_state.cb = cb;
-
- av_extend(merged_state.fid_fileinfo_av, 64); /* grow
them up front. */
- av_extend(merged_state.fid_srclines_av, 64);
- av_extend(merged_state.fid_line_time_av, 64);
-
if (1) {
if (!NYTP_gets(in, &buffer, &buffer_len))
croak("NYTProf data format error while reading header");
@@ -4287,37 +4264,10 @@
warn("NYTProf data format version %d.%d is newer than that
understood by this NYTProf %s, so errors are likely",
file_major, file_minor, XS_VERSION);
}
-
- if (cb && SvROK(cb)) {
- int i;
- merged_state.input_chunk_seqn_sv = save_scalar(gv_fetchpv(".",
GV_ADD, SVt_IV));
- sv_setuv(merged_state.input_chunk_seqn_sv,
state->input_chunk_seqn);
-
- i = C_ARRAY_LENGTH(merged_state.tag_names);
- while (--i) {
- if (callback_info[i].args) {
- merged_state.tag_names[i]
- = newSVpvn_flags(callback_info[i].description,
- callback_info[i].len, SVs_TEMP);
- SvREADONLY_on(merged_state.tag_names[i]);
- /* Don't steal the string buffer. */
- SvTEMP_off(merged_state.tag_names[i]);
- }
- }
- for (i = 0; i < C_ARRAY_LENGTH(merged_state.cb_args); i++)
- merged_state.cb_args[i] = sv_newmortal();
-
- callbacks = perl_callbacks;
- }
- else {
- cb = Nullsv;
- callbacks = processing_callbacks;
- }
if (callbacks[nytp_version])
callbacks[nytp_version](state, nytp_version, file_major,
file_minor);
-
while (1) {
/* Loop "forever" until EOF. We can only check the EOF flag
*after* we
attempt a read. */
@@ -4524,92 +4474,150 @@
}
}
- if (HvKEYS(merged_state.live_pids_hv)) {
+ sv_free(tmp_str1_sv);
+ sv_free(tmp_str2_sv);
+ Safefree(buffer);
+}
+
+static HV*
+load_profile_to_hv(pTHX)
+{
+ Loader_state_profiler state;
+ HV *profile_hv;
+ HV *profile_modes;
+
+ Zero(&state, 1, Loader_state_profiler);
+ state.total_stmts_duration = 0.0;
+ state.profiler_start_time = 0.0;
+ state.profiler_start_time = 0.0;
+ state.profiler_end_time = 0.0;
+ state.profiler_duration = 0.0;
+#ifdef MULTIPLICITY
+ state.interp = my_perl;
+#endif
+ state.fid_line_time_av = newAV();
+ state.fid_srclines_av = newAV();
+ state.fid_fileinfo_av = newAV();
+ state.sub_subinfo_hv = newHV();
+ state.live_pids_hv = newHV();
+ state.attr_hv = newHV();
+ state.file_info_stash = gv_stashpv("Devel::NYTProf::FileInfo",
GV_ADDWARN);
+
+ av_extend(state.fid_fileinfo_av, 64); /* grow them up front. */
+ av_extend(state.fid_srclines_av, 64);
+ av_extend(state.fid_line_time_av, 64);
+
+ load_profile_data_from_stream(processing_callbacks,
+ (Loader_state_base *)&state);
+
+
+ if (HvKEYS(state.live_pids_hv)) {
logwarn("profile data possibly truncated, no terminator
for %"IVdf" pids\n",
- HvKEYS(merged_state.live_pids_hv));
- store_attrib_sv(aTHX_ merged_state.attr_hv,
STR_WITH_LEN("complete"),
+ HvKEYS(state.live_pids_hv));
+ store_attrib_sv(aTHX_ state.attr_hv, STR_WITH_LEN("complete"),
&PL_sv_no);
}
else {
- store_attrib_sv(aTHX_ merged_state.attr_hv,
STR_WITH_LEN("complete"),
+ store_attrib_sv(aTHX_ state.attr_hv, STR_WITH_LEN("complete"),
&PL_sv_yes);
}
- sv_free((SV*)merged_state.live_pids_hv);
- sv_free(tmp_str1_sv);
- sv_free(tmp_str2_sv);
- Safefree(buffer);
-
- if (cb) {
- SvREFCNT_dec(profile_modes);
- SvREFCNT_dec(merged_state.attr_hv);
- SvREFCNT_dec(merged_state.fid_fileinfo_av);
- SvREFCNT_dec(merged_state.fid_srclines_av);
- SvREFCNT_dec(merged_state.fid_line_time_av);
- SvREFCNT_dec(merged_state.fid_block_time_av);
- SvREFCNT_dec(merged_state.fid_sub_time_av);
- SvREFCNT_dec(merged_state.sub_subinfo_hv);
-
- return newHV(); /* dummy */
- }
-
- if (merged_state.statement_discount) /* discard unused
statement_discount */
- merged_state.total_stmts_discounted -=
merged_state.statement_discount;
- store_attrib_sv(aTHX_ merged_state.attr_hv,
STR_WITH_LEN("total_stmts_measured"),
- newSVnv(merged_state.total_stmts_measured));
- store_attrib_sv(aTHX_ merged_state.attr_hv,
STR_WITH_LEN("total_stmts_discounted"),
- newSVnv(merged_state.total_stmts_discounted));
- store_attrib_sv(aTHX_ merged_state.attr_hv,
STR_WITH_LEN("total_stmts_duration"),
- newSVnv(merged_state.total_stmts_duration));
- store_attrib_sv(aTHX_ merged_state.attr_hv,
STR_WITH_LEN("total_sub_calls"),
- newSVnv(merged_state.total_sub_calls));
+ sv_free((SV*)state.live_pids_hv);
+
+ if (state.statement_discount) /* discard unused statement_discount */
+ state.total_stmts_discounted -= state.statement_discount;
+ store_attrib_sv(aTHX_ state.attr_hv,
STR_WITH_LEN("total_stmts_measured"),
+ newSVnv(state.total_stmts_measured));
+ store_attrib_sv(aTHX_ state.attr_hv,
STR_WITH_LEN("total_stmts_discounted"),
+ newSVnv(state.total_stmts_discounted));
+ store_attrib_sv(aTHX_ state.attr_hv,
STR_WITH_LEN("total_stmts_duration"),
+ newSVnv(state.total_stmts_duration));
+ store_attrib_sv(aTHX_ state.attr_hv, STR_WITH_LEN("total_sub_calls"),
+ newSVnv(state.total_sub_calls));
if (1) {
int show_summary_stats = (trace_level >= 1);
- if (merged_state.profiler_end_time
- && merged_state.total_stmts_duration >
merged_state.profiler_duration * 1.1) {
+ if (state.profiler_end_time
+ && state.total_stmts_duration > state.profiler_duration * 1.1)
{
logwarn("The sum of the statement timings is %.1"NVff"%% of
the total time profiling."
" (Values slightly over 100%% can be due simply to
cumulative timing errors,"
" whereas larger values can indicate a problem with the
clock used.)\n",
- merged_state.total_stmts_duration /
merged_state.profiler_duration * 100);
+ state.total_stmts_duration / state.profiler_duration *
100);
show_summary_stats = 1;
}
if (show_summary_stats)
logwarn("Summary: statements profiled %d (%d-%d), sum of
time %"NVff"s, profile spanned %"NVff"s\n",
- merged_state.total_stmts_measured -
merged_state.total_stmts_discounted,
- merged_state.total_stmts_measured,
merged_state.total_stmts_discounted,
- merged_state.total_stmts_duration,
- merged_state.profiler_end_time -
merged_state.profiler_start_time);
+ state.total_stmts_measured - state.total_stmts_discounted,
+ state.total_stmts_measured, state.total_stmts_discounted,
+ state.total_stmts_duration,
+ state.profiler_end_time - state.profiler_start_time);
}
profile_hv = newHV();
+ profile_modes = newHV();
(void)hv_stores(profile_hv, "attribute",
- newRV_noinc((SV*)merged_state.attr_hv));
+ newRV_noinc((SV*)state.attr_hv));
(void)hv_stores(profile_hv, "fid_fileinfo",
- newRV_noinc((SV*)merged_state.fid_fileinfo_av));
+ newRV_noinc((SV*)state.fid_fileinfo_av));
(void)hv_stores(profile_hv, "fid_srclines",
- newRV_noinc((SV*)merged_state.fid_srclines_av));
+ newRV_noinc((SV*)state.fid_srclines_av));
(void)hv_stores(profile_hv, "fid_line_time",
- newRV_noinc((SV*)merged_state.fid_line_time_av));
+ newRV_noinc((SV*)state.fid_line_time_av));
(void)hv_stores(profile_modes, "fid_line_time", newSVpvs("line"));
- if (merged_state.fid_block_time_av) {
+ if (state.fid_block_time_av) {
(void)hv_stores(profile_hv, "fid_block_time",
- newRV_noinc((SV*)merged_state.fid_block_time_av));
+ newRV_noinc((SV*)state.fid_block_time_av));
(void)hv_stores(profile_modes, "fid_block_time",
newSVpvs("block"));
}
- if (merged_state.fid_sub_time_av) {
+ if (state.fid_sub_time_av) {
(void)hv_stores(profile_hv, "fid_sub_time",
- newRV_noinc((SV*)merged_state.fid_sub_time_av));
+ newRV_noinc((SV*)state.fid_sub_time_av));
(void)hv_stores(profile_modes, "fid_sub_time", newSVpvs("sub"));
}
(void)hv_stores(profile_hv, "sub_subinfo",
- newRV_noinc((SV*)merged_state.sub_subinfo_hv));
- (void)hv_stores(profile_hv, "profile_modes",
newRV_noinc((SV*)profile_modes));
+ newRV_noinc((SV*)state.sub_subinfo_hv));
+ (void)hv_stores(profile_hv, "profile_modes",
+ newRV_noinc((SV*)profile_modes));
return profile_hv;
}
+static void
+load_profile_to_callback(pTHX_ SV *cb)
+{
+ Loader_state_callback state;
+ int i;
+
+#ifdef MULTIPLICITY
+ state.interp = my_perl;
+#endif
+
+ state.base_state.input_chunk_seqn = 0;
+ state.cb = cb;
+
+ state.input_chunk_seqn_sv = save_scalar(gv_fetchpv(".", GV_ADD,
SVt_IV));
+ sv_setuv(state.input_chunk_seqn_sv, 0);
+
+ i = C_ARRAY_LENGTH(state.tag_names);
+ while (--i) {
+ if (callback_info[i].args) {
+ state.tag_names[i]
+ = newSVpvn_flags(callback_info[i].description,
+ callback_info[i].len, SVs_TEMP);
+ SvREADONLY_on(state.tag_names[i]);
+ /* Don't steal the string buffer. */
+ SvTEMP_off(state.tag_names[i]);
+ } else
+ state.tag_names[i] = NULL;
+ }
+ for (i = 0; i < C_ARRAY_LENGTH(state.cb_args); i++)
+ state.cb_args[i] = sv_newmortal();
+
+ load_profile_data_from_stream(perl_callbacks, (Loader_state_base
*)&state);
+}
+
+
/***********************************
* Perl XS Code Below Here *
@@ -4795,7 +4803,12 @@
if (in == NULL) {
croak("Failed to open input '%s': %s", file, strerror(errno));
}
- RETVAL = load_profile_data_from_stream(cb);
+ if (cb && SvROK(cb)) {
+ load_profile_to_callback(aTHX_ cb);
+ RETVAL = newHV(); /* Can we change this to PL_sv_undef? */
+ } else
+ RETVAL = load_profile_to_hv(aTHX);
+
if ((result = NYTP_close(in, 0)))
logwarn("Error closing profile data file: %s\n", strerror(result));
OUTPUT:
--
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]