Mercurial > hg > truffle
comparison src/share/vm/gc_implementation/g1/sparsePRT.cpp @ 1045:fa2f65ebeb08
6870843: G1: G1 GC memory leak
Summary: The fix addresses two memory leaks in G1 code: (1) _evac_failure_scan_stack - a resource object allocated on the C heap was not freed; (2) RSHashTable were linked into deleted list which was only cleared at full GC.
Reviewed-by: tonyp, iveresov
author | apetrusenko |
---|---|
date | Tue, 27 Oct 2009 02:42:24 -0700 |
parents | 2c79770d1f6e |
children | 0414c1049f15 |
comparison
equal
deleted
inserted
replaced
1044:6270f80a7331 | 1045:fa2f65ebeb08 |
---|---|
133 RSHashTable::RSHashTable(size_t capacity) : | 133 RSHashTable::RSHashTable(size_t capacity) : |
134 _capacity(capacity), _capacity_mask(capacity-1), | 134 _capacity(capacity), _capacity_mask(capacity-1), |
135 _occupied_entries(0), _occupied_cards(0), | 135 _occupied_entries(0), _occupied_cards(0), |
136 _entries(NEW_C_HEAP_ARRAY(SparsePRTEntry, capacity)), | 136 _entries(NEW_C_HEAP_ARRAY(SparsePRTEntry, capacity)), |
137 _buckets(NEW_C_HEAP_ARRAY(int, capacity)), | 137 _buckets(NEW_C_HEAP_ARRAY(int, capacity)), |
138 _next_deleted(NULL), _deleted(false), | |
139 _free_list(NullEntry), _free_region(0) | 138 _free_list(NullEntry), _free_region(0) |
140 { | 139 { |
141 clear(); | 140 clear(); |
142 } | 141 } |
143 | 142 |
294 e->copy_cards(e2); | 293 e->copy_cards(e2); |
295 _occupied_cards += e2->num_valid_cards(); | 294 _occupied_cards += e2->num_valid_cards(); |
296 assert(e2->num_valid_cards() > 0, "Postcondition."); | 295 assert(e2->num_valid_cards() > 0, "Postcondition."); |
297 } | 296 } |
298 | 297 |
299 RSHashTable* RSHashTable::_head_deleted_list = NULL; | |
300 | |
301 void RSHashTable::add_to_deleted_list(RSHashTable* rsht) { | |
302 assert(!rsht->deleted(), "Should delete only once."); | |
303 rsht->set_deleted(true); | |
304 RSHashTable* hd = _head_deleted_list; | |
305 while (true) { | |
306 rsht->_next_deleted = hd; | |
307 RSHashTable* res = | |
308 (RSHashTable*) | |
309 Atomic::cmpxchg_ptr(rsht, &_head_deleted_list, hd); | |
310 if (res == hd) return; | |
311 else hd = res; | |
312 } | |
313 } | |
314 | |
315 RSHashTable* RSHashTable::get_from_deleted_list() { | |
316 RSHashTable* hd = _head_deleted_list; | |
317 while (hd != NULL) { | |
318 RSHashTable* next = hd->next_deleted(); | |
319 RSHashTable* res = | |
320 (RSHashTable*) | |
321 Atomic::cmpxchg_ptr(next, &_head_deleted_list, hd); | |
322 if (res == hd) { | |
323 hd->set_next_deleted(NULL); | |
324 hd->set_deleted(false); | |
325 return hd; | |
326 } else { | |
327 hd = res; | |
328 } | |
329 } | |
330 return NULL; | |
331 } | |
332 | |
333 CardIdx_t /* RSHashTable:: */ RSHashTableIter::find_first_card_in_list() { | 298 CardIdx_t /* RSHashTable:: */ RSHashTableIter::find_first_card_in_list() { |
334 CardIdx_t res; | 299 CardIdx_t res; |
335 while (_bl_ind != RSHashTable::NullEntry) { | 300 while (_bl_ind != RSHashTable::NullEntry) { |
336 res = _rsht->entry(_bl_ind)->card(0); | 301 res = _rsht->entry(_bl_ind)->card(0); |
337 if (res != SparsePRTEntry::NullEntry) { | 302 if (res != SparsePRTEntry::NullEntry) { |
440 SparsePRT* sprt = get_from_expanded_list(); | 405 SparsePRT* sprt = get_from_expanded_list(); |
441 while (sprt != NULL) { | 406 while (sprt != NULL) { |
442 sprt->cleanup(); | 407 sprt->cleanup(); |
443 sprt = get_from_expanded_list(); | 408 sprt = get_from_expanded_list(); |
444 } | 409 } |
445 // Now delete all deleted RSHashTables. | |
446 RSHashTable* rsht = RSHashTable::get_from_deleted_list(); | |
447 while (rsht != NULL) { | |
448 #if SPARSE_PRT_VERBOSE | |
449 gclog_or_tty->print_cr("About to delete RSHT " PTR_FORMAT ".", rsht); | |
450 #endif | |
451 delete rsht; | |
452 rsht = RSHashTable::get_from_deleted_list(); | |
453 } | |
454 } | 410 } |
455 | 411 |
456 | 412 |
457 SparsePRT::SparsePRT(HeapRegion* hr) : | 413 SparsePRT::SparsePRT(HeapRegion* hr) : |
458 _expanded(false), _next_expanded(NULL) | 414 _expanded(false), _next_expanded(NULL) |
509 } | 465 } |
510 _next = _cur; | 466 _next = _cur; |
511 } | 467 } |
512 | 468 |
513 void SparsePRT::cleanup() { | 469 void SparsePRT::cleanup() { |
514 // Make sure that the current and next tables agree. (Another mechanism | 470 // Make sure that the current and next tables agree. |
515 // takes care of deleting now-unused tables.) | 471 if (_cur != _next) { |
472 delete _cur; | |
473 } | |
516 _cur = _next; | 474 _cur = _next; |
517 set_expanded(false); | 475 set_expanded(false); |
518 } | 476 } |
519 | 477 |
520 void SparsePRT::expand() { | 478 void SparsePRT::expand() { |
533 e->r_ind()); | 491 e->r_ind()); |
534 #endif | 492 #endif |
535 _next->add_entry(e); | 493 _next->add_entry(e); |
536 } | 494 } |
537 } | 495 } |
538 if (last != _cur) | 496 if (last != _cur) { |
539 RSHashTable::add_to_deleted_list(last); | 497 delete last; |
498 } | |
540 add_to_expanded_list(this); | 499 add_to_expanded_list(this); |
541 } | 500 } |