Mercurial > hg > graal-compiler
annotate src/share/vm/gc_implementation/g1/g1CodeCacheRemSet.cpp @ 20795:ae52ee069062
8062063: Usage of UseHugeTLBFS, UseLargePagesInMetaspace and huge SurvivorAlignmentInBytes cause crashes in CMBitMapClosure::do_bit
Summary: Making sure committed memory is cleared when re-committed, even if using large pages.
Reviewed-by: jwilhelm, tschatzl
author | sjohanss |
---|---|
date | Mon, 12 Jan 2015 15:24:29 +0100 |
parents | 58925d1f325e |
children |
rev | line source |
---|---|
17753
191174b49bec
8035406: Improve data structure for Code Cache remembered sets
tschatzl
parents:
diff
changeset
|
1 /* |
191174b49bec
8035406: Improve data structure for Code Cache remembered sets
tschatzl
parents:
diff
changeset
|
2 * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. |
191174b49bec
8035406: Improve data structure for Code Cache remembered sets
tschatzl
parents:
diff
changeset
|
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
191174b49bec
8035406: Improve data structure for Code Cache remembered sets
tschatzl
parents:
diff
changeset
|
4 * |
191174b49bec
8035406: Improve data structure for Code Cache remembered sets
tschatzl
parents:
diff
changeset
|
5 * This code is free software; you can redistribute it and/or modify it |
191174b49bec
8035406: Improve data structure for Code Cache remembered sets
tschatzl
parents:
diff
changeset
|
6 * under the terms of the GNU General Public License version 2 only, as |
191174b49bec
8035406: Improve data structure for Code Cache remembered sets
tschatzl
parents:
diff
changeset
|
7 * published by the Free Software Foundation. |
191174b49bec
8035406: Improve data structure for Code Cache remembered sets
tschatzl
parents:
diff
changeset
|
8 * |
191174b49bec
8035406: Improve data structure for Code Cache remembered sets
tschatzl
parents:
diff
changeset
|
9 * This code is distributed in the hope that it will be useful, but WITHOUT |
191174b49bec
8035406: Improve data structure for Code Cache remembered sets
tschatzl
parents:
diff
changeset
|
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
191174b49bec
8035406: Improve data structure for Code Cache remembered sets
tschatzl
parents:
diff
changeset
|
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
191174b49bec
8035406: Improve data structure for Code Cache remembered sets
tschatzl
parents:
diff
changeset
|
12 * version 2 for more details (a copy is included in the LICENSE file that |
191174b49bec
8035406: Improve data structure for Code Cache remembered sets
tschatzl
parents:
diff
changeset
|
13 * accompanied this code). |
191174b49bec
8035406: Improve data structure for Code Cache remembered sets
tschatzl
parents:
diff
changeset
|
14 * |
191174b49bec
8035406: Improve data structure for Code Cache remembered sets
tschatzl
parents:
diff
changeset
|
15 * You should have received a copy of the GNU General Public License version |
191174b49bec
8035406: Improve data structure for Code Cache remembered sets
tschatzl
parents:
diff
changeset
|
16 * 2 along with this work; if not, write to the Free Software Foundation, |
191174b49bec
8035406: Improve data structure for Code Cache remembered sets
tschatzl
parents:
diff
changeset
|
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
191174b49bec
8035406: Improve data structure for Code Cache remembered sets
tschatzl
parents:
diff
changeset
|
18 * |
191174b49bec
8035406: Improve data structure for Code Cache remembered sets
tschatzl
parents:
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
191174b49bec
8035406: Improve data structure for Code Cache remembered sets
tschatzl
parents:
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
191174b49bec
8035406: Improve data structure for Code Cache remembered sets
tschatzl
parents:
diff
changeset
|
21 * questions. |
191174b49bec
8035406: Improve data structure for Code Cache remembered sets
tschatzl
parents:
diff
changeset
|
22 * |
191174b49bec
8035406: Improve data structure for Code Cache remembered sets
tschatzl
parents:
diff
changeset
|
23 */ |
191174b49bec
8035406: Improve data structure for Code Cache remembered sets
tschatzl
parents:
diff
changeset
|
24 |
191174b49bec
8035406: Improve data structure for Code Cache remembered sets
tschatzl
parents:
diff
changeset
|
25 #include "precompiled.hpp" |
20494 | 26 #include "code/codeCache.hpp" |
17753
191174b49bec
8035406: Improve data structure for Code Cache remembered sets
tschatzl
parents:
diff
changeset
|
27 #include "code/nmethod.hpp" |
191174b49bec
8035406: Improve data structure for Code Cache remembered sets
tschatzl
parents:
diff
changeset
|
28 #include "gc_implementation/g1/g1CodeCacheRemSet.hpp" |
20494 | 29 #include "gc_implementation/g1/heapRegion.hpp" |
30 #include "memory/heap.hpp" | |
17753
191174b49bec
8035406: Improve data structure for Code Cache remembered sets
tschatzl
parents:
diff
changeset
|
31 #include "memory/iterator.hpp" |
20494 | 32 #include "oops/oop.inline.hpp" |
33 #include "utilities/hashtable.inline.hpp" | |
34 #include "utilities/stack.inline.hpp" | |
17753
191174b49bec
8035406: Improve data structure for Code Cache remembered sets
tschatzl
parents:
diff
changeset
|
35 |
17937
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
17753
diff
changeset
|
36 PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC |
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
17753
diff
changeset
|
37 |
20494 | 38 class CodeRootSetTable : public Hashtable<nmethod*, mtGC> { |
39 friend class G1CodeRootSetTest; | |
40 typedef HashtableEntry<nmethod*, mtGC> Entry; | |
41 | |
42 static CodeRootSetTable* volatile _purge_list; | |
43 | |
44 CodeRootSetTable* _purge_next; | |
45 | |
46 unsigned int compute_hash(nmethod* nm) { | |
47 uintptr_t hash = (uintptr_t)nm; | |
48 return hash ^ (hash >> 7); // code heap blocks are 128byte aligned | |
49 } | |
50 | |
20495
58925d1f325e
8057722: G1: Code root hashtable updated incorrectly when evacuation failed
mgerdin
parents:
20494
diff
changeset
|
51 void remove_entry(Entry* e, Entry* previous); |
20494 | 52 Entry* new_entry(nmethod* nm); |
53 | |
54 public: | |
55 CodeRootSetTable(int size) : Hashtable<nmethod*, mtGC>(size, sizeof(Entry)), _purge_next(NULL) {} | |
56 ~CodeRootSetTable(); | |
57 | |
58 // Needs to be protected locks | |
59 bool add(nmethod* nm); | |
60 bool remove(nmethod* nm); | |
61 | |
62 // Can be called without locking | |
63 bool contains(nmethod* nm); | |
64 | |
65 int entry_size() const { return BasicHashtable<mtGC>::entry_size(); } | |
66 | |
67 void copy_to(CodeRootSetTable* new_table); | |
68 void nmethods_do(CodeBlobClosure* blk); | |
69 | |
70 template<typename CB> | |
20495
58925d1f325e
8057722: G1: Code root hashtable updated incorrectly when evacuation failed
mgerdin
parents:
20494
diff
changeset
|
71 int remove_if(CB& should_remove); |
20494 | 72 |
73 static void purge_list_append(CodeRootSetTable* tbl); | |
74 static void purge(); | |
75 | |
76 static size_t static_mem_size() { | |
77 return sizeof(_purge_list); | |
78 } | |
79 }; | |
80 | |
81 CodeRootSetTable* volatile CodeRootSetTable::_purge_list = NULL; | |
82 | |
83 CodeRootSetTable::Entry* CodeRootSetTable::new_entry(nmethod* nm) { | |
84 unsigned int hash = compute_hash(nm); | |
85 Entry* entry = (Entry*) new_entry_free_list(); | |
86 if (entry == NULL) { | |
87 entry = (Entry*) NEW_C_HEAP_ARRAY2(char, entry_size(), mtGC, CURRENT_PC); | |
88 } | |
89 entry->set_next(NULL); | |
90 entry->set_hash(hash); | |
91 entry->set_literal(nm); | |
92 return entry; | |
17753
191174b49bec
8035406: Improve data structure for Code Cache remembered sets
tschatzl
parents:
diff
changeset
|
93 } |
191174b49bec
8035406: Improve data structure for Code Cache remembered sets
tschatzl
parents:
diff
changeset
|
94 |
20495
58925d1f325e
8057722: G1: Code root hashtable updated incorrectly when evacuation failed
mgerdin
parents:
20494
diff
changeset
|
95 void CodeRootSetTable::remove_entry(Entry* e, Entry* previous) { |
58925d1f325e
8057722: G1: Code root hashtable updated incorrectly when evacuation failed
mgerdin
parents:
20494
diff
changeset
|
96 int index = hash_to_index(e->hash()); |
58925d1f325e
8057722: G1: Code root hashtable updated incorrectly when evacuation failed
mgerdin
parents:
20494
diff
changeset
|
97 assert((e == bucket(index)) == (previous == NULL), "if e is the first entry then previous should be null"); |
58925d1f325e
8057722: G1: Code root hashtable updated incorrectly when evacuation failed
mgerdin
parents:
20494
diff
changeset
|
98 |
58925d1f325e
8057722: G1: Code root hashtable updated incorrectly when evacuation failed
mgerdin
parents:
20494
diff
changeset
|
99 if (previous == NULL) { |
58925d1f325e
8057722: G1: Code root hashtable updated incorrectly when evacuation failed
mgerdin
parents:
20494
diff
changeset
|
100 set_entry(index, e->next()); |
58925d1f325e
8057722: G1: Code root hashtable updated incorrectly when evacuation failed
mgerdin
parents:
20494
diff
changeset
|
101 } else { |
58925d1f325e
8057722: G1: Code root hashtable updated incorrectly when evacuation failed
mgerdin
parents:
20494
diff
changeset
|
102 previous->set_next(e->next()); |
58925d1f325e
8057722: G1: Code root hashtable updated incorrectly when evacuation failed
mgerdin
parents:
20494
diff
changeset
|
103 } |
58925d1f325e
8057722: G1: Code root hashtable updated incorrectly when evacuation failed
mgerdin
parents:
20494
diff
changeset
|
104 free_entry(e); |
58925d1f325e
8057722: G1: Code root hashtable updated incorrectly when evacuation failed
mgerdin
parents:
20494
diff
changeset
|
105 } |
58925d1f325e
8057722: G1: Code root hashtable updated incorrectly when evacuation failed
mgerdin
parents:
20494
diff
changeset
|
106 |
20494 | 107 CodeRootSetTable::~CodeRootSetTable() { |
108 for (int index = 0; index < table_size(); ++index) { | |
109 for (Entry* e = bucket(index); e != NULL; ) { | |
110 Entry* to_remove = e; | |
111 // read next before freeing. | |
112 e = e->next(); | |
113 unlink_entry(to_remove); | |
114 FREE_C_HEAP_ARRAY(char, to_remove, mtGC); | |
20278
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20218
diff
changeset
|
115 } |
20494 | 116 } |
117 assert(number_of_entries() == 0, "should have removed all entries"); | |
118 free_buckets(); | |
119 for (BasicHashtableEntry<mtGC>* e = new_entry_free_list(); e != NULL; e = new_entry_free_list()) { | |
120 FREE_C_HEAP_ARRAY(char, e, mtGC); | |
17753
191174b49bec
8035406: Improve data structure for Code Cache remembered sets
tschatzl
parents:
diff
changeset
|
121 } |
191174b49bec
8035406: Improve data structure for Code Cache remembered sets
tschatzl
parents:
diff
changeset
|
122 } |
191174b49bec
8035406: Improve data structure for Code Cache remembered sets
tschatzl
parents:
diff
changeset
|
123 |
20494 | 124 bool CodeRootSetTable::add(nmethod* nm) { |
125 if (!contains(nm)) { | |
126 Entry* e = new_entry(nm); | |
127 int index = hash_to_index(e->hash()); | |
128 add_entry(index, e); | |
129 return true; | |
130 } | |
131 return false; | |
132 } | |
20278
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20218
diff
changeset
|
133 |
20494 | 134 bool CodeRootSetTable::contains(nmethod* nm) { |
135 int index = hash_to_index(compute_hash(nm)); | |
136 for (Entry* e = bucket(index); e != NULL; e = e->next()) { | |
137 if (e->literal() == nm) { | |
138 return true; | |
139 } | |
140 } | |
141 return false; | |
142 } | |
20278
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20218
diff
changeset
|
143 |
20494 | 144 bool CodeRootSetTable::remove(nmethod* nm) { |
145 int index = hash_to_index(compute_hash(nm)); | |
146 Entry* previous = NULL; | |
147 for (Entry* e = bucket(index); e != NULL; previous = e, e = e->next()) { | |
148 if (e->literal() == nm) { | |
20495
58925d1f325e
8057722: G1: Code root hashtable updated incorrectly when evacuation failed
mgerdin
parents:
20494
diff
changeset
|
149 remove_entry(e, previous); |
20278
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20218
diff
changeset
|
150 return true; |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20218
diff
changeset
|
151 } |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20218
diff
changeset
|
152 } |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20218
diff
changeset
|
153 return false; |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20218
diff
changeset
|
154 } |
2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
stefank
parents:
20218
diff
changeset
|
155 |
20494 | 156 void CodeRootSetTable::copy_to(CodeRootSetTable* new_table) { |
157 for (int index = 0; index < table_size(); ++index) { | |
158 for (Entry* e = bucket(index); e != NULL; e = e->next()) { | |
159 new_table->add(e->literal()); | |
160 } | |
161 } | |
162 new_table->copy_freelist(this); | |
17753
191174b49bec
8035406: Improve data structure for Code Cache remembered sets
tschatzl
parents:
diff
changeset
|
163 } |
191174b49bec
8035406: Improve data structure for Code Cache remembered sets
tschatzl
parents:
diff
changeset
|
164 |
20494 | 165 void CodeRootSetTable::nmethods_do(CodeBlobClosure* blk) { |
166 for (int index = 0; index < table_size(); ++index) { | |
167 for (Entry* e = bucket(index); e != NULL; e = e->next()) { | |
168 blk->do_code_blob(e->literal()); | |
169 } | |
170 } | |
17753
191174b49bec
8035406: Improve data structure for Code Cache remembered sets
tschatzl
parents:
diff
changeset
|
171 } |
191174b49bec
8035406: Improve data structure for Code Cache remembered sets
tschatzl
parents:
diff
changeset
|
172 |
20494 | 173 template<typename CB> |
20495
58925d1f325e
8057722: G1: Code root hashtable updated incorrectly when evacuation failed
mgerdin
parents:
20494
diff
changeset
|
174 int CodeRootSetTable::remove_if(CB& should_remove) { |
58925d1f325e
8057722: G1: Code root hashtable updated incorrectly when evacuation failed
mgerdin
parents:
20494
diff
changeset
|
175 int num_removed = 0; |
20494 | 176 for (int index = 0; index < table_size(); ++index) { |
177 Entry* previous = NULL; | |
178 Entry* e = bucket(index); | |
179 while (e != NULL) { | |
180 Entry* next = e->next(); | |
181 if (should_remove(e->literal())) { | |
20495
58925d1f325e
8057722: G1: Code root hashtable updated incorrectly when evacuation failed
mgerdin
parents:
20494
diff
changeset
|
182 remove_entry(e, previous); |
58925d1f325e
8057722: G1: Code root hashtable updated incorrectly when evacuation failed
mgerdin
parents:
20494
diff
changeset
|
183 ++num_removed; |
20494 | 184 } else { |
185 previous = e; | |
186 } | |
187 e = next; | |
188 } | |
189 } | |
20495
58925d1f325e
8057722: G1: Code root hashtable updated incorrectly when evacuation failed
mgerdin
parents:
20494
diff
changeset
|
190 return num_removed; |
20494 | 191 } |
192 | |
193 G1CodeRootSet::~G1CodeRootSet() { | |
194 delete _table; | |
20211
82693fb204a5
8038930: G1CodeRootSet::test fails with assert(_num_chunks_handed_out == 0) failed: No elements must have been handed out yet
tschatzl
parents:
17937
diff
changeset
|
195 } |
17753
191174b49bec
8035406: Improve data structure for Code Cache remembered sets
tschatzl
parents:
diff
changeset
|
196 |
20494 | 197 CodeRootSetTable* G1CodeRootSet::load_acquire_table() { |
198 return (CodeRootSetTable*) OrderAccess::load_ptr_acquire(&_table); | |
199 } | |
200 | |
201 void G1CodeRootSet::allocate_small_table() { | |
202 _table = new CodeRootSetTable(SmallSize); | |
203 } | |
17753
191174b49bec
8035406: Improve data structure for Code Cache remembered sets
tschatzl
parents:
diff
changeset
|
204 |
20494 | 205 void CodeRootSetTable::purge_list_append(CodeRootSetTable* table) { |
206 for (;;) { | |
207 table->_purge_next = _purge_list; | |
208 CodeRootSetTable* old = (CodeRootSetTable*) Atomic::cmpxchg_ptr(table, &_purge_list, table->_purge_next); | |
209 if (old == table->_purge_next) { | |
210 break; | |
211 } | |
212 } | |
213 } | |
17753
191174b49bec
8035406: Improve data structure for Code Cache remembered sets
tschatzl
parents:
diff
changeset
|
214 |
20494 | 215 void CodeRootSetTable::purge() { |
216 CodeRootSetTable* table = _purge_list; | |
217 _purge_list = NULL; | |
218 while (table != NULL) { | |
219 CodeRootSetTable* to_purge = table; | |
220 table = table->_purge_next; | |
221 delete to_purge; | |
17753
191174b49bec
8035406: Improve data structure for Code Cache remembered sets
tschatzl
parents:
diff
changeset
|
222 } |
191174b49bec
8035406: Improve data structure for Code Cache remembered sets
tschatzl
parents:
diff
changeset
|
223 } |
191174b49bec
8035406: Improve data structure for Code Cache remembered sets
tschatzl
parents:
diff
changeset
|
224 |
20494 | 225 void G1CodeRootSet::move_to_large() { |
226 CodeRootSetTable* temp = new CodeRootSetTable(LargeSize); | |
227 | |
228 _table->copy_to(temp); | |
229 | |
230 CodeRootSetTable::purge_list_append(_table); | |
231 | |
232 OrderAccess::release_store_ptr(&_table, temp); | |
20211
82693fb204a5
8038930: G1CodeRootSet::test fails with assert(_num_chunks_handed_out == 0) failed: No elements must have been handed out yet
tschatzl
parents:
17937
diff
changeset
|
233 } |
82693fb204a5
8038930: G1CodeRootSet::test fails with assert(_num_chunks_handed_out == 0) failed: No elements must have been handed out yet
tschatzl
parents:
17937
diff
changeset
|
234 |
82693fb204a5
8038930: G1CodeRootSet::test fails with assert(_num_chunks_handed_out == 0) failed: No elements must have been handed out yet
tschatzl
parents:
17937
diff
changeset
|
235 |
20494 | 236 void G1CodeRootSet::purge() { |
237 CodeRootSetTable::purge(); | |
238 } | |
239 | |
240 size_t G1CodeRootSet::static_mem_size() { | |
241 return CodeRootSetTable::static_mem_size(); | |
242 } | |
243 | |
244 void G1CodeRootSet::add(nmethod* method) { | |
245 bool added = false; | |
246 if (is_empty()) { | |
247 allocate_small_table(); | |
248 } | |
249 added = _table->add(method); | |
250 if (_length == Threshold) { | |
251 move_to_large(); | |
252 } | |
253 if (added) { | |
254 ++_length; | |
255 } | |
256 } | |
257 | |
258 bool G1CodeRootSet::remove(nmethod* method) { | |
259 bool removed = false; | |
260 if (_table != NULL) { | |
261 removed = _table->remove(method); | |
262 } | |
263 if (removed) { | |
264 _length--; | |
265 if (_length == 0) { | |
266 clear(); | |
267 } | |
268 } | |
269 return removed; | |
270 } | |
271 | |
272 bool G1CodeRootSet::contains(nmethod* method) { | |
273 CodeRootSetTable* table = load_acquire_table(); | |
274 if (table != NULL) { | |
275 return table->contains(method); | |
20211
82693fb204a5
8038930: G1CodeRootSet::test fails with assert(_num_chunks_handed_out == 0) failed: No elements must have been handed out yet
tschatzl
parents:
17937
diff
changeset
|
276 } |
20494 | 277 return false; |
278 } | |
279 | |
280 void G1CodeRootSet::clear() { | |
281 delete _table; | |
282 _table = NULL; | |
283 _length = 0; | |
284 } | |
285 | |
286 size_t G1CodeRootSet::mem_size() { | |
287 return sizeof(*this) + | |
288 (_table != NULL ? sizeof(CodeRootSetTable) + _table->entry_size() * _length : 0); | |
289 } | |
290 | |
291 void G1CodeRootSet::nmethods_do(CodeBlobClosure* blk) const { | |
292 if (_table != NULL) { | |
293 _table->nmethods_do(blk); | |
294 } | |
295 } | |
296 | |
297 class CleanCallback : public StackObj { | |
298 class PointsIntoHRDetectionClosure : public OopClosure { | |
299 HeapRegion* _hr; | |
300 public: | |
301 bool _points_into; | |
302 PointsIntoHRDetectionClosure(HeapRegion* hr) : _hr(hr), _points_into(false) {} | |
303 | |
304 void do_oop(narrowOop* o) { | |
305 do_oop_work(o); | |
306 } | |
307 | |
308 void do_oop(oop* o) { | |
309 do_oop_work(o); | |
310 } | |
311 | |
312 template <typename T> | |
313 void do_oop_work(T* p) { | |
314 if (_hr->is_in(oopDesc::load_decode_heap_oop(p))) { | |
315 _points_into = true; | |
316 } | |
317 } | |
318 }; | |
319 | |
320 PointsIntoHRDetectionClosure _detector; | |
321 CodeBlobToOopClosure _blobs; | |
322 | |
323 public: | |
324 CleanCallback(HeapRegion* hr) : _detector(hr), _blobs(&_detector, !CodeBlobToOopClosure::FixRelocations) {} | |
325 | |
326 bool operator() (nmethod* nm) { | |
327 _detector._points_into = false; | |
328 _blobs.do_code_blob(nm); | |
20495
58925d1f325e
8057722: G1: Code root hashtable updated incorrectly when evacuation failed
mgerdin
parents:
20494
diff
changeset
|
329 return !_detector._points_into; |
20494 | 330 } |
331 }; | |
332 | |
333 void G1CodeRootSet::clean(HeapRegion* owner) { | |
334 CleanCallback should_clean(owner); | |
335 if (_table != NULL) { | |
20495
58925d1f325e
8057722: G1: Code root hashtable updated incorrectly when evacuation failed
mgerdin
parents:
20494
diff
changeset
|
336 int removed = _table->remove_if(should_clean); |
58925d1f325e
8057722: G1: Code root hashtable updated incorrectly when evacuation failed
mgerdin
parents:
20494
diff
changeset
|
337 assert((size_t)removed <= _length, "impossible"); |
58925d1f325e
8057722: G1: Code root hashtable updated incorrectly when evacuation failed
mgerdin
parents:
20494
diff
changeset
|
338 _length -= removed; |
58925d1f325e
8057722: G1: Code root hashtable updated incorrectly when evacuation failed
mgerdin
parents:
20494
diff
changeset
|
339 } |
58925d1f325e
8057722: G1: Code root hashtable updated incorrectly when evacuation failed
mgerdin
parents:
20494
diff
changeset
|
340 if (_length == 0) { |
58925d1f325e
8057722: G1: Code root hashtable updated incorrectly when evacuation failed
mgerdin
parents:
20494
diff
changeset
|
341 clear(); |
20494 | 342 } |
20211
82693fb204a5
8038930: G1CodeRootSet::test fails with assert(_num_chunks_handed_out == 0) failed: No elements must have been handed out yet
tschatzl
parents:
17937
diff
changeset
|
343 } |
82693fb204a5
8038930: G1CodeRootSet::test fails with assert(_num_chunks_handed_out == 0) failed: No elements must have been handed out yet
tschatzl
parents:
17937
diff
changeset
|
344 |
82693fb204a5
8038930: G1CodeRootSet::test fails with assert(_num_chunks_handed_out == 0) failed: No elements must have been handed out yet
tschatzl
parents:
17937
diff
changeset
|
345 #ifndef PRODUCT |
82693fb204a5
8038930: G1CodeRootSet::test fails with assert(_num_chunks_handed_out == 0) failed: No elements must have been handed out yet
tschatzl
parents:
17937
diff
changeset
|
346 |
20494 | 347 class G1CodeRootSetTest { |
348 public: | |
349 static void test() { | |
350 { | |
351 G1CodeRootSet set1; | |
352 assert(set1.is_empty(), "Code root set must be initially empty but is not."); | |
353 | |
354 assert(G1CodeRootSet::static_mem_size() == sizeof(void*), | |
355 err_msg("The code root set's static memory usage is incorrect, "SIZE_FORMAT" bytes", G1CodeRootSet::static_mem_size())); | |
356 | |
357 set1.add((nmethod*)1); | |
358 assert(set1.length() == 1, err_msg("Added exactly one element, but set contains " | |
359 SIZE_FORMAT" elements", set1.length())); | |
360 | |
361 const size_t num_to_add = (size_t)G1CodeRootSet::Threshold + 1; | |
362 | |
363 for (size_t i = 1; i <= num_to_add; i++) { | |
364 set1.add((nmethod*)1); | |
365 } | |
366 assert(set1.length() == 1, | |
367 err_msg("Duplicate detection should not have increased the set size but " | |
368 "is "SIZE_FORMAT, set1.length())); | |
17753
191174b49bec
8035406: Improve data structure for Code Cache remembered sets
tschatzl
parents:
diff
changeset
|
369 |
20494 | 370 for (size_t i = 2; i <= num_to_add; i++) { |
371 set1.add((nmethod*)(uintptr_t)(i)); | |
372 } | |
373 assert(set1.length() == num_to_add, | |
374 err_msg("After adding in total "SIZE_FORMAT" distinct code roots, they " | |
375 "need to be in the set, but there are only "SIZE_FORMAT, | |
376 num_to_add, set1.length())); | |
377 | |
378 assert(CodeRootSetTable::_purge_list != NULL, "should have grown to large hashtable"); | |
379 | |
380 size_t num_popped = 0; | |
381 for (size_t i = 1; i <= num_to_add; i++) { | |
382 bool removed = set1.remove((nmethod*)i); | |
383 if (removed) { | |
384 num_popped += 1; | |
385 } else { | |
386 break; | |
387 } | |
388 } | |
389 assert(num_popped == num_to_add, | |
390 err_msg("Managed to pop "SIZE_FORMAT" code roots, but only "SIZE_FORMAT" " | |
391 "were added", num_popped, num_to_add)); | |
392 assert(CodeRootSetTable::_purge_list != NULL, "should have grown to large hashtable"); | |
393 | |
394 G1CodeRootSet::purge(); | |
395 | |
396 assert(CodeRootSetTable::_purge_list == NULL, "should have purged old small tables"); | |
397 | |
398 } | |
399 | |
400 } | |
401 }; | |
402 | |
403 void TestCodeCacheRemSet_test() { | |
404 G1CodeRootSetTest::test(); | |
20211
82693fb204a5
8038930: G1CodeRootSet::test fails with assert(_num_chunks_handed_out == 0) failed: No elements must have been handed out yet
tschatzl
parents:
17937
diff
changeset
|
405 } |
82693fb204a5
8038930: G1CodeRootSet::test fails with assert(_num_chunks_handed_out == 0) failed: No elements must have been handed out yet
tschatzl
parents:
17937
diff
changeset
|
406 |
82693fb204a5
8038930: G1CodeRootSet::test fails with assert(_num_chunks_handed_out == 0) failed: No elements must have been handed out yet
tschatzl
parents:
17937
diff
changeset
|
407 #endif |