diff options
author | fche <fche> | 2006-01-10 18:52:33 +0000 |
---|---|---|
committer | fche <fche> | 2006-01-10 18:52:33 +0000 |
commit | db22e55f4280ceaf3181e5b17aacd0ba4075e85f (patch) | |
tree | b2d2af0803c6e966e6fd7ce3b6c8ecf0ef8e33a1 | |
parent | a9a29deb6ee0f9e38dea288e12477acb5f672f32 (diff) | |
download | systemtap-steved-db22e55f4280ceaf3181e5b17aacd0ba4075e85f.tar.gz systemtap-steved-db22e55f4280ceaf3181e5b17aacd0ba4075e85f.tar.xz systemtap-steved-db22e55f4280ceaf3181e5b17aacd0ba4075e85f.zip |
2006-01-10 Frank Ch. Eigler <fche@redhat.com>
PR 2060.
* buildrun.cxx (compile_pass): Add "V=1" to kbuild if verbose.
* translate.cxx (translator_output): For output-file constructor,
set an explicit output buffer.
(emit_module_init, emit_module_exit): Reorganize output, to spit
each individual probe registration/deregistration blurb into a
separate function.
* translate.h: Corresponding changes; set default buffer size to 8K.
* translate.cxx, tapsets.cxx: Replace "endl" by buffer-friendly "\n"
throughout code generation routines.
-rw-r--r-- | ChangeLog | 13 | ||||
-rw-r--r-- | buildrun.cxx | 11 | ||||
-rw-r--r-- | tapsets.cxx | 66 | ||||
-rw-r--r-- | translate.cxx | 113 | ||||
-rw-r--r-- | translate.h | 3 |
5 files changed, 125 insertions, 81 deletions
@@ -1,3 +1,16 @@ +2006-01-10 Frank Ch. Eigler <fche@redhat.com> + + PR 2060. + * buildrun.cxx (compile_pass): Add "V=1" to kbuild if verbose. + * translate.cxx (translator_output): For output-file constructor, + set an explicit output buffer. + (emit_module_init, emit_module_exit): Reorganize output, to spit + each individual probe registration/deregistration blurb into a + separate function. + * translate.h: Corresponding changes; set default buffer size to 8K. + * translate.cxx, tapsets.cxx: Replace "endl" by buffer-friendly "\n" + throughout code generation routines. + 2006-01-09 Frank Ch. Eigler <fche@redhat.com> * HACKING: Extend guidelines for tapset testing. diff --git a/buildrun.cxx b/buildrun.cxx index 05d903d5..d678e874 100644 --- a/buildrun.cxx +++ b/buildrun.cxx @@ -66,6 +66,9 @@ compile_pass (systemtap_session& s) for (unsigned i=0; i<s.macros.size(); i++) o << "CFLAGS += -D " << lex_cast_qstring(s.macros[i]) << endl; + // XXX + // o << "CFLAGS += -ftime-report" << endl; + if (s.test_mode) { string module_dir = string("/lib/modules/") @@ -95,7 +98,9 @@ compile_pass (systemtap_session& s) { string make_cmd = string("make -C \"") + s.tmpdir + "\""; - if (! s.verbose) + if (s.verbose) + make_cmd += " V=1"; + else make_cmd += " -s >/dev/null 2>&1"; if (s.verbose) clog << "Running " << make_cmd << endl; @@ -113,7 +118,9 @@ compile_pass (systemtap_session& s) + string (" -C \"") + module_dir + string("\""); make_cmd += string(" M=\"") + s.tmpdir + string("\" modules"); - if (! s.verbose) + if (s.verbose) + make_cmd += " V=1"; + else make_cmd += " -s >/dev/null 2>&1"; if (s.verbose) clog << "Running " << make_cmd << endl; diff --git a/tapsets.cxx b/tapsets.cxx index b6533a10..57429cbd 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -217,7 +217,7 @@ be_derived_probe::emit_probe_entries (translator_output* o, unsigned j) emit_probe_epilogue (o); - o->newline(-1) << "}" << endl; + o->newline(-1) << "}\n"; } } @@ -456,7 +456,7 @@ dwflpp if (in) return in; if (false && sess.verbose) - clog << "WARNING: no name found for " << type << endl; + clog << "WARNING: no name found for " << type << "\n"; return string(""); } @@ -482,7 +482,7 @@ dwflpp if (required) throw semantic_error (msg); else - cerr << "WARNING: " << msg << endl; + cerr << "WARNING: " << msg << "\n"; } } @@ -549,8 +549,6 @@ dwflpp { assert(dwfl); cu = NULL; - if (false && sess.verbose) - clog << "focusing on module containing global addr " << a << endl; Dwfl_Module* mod = dwfl_addrmodule(dwfl, a); if (mod) // address could be wildly out of range focus_on_module(mod); @@ -586,7 +584,7 @@ dwflpp if (false && sess.verbose) clog << "module addr " << hex << a << " + module start " << module_start - << " -> global addr " << (a + module_start) << dec << endl; + << " -> global addr " << (a + module_start) << dec << "\n"; return a + module_start; } @@ -598,7 +596,7 @@ dwflpp if (false && sess.verbose) clog << "global addr " << a << " - module start " << hex << module_start - << " -> module addr " << (a - module_start) << dec << endl; + << " -> module addr " << (a - module_start) << dec << "\n"; return a - module_bias; } @@ -610,7 +608,7 @@ dwflpp if (t && sess.verbose) clog << "pattern '" << pattern << "' " << "matches " - << "module '" << module_name << "'" << endl; + << "module '" << module_name << "'" << "\n"; return t; } @@ -622,7 +620,7 @@ dwflpp if (t && sess.verbose) clog << "pattern '" << pattern << "' " << "matches " - << "function '" << function_name << "'" << endl; + << "function '" << function_name << "'" << "\n"; return t; } @@ -634,7 +632,7 @@ dwflpp if (t && sess.verbose) clog << "pattern '" << pattern << "' " << "matches " - << "CU '" << cu_name << "'" << endl; + << "CU '" << cu_name << "'" << "\n"; return t; } @@ -893,7 +891,7 @@ dwflpp { filtered_srcfiles.insert (fname); if (sess.verbose) - clog << "selected source file '" << fname << "'" << endl; + clog << "selected source file '" << fname << "'\n"; } } } @@ -994,7 +992,7 @@ dwflpp << last_function->name << " heur0=" << hex << addr0 << " heur1=" << addr << dec - << endl; + << "\n"; } choose_next_line_otherthan = -1; continue; @@ -1017,7 +1015,7 @@ dwflpp clog << "prologue disagreement: " << last_function->name << " heur0=" << hex << addr0 << " heur1=" << addr << dec - << endl; + << "\n"; } choose_next_line_otherthan = -1; continue; @@ -1043,7 +1041,7 @@ dwflpp << last_function->name << "' entrypc=0x" << hex << addr << " highpc=0x" << last_function_highpc - << endl; + << "\n"; } } @@ -1437,7 +1435,7 @@ dwflpp clog << "finding location for local '" << local << "' near address " << hex << pc << ", module bias " << module_bias << dec - << endl; + << "\n"; Dwarf_Attribute attr_mem; if (dwarf_attr_integrate (&vardie, DW_AT_location, &attr_mem) == NULL) @@ -1794,7 +1792,7 @@ dwarf_query::parse_function_spec(string & spec) if (sess.verbose) clog << "parsed '" << spec << "' -> func '" << function - << "'" << endl; + << "'\n"; return function_alone; } @@ -1810,7 +1808,7 @@ dwarf_query::parse_function_spec(string & spec) clog << "parsed '" << spec << "' -> func '"<< function << "', file '" << file - << "'" << endl; + << "'\n"; return function_and_file; } @@ -1824,7 +1822,7 @@ dwarf_query::parse_function_spec(string & spec) clog << "parsed '" << spec << "' -> func '"<< function << "', file '" << file - << "', line " << line << endl; + << "', line " << line << "\n"; return function_file_and_line; } catch (runtime_error & exn) @@ -1935,7 +1933,7 @@ dwarf_query::blacklisted_p(string const & funcname, if (sess.verbose) clog << "skipping function '" << funcname << "' base 0x" << hex << addr << dec << " is within section '" - << name << "'" << endl; + << name << "'\n"; return true; } } @@ -1970,7 +1968,7 @@ dwarf_query::blacklisted_p(string const & funcname, if (sess.verbose) clog << "skipping function '" << funcname << "' base 0x" << hex << addr << dec << " is within section '" - << name << "'" << endl; + << name << "'\n"; return true; } } @@ -1993,7 +1991,7 @@ dwarf_query::blacklisted_p(string const & funcname, { if (sess.verbose) clog << "skipping function '" << funcname << "' file '" - << filename << "' is blacklisted" << endl; + << filename << "' is blacklisted\n"; return true; } @@ -2113,7 +2111,7 @@ query_inline_instance_info (Dwarf_Addr entrypc, if (q->sess.verbose) clog << "querying entrypc " << hex << entrypc << dec - << " of instance of inline '" << ii.name << "'" << endl; + << " of instance of inline '" << ii.name << "'\n"; query_statement (ii.name, ii.decl_file, ii.decl_line, &ii.die, entrypc, q); } @@ -2176,7 +2174,7 @@ query_srcfile_line (Dwarf_Line * line, void * arg) if (q->dw.die_has_pc (&(i->second.die), addr)) { if (q->sess.verbose) - clog << "function DIE lands on srcfile" << endl; + clog << "function DIE lands on srcfile\n"; if (q->has_statement_str) query_statement (i->second.name, i->second.decl_file, q->line, NULL, addr, q); @@ -2192,7 +2190,7 @@ query_srcfile_line (Dwarf_Line * line, void * arg) if (q->dw.die_has_pc (&(i->second.die), addr)) { if (q->sess.verbose) - clog << "inline instance DIE lands on srcfile" << endl; + clog << "inline instance DIE lands on srcfile\n"; if (q->has_statement_str) query_statement (i->second.name, i->second.decl_file, q->line, NULL, addr, q); @@ -2215,7 +2213,7 @@ query_dwarf_inline_instance (Dwarf_Die * die, void * arg) bool record_this_inline = false; if (q->sess.verbose) - clog << "examining inline instance of " << q->dw.function_name << endl; + clog << "examining inline instance of " << q->dw.function_name << "\n"; if (q->has_inline_str || q->has_statement_str) record_this_inline = true; @@ -2234,7 +2232,8 @@ query_dwarf_inline_instance (Dwarf_Die * die, void * arg) if (record_this_inline) { if (q->sess.verbose) - clog << "selected inline instance of " << q->dw.function_name << endl; + clog << "selected inline instance of " << q->dw.function_name + << "\n"; Dwarf_Addr entrypc; if (q->dw.die_entrypc (die, &entrypc)) @@ -2281,7 +2280,8 @@ query_dwarf_func (Dwarf_Die * func, void * arg) || q->has_inline_num)) { if (q->sess.verbose) - clog << "checking instances of inline " << q->dw.function_name << endl; + clog << "checking instances of inline " << q->dw.function_name + << "\n"; q->dw.iterate_over_inline_instances (query_dwarf_inline_instance, arg); } else if (!q->dw.func_is_inline ()) @@ -2310,7 +2310,7 @@ query_dwarf_func (Dwarf_Die * func, void * arg) if (record_this_function) { if (q->sess.verbose) - clog << "selected function " << q->dw.function_name << endl; + clog << "selected function " << q->dw.function_name << "\n"; Dwarf_Addr entrypc; if (q->dw.function_entrypc (&entrypc)) @@ -2347,7 +2347,7 @@ query_cu (Dwarf_Die * cudie, void * arg) if (false && q->sess.verbose) clog << "focused on CU '" << q->dw.cu_name - << "', in module '" << q->dw.module_name << "'" << endl; + << "', in module '" << q->dw.module_name << "'\n"; if (q->has_statement_str || q->has_inline_str || q->has_inline_num @@ -2474,7 +2474,7 @@ query_module (Dwfl_Module *mod __attribute__ ((unused)), clog << "focused on module '" << q->dw.module_name << "' = [" << hex << q->dw.module_start << "-" << q->dw.module_end - << ", bias " << q->dw.module_bias << "]" << dec << endl; + << ", bias " << q->dw.module_bias << "]" << dec << "\n"; if (q->has_inline_num || q->has_function_num || q->has_statement_num) { @@ -3121,7 +3121,7 @@ dwarf_derived_probe::emit_probe_entries (translator_output* o, emit_probe_epilogue (o); o->newline() << "return 0;"; - o->newline(-1) << "}" << endl; + o->newline(-1) << "}\n"; if (has_return) o->newline() << "#endif /* ARCH_SUPPORTS_KRETPROBES */"; @@ -3291,7 +3291,7 @@ timer_derived_probe::emit_probe_entries (translator_output* o, unsigned j) o->newline() << "probe_" << j << " (c);"; emit_probe_epilogue (o); - o->newline(-1) << "}" << endl; + o->newline(-1) << "}\n"; } @@ -3410,7 +3410,7 @@ profile_derived_probe::emit_probe_entries (translator_output* o, unsigned j) emit_probe_epilogue (o); o->newline() << "return 0;"; - o->newline(-1) << "}" << endl; + o->newline(-1) << "}\n"; } diff --git a/translate.cxx b/translate.cxx index 791e5434..992bd96c 100644 --- a/translate.cxx +++ b/translate.cxx @@ -776,20 +776,25 @@ ostream & operator<<(ostream & o, itervar const & v) translator_output::translator_output (ostream& f): - o2 (0), o (f), tablevel (0) + buf(0), o2 (0), o (f), tablevel (0) { } -translator_output::translator_output (const string& filename): - o2 (new ofstream (filename.c_str ())), o (*o2), tablevel (0) +translator_output::translator_output (const string& filename, size_t bufsize): + buf (new char[bufsize]), + o2 (new ofstream (filename.c_str ())), + o (*o2), + tablevel (0) { + o2->rdbuf()->pubsetbuf(buf, bufsize); } translator_output::~translator_output () { delete o2; + delete buf; } @@ -798,7 +803,7 @@ translator_output::newline (int indent) { assert (indent > 0 || tablevel >= (unsigned)-indent); tablevel += indent; - o << endl; + o << "\n"; for (unsigned i=0; i<tablevel; i++) o << " "; return o; @@ -921,13 +926,13 @@ c_unparser::emit_common_header () o->newline(-1) << "} function_" << c_varname (fd->name) << ";"; } o->newline(-1) << "} locals [MAXNESTING];"; - o->newline(-1) << "};" << endl; - o->newline() << "void *contexts = NULL; /* alloc_percpu */" << endl; + o->newline(-1) << "};\n"; + o->newline() << "void *contexts = NULL; /* alloc_percpu */\n"; emit_map_type_instantiations (); if (!session->stat_decls.empty()) - o->newline() << "#include \"stat.c\"" << endl; + o->newline() << "#include \"stat.c\"\n"; } @@ -966,8 +971,45 @@ c_unparser::emit_functionsig (functiondecl* v) void c_unparser::emit_module_init () { - o->newline() << "static int systemtap_module_init (void);"; - o->newline() << "int systemtap_module_init () {"; + // Emit the per-probe-point registrations into individual functions, + // to avoid forcing the compiler to work too hard at optimizing such + // a silly function. A "don't optimize this function" pragma could + // come in handy too. + for (unsigned i=0; i<session->probes.size(); i++) + { + o->newline() << "noinline int register_probe_" << i << " (void) {"; + o->indent(1); + // By default, mark the first location as the site of possible + // registration failure. This is helpful since non-dwarf + // derived_probes tend to have only a single location. + assert (session->probes[i]->locations.size() > 0); + o->newline() << "int rc = 0;"; + o->newline() << "const char *probe_point = " << + lex_cast_qstring (*session->probes[i]->locations[0]) << ";"; + session->probes[i]->emit_registrations (o, i); + + o->newline() << "if (unlikely (rc)) {"; + // In case it's just a lower-layer (kprobes) error that set rc + // but not session_state, do that here to prevent any other BEGIN + // probe from attempting to run. + o->newline(1) << "atomic_set (&session_state, STAP_SESSION_ERROR);"; + + o->newline() << "_stp_error (\"probe " << i << " registration failed" + << ", rc=%d, %s\\n\", rc, probe_point);"; + o->newline(-1) << "}"; + + o->newline() << "return rc;"; + o->newline(-1) << "}"; + + o->newline(); + o->newline() << "noinline void unregister_probe_" << i << " (void) {"; + o->indent(1); + session->probes[i]->emit_deregistrations (o, i); + o->newline(-1) << "}"; + } + + o->newline(); + o->newline() << "int systemtap_module_init (void) {"; o->newline(1) << "int rc = 0;"; o->newline() << "const char *probe_point = \"\";"; @@ -998,34 +1040,16 @@ c_unparser::emit_module_init () for (unsigned i=0; i<session->probes.size(); i++) { - o->newline() << "/* register probe #" << i << ", "; - o->line() << session->probes[i]->locations.size() << " location(s) */"; - - // By default, mark the first location as the site of possible - // registration failure. This is helpful since non-dwarf - // derived_probes tend to have only a single location. - assert (session->probes[i]->locations.size() > 0); - o->newline() << "probe_point = " << - lex_cast_qstring (*session->probes[i]->locations[0]) << ";"; - session->probes[i]->emit_registrations (o, i); - - o->newline() << "if (unlikely (rc)) {"; - // In case it's just a lower-layer (kprobes) error that set rc - // but not session_state, do that here to prevent any other BEGIN - // probe from attempting to run. - o->newline(1) << "atomic_set (&session_state, STAP_SESSION_ERROR);"; - - o->newline() << "_stp_error (\"probe " << i << " registration failed" - << ", rc=%d, %s\\n\", rc, probe_point);"; - + o->newline() << "rc = register_probe_" << i << "();"; + o->newline() << "if (rc)"; + o->indent(1); // We need to deregister any already probes set up - this is // essential for kprobes. if (i > 0) o->newline() << "goto unregister_" << (i-1) << ";"; else o->newline() << "goto out;"; - - o->newline(-1) << "}"; + o->indent(-1); } // BEGIN probes would have all been run by now. One of them may @@ -1045,8 +1069,7 @@ c_unparser::emit_module_init () for (int i=session->probes.size()-2; i >= 0; i--) // NB: -2 { o->newline(-1) << "unregister_" << i << ":"; - o->indent(1); - session->probes[i]->emit_deregistrations (o, i); + o->newline(1) << "unregister_probe_" << i << "();"; // NB: This may be an END probe. It will refuse to run // if the session_state was ERRORed. } @@ -1063,15 +1086,14 @@ c_unparser::emit_module_init () o->newline(-1) << "out:"; o->newline(1) << "return rc;"; - o->newline(-1) << "}" << endl; + o->newline(-1) << "}\n"; } void c_unparser::emit_module_exit () { - o->newline() << "static void systemtap_module_exit (void);"; - o->newline() << "void systemtap_module_exit () {"; + o->newline() << "void systemtap_module_exit (void) {"; // rc? o->newline(1) << "int holdon;"; @@ -1107,7 +1129,7 @@ c_unparser::emit_module_exit () // genuinely stuck somehow for (int i=session->probes.size()-1; i>=0; i--) - session->probes[i]->emit_deregistrations (o, i); // NB: runs "end" probes + o->newline() << "unregister_probe_" << i << "();"; // NB: runs "end" probes for (unsigned i=0; i<session->globals.size(); i++) { @@ -1127,7 +1149,7 @@ c_unparser::emit_module_exit () << "(int) atomic_read (& skipped_count));"; o->indent(-1); - o->newline(-1) << "}" << endl; + o->newline(-1) << "}\n"; } @@ -1179,7 +1201,7 @@ c_unparser::emit_function (functiondecl* v) o->newline() << "#undef CONTEXT"; o->newline() << "#undef THIS"; - o->newline(-1) << "}" << endl; + o->newline(-1) << "}\n"; } @@ -1187,7 +1209,7 @@ void c_unparser::emit_probe (derived_probe* v, unsigned i) { // o->newline() << "static void probe_" << i << " (struct context *c);"; - o->newline() << "static void probe_" << i << " (struct context * __restrict__ c) {"; + o->newline() << "void probe_" << i << " (struct context * __restrict__ c) {"; o->indent(1); // initialize frame pointer @@ -1222,7 +1244,8 @@ c_unparser::emit_probe (derived_probe* v, unsigned i) o->newline(-1) << "out:"; // NB: no need to uninitialize locals, except if arrays can somedays be local o->newline(1) << "_stp_print_flush();"; - o->newline(-1) << "}" << endl; + + o->newline(-1) << "}\n"; v->emit_probe_entries (o, i); } @@ -3455,7 +3478,7 @@ emit_symbol_data (systemtap_session& s) } } s.op->newline(-1) << "};"; - s.op->newline() << "unsigned stap_num_symbols = " << i << ";" << endl; + s.op->newline() << "unsigned stap_num_symbols = " << i << ";\n"; } return rc; @@ -3474,7 +3497,7 @@ translate_pass (systemtap_session& s) try { // This is at the very top of the file. - s.op->line() << "#define TEST_MODE " << (s.test_mode ? 1 : 0) << endl; + s.op->line() << "#define TEST_MODE " << (s.test_mode ? 1 : 0) << "\n"; s.op->newline() << "#ifndef MAXNESTING"; s.op->newline() << "#define MAXNESTING 10"; @@ -3526,7 +3549,7 @@ translate_pass (systemtap_session& s) for (unsigned i=0; i<s.embeds.size(); i++) { - s.op->newline() << s.embeds[i]->code << endl; + s.op->newline() << s.embeds[i]->code << "\n"; } for (unsigned i=0; i<s.globals.size(); i++) @@ -3590,7 +3613,7 @@ translate_pass (systemtap_session& s) } rc |= emit_symbol_data (s); - s.op->line() << endl; + s.op->line() << "\n"; delete s.op; s.op = 0; diff --git a/translate.h b/translate.h index 39e56dd7..1c6dc9f6 100644 --- a/translate.h +++ b/translate.h @@ -21,13 +21,14 @@ // pretty-printing. class translator_output { + char *buf; std::ofstream* o2; std::ostream& o; unsigned tablevel; public: translator_output (std::ostream& file); - translator_output (const std::string& filename); + translator_output (const std::string& filename, size_t bufsize = 8192); ~translator_output (); std::ostream& newline (int indent = 0); |