< prev index next >

src/hotspot/share/asm/codeBuffer.cpp

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


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

  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   _code_strings.add_comment(offset, comment);

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


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







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

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






1218 }
1219 
1220 #endif // PRODUCT


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


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


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