Mercurial > hg > truffle
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 |