src/share/vm/compiler/disassembler.cpp

Print this page
rev 4202 : 8008555: Debugging code in compiled method sometimes leaks memory
Summary: support for strings that have same life-time as code that uses them.
Reviewed-by:


 141     tty->print_cr("Could not load %s; %s; %s", buf,
 142                   ((_library != NULL)
 143                    ? "entry point is missing"
 144                    : (WizardMode || PrintMiscellaneous)
 145                    ? (const char*)ebuf
 146                    : "library not loadable"),
 147                   "PrintAssembly is disabled");
 148     return false;
 149   }
 150 
 151   // Success.
 152   tty->print_cr("Loaded disassembler from %s", buf);
 153   return true;
 154 }
 155 
 156 
 157 class decode_env {
 158  private:
 159   nmethod*      _nm;
 160   CodeBlob*     _code;
 161   CodeComments  _comments;
 162   outputStream* _output;
 163   address       _start, _end;
 164 
 165   char          _option_buf[512];
 166   char          _print_raw;
 167   bool          _print_pc;
 168   bool          _print_bytes;
 169   address       _cur_insn;
 170   int           _total_ticks;
 171   int           _bytes_per_line; // arch-specific formatting option
 172 
 173   static bool match(const char* event, const char* tag) {
 174     size_t taglen = strlen(tag);
 175     if (strncmp(event, tag, taglen) != 0)
 176       return false;
 177     char delim = event[taglen];
 178     return delim == '\0' || delim == ' ' || delim == '/' || delim == '=';
 179   }
 180 
 181   void collect_options(const char* p) {
 182     if (p == NULL || p[0] == '\0')  return;
 183     size_t opt_so_far = strlen(_option_buf);
 184     if (opt_so_far + 1 + strlen(p) + 1 > sizeof(_option_buf))  return;
 185     char* fillp = &_option_buf[opt_so_far];
 186     if (opt_so_far > 0) *fillp++ = ',';
 187     strcat(fillp, p);
 188     // replace white space by commas:
 189     char* q = fillp;
 190     while ((q = strpbrk(q, " \t\n")) != NULL)
 191       *q++ = ',';
 192     // Note that multiple PrintAssemblyOptions flags accumulate with \n,
 193     // which we want to be changed to a comma...
 194   }
 195 
 196   void print_insn_labels();
 197   void print_insn_bytes(address pc0, address pc);
 198   void print_address(address value);
 199 
 200  public:
 201   decode_env(CodeBlob* code, outputStream* output, CodeComments c = CodeComments());
 202 
 203   address decode_instructions(address start, address end);
 204 
 205   void start_insn(address pc) {
 206     _cur_insn = pc;
 207     output()->bol();
 208     print_insn_labels();
 209   }
 210 
 211   void end_insn(address pc) {
 212     address pc0 = cur_insn();
 213     outputStream* st = output();
 214     if (_print_bytes && pc > pc0)
 215       print_insn_bytes(pc0, pc);
 216     if (_nm != NULL) {
 217       _nm->print_code_comment_on(st, COMMENT_COLUMN, pc0, pc);
 218       // this calls reloc_string_for which calls oop::print_value_on
 219     }
 220 
 221     // Output pc bucket ticks if we have any


 225         int bucket_count = FlatProfiler::bucket_count_for(pc0);
 226         if (bucket_count != 0) {
 227           st->bol();
 228           st->print_cr("%3.1f%% [%d]", bucket_count*100.0/total_ticks(), bucket_count);
 229         }
 230       }
 231     }
 232     // follow each complete insn by a nice newline
 233     st->cr();
 234   }
 235 
 236   address handle_event(const char* event, address arg);
 237 
 238   outputStream* output() { return _output; }
 239   address cur_insn() { return _cur_insn; }
 240   int total_ticks() { return _total_ticks; }
 241   void set_total_ticks(int n) { _total_ticks = n; }
 242   const char* options() { return _option_buf; }
 243 };
 244 
 245 decode_env::decode_env(CodeBlob* code, outputStream* output, CodeComments c) {
 246   memset(this, 0, sizeof(*this));
 247   _output = output ? output : tty;
 248   _code = code;
 249   if (code != NULL && code->is_nmethod())
 250     _nm = (nmethod*) code;
 251   _comments.assign(c);
 252 
 253   // by default, output pc but not bytes:
 254   _print_pc       = true;
 255   _print_bytes    = false;
 256   _bytes_per_line = Disassembler::pd_instruction_alignment();
 257 
 258   // parse the global option string:
 259   collect_options(Disassembler::pd_cpu_opts());
 260   collect_options(PrintAssemblyOptions);
 261 
 262   if (strstr(options(), "hsdis-")) {
 263     if (strstr(options(), "hsdis-print-raw"))
 264       _print_raw = (strstr(options(), "xml") ? 2 : 1);
 265     if (strstr(options(), "hsdis-print-pc"))
 266       _print_pc = !_print_pc;
 267     if (strstr(options(), "hsdis-print-bytes"))
 268       _print_bytes = !_print_bytes;
 269   }
 270   if (strstr(options(), "help")) {
 271     tty->print_cr("PrintAssemblyOptions help:");


 353       obj->print_value_on(st);
 354       if (st->count() == c) {
 355         // No output.  (Can happen in product builds.)
 356         st->print("(a %s)", obj->klass()->external_name());
 357       }
 358       return;
 359     }
 360   }
 361 
 362   // Fall through to a simple (hexadecimal) numeral.
 363   st->print(PTR_FORMAT, adr);
 364 }
 365 
 366 void decode_env::print_insn_labels() {
 367   address p = cur_insn();
 368   outputStream* st = output();
 369   CodeBlob* cb = _code;
 370   if (cb != NULL) {
 371     cb->print_block_comment(st, p);
 372   }
 373   _comments.print_block_comment(st, (intptr_t)(p - _start));
 374   if (_print_pc) {
 375     st->print("  " PTR_FORMAT ": ", p);
 376   }
 377 }
 378 
 379 void decode_env::print_insn_bytes(address pc, address pc_limit) {
 380   outputStream* st = output();
 381   size_t incr = 1;
 382   size_t perline = _bytes_per_line;
 383   if ((size_t) Disassembler::pd_instruction_alignment() >= sizeof(int)
 384       && !((uintptr_t)pc % sizeof(int))
 385       && !((uintptr_t)pc_limit % sizeof(int))) {
 386     incr = sizeof(int);
 387     if (perline % incr)  perline += incr - (perline % incr);
 388   }
 389   while (pc < pc_limit) {
 390     // tab to the desired column:
 391     st->move_to(COMMENT_COLUMN);
 392     address pc0 = pc;
 393     address pc1 = pc + perline;


 481                                                   start, end - start,
 482                                                   &event_to_env,  (void*) this,
 483                                                   &printf_to_env, (void*) this,
 484                                                   options(), 0/*nice new line*/)
 485     :
 486     (address)
 487     (*Disassembler::_decode_instructions)(start, end,
 488                                           &event_to_env,  (void*) this,
 489                                           &printf_to_env, (void*) this,
 490                                           options());
 491 }
 492 
 493 
 494 void Disassembler::decode(CodeBlob* cb, outputStream* st) {
 495   if (!load_library())  return;
 496   decode_env env(cb, st);
 497   env.output()->print_cr("Decoding CodeBlob " PTR_FORMAT, cb);
 498   env.decode_instructions(cb->code_begin(), cb->code_end());
 499 }
 500 
 501 void Disassembler::decode(address start, address end, outputStream* st, CodeComments c) {
 502   if (!load_library())  return;
 503   decode_env env(CodeCache::find_blob_unsafe(start), st, c);
 504   env.decode_instructions(start, end);
 505 }
 506 
 507 void Disassembler::decode(nmethod* nm, outputStream* st) {
 508   if (!load_library())  return;
 509   decode_env env(nm, st);
 510   env.output()->print_cr("Decoding compiled method " PTR_FORMAT ":", nm);
 511   env.output()->print_cr("Code:");
 512 
 513 #ifdef SHARK
 514   SharkEntry* entry = (SharkEntry *) nm->code_begin();
 515   unsigned char* p   = entry->code_start();
 516   unsigned char* end = entry->code_limit();
 517 #else
 518   unsigned char* p   = nm->code_begin();
 519   unsigned char* end = nm->code_end();
 520 #endif // SHARK
 521 




 141     tty->print_cr("Could not load %s; %s; %s", buf,
 142                   ((_library != NULL)
 143                    ? "entry point is missing"
 144                    : (WizardMode || PrintMiscellaneous)
 145                    ? (const char*)ebuf
 146                    : "library not loadable"),
 147                   "PrintAssembly is disabled");
 148     return false;
 149   }
 150 
 151   // Success.
 152   tty->print_cr("Loaded disassembler from %s", buf);
 153   return true;
 154 }
 155 
 156 
 157 class decode_env {
 158  private:
 159   nmethod*      _nm;
 160   CodeBlob*     _code;
 161   CodeStrings   _strings;
 162   outputStream* _output;
 163   address       _start, _end;
 164 
 165   char          _option_buf[512];
 166   char          _print_raw;
 167   bool          _print_pc;
 168   bool          _print_bytes;
 169   address       _cur_insn;
 170   int           _total_ticks;
 171   int           _bytes_per_line; // arch-specific formatting option
 172 
 173   static bool match(const char* event, const char* tag) {
 174     size_t taglen = strlen(tag);
 175     if (strncmp(event, tag, taglen) != 0)
 176       return false;
 177     char delim = event[taglen];
 178     return delim == '\0' || delim == ' ' || delim == '/' || delim == '=';
 179   }
 180 
 181   void collect_options(const char* p) {
 182     if (p == NULL || p[0] == '\0')  return;
 183     size_t opt_so_far = strlen(_option_buf);
 184     if (opt_so_far + 1 + strlen(p) + 1 > sizeof(_option_buf))  return;
 185     char* fillp = &_option_buf[opt_so_far];
 186     if (opt_so_far > 0) *fillp++ = ',';
 187     strcat(fillp, p);
 188     // replace white space by commas:
 189     char* q = fillp;
 190     while ((q = strpbrk(q, " \t\n")) != NULL)
 191       *q++ = ',';
 192     // Note that multiple PrintAssemblyOptions flags accumulate with \n,
 193     // which we want to be changed to a comma...
 194   }
 195 
 196   void print_insn_labels();
 197   void print_insn_bytes(address pc0, address pc);
 198   void print_address(address value);
 199 
 200  public:
 201   decode_env(CodeBlob* code, outputStream* output, CodeStrings c = CodeStrings());
 202 
 203   address decode_instructions(address start, address end);
 204 
 205   void start_insn(address pc) {
 206     _cur_insn = pc;
 207     output()->bol();
 208     print_insn_labels();
 209   }
 210 
 211   void end_insn(address pc) {
 212     address pc0 = cur_insn();
 213     outputStream* st = output();
 214     if (_print_bytes && pc > pc0)
 215       print_insn_bytes(pc0, pc);
 216     if (_nm != NULL) {
 217       _nm->print_code_comment_on(st, COMMENT_COLUMN, pc0, pc);
 218       // this calls reloc_string_for which calls oop::print_value_on
 219     }
 220 
 221     // Output pc bucket ticks if we have any


 225         int bucket_count = FlatProfiler::bucket_count_for(pc0);
 226         if (bucket_count != 0) {
 227           st->bol();
 228           st->print_cr("%3.1f%% [%d]", bucket_count*100.0/total_ticks(), bucket_count);
 229         }
 230       }
 231     }
 232     // follow each complete insn by a nice newline
 233     st->cr();
 234   }
 235 
 236   address handle_event(const char* event, address arg);
 237 
 238   outputStream* output() { return _output; }
 239   address cur_insn() { return _cur_insn; }
 240   int total_ticks() { return _total_ticks; }
 241   void set_total_ticks(int n) { _total_ticks = n; }
 242   const char* options() { return _option_buf; }
 243 };
 244 
 245 decode_env::decode_env(CodeBlob* code, outputStream* output, CodeStrings c) {
 246   memset(this, 0, sizeof(*this));
 247   _output = output ? output : tty;
 248   _code = code;
 249   if (code != NULL && code->is_nmethod())
 250     _nm = (nmethod*) code;
 251   _strings.assign(c);
 252 
 253   // by default, output pc but not bytes:
 254   _print_pc       = true;
 255   _print_bytes    = false;
 256   _bytes_per_line = Disassembler::pd_instruction_alignment();
 257 
 258   // parse the global option string:
 259   collect_options(Disassembler::pd_cpu_opts());
 260   collect_options(PrintAssemblyOptions);
 261 
 262   if (strstr(options(), "hsdis-")) {
 263     if (strstr(options(), "hsdis-print-raw"))
 264       _print_raw = (strstr(options(), "xml") ? 2 : 1);
 265     if (strstr(options(), "hsdis-print-pc"))
 266       _print_pc = !_print_pc;
 267     if (strstr(options(), "hsdis-print-bytes"))
 268       _print_bytes = !_print_bytes;
 269   }
 270   if (strstr(options(), "help")) {
 271     tty->print_cr("PrintAssemblyOptions help:");


 353       obj->print_value_on(st);
 354       if (st->count() == c) {
 355         // No output.  (Can happen in product builds.)
 356         st->print("(a %s)", obj->klass()->external_name());
 357       }
 358       return;
 359     }
 360   }
 361 
 362   // Fall through to a simple (hexadecimal) numeral.
 363   st->print(PTR_FORMAT, adr);
 364 }
 365 
 366 void decode_env::print_insn_labels() {
 367   address p = cur_insn();
 368   outputStream* st = output();
 369   CodeBlob* cb = _code;
 370   if (cb != NULL) {
 371     cb->print_block_comment(st, p);
 372   }
 373   _strings.print_block_comment(st, (intptr_t)(p - _start));
 374   if (_print_pc) {
 375     st->print("  " PTR_FORMAT ": ", p);
 376   }
 377 }
 378 
 379 void decode_env::print_insn_bytes(address pc, address pc_limit) {
 380   outputStream* st = output();
 381   size_t incr = 1;
 382   size_t perline = _bytes_per_line;
 383   if ((size_t) Disassembler::pd_instruction_alignment() >= sizeof(int)
 384       && !((uintptr_t)pc % sizeof(int))
 385       && !((uintptr_t)pc_limit % sizeof(int))) {
 386     incr = sizeof(int);
 387     if (perline % incr)  perline += incr - (perline % incr);
 388   }
 389   while (pc < pc_limit) {
 390     // tab to the desired column:
 391     st->move_to(COMMENT_COLUMN);
 392     address pc0 = pc;
 393     address pc1 = pc + perline;


 481                                                   start, end - start,
 482                                                   &event_to_env,  (void*) this,
 483                                                   &printf_to_env, (void*) this,
 484                                                   options(), 0/*nice new line*/)
 485     :
 486     (address)
 487     (*Disassembler::_decode_instructions)(start, end,
 488                                           &event_to_env,  (void*) this,
 489                                           &printf_to_env, (void*) this,
 490                                           options());
 491 }
 492 
 493 
 494 void Disassembler::decode(CodeBlob* cb, outputStream* st) {
 495   if (!load_library())  return;
 496   decode_env env(cb, st);
 497   env.output()->print_cr("Decoding CodeBlob " PTR_FORMAT, cb);
 498   env.decode_instructions(cb->code_begin(), cb->code_end());
 499 }
 500 
 501 void Disassembler::decode(address start, address end, outputStream* st, CodeStrings c) {
 502   if (!load_library())  return;
 503   decode_env env(CodeCache::find_blob_unsafe(start), st, c);
 504   env.decode_instructions(start, end);
 505 }
 506 
 507 void Disassembler::decode(nmethod* nm, outputStream* st) {
 508   if (!load_library())  return;
 509   decode_env env(nm, st);
 510   env.output()->print_cr("Decoding compiled method " PTR_FORMAT ":", nm);
 511   env.output()->print_cr("Code:");
 512 
 513 #ifdef SHARK
 514   SharkEntry* entry = (SharkEntry *) nm->code_begin();
 515   unsigned char* p   = entry->code_start();
 516   unsigned char* end = entry->code_limit();
 517 #else
 518   unsigned char* p   = nm->code_begin();
 519   unsigned char* end = nm->code_end();
 520 #endif // SHARK
 521