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 }