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();