Mercurial > hg > graal-jvmci-8
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 |