< prev index next >

src/hotspot/share/asm/codeBuffer.cpp

Print this page




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   CodeString*  _prev;
1054   intptr_t     _offset;
1055 
1056   ~CodeString() {
1057     assert(_next == NULL && _prev == NULL, "wrong interface for freeing list");
1058     os::free((void*)_string);
1059   }
1060 
1061   bool is_comment() const { return _offset >= 0; }
1062 
1063  public:
1064   CodeString(const char * string, intptr_t offset = -1)
1065     : _next(NULL), _prev(NULL), _offset(offset) {
1066     _string = os::strdup(string, mtCode);
1067   }
1068 
1069   const char * string() const { return _string; }
1070   intptr_t     offset() const { assert(_offset >= 0, "offset for non comment?"); return _offset;  }
1071   CodeString* next()    const { return _next; }
1072 
1073   void set_next(CodeString* next) {
1074     _next = next;
1075     if (next != NULL) {
1076       next->_prev = this;
1077     }
1078   }
1079 
1080   CodeString* first_comment() {
1081     if (is_comment()) {
1082       return this;
1083     } else {
1084       return next_comment();
1085     }
1086   }
1087   CodeString* next_comment() const {
1088     CodeString* s = _next;
1089     while (s != NULL && !s->is_comment()) {
1090       s = s->_next;
1091     }
1092     return s;
1093   }
1094 };
1095 
1096 CodeString* CodeStrings::find(intptr_t offset) const {
1097   CodeString* a = _strings->first_comment();
1098   while (a != NULL && a->offset() != offset) {
1099     a = a->next_comment();
1100   }
1101   return a;
1102 }
1103 
1104 // Convenience for add_comment.
1105 CodeString* CodeStrings::find_last(intptr_t offset) const {
1106   CodeString* a = _strings_last;
1107   while (a != NULL && !a->is_comment() && a->offset() > offset) {
1108     a = a->_prev;



1109   }
1110   return a;
1111 }
1112 
1113 void CodeStrings::add_comment(intptr_t offset, const char * comment) {
1114   check_valid();
1115   CodeString* c      = new CodeString(comment, offset);
1116   CodeString* inspos = (_strings == NULL) ? NULL : find_last(offset);
1117 
1118   if (inspos) {
1119     // insert after already existing comments with same offset
1120     c->set_next(inspos->next());
1121     inspos->set_next(c);
1122   } else {
1123     // no comments with such offset, yet. Insert before anything else.
1124     c->set_next(_strings);
1125     _strings = c;
1126   }
1127   if (c->next() == NULL) {
1128     _strings_last = c;
1129   }
1130 }
1131 
1132 void CodeStrings::assign(CodeStrings& other) {
1133   other.check_valid();
1134   assert(is_null(), "Cannot assign onto non-empty CodeStrings");
1135   _strings = other._strings;
1136   _strings_last = other._strings_last;
1137 #ifdef ASSERT
1138   _defunct = false;
1139 #endif
1140   other.set_null_and_invalidate();
1141 }
1142 
1143 // Deep copy of CodeStrings for consistent memory management.
1144 // Only used for actual disassembly so this is cheaper than reference counting
1145 // for the "normal" fastdebug case.
1146 void CodeStrings::copy(CodeStrings& other) {
1147   other.check_valid();
1148   check_valid();
1149   assert(is_null(), "Cannot copy onto non-empty CodeStrings");
1150   CodeString* n = other._strings;
1151   CodeString** ps = &_strings;
1152   CodeString* prev = NULL;
1153   while (n != NULL) {
1154     *ps = new CodeString(n->string(),n->offset());
1155     (*ps)->_prev = prev;
1156     prev = *ps;
1157     ps = &((*ps)->_next);
1158     n = n->next();
1159   }
1160 }
1161 
1162 const char* CodeStrings::_prefix = " ;; ";  // default: can be changed via set_prefix
1163 
1164 // Check if any block comments are pending for the given offset.
1165 bool CodeStrings::has_block_comment(intptr_t offset) const {
1166   if (_strings == NULL) return false;
1167   CodeString* c = find(offset);
1168   return c != NULL;
1169 }
1170 
1171 void CodeStrings::print_block_comment(outputStream* stream, intptr_t offset) const {
1172   check_valid();
1173   if (_strings != NULL) {
1174     CodeString* c = find(offset);
1175     while (c && c->offset() == offset) {
1176       stream->bol();
1177       stream->print("%s", _prefix);
1178       // Don't interpret as format strings since it could contain %
1179       stream->print_raw(c->string());
1180       stream->bol(); // advance to next line only if string didn't contain a cr() at the end.
1181       c = c->next_comment();
1182     }
1183   }
1184 }
1185 
1186 // Also sets isNull()
1187 void CodeStrings::free() {
1188   CodeString* n = _strings;
1189   while (n) {
1190     // unlink the node from the list saving a pointer to the next
1191     CodeString* p = n->next();
1192     n->set_next(NULL);
1193     if (p != NULL) {
1194       assert(p->_prev == n, "missing prev link");
1195       p->_prev = NULL;
1196     }
1197     delete n;
1198     n = p;
1199   }
1200   set_null_and_invalidate();
1201 }
1202 
1203 const char* CodeStrings::add_string(const char * string) {
1204   check_valid();
1205   CodeString* s = new CodeString(string);
1206   s->set_next(_strings);
1207   if (_strings == NULL) {
1208     _strings_last = s;
1209   }
1210   _strings = s;
1211   assert(s->string() != NULL, "should have a string");
1212   return s->string();
1213 }
1214 
1215 void CodeBuffer::decode() {
1216   ttyLocker ttyl;
1217   Disassembler::decode(decode_begin(), insts_end(), tty);
1218   _decode_begin = insts_end();
1219 }
1220 
1221 void CodeSection::print(const char* name) {
1222   csize_t locs_size = locs_end() - locs_start();
1223   tty->print_cr(" %7s.code = " PTR_FORMAT " : " PTR_FORMAT " : " PTR_FORMAT " (%d of %d)%s",
1224                 name, p2i(start()), p2i(end()), p2i(limit()), size(), capacity(),
1225                 is_frozen()? " [frozen]": "");
1226   tty->print_cr(" %7s.locs = " PTR_FORMAT " : " PTR_FORMAT " : " PTR_FORMAT " (%d of %d) point=%d",
1227                 name, p2i(locs_start()), p2i(locs_end()), p2i(locs_limit()), locs_size, locs_capacity(), locs_point_off());
1228   if (PrintRelocations) {
1229     RelocIterator iter(this);




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 
1062  public:
1063   CodeString(const char * string, intptr_t offset = -1)
1064     : _next(NULL), _offset(offset) {
1065     _string = os::strdup(string, mtCode);
1066   }
1067 
1068   const char * string() const { return _string; }
1069   intptr_t     offset() const { assert(_offset >= 0, "offset for non comment?"); return _offset;  }
1070   CodeString* next()    const { return _next; }
1071 
1072   void set_next(CodeString* next) { _next = next; }





1073 
1074   CodeString* first_comment() {
1075     if (is_comment()) {
1076       return this;
1077     } else {
1078       return next_comment();
1079     }
1080   }
1081   CodeString* next_comment() const {
1082     CodeString* s = _next;
1083     while (s != NULL && !s->is_comment()) {
1084       s = s->_next;
1085     }
1086     return s;
1087   }
1088 };
1089 
1090 CodeString* CodeStrings::find(intptr_t offset) const {
1091   CodeString* a = _strings->first_comment();
1092   while (a != NULL && a->offset() != offset) {
1093     a = a->next_comment();
1094   }
1095   return a;
1096 }
1097 
1098 // Convenience for add_comment.
1099 CodeString* CodeStrings::find_last(intptr_t offset) const {
1100   CodeString* a = find(offset);
1101   if (a != NULL) {
1102     CodeString* c = NULL;
1103     while (((c = a->next_comment()) != NULL) && (c->offset() == offset)) {
1104       a = c;
1105     }
1106   }
1107   return a;
1108 }
1109 
1110 void CodeStrings::add_comment(intptr_t offset, const char * comment) {
1111   check_valid();
1112   CodeString* c      = new CodeString(comment, offset);
1113   CodeString* inspos = (_strings == NULL) ? NULL : find_last(offset);
1114 
1115   if (inspos) {
1116     // insert after already existing comments with same offset
1117     c->set_next(inspos->next());
1118     inspos->set_next(c);
1119   } else {
1120     // no comments with such offset, yet. Insert before anything else.
1121     c->set_next(_strings);
1122     _strings = c;
1123   }



1124 }
1125 
1126 void CodeStrings::assign(CodeStrings& other) {
1127   other.check_valid();
1128   assert(is_null(), "Cannot assign onto non-empty CodeStrings");
1129   _strings = other._strings;

1130 #ifdef ASSERT
1131   _defunct = false;
1132 #endif
1133   other.set_null_and_invalidate();
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);


< prev index next >