1048 class CodeString: public CHeapObj<mtCode> { |
1048 class CodeString: public CHeapObj<mtCode> { |
1049 private: |
1049 private: |
1050 friend class CodeStrings; |
1050 friend class CodeStrings; |
1051 const char * _string; |
1051 const char * _string; |
1052 CodeString* _next; |
1052 CodeString* _next; |
|
1053 CodeString* _prev; |
1053 intptr_t _offset; |
1054 intptr_t _offset; |
1054 |
1055 |
1055 ~CodeString() { |
1056 ~CodeString() { |
1056 assert(_next == NULL, "wrong interface for freeing list"); |
1057 assert(_next == NULL && _prev == NULL, "wrong interface for freeing list"); |
1057 os::free((void*)_string); |
1058 os::free((void*)_string); |
1058 } |
1059 } |
1059 |
1060 |
1060 bool is_comment() const { return _offset >= 0; } |
1061 bool is_comment() const { return _offset >= 0; } |
1061 |
1062 |
1062 public: |
1063 public: |
1063 CodeString(const char * string, intptr_t offset = -1) |
1064 CodeString(const char * string, intptr_t offset = -1) |
1064 : _next(NULL), _offset(offset) { |
1065 : _next(NULL), _prev(NULL), _offset(offset) { |
1065 _string = os::strdup(string, mtCode); |
1066 _string = os::strdup(string, mtCode); |
1066 } |
1067 } |
1067 |
1068 |
1068 const char * string() const { return _string; } |
1069 const char * string() const { return _string; } |
1069 intptr_t offset() const { assert(_offset >= 0, "offset for non comment?"); return _offset; } |
1070 intptr_t offset() const { assert(_offset >= 0, "offset for non comment?"); return _offset; } |
1070 CodeString* next() const { return _next; } |
1071 CodeString* next() const { return _next; } |
1071 |
1072 |
1072 void set_next(CodeString* next) { _next = next; } |
1073 void set_next(CodeString* next) { |
|
1074 _next = next; |
|
1075 if (next != NULL) { |
|
1076 next->_prev = this; |
|
1077 } |
|
1078 } |
1073 |
1079 |
1074 CodeString* first_comment() { |
1080 CodeString* first_comment() { |
1075 if (is_comment()) { |
1081 if (is_comment()) { |
1076 return this; |
1082 return this; |
1077 } else { |
1083 } else { |
1095 return a; |
1101 return a; |
1096 } |
1102 } |
1097 |
1103 |
1098 // Convenience for add_comment. |
1104 // Convenience for add_comment. |
1099 CodeString* CodeStrings::find_last(intptr_t offset) const { |
1105 CodeString* CodeStrings::find_last(intptr_t offset) const { |
1100 CodeString* a = find(offset); |
1106 CodeString* a = _strings_last; |
1101 if (a != NULL) { |
1107 while (a != NULL && !a->is_comment() && a->offset() > offset) { |
1102 CodeString* c = NULL; |
1108 a = a->_prev; |
1103 while (((c = a->next_comment()) != NULL) && (c->offset() == offset)) { |
|
1104 a = c; |
|
1105 } |
|
1106 } |
1109 } |
1107 return a; |
1110 return a; |
1108 } |
1111 } |
1109 |
1112 |
1110 void CodeStrings::add_comment(intptr_t offset, const char * comment) { |
1113 void CodeStrings::add_comment(intptr_t offset, const char * comment) { |
1119 } else { |
1122 } else { |
1120 // no comments with such offset, yet. Insert before anything else. |
1123 // no comments with such offset, yet. Insert before anything else. |
1121 c->set_next(_strings); |
1124 c->set_next(_strings); |
1122 _strings = c; |
1125 _strings = c; |
1123 } |
1126 } |
|
1127 if (c->next() == NULL) { |
|
1128 _strings_last = c; |
|
1129 } |
1124 } |
1130 } |
1125 |
1131 |
1126 void CodeStrings::assign(CodeStrings& other) { |
1132 void CodeStrings::assign(CodeStrings& other) { |
1127 other.check_valid(); |
1133 other.check_valid(); |
1128 assert(is_null(), "Cannot assign onto non-empty CodeStrings"); |
1134 assert(is_null(), "Cannot assign onto non-empty CodeStrings"); |
1129 _strings = other._strings; |
1135 _strings = other._strings; |
|
1136 _strings_last = other._strings_last; |
1130 #ifdef ASSERT |
1137 #ifdef ASSERT |
1131 _defunct = false; |
1138 _defunct = false; |
1132 #endif |
1139 #endif |
1133 other.set_null_and_invalidate(); |
1140 other.set_null_and_invalidate(); |
1134 } |
1141 } |
1140 other.check_valid(); |
1147 other.check_valid(); |
1141 check_valid(); |
1148 check_valid(); |
1142 assert(is_null(), "Cannot copy onto non-empty CodeStrings"); |
1149 assert(is_null(), "Cannot copy onto non-empty CodeStrings"); |
1143 CodeString* n = other._strings; |
1150 CodeString* n = other._strings; |
1144 CodeString** ps = &_strings; |
1151 CodeString** ps = &_strings; |
|
1152 CodeString* prev = NULL; |
1145 while (n != NULL) { |
1153 while (n != NULL) { |
1146 *ps = new CodeString(n->string(),n->offset()); |
1154 *ps = new CodeString(n->string(),n->offset()); |
|
1155 (*ps)->_prev = prev; |
|
1156 prev = *ps; |
1147 ps = &((*ps)->_next); |
1157 ps = &((*ps)->_next); |
1148 n = n->next(); |
1158 n = n->next(); |
1149 } |
1159 } |
1150 } |
1160 } |
1151 |
1161 |
1178 CodeString* n = _strings; |
1188 CodeString* n = _strings; |
1179 while (n) { |
1189 while (n) { |
1180 // unlink the node from the list saving a pointer to the next |
1190 // unlink the node from the list saving a pointer to the next |
1181 CodeString* p = n->next(); |
1191 CodeString* p = n->next(); |
1182 n->set_next(NULL); |
1192 n->set_next(NULL); |
|
1193 if (p != NULL) { |
|
1194 assert(p->_prev == n, "missing prev link"); |
|
1195 p->_prev = NULL; |
|
1196 } |
1183 delete n; |
1197 delete n; |
1184 n = p; |
1198 n = p; |
1185 } |
1199 } |
1186 set_null_and_invalidate(); |
1200 set_null_and_invalidate(); |
1187 } |
1201 } |
1188 |
1202 |
1189 const char* CodeStrings::add_string(const char * string) { |
1203 const char* CodeStrings::add_string(const char * string) { |
1190 check_valid(); |
1204 check_valid(); |
1191 CodeString* s = new CodeString(string); |
1205 CodeString* s = new CodeString(string); |
1192 s->set_next(_strings); |
1206 s->set_next(_strings); |
|
1207 if (_strings == NULL) { |
|
1208 _strings_last = s; |
|
1209 } |
1193 _strings = s; |
1210 _strings = s; |
1194 assert(s->string() != NULL, "should have a string"); |
1211 assert(s->string() != NULL, "should have a string"); |
1195 return s->string(); |
1212 return s->string(); |
1196 } |
1213 } |
1197 |
1214 |