Print this page
rev 2755 : 7099824: G1: we should take the pending list lock before doing the remark pause
Summary: Acquire the pending list lock in the prologue method of G1's
concurrent VM_Operation and release the lock in the epilogue() method.
The locking/unlocking order of the pending list lock and the Heap_lock
should match that in the prologue and epilogue methods of VM_GC_Operation.
Reviewed-by:

Split Close
Expand all
Collapse all
          --- old/src/share/vm/gc_implementation/g1/vm_operations_g1.cpp
          +++ new/src/share/vm/gc_implementation/g1/vm_operations_g1.cpp
↓ open down ↓ 15 lines elided ↑ open up ↑
  16   16   * 2 along with this work; if not, write to the Free Software Foundation,
  17   17   * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18   18   *
  19   19   * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20   20   * or visit www.oracle.com if you need additional information or have any
  21   21   * questions.
  22   22   *
  23   23   */
  24   24  
  25   25  #include "precompiled.hpp"
       26 +#include "gc_implementation/g1/concurrentMarkThread.inline.hpp"
  26   27  #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
  27   28  #include "gc_implementation/g1/g1CollectorPolicy.hpp"
  28   29  #include "gc_implementation/g1/vm_operations_g1.hpp"
  29   30  #include "gc_implementation/shared/isGCActiveMark.hpp"
  30   31  #include "gc_implementation/g1/vm_operations_g1.hpp"
  31   32  #include "runtime/interfaceSupport.hpp"
  32   33  
  33   34  VM_G1CollectForAllocation::VM_G1CollectForAllocation(
  34   35                                                    unsigned int gc_count_before,
  35   36                                                    size_t word_size)
↓ open down ↓ 122 lines elided ↑ open up ↑
 158  159  
 159  160        MutexLockerEx x(FullGCCount_lock, Mutex::_no_safepoint_check_flag);
 160  161        while (g1h->full_collections_completed() <=
 161  162                                            _full_collections_completed_before) {
 162  163          FullGCCount_lock->wait(Mutex::_no_safepoint_check_flag);
 163  164        }
 164  165      }
 165  166    }
 166  167  }
 167  168  
      169 +void VM_CGC_Operation::acquire_pending_list_lock() {
      170 +  // The caller may block while communicating
      171 +  // with the SLT thread in order to acquire/release the PLL.
      172 +  ConcurrentMarkThread::slt()->
      173 +    manipulatePLL(SurrogateLockerThread::acquirePLL);
      174 +}
      175 +
      176 +void VM_CGC_Operation::release_and_notify_pending_list_lock() {
      177 +  // The caller may block while communicating
      178 +  // with the SLT thread in order to acquire/release the PLL.
      179 +  ConcurrentMarkThread::slt()->
      180 +    manipulatePLL(SurrogateLockerThread::releaseAndNotifyPLL);
      181 +}
      182 +
 168  183  void VM_CGC_Operation::doit() {
 169  184    gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps);
 170  185    TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
 171  186    TraceTime t(_printGCMessage, PrintGC, true, gclog_or_tty);
 172  187    SharedHeap* sh = SharedHeap::heap();
 173  188    // This could go away if CollectedHeap gave access to _gc_is_active...
 174  189    if (sh != NULL) {
 175  190      IsGCActiveMark x;
 176  191      _cl->do_void();
 177  192    } else {
 178  193      _cl->do_void();
 179  194    }
 180  195  }
 181  196  
 182  197  bool VM_CGC_Operation::doit_prologue() {
      198 +  // Note the relative order of the locks must match that in
      199 +  // VM_GC_Operation::doit_prologue() or deadlocks can occur
      200 +  acquire_pending_list_lock();
      201 +
 183  202    Heap_lock->lock();
 184  203    SharedHeap::heap()->_thread_holds_heap_lock_for_gc = true;
 185  204    return true;
 186  205  }
 187  206  
 188  207  void VM_CGC_Operation::doit_epilogue() {
      208 +  // Note the relative order of the unlocks must match that in
      209 +  // VM_GC_Operation::doit_epilogue()
 189  210    SharedHeap::heap()->_thread_holds_heap_lock_for_gc = false;
 190  211    Heap_lock->unlock();
      212 +  release_and_notify_pending_list_lock();
 191  213  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX