6899058: G1: Internal error in ptrQueue.cpp:201 in nightly tests

Tue, 24 Nov 2009 15:19:30 -0800

author
johnc
date
Tue, 24 Nov 2009 15:19:30 -0800
changeset 1525
fa357420e7d2
parent 1524
db0d5eba9d20
child 1526
6aa7255741f3

6899058: G1: Internal error in ptrQueue.cpp:201 in nightly tests
Summary: Fixes a race on the dirty card queue completed buffer list between worker thread(s) performing a flush of a deferred store barrier (enqueueing a newly completed buffer) and worker thread(s) in the RSet updating code claiming completed buffers. Removed the routine that removes elements from the completed update buffer queue using a CAS.
Reviewed-by: ysr, tonyp

src/share/vm/gc_implementation/g1/dirtyCardQueue.cpp file | annotate | diff | comparison | revisions
src/share/vm/gc_implementation/g1/dirtyCardQueue.hpp file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/vm/gc_implementation/g1/dirtyCardQueue.cpp	Fri Nov 20 14:47:01 2009 -0500
     1.2 +++ b/src/share/vm/gc_implementation/g1/dirtyCardQueue.cpp	Tue Nov 24 15:19:30 2009 -0800
     1.3 @@ -155,7 +155,7 @@
     1.4  }
     1.5  
     1.6  DirtyCardQueueSet::CompletedBufferNode*
     1.7 -DirtyCardQueueSet::get_completed_buffer_lock(int stop_at) {
     1.8 +DirtyCardQueueSet::get_completed_buffer(int stop_at) {
     1.9    CompletedBufferNode* nd = NULL;
    1.10    MutexLockerEx x(_cbl_mon, Mutex::_no_safepoint_check_flag);
    1.11  
    1.12 @@ -175,28 +175,6 @@
    1.13    return nd;
    1.14  }
    1.15  
    1.16 -// We only do this in contexts where there is no concurrent enqueueing.
    1.17 -DirtyCardQueueSet::CompletedBufferNode*
    1.18 -DirtyCardQueueSet::get_completed_buffer_CAS() {
    1.19 -  CompletedBufferNode* nd = _completed_buffers_head;
    1.20 -
    1.21 -  while (nd != NULL) {
    1.22 -    CompletedBufferNode* next = nd->next;
    1.23 -    CompletedBufferNode* result =
    1.24 -      (CompletedBufferNode*)Atomic::cmpxchg_ptr(next,
    1.25 -                                                &_completed_buffers_head,
    1.26 -                                                nd);
    1.27 -    if (result == nd) {
    1.28 -      return result;
    1.29 -    } else {
    1.30 -      nd = _completed_buffers_head;
    1.31 -    }
    1.32 -  }
    1.33 -  assert(_completed_buffers_head == NULL, "Loop post");
    1.34 -  _completed_buffers_tail = NULL;
    1.35 -  return NULL;
    1.36 -}
    1.37 -
    1.38  bool DirtyCardQueueSet::
    1.39  apply_closure_to_completed_buffer_helper(int worker_i,
    1.40                                           CompletedBufferNode* nd) {
    1.41 @@ -222,15 +200,10 @@
    1.42  
    1.43  bool DirtyCardQueueSet::apply_closure_to_completed_buffer(int worker_i,
    1.44                                                            int stop_at,
    1.45 -                                                          bool with_CAS)
    1.46 +                                                          bool during_pause)
    1.47  {
    1.48 -  CompletedBufferNode* nd = NULL;
    1.49 -  if (with_CAS) {
    1.50 -    guarantee(stop_at == 0, "Precondition");
    1.51 -    nd = get_completed_buffer_CAS();
    1.52 -  } else {
    1.53 -    nd = get_completed_buffer_lock(stop_at);
    1.54 -  }
    1.55 +  assert(!during_pause || stop_at == 0, "Should not leave any completed buffers during a pause");
    1.56 +  CompletedBufferNode* nd = get_completed_buffer(stop_at);
    1.57    bool res = apply_closure_to_completed_buffer_helper(worker_i, nd);
    1.58    if (res) Atomic::inc(&_processed_buffers_rs_thread);
    1.59    return res;
     2.1 --- a/src/share/vm/gc_implementation/g1/dirtyCardQueue.hpp	Fri Nov 20 14:47:01 2009 -0500
     2.2 +++ b/src/share/vm/gc_implementation/g1/dirtyCardQueue.hpp	Tue Nov 24 15:19:30 2009 -0800
     2.3 @@ -1,5 +1,5 @@
     2.4  /*
     2.5 - * Copyright 2001-2007 Sun Microsystems, Inc.  All Rights Reserved.
     2.6 + * Copyright 2001-2009 Sun Microsystems, Inc.  All Rights Reserved.
     2.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     2.8   *
     2.9   * This code is free software; you can redistribute it and/or modify it
    2.10 @@ -120,12 +120,13 @@
    2.11    // is returned to the completed buffer set, and this call returns false.
    2.12    bool apply_closure_to_completed_buffer(int worker_i = 0,
    2.13                                           int stop_at = 0,
    2.14 -                                         bool with_CAS = false);
    2.15 +                                         bool during_pause = false);
    2.16 +
    2.17    bool apply_closure_to_completed_buffer_helper(int worker_i,
    2.18                                                  CompletedBufferNode* nd);
    2.19  
    2.20 -  CompletedBufferNode* get_completed_buffer_CAS();
    2.21 -  CompletedBufferNode* get_completed_buffer_lock(int stop_at);
    2.22 +  CompletedBufferNode* get_completed_buffer(int stop_at);
    2.23 +
    2.24    // Applies the current closure to all completed buffers,
    2.25    // non-consumptively.
    2.26    void apply_closure_to_all_completed_buffers();

mercurial