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() {