Mercurial > hg > truffle
comparison src/share/vm/gc_implementation/g1/concurrentMark.hpp @ 1358:72f725c5a7be
6940310: G1: MT-unsafe calls to CM::region_stack_push() / CM::region_stack_pop()
Summary: Calling the methods region_stack_push() and region_stack_pop() concurrent is not MT-safe. The assumption is that we will only call region_stack_push() during a GC pause and region_stack_pop() during marking. Unfortunately, we also call region_stack_push() during marking which seems to be introducing subtle marking failures. This change introduces lock-based methods for pushing / popping to be called during marking.
Reviewed-by: iveresov, johnc
author | tonyp |
---|---|
date | Mon, 05 Apr 2010 12:19:22 -0400 |
parents | 2a1472c30599 |
children | 7666957bc44d |
comparison
equal
deleted
inserted
replaced
1357:781e29eb8e08 | 1358:72f725c5a7be |
---|---|
250 | 250 |
251 // This is lock-free; assumes that it will only be called in parallel | 251 // This is lock-free; assumes that it will only be called in parallel |
252 // with other "push" operations (no pops). | 252 // with other "push" operations (no pops). |
253 void push(MemRegion mr); | 253 void push(MemRegion mr); |
254 | 254 |
255 #if 0 | |
256 // This is currently not used. See the comment in the .cpp file. | |
257 | |
255 // Lock-free; assumes that it will only be called in parallel | 258 // Lock-free; assumes that it will only be called in parallel |
256 // with other "pop" operations (no pushes). | 259 // with other "pop" operations (no pushes). |
257 MemRegion pop(); | 260 MemRegion pop(); |
261 #endif // 0 | |
262 | |
263 // These two are the implementations that use a lock. They can be | |
264 // called concurrently with each other but they should not be called | |
265 // concurrently with the lock-free versions (push() / pop()). | |
266 void push_with_lock(MemRegion mr); | |
267 MemRegion pop_with_lock(); | |
258 | 268 |
259 bool isEmpty() { return _index == 0; } | 269 bool isEmpty() { return _index == 0; } |
260 bool isFull() { return _index == _capacity; } | 270 bool isFull() { return _index == _capacity; } |
261 | 271 |
262 bool overflow() { return _overflow; } | 272 bool overflow() { return _overflow; } |
538 bool mark_stack_overflow() { return _markStack.overflow(); } | 548 bool mark_stack_overflow() { return _markStack.overflow(); } |
539 bool mark_stack_empty() { return _markStack.isEmpty(); } | 549 bool mark_stack_empty() { return _markStack.isEmpty(); } |
540 | 550 |
541 // Manipulation of the region stack | 551 // Manipulation of the region stack |
542 bool region_stack_push(MemRegion mr) { | 552 bool region_stack_push(MemRegion mr) { |
553 // Currently we only call the lock-free version during evacuation | |
554 // pauses. | |
555 assert(SafepointSynchronize::is_at_safepoint(), "world should be stopped"); | |
556 | |
543 _regionStack.push(mr); | 557 _regionStack.push(mr); |
544 if (_regionStack.overflow()) { | 558 if (_regionStack.overflow()) { |
545 set_has_overflown(); | 559 set_has_overflown(); |
546 return false; | 560 return false; |
547 } | 561 } |
548 return true; | 562 return true; |
549 } | 563 } |
550 MemRegion region_stack_pop() { return _regionStack.pop(); } | 564 #if 0 |
565 // Currently this is not used. See the comment in the .cpp file. | |
566 MemRegion region_stack_pop() { return _regionStack.pop(); } | |
567 #endif // 0 | |
568 | |
569 bool region_stack_push_with_lock(MemRegion mr) { | |
570 // Currently we only call the lock-based version during either | |
571 // concurrent marking or remark. | |
572 assert(!SafepointSynchronize::is_at_safepoint() || !concurrent(), | |
573 "if we are at a safepoint it should be the remark safepoint"); | |
574 | |
575 _regionStack.push_with_lock(mr); | |
576 if (_regionStack.overflow()) { | |
577 set_has_overflown(); | |
578 return false; | |
579 } | |
580 return true; | |
581 } | |
582 MemRegion region_stack_pop_with_lock() { | |
583 // Currently we only call the lock-based version during either | |
584 // concurrent marking or remark. | |
585 assert(!SafepointSynchronize::is_at_safepoint() || !concurrent(), | |
586 "if we are at a safepoint it should be the remark safepoint"); | |
587 | |
588 return _regionStack.pop_with_lock(); | |
589 } | |
590 | |
551 int region_stack_size() { return _regionStack.size(); } | 591 int region_stack_size() { return _regionStack.size(); } |
552 bool region_stack_overflow() { return _regionStack.overflow(); } | 592 bool region_stack_overflow() { return _regionStack.overflow(); } |
553 bool region_stack_empty() { return _regionStack.isEmpty(); } | 593 bool region_stack_empty() { return _regionStack.isEmpty(); } |
554 | 594 |
555 bool concurrent_marking_in_progress() { | 595 bool concurrent_marking_in_progress() { |