comparison src/share/vm/code/debugInfoRec.cpp @ 17376:b888ded3ee42

Be more aggressive about sharing of debug info
author Tom Rodriguez <tom.rodriguez@oracle.com>
date Wed, 08 Oct 2014 11:52:00 -0700
parents 8638307944be
children 15ef24874df7
comparison
equal deleted inserted replaced
17375:44b83285b645 17376:b888ded3ee42
35 class DIR_Chunk { 35 class DIR_Chunk {
36 friend class DebugInformationRecorder; 36 friend class DebugInformationRecorder;
37 int _offset; // location in the stream of this scope 37 int _offset; // location in the stream of this scope
38 int _length; // number of bytes in the stream 38 int _length; // number of bytes in the stream
39 int _hash; // hash of stream bytes (for quicker reuse) 39 int _hash; // hash of stream bytes (for quicker reuse)
40 #ifdef GRAAL
41 DebugInformationRecorder* _DIR;
42 #endif
40 43
41 void* operator new(size_t ignore, DebugInformationRecorder* dir) throw() { 44 void* operator new(size_t ignore, DebugInformationRecorder* dir) throw() {
42 assert(ignore == sizeof(DIR_Chunk), ""); 45 assert(ignore == sizeof(DIR_Chunk), "");
43 if (dir->_next_chunk >= dir->_next_chunk_limit) { 46 if (dir->_next_chunk >= dir->_next_chunk_limit) {
44 const int CHUNK = 100; 47 const int CHUNK = 100;
49 } 52 }
50 53
51 DIR_Chunk(int offset, int length, DebugInformationRecorder* dir) { 54 DIR_Chunk(int offset, int length, DebugInformationRecorder* dir) {
52 _offset = offset; 55 _offset = offset;
53 _length = length; 56 _length = length;
57 #ifdef GRAAL
58 _DIR = dir;
59 #endif
54 unsigned int hash = 0; 60 unsigned int hash = 0;
55 address p = dir->stream()->buffer() + _offset; 61 address p = dir->stream()->buffer() + _offset;
56 for (int i = 0; i < length; i++) { 62 for (int i = 0; i < length; i++) {
57 if (i == 6) break; 63 if (i == 6) break;
58 hash *= 127; 64 hash *= 127;
75 return that; 81 return that;
76 } 82 }
77 } 83 }
78 return NULL; 84 return NULL;
79 } 85 }
86
87 #ifdef GRAAL
88 static int compare(DIR_Chunk* a, DIR_Chunk* b) {
89 if (b->_hash > a->_hash) {
90 return 1;
91 }
92 if (b->_hash < a->_hash) {
93 return -1;
94 }
95 if (b->_length > a->_length) {
96 return 1;
97 }
98 if (b->_length < a->_length) {
99 return -1;
100 }
101 address buf = a->_DIR->stream()->buffer();
102 return memcmp(buf + b->_offset, buf + a->_offset, a->_length);
103 }
104 #endif
80 }; 105 };
81 106
82 static inline bool compute_recording_non_safepoints() { 107 static inline bool compute_recording_non_safepoints() {
83 if (JvmtiExport::should_post_compiled_method_load() 108 if (JvmtiExport::should_post_compiled_method_load()
84 && FLAG_IS_DEFAULT(DebugNonSafepoints)) { 109 && FLAG_IS_DEFAULT(DebugNonSafepoints)) {
111 assert(_stream->position() > serialized_null, "sanity"); 136 assert(_stream->position() > serialized_null, "sanity");
112 137
113 _oop_recorder = oop_recorder; 138 _oop_recorder = oop_recorder;
114 139
115 _all_chunks = new GrowableArray<DIR_Chunk*>(300); 140 _all_chunks = new GrowableArray<DIR_Chunk*>(300);
141 #ifndef GRAAL
116 _shared_chunks = new GrowableArray<DIR_Chunk*>(30); 142 _shared_chunks = new GrowableArray<DIR_Chunk*>(30);
143 #endif
117 _next_chunk = _next_chunk_limit = NULL; 144 _next_chunk = _next_chunk_limit = NULL;
118 145
119 add_new_pc_offset(PcDesc::lower_offset_limit); // sentinel record 146 add_new_pc_offset(PcDesc::lower_offset_limit); // sentinel record
120 147
121 debug_only(_recording_state = rs_null); 148 debug_only(_recording_state = rs_null);
248 assert(stream_offset != serialized_null, "should not be null"); 275 assert(stream_offset != serialized_null, "should not be null");
249 assert(stream_length != 0, "should not be empty"); 276 assert(stream_length != 0, "should not be empty");
250 277
251 DIR_Chunk* ns = new(this) DIR_Chunk(stream_offset, stream_length, this); 278 DIR_Chunk* ns = new(this) DIR_Chunk(stream_offset, stream_length, this);
252 279
280 #ifdef GRAAL
281 DIR_Chunk* match = _all_chunks->find_insert_binary<DIR_Chunk::compare>(ns);
282 if (match != ns) {
283 // Found an existing chunk
284 NOT_PRODUCT(++dir_stats.chunks_shared);
285 assert(ns+1 == _next_chunk, "");
286 _next_chunk = ns;
287 return match->_offset;
288 } else {
289 // Inserted this chunk, so nothing to do
290 return serialized_null;
291 }
292 #else
253 // Look in previously shared scopes first: 293 // Look in previously shared scopes first:
254 DIR_Chunk* ms = ns->find_match(_shared_chunks, 0, this); 294 DIR_Chunk* ms = ns->find_match(_shared_chunks, 0, this);
255 if (ms != NULL) { 295 if (ms != NULL) {
256 NOT_PRODUCT(++dir_stats.chunks_reshared); 296 NOT_PRODUCT(++dir_stats.chunks_reshared);
257 assert(ns+1 == _next_chunk, ""); 297 assert(ns+1 == _next_chunk, "");
275 } 315 }
276 316
277 // No match. Add this guy to the list, in hopes of future shares. 317 // No match. Add this guy to the list, in hopes of future shares.
278 _all_chunks->append(ns); 318 _all_chunks->append(ns);
279 return serialized_null; 319 return serialized_null;
320 #endif
280 } 321 }
281 322
282 323
283 // must call add_safepoint before: it sets PcDesc and this routine uses 324 // must call add_safepoint before: it sets PcDesc and this routine uses
284 // the last PcDesc set 325 // the last PcDesc set