Print this page
rev 3708 : 8000244: G1: Ergonomically set MarkStackSize and use virtual space for global marking stack
Summary: Set the value of MarkStackSize to a value based on the number of parallel marking threads with a reasonable minimum. Expand the marking stack if we have to restart marking due to an overflow up to a reasonable maximum. Allocate the underlying space for the marking stack from virtual memory.
Reviewed-by: jmasa
rev 3709 : imported patch reuse-old-marking-stack

Split Close
Expand all
Collapse all
          --- old/src/share/vm/gc_implementation/g1/concurrentMark.cpp
          +++ new/src/share/vm/gc_implementation/g1/concurrentMark.cpp
↓ open down ↓ 180 lines elided ↑ open up ↑
 181  181    }
 182  182    MemTracker::record_virtual_memory_type((address)rs.base(), mtGC);
 183  183    if (!_virtual_space.initialize(rs, rs.size())) {
 184  184      warning("ConcurrentMark MarkStack backing store failure");
 185  185      // Release the virtual memory reserved for the marking stack
 186  186      rs.release();
 187  187      return false;
 188  188    }
 189  189    assert(_virtual_space.committed_size() == rs.size(),
 190  190           "Didn't reserve backing store for all of ConcurrentMark stack?");
      191 +  _rs = rs;
 191  192    _base = (oop*) _virtual_space.low();
 192  193    setEmpty();
 193  194    _capacity = (jint) capacity;
 194  195    _saved_index = -1;
 195  196    NOT_PRODUCT(_max_depth = 0);
 196  197    return true;
 197  198  }
 198  199  
 199  200  void CMMarkStack::expand() {
 200  201    // Called, during remark, if we've overflown the marking stack during marking.
↓ open down ↓ 6 lines elided ↑ open up ↑
 207  208        gclog_or_tty->print_cr(" (benign) Can't expand marking stack capacity, at max size limit");
 208  209      }
 209  210      return;
 210  211    }
 211  212    // Double capacity if possible
 212  213    jint new_capacity = MIN2(_capacity*2, (jint) MarkStackSizeMax);
 213  214    // Do not give up existing stack until we have managed to
 214  215    // get the double capacity that we desired.
 215  216    ReservedSpace rs(ReservedSpace::allocation_align_size_up(new_capacity *
 216  217                                                             sizeof(oop)));
 217      -  if (rs.is_reserved()) {
 218      -    // Release the backing store associated with old stack
 219      -    _virtual_space.release();
 220      -    // Reinitialize virtual space for new stack
 221      -    if (!_virtual_space.initialize(rs, rs.size())) {
 222      -      fatal("Not enough swap for expanded marking stack capacity");
 223      -    }
 224      -    _base = (oop*)(_virtual_space.low());
 225      -    _index = 0;
 226      -    _capacity = new_capacity;
 227      -  } else {
      218 +  if (!rs.is_reserved()) {
 228  219      if (PrintGCDetails && Verbose) {
 229  220        // Failed to double capacity, continue;
 230  221        gclog_or_tty->print(" (benign) Failed to expand marking stack capacity from "
 231      -                          SIZE_FORMAT"K to " SIZE_FORMAT"K",
      222 +                          SIZE_FORMAT "K to " SIZE_FORMAT "K",
 232  223                            _capacity / K, new_capacity / K);
 233  224      }
      225 +    return;
      226 +  }
      227 +
      228 +  // Clear the backing store fields associated with the space for the
      229 +  // old marking stack. Note this doesn't actuall release the space.
      230 +  _virtual_space.release();
      231 +
      232 +  // Reinitialize virtual space for the expanded stack.
      233 +  if (!_virtual_space.initialize(rs, rs.size())) {
      234 +    // We failed to commit the the space for the expanded marking stack
      235 +    // Release the expanded reserved space...
      236 +    rs.release();
      237 +    // ... and reinitialize with the previous un-expanded space.
      238 +    if (_virtual_space.initialize(_rs, _rs.size())) {
      239 +      if (PrintGCDetails && Verbose) {
      240 +        gclog_or_tty->print(" (benign) Failed to expand marking stack capacity from "
      241 +                            SIZE_FORMAT "K to " SIZE_FORMAT "K",
      242 +                            _capacity / K, new_capacity / K);
      243 +      }
      244 +    } else {
      245 +      // The previous backing store space should have been already
      246 +      // committed but we failed to initialize the virtual space
      247 +      // for some reason.
      248 +      fatal("Error re-initializing marking stack with old capacity");
      249 +    }
      250 +  } else {
      251 +    // We successfully committed the space for the expanded marking stack.
      252 +    if (PrintGCDetails && Verbose) {
      253 +      gclog_or_tty->print(" Successfully expanded marking stack capacity from "
      254 +                          SIZE_FORMAT "K to " SIZE_FORMAT "K",
      255 +                          _capacity / K, new_capacity / K);
      256 +    }
      257 +    // Release the previous (unexpanded) space.
      258 +    _rs.release();
      259 +    // Record the new (expanded) space.
      260 +    _rs = rs;
      261 +    // Record the new capacity
      262 +    _capacity = new_capacity;
 234  263    }
      264 +  assert(_virtual_space.committed_size() == _rs.size(),
      265 +         "Didn't reserve backing store for all of ConcurrentMark stack?");
      266 +  _base = (oop*)(_virtual_space.low());
      267 +  _index = 0;
 235  268  }
 236  269  
 237  270  void CMMarkStack::set_should_expand() {
 238  271    // If we're resetting the marking state because of an
 239  272    // marking stack overflow, record that we should, if
 240  273    // possible, expand the stack.
 241  274    _should_expand = _cm->has_overflown();
 242  275  }
 243  276  
 244  277  CMMarkStack::~CMMarkStack() {
↓ open down ↓ 4326 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX