comparison src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp @ 2173:97ba643ea3ed

7014261: G1: RSet-related failures Summary: A race between the concurrent cleanup thread and the VM thread while it is processing the "expanded sparse table list" causes both threads to try to free the same sparse table entry and either causes one of the threads to fail or leaves the entry in an inconsistent state. The solution is purge all entries on the expanded list that correspond go regions that are being cleaned up. Reviewed-by: brutisso, johnc
author tonyp
date Tue, 25 Jan 2011 17:58:19 -0500
parents f95d63e2154a
children c3f1170908be
comparison
equal deleted inserted replaced
2172:a672e43650cc 2173:97ba643ea3ed
1 /* 1 /*
2 * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. 2 * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 * 4 *
5 * This code is free software; you can redistribute it and/or modify it 5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as 6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
461 } 461 }
462 return false; 462 return false;
463 } 463 }
464 464
465 static void par_contract_all(); 465 static void par_contract_all();
466
467 }; 466 };
468 467
469 void PosParPRT::par_contract_all() { 468 void PosParPRT::par_contract_all() {
470 PosParPRT* hd = _par_expanded_list; 469 PosParPRT* hd = _par_expanded_list;
471 while (hd != NULL) { 470 while (hd != NULL) {
1068 } 1067 }
1069 1068
1070 1069
1071 } 1070 }
1072 1071
1072 void
1073 OtherRegionsTable::do_cleanup_work(HRRSCleanupTask* hrrs_cleanup_task) {
1074 _sparse_table.do_cleanup_work(hrrs_cleanup_task);
1075 }
1076
1073 // Determines how many threads can add records to an rset in parallel. 1077 // Determines how many threads can add records to an rset in parallel.
1074 // This can be done by either mutator threads together with the 1078 // This can be done by either mutator threads together with the
1075 // concurrent refinement threads or GC threads. 1079 // concurrent refinement threads or GC threads.
1076 int HeapRegionRemSet::num_par_rem_sets() { 1080 int HeapRegionRemSet::num_par_rem_sets() {
1077 return (int)MAX2(DirtyCardQueueSet::num_par_ids() + ConcurrentG1Refine::thread_num(), ParallelGCThreads); 1081 return (int)MAX2(DirtyCardQueueSet::num_par_ids() + ConcurrentG1Refine::thread_num(), ParallelGCThreads);
1382 _recorded_cards[i], _recorded_regions[i]->bottom(), 1386 _recorded_cards[i], _recorded_regions[i]->bottom(),
1383 _recorded_oops[i]); 1387 _recorded_oops[i]);
1384 } 1388 }
1385 } 1389 }
1386 1390
1391 void HeapRegionRemSet::reset_for_cleanup_tasks() {
1392 SparsePRT::reset_for_cleanup_tasks();
1393 }
1394
1395 void HeapRegionRemSet::do_cleanup_work(HRRSCleanupTask* hrrs_cleanup_task) {
1396 _other_regions.do_cleanup_work(hrrs_cleanup_task);
1397 }
1398
1399 void
1400 HeapRegionRemSet::finish_cleanup_task(HRRSCleanupTask* hrrs_cleanup_task) {
1401 SparsePRT::finish_cleanup_task(hrrs_cleanup_task);
1402 }
1403
1387 #ifndef PRODUCT 1404 #ifndef PRODUCT
1388 void HeapRegionRemSet::test() { 1405 void HeapRegionRemSet::test() {
1389 os::sleep(Thread::current(), (jlong)5000, false); 1406 os::sleep(Thread::current(), (jlong)5000, false);
1390 G1CollectedHeap* g1h = G1CollectedHeap::heap(); 1407 G1CollectedHeap* g1h = G1CollectedHeap::heap();
1391 1408