< prev index next >

src/hotspot/share/asm/codeBuffer.cpp

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


  68 //    _stubs._start ->              |----------------|
  69 //                                  |                |
  70 //                                  |    Stubs       | (also handlers for deopt/exception)
  71 //                                  |                |
  72 //    _consts._start ->             |----------------|
  73 //                                  |                |
  74 //                                  |   Constants    |
  75 //                                  |                |
  76 //                                  +----------------+
  77 //    + _total_size ->              |                |
  78 //
  79 // When the code and relocations are copied to the code cache,
  80 // the empty parts of each section are removed, and everything
  81 // is copied into contiguous locations.
  82 
  83 typedef CodeBuffer::csize_t csize_t;  // file-local definition
  84 
  85 // External buffer, in a predefined CodeBlob.
  86 // Important: The code_start must be taken exactly, and not realigned.
  87 CodeBuffer::CodeBuffer(CodeBlob* blob) {
  88   initialize_misc("static buffer");

  89   initialize(blob->content_begin(), blob->content_size());
  90   verify_section_allocation();
  91 }
  92 
  93 void CodeBuffer::initialize(csize_t code_size, csize_t locs_size) {
  94   // Compute maximal alignment.
  95   int align = _insts.alignment();
  96   // Always allow for empty slop around each section.
  97   int slop = (int) CodeSection::end_slop();
  98 
  99   assert(blob() == NULL, "only once");
 100   set_blob(BufferBlob::create(_name, code_size + (align+slop) * (SECT_LIMIT+1)));
 101   if (blob() == NULL) {
 102     // The assembler constructor will throw a fatal on an empty CodeBuffer.
 103     return;  // caller must test this
 104   }
 105 
 106   // Set up various pointers into the blob.
 107   initialize(_total_start, _total_size);
 108 


1017     ttyLocker ttyl;
1018     // log info about buffer usage
1019     xtty->print_cr("<blob name='%s' size='%d'>", name, _total_size);
1020     for (int n = (int) CodeBuffer::SECT_FIRST; n < (int) CodeBuffer::SECT_LIMIT; n++) {
1021       CodeSection* sect = code_section(n);
1022       if (!sect->is_allocated() || sect->is_empty())  continue;
1023       xtty->print_cr("<sect index='%d' size='" SIZE_FORMAT "' free='" SIZE_FORMAT "'/>",
1024                      n, sect->limit() - sect->start(), sect->limit() - sect->end());
1025     }
1026     xtty->print_cr("</blob>");
1027   }
1028 }
1029 
1030 #ifndef PRODUCT
1031 
1032 void CodeSection::decode() {
1033   Disassembler::decode(start(), end());
1034 }
1035 
1036 void CodeBuffer::block_comment(intptr_t offset, const char * comment) {

1037   _code_strings.add_comment(offset, comment);

1038 }
1039 
1040 const char* CodeBuffer::code_string(const char* str) {
1041   return _code_strings.add_string(str);
1042 }
1043 
1044 class CodeString: public CHeapObj<mtCode> {
1045  private:
1046   friend class CodeStrings;
1047   const char * _string;
1048   CodeString*  _next;
1049   intptr_t     _offset;
1050 
1051   ~CodeString() {
1052     assert(_next == NULL, "wrong interface for freeing list");
1053     os::free((void*)_string);
1054   }
1055 
1056   bool is_comment() const { return _offset >= 0; }
1057 


1130 }
1131 
1132 // Deep copy of CodeStrings for consistent memory management.
1133 // Only used for actual disassembly so this is cheaper than reference counting
1134 // for the "normal" fastdebug case.
1135 void CodeStrings::copy(CodeStrings& other) {
1136   other.check_valid();
1137   check_valid();
1138   assert(is_null(), "Cannot copy onto non-empty CodeStrings");
1139   CodeString* n = other._strings;
1140   CodeString** ps = &_strings;
1141   while (n != NULL) {
1142     *ps = new CodeString(n->string(),n->offset());
1143     ps = &((*ps)->_next);
1144     n = n->next();
1145   }
1146 }
1147 
1148 const char* CodeStrings::_prefix = " ;; ";  // default: can be changed via set_prefix
1149 







1150 void CodeStrings::print_block_comment(outputStream* stream, intptr_t offset) const {
1151     check_valid();
1152     if (_strings != NULL) {
1153     CodeString* c = find(offset);
1154     while (c && c->offset() == offset) {
1155       stream->bol();
1156       stream->print("%s", _prefix);
1157       // Don't interpret as format strings since it could contain %
1158       stream->print_raw_cr(c->string());

1159       c = c->next_comment();
1160     }
1161   }
1162 }
1163 
1164 // Also sets isNull()
1165 void CodeStrings::free() {
1166   CodeString* n = _strings;
1167   while (n) {
1168     // unlink the node from the list saving a pointer to the next
1169     CodeString* p = n->next();
1170     n->set_next(NULL);
1171     delete n;
1172     n = p;
1173   }
1174   set_null_and_invalidate();
1175 }
1176 
1177 const char* CodeStrings::add_string(const char * string) {
1178   check_valid();
1179   CodeString* s = new CodeString(string);
1180   s->set_next(_strings);
1181   _strings = s;
1182   assert(s->string() != NULL, "should have a string");
1183   return s->string();
1184 }
1185 
1186 void CodeBuffer::decode() {
1187   ttyLocker ttyl;
1188   Disassembler::decode(decode_begin(), insts_end());
1189   _decode_begin = insts_end();
1190 }
1191 
1192 void CodeSection::print(const char* name) {
1193   csize_t locs_size = locs_end() - locs_start();
1194   tty->print_cr(" %7s.code = " PTR_FORMAT " : " PTR_FORMAT " : " PTR_FORMAT " (%d of %d)%s",
1195                 name, p2i(start()), p2i(end()), p2i(limit()), size(), capacity(),
1196                 is_frozen()? " [frozen]": "");
1197   tty->print_cr(" %7s.locs = " PTR_FORMAT " : " PTR_FORMAT " : " PTR_FORMAT " (%d of %d) point=%d",
1198                 name, p2i(locs_start()), p2i(locs_end()), p2i(locs_limit()), locs_size, locs_capacity(), locs_point_off());
1199   if (PrintRelocations) {
1200     RelocIterator iter(this);
1201     iter.print();
1202   }
1203 }
1204 
1205 void CodeBuffer::print() {
1206   if (this == NULL) {
1207     tty->print_cr("NULL CodeBuffer pointer");
1208     return;
1209   }
1210 
1211   tty->print_cr("CodeBuffer:");
1212   for (int n = 0; n < (int)SECT_LIMIT; n++) {
1213     // print each section
1214     CodeSection* cs = code_section(n);
1215     cs->print(code_section_name(n));
1216   }






1217 }
1218 
1219 #endif // PRODUCT


  68 //    _stubs._start ->              |----------------|
  69 //                                  |                |
  70 //                                  |    Stubs       | (also handlers for deopt/exception)
  71 //                                  |                |
  72 //    _consts._start ->             |----------------|
  73 //                                  |                |
  74 //                                  |   Constants    |
  75 //                                  |                |
  76 //                                  +----------------+
  77 //    + _total_size ->              |                |
  78 //
  79 // When the code and relocations are copied to the code cache,
  80 // the empty parts of each section are removed, and everything
  81 // is copied into contiguous locations.
  82 
  83 typedef CodeBuffer::csize_t csize_t;  // file-local definition
  84 
  85 // External buffer, in a predefined CodeBlob.
  86 // Important: The code_start must be taken exactly, and not realigned.
  87 CodeBuffer::CodeBuffer(CodeBlob* blob) {
  88   // Provide code buffer with meaningful name
  89   initialize_misc(blob->name());
  90   initialize(blob->content_begin(), blob->content_size());
  91   verify_section_allocation();
  92 }
  93 
  94 void CodeBuffer::initialize(csize_t code_size, csize_t locs_size) {
  95   // Compute maximal alignment.
  96   int align = _insts.alignment();
  97   // Always allow for empty slop around each section.
  98   int slop = (int) CodeSection::end_slop();
  99 
 100   assert(blob() == NULL, "only once");
 101   set_blob(BufferBlob::create(_name, code_size + (align+slop) * (SECT_LIMIT+1)));
 102   if (blob() == NULL) {
 103     // The assembler constructor will throw a fatal on an empty CodeBuffer.
 104     return;  // caller must test this
 105   }
 106 
 107   // Set up various pointers into the blob.
 108   initialize(_total_start, _total_size);
 109 


1018     ttyLocker ttyl;
1019     // log info about buffer usage
1020     xtty->print_cr("<blob name='%s' size='%d'>", name, _total_size);
1021     for (int n = (int) CodeBuffer::SECT_FIRST; n < (int) CodeBuffer::SECT_LIMIT; n++) {
1022       CodeSection* sect = code_section(n);
1023       if (!sect->is_allocated() || sect->is_empty())  continue;
1024       xtty->print_cr("<sect index='%d' size='" SIZE_FORMAT "' free='" SIZE_FORMAT "'/>",
1025                      n, sect->limit() - sect->start(), sect->limit() - sect->end());
1026     }
1027     xtty->print_cr("</blob>");
1028   }
1029 }
1030 
1031 #ifndef PRODUCT
1032 
1033 void CodeSection::decode() {
1034   Disassembler::decode(start(), end());
1035 }
1036 
1037 void CodeBuffer::block_comment(intptr_t offset, const char * comment) {
1038   if (_collect_comments) {
1039     _code_strings.add_comment(offset, comment);
1040   }
1041 }
1042 
1043 const char* CodeBuffer::code_string(const char* str) {
1044   return _code_strings.add_string(str);
1045 }
1046 
1047 class CodeString: public CHeapObj<mtCode> {
1048  private:
1049   friend class CodeStrings;
1050   const char * _string;
1051   CodeString*  _next;
1052   intptr_t     _offset;
1053 
1054   ~CodeString() {
1055     assert(_next == NULL, "wrong interface for freeing list");
1056     os::free((void*)_string);
1057   }
1058 
1059   bool is_comment() const { return _offset >= 0; }
1060 


1133 }
1134 
1135 // Deep copy of CodeStrings for consistent memory management.
1136 // Only used for actual disassembly so this is cheaper than reference counting
1137 // for the "normal" fastdebug case.
1138 void CodeStrings::copy(CodeStrings& other) {
1139   other.check_valid();
1140   check_valid();
1141   assert(is_null(), "Cannot copy onto non-empty CodeStrings");
1142   CodeString* n = other._strings;
1143   CodeString** ps = &_strings;
1144   while (n != NULL) {
1145     *ps = new CodeString(n->string(),n->offset());
1146     ps = &((*ps)->_next);
1147     n = n->next();
1148   }
1149 }
1150 
1151 const char* CodeStrings::_prefix = " ;; ";  // default: can be changed via set_prefix
1152 
1153 // Check if any block comments are pending for the given offset.
1154 bool CodeStrings::has_block_comment(intptr_t offset) const {
1155   if (_strings == NULL) return false;
1156   CodeString* c = find(offset);
1157   return c != NULL;
1158 }
1159 
1160 void CodeStrings::print_block_comment(outputStream* stream, intptr_t offset) const {
1161   check_valid();
1162   if (_strings != NULL) {
1163     CodeString* c = find(offset);
1164     while (c && c->offset() == offset) {
1165       stream->bol();
1166       stream->print("%s", _prefix);
1167       // Don't interpret as format strings since it could contain %
1168       stream->print_raw(c->string());
1169       stream->bol(); // advance to next line only if string didn't contain a cr() at the end.
1170       c = c->next_comment();
1171     }
1172   }
1173 }
1174 
1175 // Also sets isNull()
1176 void CodeStrings::free() {
1177   CodeString* n = _strings;
1178   while (n) {
1179     // unlink the node from the list saving a pointer to the next
1180     CodeString* p = n->next();
1181     n->set_next(NULL);
1182     delete n;
1183     n = p;
1184   }
1185   set_null_and_invalidate();
1186 }
1187 
1188 const char* CodeStrings::add_string(const char * string) {
1189   check_valid();
1190   CodeString* s = new CodeString(string);
1191   s->set_next(_strings);
1192   _strings = s;
1193   assert(s->string() != NULL, "should have a string");
1194   return s->string();
1195 }
1196 
1197 void CodeBuffer::decode() {
1198   ttyLocker ttyl;
1199   Disassembler::decode(decode_begin(), insts_end(), tty);
1200   _decode_begin = insts_end();
1201 }
1202 
1203 void CodeSection::print(const char* name) {
1204   csize_t locs_size = locs_end() - locs_start();
1205   tty->print_cr(" %7s.code = " PTR_FORMAT " : " PTR_FORMAT " : " PTR_FORMAT " (%d of %d)%s",
1206                 name, p2i(start()), p2i(end()), p2i(limit()), size(), capacity(),
1207                 is_frozen()? " [frozen]": "");
1208   tty->print_cr(" %7s.locs = " PTR_FORMAT " : " PTR_FORMAT " : " PTR_FORMAT " (%d of %d) point=%d",
1209                 name, p2i(locs_start()), p2i(locs_end()), p2i(locs_limit()), locs_size, locs_capacity(), locs_point_off());
1210   if (PrintRelocations) {
1211     RelocIterator iter(this);
1212     iter.print();
1213   }
1214 }
1215 
1216 void CodeBuffer::print() {
1217   if (this == NULL) {
1218     tty->print_cr("NULL CodeBuffer pointer");
1219     return;
1220   }
1221 
1222   tty->print_cr("CodeBuffer:");
1223   for (int n = 0; n < (int)SECT_LIMIT; n++) {
1224     // print each section
1225     CodeSection* cs = code_section(n);
1226     cs->print(code_section_name(n));
1227   }
1228 }
1229 
1230 // Directly disassemble code buffer.
1231 void CodeBuffer::decode(address start, address end) {
1232   ttyLocker ttyl;
1233   Disassembler::decode(this, start, end, tty);
1234 }
1235 
1236 #endif // PRODUCT
< prev index next >