diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index bb834a709a..c93a9fa5a5 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -56,7 +56,7 @@ struct Gen { auto_str_funcs strings.Builder // function bodies of all auto generated _str funcs comptime_defines strings.Builder // custom defines, given by -d/-define flags on the CLI pcs_declarations strings.Builder // -prof profile counter declarations for each function - pcs map[string]string // -prof profile counter fn_names => fn counter name + pcs []ProfileCounterMeta // -prof profile counter fn_names => fn counter name table &table.Table pref &pref.Preferences mut: @@ -159,6 +159,7 @@ pub fn cgen(files []ast.File, table &table.Table, pref &pref.Preferences) string // g.finish() // + b := strings.new_builder(250000) b.writeln(g.hashes()) b.writeln(g.comptime_defines.str()) @@ -237,6 +238,10 @@ pub fn (mut g Gen) finish() { } g.stringliterals.writeln('// << string literal consts') g.stringliterals.writeln('') + + if g.pref.is_prof { + g.gen_vprint_profile_stats() + } } pub fn (mut g Gen) write_typeof_functions() { diff --git a/vlib/v/gen/fn.v b/vlib/v/gen/fn.v index 5951075b88..45833b31d7 100644 --- a/vlib/v/gen/fn.v +++ b/vlib/v/gen/fn.v @@ -104,22 +104,7 @@ fn (mut g Gen) gen_fn_decl(it ast.FnDecl) { } // Profiling mode? Start counting at the beginning of the function (save current time). if g.pref.is_prof { - if is_main { - g.writeln('') - g.writeln('\tatexit(vprint_profile_stats);') - g.writeln('') - } - if it.name == 'time.vpc_now' { - g.defer_profile_code = '' - } else { - fn_profile_counter_name := 'vpc_${g.last_fn_c_name}' - g.writeln('') - g.writeln('\tdouble _PROF_FN_START = time__vpc_now(); ${fn_profile_counter_name}_calls++; // $it.name') - g.writeln('') - g.defer_profile_code = '\t${fn_profile_counter_name} += time__vpc_now() - _PROF_FN_START;' - g.pcs_declarations.writeln('double ${fn_profile_counter_name} = 0.0; u64 ${fn_profile_counter_name}_calls = 0;') - g.pcs[g.last_fn_c_name] = fn_profile_counter_name - } + g.profile_fn( it.name, is_main ) } g.stmts(it.stmts) // //////////// @@ -137,22 +122,6 @@ fn (mut g Gen) gen_fn_decl(it ast.FnDecl) { } g.write_defer_stmts_when_needed() if is_main { - if g.pref.is_prof { - g.pcs_declarations.writeln('void vprint_profile_stats(){') - if g.pref.profile_file == '-' { - for pfn_name, pcounter_name in g.pcs { - g.pcs_declarations.writeln('\tif (${pcounter_name}_calls) printf("%llu %f %f ${pfn_name} \\n", ${pcounter_name}_calls, $pcounter_name, $pcounter_name / ${pcounter_name}_calls );') - } - } else { - g.pcs_declarations.writeln('\tFILE * fp;') - g.pcs_declarations.writeln('\tfp = fopen ("${g.pref.profile_file}", "w+");') - for pfn_name, pcounter_name in g.pcs { - g.pcs_declarations.writeln('\tif (${pcounter_name}_calls) fprintf(fp, "%llu %f %f ${pfn_name} \\n", ${pcounter_name}_calls, $pcounter_name, $pcounter_name / ${pcounter_name}_calls );') - } - g.pcs_declarations.writeln('\tfclose(fp);') - } - g.pcs_declarations.writeln('}') - } g.writeln('\treturn 0;') } g.writeln('}') diff --git a/vlib/v/gen/profile.v b/vlib/v/gen/profile.v new file mode 100644 index 0000000000..ad258a5286 --- /dev/null +++ b/vlib/v/gen/profile.v @@ -0,0 +1,45 @@ +module gen + +pub struct ProfileCounterMeta{ + fn_name string + vpc_name string + vpc_calls string +} + +fn (mut g Gen) profile_fn(fn_name string, is_main bool){ + if is_main { + g.writeln('') + g.writeln('\tatexit(vprint_profile_stats);') + g.writeln('') + } + if fn_name == 'time.vpc_now' { + g.defer_profile_code = '' + } else { + fn_profile_counter_name := 'vpc_${g.last_fn_c_name}' + fn_profile_counter_name_calls := '${fn_profile_counter_name}_calls' + g.writeln('') + g.writeln('\tdouble _PROF_FN_START = time__vpc_now(); ${fn_profile_counter_name_calls}++; // $fn_name') + g.writeln('') + g.defer_profile_code = '\t${fn_profile_counter_name} += time__vpc_now() - _PROF_FN_START;' + g.pcs_declarations.writeln('double ${fn_profile_counter_name} = 0.0; u64 ${fn_profile_counter_name_calls} = 0;') + g.pcs << ProfileCounterMeta{ g.last_fn_c_name, fn_profile_counter_name, fn_profile_counter_name_calls } + } +} + + +pub fn (mut g Gen) gen_vprint_profile_stats() { + g.pcs_declarations.writeln('void vprint_profile_stats(){') + if g.pref.profile_file == '-' { + for pc_meta in g.pcs { + g.pcs_declarations.writeln('\tif (${pc_meta.vpc_calls}) printf("%llu %f %f ${pc_meta.fn_name} \\n", ${pc_meta.vpc_calls}, ${pc_meta.vpc_name}, ${pc_meta.vpc_name}/${pc_meta.vpc_calls} );') + } + } else { + g.pcs_declarations.writeln('\tFILE * fp;') + g.pcs_declarations.writeln('\tfp = fopen ("${g.pref.profile_file}", "w+");') + for pc_meta in g.pcs { + g.pcs_declarations.writeln('\tif (${pc_meta.vpc_calls}) fprintf(fp, "%llu %f %f ${pc_meta.fn_name} \\n", ${pc_meta.vpc_calls}, ${pc_meta.vpc_name}, ${pc_meta.vpc_name}/${pc_meta.vpc_calls} );') + } + g.pcs_declarations.writeln('\tfclose(fp);') + } + g.pcs_declarations.writeln('}') +}