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 /translate.cxx | |
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.
Diffstat (limited to 'translate.cxx')
-rw-r--r-- | translate.cxx | 113 |
1 files changed, 68 insertions, 45 deletions
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; |