Mercurial > hg > graal-compiler
comparison src/share/vm/asm/codeBuffer.cpp @ 8767:a5de0cc2f91c
8008555: Debugging code in compiled method sometimes leaks memory
Summary: support for strings that have same life-time as code that uses them.
Reviewed-by: kvn, twisti
author | roland |
---|---|
date | Mon, 18 Mar 2013 13:19:06 +0100 |
parents | 30866cd626b0 |
children | b9a918201d47 de6a9e811145 |
comparison
equal
deleted
inserted
replaced
8765:592f9722c72e | 8767:a5de0cc2f91c |
---|---|
701 CodeBuffer dest(dest_blob); | 701 CodeBuffer dest(dest_blob); |
702 assert(dest_blob->content_size() >= total_content_size(), "good sizing"); | 702 assert(dest_blob->content_size() >= total_content_size(), "good sizing"); |
703 this->compute_final_layout(&dest); | 703 this->compute_final_layout(&dest); |
704 relocate_code_to(&dest); | 704 relocate_code_to(&dest); |
705 | 705 |
706 // transfer comments from buffer to blob | 706 // transfer strings and comments from buffer to blob |
707 dest_blob->set_comments(_comments); | 707 dest_blob->set_strings(_strings); |
708 | 708 |
709 // Done moving code bytes; were they the right size? | 709 // Done moving code bytes; were they the right size? |
710 assert(round_to(dest.total_content_size(), oopSize) == dest_blob->content_size(), "sanity"); | 710 assert(round_to(dest.total_content_size(), oopSize) == dest_blob->content_size(), "sanity"); |
711 | 711 |
712 // Flush generated code | 712 // Flush generated code |
1001 Disassembler::decode(start(), end()); | 1001 Disassembler::decode(start(), end()); |
1002 } | 1002 } |
1003 | 1003 |
1004 | 1004 |
1005 void CodeBuffer::block_comment(intptr_t offset, const char * comment) { | 1005 void CodeBuffer::block_comment(intptr_t offset, const char * comment) { |
1006 _comments.add_comment(offset, comment); | 1006 _strings.add_comment(offset, comment); |
1007 } | 1007 } |
1008 | 1008 |
1009 class CodeComment: public CHeapObj<mtCode> { | 1009 const char* CodeBuffer::code_string(const char* str) { |
1010 return _strings.add_string(str); | |
1011 } | |
1012 | |
1013 class CodeString: public CHeapObj<mtCode> { | |
1010 private: | 1014 private: |
1011 friend class CodeComments; | 1015 friend class CodeStrings; |
1016 const char * _string; | |
1017 CodeString* _next; | |
1012 intptr_t _offset; | 1018 intptr_t _offset; |
1013 const char * _comment; | 1019 |
1014 CodeComment* _next; | 1020 ~CodeString() { |
1015 | |
1016 ~CodeComment() { | |
1017 assert(_next == NULL, "wrong interface for freeing list"); | 1021 assert(_next == NULL, "wrong interface for freeing list"); |
1018 os::free((void*)_comment, mtCode); | 1022 os::free((void*)_string, mtCode); |
1019 } | 1023 } |
1024 | |
1025 bool is_comment() const { return _offset >= 0; } | |
1020 | 1026 |
1021 public: | 1027 public: |
1022 CodeComment(intptr_t offset, const char * comment) { | 1028 CodeString(const char * string, intptr_t offset = -1) |
1023 _offset = offset; | 1029 : _next(NULL), _offset(offset) { |
1024 _comment = os::strdup(comment, mtCode); | 1030 _string = os::strdup(string, mtCode); |
1025 _next = NULL; | 1031 } |
1026 } | 1032 |
1027 | 1033 const char * string() const { return _string; } |
1028 intptr_t offset() const { return _offset; } | 1034 intptr_t offset() const { assert(_offset >= 0, "offset for non comment?"); return _offset; } |
1029 const char * comment() const { return _comment; } | 1035 CodeString* next() const { return _next; } |
1030 CodeComment* next() { return _next; } | 1036 |
1031 | 1037 void set_next(CodeString* next) { _next = next; } |
1032 void set_next(CodeComment* next) { _next = next; } | 1038 |
1033 | 1039 CodeString* first_comment() { |
1034 CodeComment* find(intptr_t offset) { | 1040 if (is_comment()) { |
1035 CodeComment* a = this; | 1041 return this; |
1036 while (a != NULL && a->_offset != offset) { | 1042 } else { |
1037 a = a->_next; | 1043 return next_comment(); |
1038 } | 1044 } |
1039 return a; | 1045 } |
1040 } | 1046 CodeString* next_comment() const { |
1041 | 1047 CodeString* s = _next; |
1042 // Convenience for add_comment. | 1048 while (s != NULL && !s->is_comment()) { |
1043 CodeComment* find_last(intptr_t offset) { | 1049 s = s->_next; |
1044 CodeComment* a = find(offset); | 1050 } |
1045 if (a != NULL) { | 1051 return s; |
1046 while ((a->_next != NULL) && (a->_next->_offset == offset)) { | |
1047 a = a->_next; | |
1048 } | |
1049 } | |
1050 return a; | |
1051 } | 1052 } |
1052 }; | 1053 }; |
1053 | 1054 |
1054 | 1055 CodeString* CodeStrings::find(intptr_t offset) const { |
1055 void CodeComments::add_comment(intptr_t offset, const char * comment) { | 1056 CodeString* a = _strings->first_comment(); |
1056 CodeComment* c = new CodeComment(offset, comment); | 1057 while (a != NULL && a->offset() != offset) { |
1057 CodeComment* inspos = (_comments == NULL) ? NULL : _comments->find_last(offset); | 1058 a = a->next_comment(); |
1059 } | |
1060 return a; | |
1061 } | |
1062 | |
1063 // Convenience for add_comment. | |
1064 CodeString* CodeStrings::find_last(intptr_t offset) const { | |
1065 CodeString* a = find(offset); | |
1066 if (a != NULL) { | |
1067 CodeString* c = NULL; | |
1068 while (((c = a->next_comment()) != NULL) && (c->offset() == offset)) { | |
1069 a = c; | |
1070 } | |
1071 } | |
1072 return a; | |
1073 } | |
1074 | |
1075 void CodeStrings::add_comment(intptr_t offset, const char * comment) { | |
1076 CodeString* c = new CodeString(comment, offset); | |
1077 CodeString* inspos = (_strings == NULL) ? NULL : find_last(offset); | |
1058 | 1078 |
1059 if (inspos) { | 1079 if (inspos) { |
1060 // insert after already existing comments with same offset | 1080 // insert after already existing comments with same offset |
1061 c->set_next(inspos->next()); | 1081 c->set_next(inspos->next()); |
1062 inspos->set_next(c); | 1082 inspos->set_next(c); |
1063 } else { | 1083 } else { |
1064 // no comments with such offset, yet. Insert before anything else. | 1084 // no comments with such offset, yet. Insert before anything else. |
1065 c->set_next(_comments); | 1085 c->set_next(_strings); |
1066 _comments = c; | 1086 _strings = c; |
1067 } | 1087 } |
1068 } | 1088 } |
1069 | 1089 |
1070 | 1090 void CodeStrings::assign(CodeStrings& other) { |
1071 void CodeComments::assign(CodeComments& other) { | 1091 _strings = other._strings; |
1072 _comments = other._comments; | 1092 } |
1073 } | 1093 |
1074 | 1094 void CodeStrings::print_block_comment(outputStream* stream, intptr_t offset) const { |
1075 | 1095 if (_strings != NULL) { |
1076 void CodeComments::print_block_comment(outputStream* stream, intptr_t offset) const { | 1096 CodeString* c = find(offset); |
1077 if (_comments != NULL) { | |
1078 CodeComment* c = _comments->find(offset); | |
1079 while (c && c->offset() == offset) { | 1097 while (c && c->offset() == offset) { |
1080 stream->bol(); | 1098 stream->bol(); |
1081 stream->print(" ;; "); | 1099 stream->print(" ;; "); |
1082 stream->print_cr(c->comment()); | 1100 stream->print_cr(c->string()); |
1083 c = c->next(); | 1101 c = c->next_comment(); |
1084 } | 1102 } |
1085 } | 1103 } |
1086 } | 1104 } |
1087 | 1105 |
1088 | 1106 |
1089 void CodeComments::free() { | 1107 void CodeStrings::free() { |
1090 CodeComment* n = _comments; | 1108 CodeString* n = _strings; |
1091 while (n) { | 1109 while (n) { |
1092 // unlink the node from the list saving a pointer to the next | 1110 // unlink the node from the list saving a pointer to the next |
1093 CodeComment* p = n->_next; | 1111 CodeString* p = n->next(); |
1094 n->_next = NULL; | 1112 n->set_next(NULL); |
1095 delete n; | 1113 delete n; |
1096 n = p; | 1114 n = p; |
1097 } | 1115 } |
1098 _comments = NULL; | 1116 _strings = NULL; |
1099 } | 1117 } |
1100 | 1118 |
1101 | 1119 const char* CodeStrings::add_string(const char * string) { |
1120 CodeString* s = new CodeString(string); | |
1121 s->set_next(_strings); | |
1122 _strings = s; | |
1123 assert(s->string() != NULL, "should have a string"); | |
1124 return s->string(); | |
1125 } | |
1102 | 1126 |
1103 void CodeBuffer::decode() { | 1127 void CodeBuffer::decode() { |
1104 ttyLocker ttyl; | 1128 ttyLocker ttyl; |
1105 Disassembler::decode(decode_begin(), insts_end()); | 1129 Disassembler::decode(decode_begin(), insts_end()); |
1106 _decode_begin = insts_end(); | 1130 _decode_begin = insts_end(); |