< prev index next >

src/hotspot/share/asm/codeBuffer.hpp

Print this page
rev 54542 : 8213084: Rework and enhance Print[Opto]Assembly output
Reviewed-by:


 272   CodeStrings() {
 273 #ifndef PRODUCT
 274     _strings = NULL;
 275 #ifdef ASSERT
 276     _defunct = false;
 277 #endif
 278 #endif
 279   }
 280 
 281   bool is_null() {
 282 #ifdef ASSERT
 283     return _strings == NULL;
 284 #else
 285     return true;
 286 #endif
 287   }
 288 
 289   const char* add_string(const char * string) PRODUCT_RETURN_(return NULL;);
 290 
 291   void add_comment(intptr_t offset, const char * comment) PRODUCT_RETURN;

 292   void print_block_comment(outputStream* stream, intptr_t offset) const PRODUCT_RETURN;
 293   // MOVE strings from other to this; invalidate other.
 294   void assign(CodeStrings& other)  PRODUCT_RETURN;
 295   // COPY strings from other to this; leave other valid.
 296   void copy(CodeStrings& other)  PRODUCT_RETURN;
 297   // FREE strings; invalidate this.
 298   void free() PRODUCT_RETURN;

 299   // Guarantee that _strings are used at most once; assign and free invalidate a buffer.
 300   inline void check_valid() const {
 301 #ifdef ASSERT
 302     assert(!_defunct, "Use of invalid CodeStrings");
 303 #endif
 304   }
 305 
 306   static void set_prefix(const char *prefix) {
 307 #ifndef PRODUCT
 308     _prefix = prefix;
 309 #endif
 310   }
 311 };
 312 
 313 // A CodeBuffer describes a memory space into which assembly
 314 // code is generated.  This memory space usually occupies the
 315 // interior of a single BufferBlob, but in some cases it may be
 316 // an arbitrary span of memory, even outside the code cache.
 317 //
 318 // A code buffer comes in two variants:


 360  private:
 361   enum {
 362     sect_bits = 2,      // assert (SECT_LIMIT <= (1<<sect_bits))
 363     sect_mask = (1<<sect_bits)-1
 364   };
 365 
 366   const char*  _name;
 367 
 368   CodeSection  _consts;             // constants, jump tables
 369   CodeSection  _insts;              // instructions (the main section)
 370   CodeSection  _stubs;              // stubs (call site support), deopt, exception handling
 371 
 372   CodeBuffer*  _before_expand;  // dead buffer, from before the last expansion
 373 
 374   BufferBlob*  _blob;           // optional buffer in CodeCache for generated code
 375   address      _total_start;    // first address of combined memory buffer
 376   csize_t      _total_size;     // size in bytes of combined memory buffer
 377 
 378   OopRecorder* _oop_recorder;
 379   CodeStrings  _code_strings;

 380   OopRecorder  _default_oop_recorder;  // override with initialize_oop_recorder
 381   Arena*       _overflow_arena;
 382 
 383   address      _last_insn;      // used to merge consecutive memory barriers, loads or stores.
 384 
 385 #if INCLUDE_AOT
 386   bool         _immutable_PIC;
 387 #endif
 388 
 389   address      _decode_begin;   // start address for decode
 390   address      decode_begin();
 391 
 392   void initialize_misc(const char * name) {
 393     // all pointers other than code_start/end and those inside the sections
 394     assert(name != NULL, "must have a name");
 395     _name            = name;
 396     _before_expand   = NULL;
 397     _blob            = NULL;
 398     _oop_recorder    = NULL;
 399     _decode_begin    = NULL;
 400     _overflow_arena  = NULL;
 401     _code_strings    = CodeStrings();
 402     _last_insn       = NULL;
 403 #if INCLUDE_AOT
 404     _immutable_PIC   = false;
 405 #endif








 406   }
 407 
 408   void initialize(address code_start, csize_t code_size) {
 409     _consts.initialize_outer(this,  SECT_CONSTS);
 410     _insts.initialize_outer(this,   SECT_INSTS);
 411     _stubs.initialize_outer(this,   SECT_STUBS);
 412     _total_start = code_start;
 413     _total_size  = code_size;
 414     // Initialize the main section:
 415     _insts.initialize(code_start, code_size);
 416     assert(!_stubs.is_allocated(),  "no garbage here");
 417     assert(!_consts.is_allocated(), "no garbage here");
 418     _oop_recorder = &_default_oop_recorder;
 419   }
 420 
 421   void initialize_section_size(CodeSection* cs, csize_t size);
 422 
 423   void freeze_section(CodeSection* cs);
 424 
 425   // helper for CodeBuffer::expand()


 587   // The section sizes are subtracted from the original insts section.
 588   // Note:  Call them in reverse section order, because each steals from insts.
 589   void initialize_consts_size(csize_t size)            { initialize_section_size(&_consts,  size); }
 590   void initialize_stubs_size(csize_t size)             { initialize_section_size(&_stubs,   size); }
 591   // Override default oop recorder.
 592   void initialize_oop_recorder(OopRecorder* r);
 593 
 594   OopRecorder* oop_recorder() const   { return _oop_recorder; }
 595   CodeStrings& strings()              { return _code_strings; }
 596 
 597   address last_insn() const { return _last_insn; }
 598   void set_last_insn(address a) { _last_insn = a; }
 599   void clear_last_insn() { set_last_insn(NULL); }
 600 
 601   void free_strings() {
 602     if (!_code_strings.is_null()) {
 603       _code_strings.free(); // sets _strings Null as a side-effect.
 604     }
 605   }
 606 

















 607   // Code generation
 608   void relocate(address at, RelocationHolder const& rspec, int format = 0) {
 609     _insts.relocate(at, rspec, format);
 610   }
 611   void relocate(address at,    relocInfo::relocType rtype, int format = 0) {
 612     _insts.relocate(at, rtype, format);
 613   }
 614 
 615   // Management of overflow storage for binding of Labels.
 616   GrowableArray<int>* create_patch_overflow();
 617 
 618   // NMethod generation
 619   void copy_code_and_locs_to(CodeBlob* blob) {
 620     assert(blob != NULL, "sane");
 621     copy_relocations_to(blob);
 622     copy_code_to(blob);
 623   }
 624   void copy_values_to(nmethod* nm) {
 625     if (!oop_recorder()->is_unused()) {
 626       oop_recorder()->copy_values_to(nm);


 633   void block_comment(intptr_t offset, const char * comment) PRODUCT_RETURN;
 634   const char* code_string(const char* str) PRODUCT_RETURN_(return NULL;);
 635 
 636   // Log a little info about section usage in the CodeBuffer
 637   void log_section_sizes(const char* name);
 638 
 639 #if INCLUDE_AOT
 640   // True if this is a code buffer used for immutable PIC, i.e. AOT
 641   // compilation.
 642   bool immutable_PIC() { return _immutable_PIC; }
 643   void set_immutable_PIC(bool pic) { _immutable_PIC = pic; }
 644 #endif
 645 
 646 #ifndef PRODUCT
 647  public:
 648   // Printing / Decoding
 649   // decodes from decode_begin() to code_end() and sets decode_begin to end
 650   void    decode();
 651   void    print();
 652 #endif
 653 

 654 
 655   // The following header contains architecture-specific implementations
 656 #include CPU_HEADER(codeBuffer)
 657 
 658 };
 659 
 660 
 661 inline void CodeSection::freeze() {
 662   _outer->freeze_section(this);
 663 }
 664 
 665 inline bool CodeSection::maybe_expand_to_ensure_remaining(csize_t amount) {
 666   if (remaining() < amount) { _outer->expand(this, amount); return true; }
 667   return false;
 668 }
 669 
 670 #endif // SHARE_ASM_CODEBUFFER_HPP


 272   CodeStrings() {
 273 #ifndef PRODUCT
 274     _strings = NULL;
 275 #ifdef ASSERT
 276     _defunct = false;
 277 #endif
 278 #endif
 279   }
 280 
 281   bool is_null() {
 282 #ifdef ASSERT
 283     return _strings == NULL;
 284 #else
 285     return true;
 286 #endif
 287   }
 288 
 289   const char* add_string(const char * string) PRODUCT_RETURN_(return NULL;);
 290 
 291   void add_comment(intptr_t offset, const char * comment) PRODUCT_RETURN;
 292   bool has_block_comment(intptr_t offset) const;
 293   void print_block_comment(outputStream* stream, intptr_t offset) const PRODUCT_RETURN;
 294   // MOVE strings from other to this; invalidate other.
 295   void assign(CodeStrings& other)  PRODUCT_RETURN;
 296   // COPY strings from other to this; leave other valid.
 297   void copy(CodeStrings& other)  PRODUCT_RETURN;
 298   // FREE strings; invalidate this.
 299   void free() PRODUCT_RETURN;
 300 
 301   // Guarantee that _strings are used at most once; assign and free invalidate a buffer.
 302   inline void check_valid() const {
 303 #ifdef ASSERT
 304     assert(!_defunct, "Use of invalid CodeStrings");
 305 #endif
 306   }
 307 
 308   static void set_prefix(const char *prefix) {
 309 #ifndef PRODUCT
 310     _prefix = prefix;
 311 #endif
 312   }
 313 };
 314 
 315 // A CodeBuffer describes a memory space into which assembly
 316 // code is generated.  This memory space usually occupies the
 317 // interior of a single BufferBlob, but in some cases it may be
 318 // an arbitrary span of memory, even outside the code cache.
 319 //
 320 // A code buffer comes in two variants:


 362  private:
 363   enum {
 364     sect_bits = 2,      // assert (SECT_LIMIT <= (1<<sect_bits))
 365     sect_mask = (1<<sect_bits)-1
 366   };
 367 
 368   const char*  _name;
 369 
 370   CodeSection  _consts;             // constants, jump tables
 371   CodeSection  _insts;              // instructions (the main section)
 372   CodeSection  _stubs;              // stubs (call site support), deopt, exception handling
 373 
 374   CodeBuffer*  _before_expand;  // dead buffer, from before the last expansion
 375 
 376   BufferBlob*  _blob;           // optional buffer in CodeCache for generated code
 377   address      _total_start;    // first address of combined memory buffer
 378   csize_t      _total_size;     // size in bytes of combined memory buffer
 379 
 380   OopRecorder* _oop_recorder;
 381   CodeStrings  _code_strings;
 382   bool         _collect_comments;      // Indicate if we need to collect block comments at all.
 383   OopRecorder  _default_oop_recorder;  // override with initialize_oop_recorder
 384   Arena*       _overflow_arena;
 385 
 386   address      _last_insn;      // used to merge consecutive memory barriers, loads or stores.
 387 
 388 #if INCLUDE_AOT
 389   bool         _immutable_PIC;
 390 #endif
 391 
 392   address      _decode_begin;   // start address for decode
 393   address      decode_begin();
 394 
 395   void initialize_misc(const char * name) {
 396     // all pointers other than code_start/end and those inside the sections
 397     assert(name != NULL, "must have a name");
 398     _name            = name;
 399     _before_expand   = NULL;
 400     _blob            = NULL;
 401     _oop_recorder    = NULL;
 402     _decode_begin    = NULL;
 403     _overflow_arena  = NULL;
 404     _code_strings    = CodeStrings();
 405     _last_insn       = NULL;
 406 #if INCLUDE_AOT
 407     _immutable_PIC   = false;
 408 #endif
 409 
 410     // Collect block comments, but restrict collection to cases where a disassembly is output.
 411     _collect_comments = ( PrintAssembly
 412                        || PrintStubCode
 413                        || PrintMethodHandleStubs
 414                        || PrintInterpreter
 415                        || PrintSignatureHandlers
 416                         );
 417   }
 418 
 419   void initialize(address code_start, csize_t code_size) {
 420     _consts.initialize_outer(this,  SECT_CONSTS);
 421     _insts.initialize_outer(this,   SECT_INSTS);
 422     _stubs.initialize_outer(this,   SECT_STUBS);
 423     _total_start = code_start;
 424     _total_size  = code_size;
 425     // Initialize the main section:
 426     _insts.initialize(code_start, code_size);
 427     assert(!_stubs.is_allocated(),  "no garbage here");
 428     assert(!_consts.is_allocated(), "no garbage here");
 429     _oop_recorder = &_default_oop_recorder;
 430   }
 431 
 432   void initialize_section_size(CodeSection* cs, csize_t size);
 433 
 434   void freeze_section(CodeSection* cs);
 435 
 436   // helper for CodeBuffer::expand()


 598   // The section sizes are subtracted from the original insts section.
 599   // Note:  Call them in reverse section order, because each steals from insts.
 600   void initialize_consts_size(csize_t size)            { initialize_section_size(&_consts,  size); }
 601   void initialize_stubs_size(csize_t size)             { initialize_section_size(&_stubs,   size); }
 602   // Override default oop recorder.
 603   void initialize_oop_recorder(OopRecorder* r);
 604 
 605   OopRecorder* oop_recorder() const   { return _oop_recorder; }
 606   CodeStrings& strings()              { return _code_strings; }
 607 
 608   address last_insn() const { return _last_insn; }
 609   void set_last_insn(address a) { _last_insn = a; }
 610   void clear_last_insn() { set_last_insn(NULL); }
 611 
 612   void free_strings() {
 613     if (!_code_strings.is_null()) {
 614       _code_strings.free(); // sets _strings Null as a side-effect.
 615     }
 616   }
 617 
 618   // Directly disassemble code buffer.
 619   // Print the comment associated with offset on stream, if there is one.
 620   virtual void print_block_comment(outputStream* stream, address block_begin) {
 621 #ifndef PRODUCT
 622     intptr_t offset = (intptr_t)(block_begin - _total_start);  // I assume total_start is not correct for all code sections.
 623     _code_strings.print_block_comment(stream, offset);
 624 #endif
 625   }
 626   bool has_block_comment(address block_begin) {
 627 #ifndef PRODUCT
 628     intptr_t offset = (intptr_t)(block_begin - _total_start);  // I assume total_start is not correct for all code sections.
 629     return _code_strings.has_block_comment(offset);
 630 #else
 631     return false;
 632 #endif
 633   }
 634 
 635   // Code generation
 636   void relocate(address at, RelocationHolder const& rspec, int format = 0) {
 637     _insts.relocate(at, rspec, format);
 638   }
 639   void relocate(address at,    relocInfo::relocType rtype, int format = 0) {
 640     _insts.relocate(at, rtype, format);
 641   }
 642 
 643   // Management of overflow storage for binding of Labels.
 644   GrowableArray<int>* create_patch_overflow();
 645 
 646   // NMethod generation
 647   void copy_code_and_locs_to(CodeBlob* blob) {
 648     assert(blob != NULL, "sane");
 649     copy_relocations_to(blob);
 650     copy_code_to(blob);
 651   }
 652   void copy_values_to(nmethod* nm) {
 653     if (!oop_recorder()->is_unused()) {
 654       oop_recorder()->copy_values_to(nm);


 661   void block_comment(intptr_t offset, const char * comment) PRODUCT_RETURN;
 662   const char* code_string(const char* str) PRODUCT_RETURN_(return NULL;);
 663 
 664   // Log a little info about section usage in the CodeBuffer
 665   void log_section_sizes(const char* name);
 666 
 667 #if INCLUDE_AOT
 668   // True if this is a code buffer used for immutable PIC, i.e. AOT
 669   // compilation.
 670   bool immutable_PIC() { return _immutable_PIC; }
 671   void set_immutable_PIC(bool pic) { _immutable_PIC = pic; }
 672 #endif
 673 
 674 #ifndef PRODUCT
 675  public:
 676   // Printing / Decoding
 677   // decodes from decode_begin() to code_end() and sets decode_begin to end
 678   void    decode();
 679   void    print();
 680 #endif
 681   // Directly disassemble code buffer.
 682   void    decode(address start, address end);
 683 
 684   // The following header contains architecture-specific implementations
 685 #include CPU_HEADER(codeBuffer)
 686 
 687 };
 688 
 689 
 690 inline void CodeSection::freeze() {
 691   _outer->freeze_section(this);
 692 }
 693 
 694 inline bool CodeSection::maybe_expand_to_ensure_remaining(csize_t amount) {
 695   if (remaining() < amount) { _outer->expand(this, amount); return true; }
 696   return false;
 697 }
 698 
 699 #endif // SHARE_ASM_CODEBUFFER_HPP
< prev index next >