Mercurial > hg > truffle
comparison src/share/vm/asm/codeBuffer.cpp @ 20435:094cbdffa87d
8054292: code comments leak in fastdebug builds
Summary: Added deallocation to destructor; hardened interface against misuse
Reviewed-by: kvn
author | drchase |
---|---|
date | Fri, 29 Aug 2014 19:45:49 -0400 |
parents | 833b0f92429a |
children | 7848fc12602b |
comparison
equal
deleted
inserted
replaced
20428:4d8781a35525 | 20435:094cbdffa87d |
---|---|
130 cb->free_blob(); | 130 cb->free_blob(); |
131 } | 131 } |
132 | 132 |
133 // free any overflow storage | 133 // free any overflow storage |
134 delete _overflow_arena; | 134 delete _overflow_arena; |
135 | |
136 // Claim is that stack allocation ensures resources are cleaned up. | |
137 // This is resource clean up, let's hope that all were properly copied out. | |
138 free_strings(); | |
135 | 139 |
136 #ifdef ASSERT | 140 #ifdef ASSERT |
137 // Save allocation type to execute assert in ~ResourceObj() | 141 // Save allocation type to execute assert in ~ResourceObj() |
138 // which is called after this destructor. | 142 // which is called after this destructor. |
139 assert(_default_oop_recorder.allocated_on_stack(), "should be embedded object"); | 143 assert(_default_oop_recorder.allocated_on_stack(), "should be embedded object"); |
702 assert(dest_blob->content_size() >= total_content_size(), "good sizing"); | 706 assert(dest_blob->content_size() >= total_content_size(), "good sizing"); |
703 this->compute_final_layout(&dest); | 707 this->compute_final_layout(&dest); |
704 relocate_code_to(&dest); | 708 relocate_code_to(&dest); |
705 | 709 |
706 // transfer strings and comments from buffer to blob | 710 // transfer strings and comments from buffer to blob |
707 dest_blob->set_strings(_strings); | 711 dest_blob->set_strings(_code_strings); |
708 | 712 |
709 // Done moving code bytes; were they the right size? | 713 // Done moving code bytes; were they the right size? |
710 assert(round_to(dest.total_content_size(), oopSize) == dest_blob->content_size(), "sanity"); | 714 assert(round_to(dest.total_content_size(), oopSize) == dest_blob->content_size(), "sanity"); |
711 | 715 |
712 // Flush generated code | 716 // Flush generated code |
1001 Disassembler::decode(start(), end()); | 1005 Disassembler::decode(start(), end()); |
1002 } | 1006 } |
1003 | 1007 |
1004 | 1008 |
1005 void CodeBuffer::block_comment(intptr_t offset, const char * comment) { | 1009 void CodeBuffer::block_comment(intptr_t offset, const char * comment) { |
1006 _strings.add_comment(offset, comment); | 1010 _code_strings.add_comment(offset, comment); |
1007 } | 1011 } |
1008 | 1012 |
1009 const char* CodeBuffer::code_string(const char* str) { | 1013 const char* CodeBuffer::code_string(const char* str) { |
1010 return _strings.add_string(str); | 1014 return _code_strings.add_string(str); |
1011 } | 1015 } |
1012 | 1016 |
1013 class CodeString: public CHeapObj<mtCode> { | 1017 class CodeString: public CHeapObj<mtCode> { |
1014 private: | 1018 private: |
1015 friend class CodeStrings; | 1019 friend class CodeStrings; |
1071 } | 1075 } |
1072 return a; | 1076 return a; |
1073 } | 1077 } |
1074 | 1078 |
1075 void CodeStrings::add_comment(intptr_t offset, const char * comment) { | 1079 void CodeStrings::add_comment(intptr_t offset, const char * comment) { |
1080 check_valid(); | |
1076 CodeString* c = new CodeString(comment, offset); | 1081 CodeString* c = new CodeString(comment, offset); |
1077 CodeString* inspos = (_strings == NULL) ? NULL : find_last(offset); | 1082 CodeString* inspos = (_strings == NULL) ? NULL : find_last(offset); |
1078 | 1083 |
1079 if (inspos) { | 1084 if (inspos) { |
1080 // insert after already existing comments with same offset | 1085 // insert after already existing comments with same offset |
1086 _strings = c; | 1091 _strings = c; |
1087 } | 1092 } |
1088 } | 1093 } |
1089 | 1094 |
1090 void CodeStrings::assign(CodeStrings& other) { | 1095 void CodeStrings::assign(CodeStrings& other) { |
1096 other.check_valid(); | |
1097 // Cannot do following because CodeStrings constructor is not alway run! | |
1098 assert(is_null(), "Cannot assign onto non-empty CodeStrings"); | |
1091 _strings = other._strings; | 1099 _strings = other._strings; |
1100 other.set_null_and_invalidate(); | |
1101 } | |
1102 | |
1103 // Deep copy of CodeStrings for consistent memory management. | |
1104 // Only used for actual disassembly so this is cheaper than reference counting | |
1105 // for the "normal" fastdebug case. | |
1106 void CodeStrings::copy(CodeStrings& other) { | |
1107 other.check_valid(); | |
1108 check_valid(); | |
1109 assert(is_null(), "Cannot copy onto non-empty CodeStrings"); | |
1110 CodeString* n = other._strings; | |
1111 CodeString** ps = &_strings; | |
1112 while (n != NULL) { | |
1113 *ps = new CodeString(n->string(),n->offset()); | |
1114 ps = &((*ps)->_next); | |
1115 n = n->next(); | |
1116 } | |
1092 } | 1117 } |
1093 | 1118 |
1094 void CodeStrings::print_block_comment(outputStream* stream, intptr_t offset) const { | 1119 void CodeStrings::print_block_comment(outputStream* stream, intptr_t offset) const { |
1095 if (_strings != NULL) { | 1120 check_valid(); |
1121 if (_strings != NULL) { | |
1096 CodeString* c = find(offset); | 1122 CodeString* c = find(offset); |
1097 while (c && c->offset() == offset) { | 1123 while (c && c->offset() == offset) { |
1098 stream->bol(); | 1124 stream->bol(); |
1099 stream->print(" ;; "); | 1125 stream->print(" ;; "); |
1100 stream->print_cr("%s", c->string()); | 1126 stream->print_cr("%s", c->string()); |
1101 c = c->next_comment(); | 1127 c = c->next_comment(); |
1102 } | 1128 } |
1103 } | 1129 } |
1104 } | 1130 } |
1105 | 1131 |
1106 | 1132 // Also sets isNull() |
1107 void CodeStrings::free() { | 1133 void CodeStrings::free() { |
1108 CodeString* n = _strings; | 1134 CodeString* n = _strings; |
1109 while (n) { | 1135 while (n) { |
1110 // unlink the node from the list saving a pointer to the next | 1136 // unlink the node from the list saving a pointer to the next |
1111 CodeString* p = n->next(); | 1137 CodeString* p = n->next(); |
1112 n->set_next(NULL); | 1138 n->set_next(NULL); |
1113 delete n; | 1139 delete n; |
1114 n = p; | 1140 n = p; |
1115 } | 1141 } |
1116 _strings = NULL; | 1142 set_null_and_invalidate(); |
1117 } | 1143 } |
1118 | 1144 |
1119 const char* CodeStrings::add_string(const char * string) { | 1145 const char* CodeStrings::add_string(const char * string) { |
1146 check_valid(); | |
1120 CodeString* s = new CodeString(string); | 1147 CodeString* s = new CodeString(string); |
1121 s->set_next(_strings); | 1148 s->set_next(_strings); |
1122 _strings = s; | 1149 _strings = s; |
1123 assert(s->string() != NULL, "should have a string"); | 1150 assert(s->string() != NULL, "should have a string"); |
1124 return s->string(); | 1151 return s->string(); |