src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp

changeset 1876
a8127dc669ba
parent 1583
05b775309e59
child 1907
c18cbe5936b8
child 1926
2d127394260e
     1.1 --- a/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp	Mon May 03 20:19:05 2010 -0700
     1.2 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp	Mon May 10 12:31:52 2010 -0700
     1.3 @@ -1926,59 +1926,6 @@
     1.4  
     1.5  ALL_SINCE_SAVE_MARKS_CLOSURES(CFLS_OOP_SINCE_SAVE_MARKS_DEFN)
     1.6  
     1.7 -//////////////////////////////////////////////////////////////////////////////
     1.8 -// We go over the list of promoted objects, removing each from the list,
     1.9 -// and applying the closure (this may, in turn, add more elements to
    1.10 -// the tail of the promoted list, and these newly added objects will
    1.11 -// also be processed) until the list is empty.
    1.12 -// To aid verification and debugging, in the non-product builds
    1.13 -// we actually forward _promoHead each time we process a promoted oop.
    1.14 -// Note that this is not necessary in general (i.e. when we don't need to
    1.15 -// call PromotionInfo::verify()) because oop_iterate can only add to the
    1.16 -// end of _promoTail, and never needs to look at _promoHead.
    1.17 -
    1.18 -#define PROMOTED_OOPS_ITERATE_DEFN(OopClosureType, nv_suffix)               \
    1.19 -                                                                            \
    1.20 -void PromotionInfo::promoted_oops_iterate##nv_suffix(OopClosureType* cl) {  \
    1.21 -  NOT_PRODUCT(verify());                                                    \
    1.22 -  PromotedObject *curObj, *nextObj;                                         \
    1.23 -  for (curObj = _promoHead; curObj != NULL; curObj = nextObj) {             \
    1.24 -    if ((nextObj = curObj->next()) == NULL) {                               \
    1.25 -      /* protect ourselves against additions due to closure application     \
    1.26 -         below by resetting the list.  */                                   \
    1.27 -      assert(_promoTail == curObj, "Should have been the tail");            \
    1.28 -      _promoHead = _promoTail = NULL;                                       \
    1.29 -    }                                                                       \
    1.30 -    if (curObj->hasDisplacedMark()) {                                       \
    1.31 -      /* restore displaced header */                                        \
    1.32 -      oop(curObj)->set_mark(nextDisplacedHeader());                         \
    1.33 -    } else {                                                                \
    1.34 -      /* restore prototypical header */                                     \
    1.35 -      oop(curObj)->init_mark();                                             \
    1.36 -    }                                                                       \
    1.37 -    /* The "promoted_mark" should now not be set */                         \
    1.38 -    assert(!curObj->hasPromotedMark(),                                      \
    1.39 -           "Should have been cleared by restoring displaced mark-word");    \
    1.40 -    NOT_PRODUCT(_promoHead = nextObj);                                      \
    1.41 -    if (cl != NULL) oop(curObj)->oop_iterate(cl);                           \
    1.42 -    if (nextObj == NULL) { /* start at head of list reset above */          \
    1.43 -      nextObj = _promoHead;                                                 \
    1.44 -    }                                                                       \
    1.45 -  }                                                                         \
    1.46 -  assert(noPromotions(), "post-condition violation");                       \
    1.47 -  assert(_promoHead == NULL && _promoTail == NULL, "emptied promoted list");\
    1.48 -  assert(_spoolHead == _spoolTail, "emptied spooling buffers");             \
    1.49 -  assert(_firstIndex == _nextIndex, "empty buffer");                        \
    1.50 -}
    1.51 -
    1.52 -// This should have been ALL_SINCE_...() just like the others,
    1.53 -// but, because the body of the method above is somehwat longer,
    1.54 -// the MSVC compiler cannot cope; as a workaround, we split the
    1.55 -// macro into its 3 constituent parts below (see original macro
    1.56 -// definition in specializedOopClosures.hpp).
    1.57 -SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES_YOUNG(PROMOTED_OOPS_ITERATE_DEFN)
    1.58 -PROMOTED_OOPS_ITERATE_DEFN(OopsInGenClosure,_v)
    1.59 -
    1.60  
    1.61  void CompactibleFreeListSpace::object_iterate_since_last_GC(ObjectClosure* cl) {
    1.62    // ugghh... how would one do this efficiently for a non-contiguous space?
    1.63 @@ -2506,281 +2453,6 @@
    1.64    _dictionary->printDictCensus();
    1.65  }
    1.66  
    1.67 -// Return the next displaced header, incrementing the pointer and
    1.68 -// recycling spool area as necessary.
    1.69 -markOop PromotionInfo::nextDisplacedHeader() {
    1.70 -  assert(_spoolHead != NULL, "promotionInfo inconsistency");
    1.71 -  assert(_spoolHead != _spoolTail || _firstIndex < _nextIndex,
    1.72 -         "Empty spool space: no displaced header can be fetched");
    1.73 -  assert(_spoolHead->bufferSize > _firstIndex, "Off by one error at head?");
    1.74 -  markOop hdr = _spoolHead->displacedHdr[_firstIndex];
    1.75 -  // Spool forward
    1.76 -  if (++_firstIndex == _spoolHead->bufferSize) { // last location in this block
    1.77 -    // forward to next block, recycling this block into spare spool buffer
    1.78 -    SpoolBlock* tmp = _spoolHead->nextSpoolBlock;
    1.79 -    assert(_spoolHead != _spoolTail, "Spooling storage mix-up");
    1.80 -    _spoolHead->nextSpoolBlock = _spareSpool;
    1.81 -    _spareSpool = _spoolHead;
    1.82 -    _spoolHead = tmp;
    1.83 -    _firstIndex = 1;
    1.84 -    NOT_PRODUCT(
    1.85 -      if (_spoolHead == NULL) {  // all buffers fully consumed
    1.86 -        assert(_spoolTail == NULL && _nextIndex == 1,
    1.87 -               "spool buffers processing inconsistency");
    1.88 -      }
    1.89 -    )
    1.90 -  }
    1.91 -  return hdr;
    1.92 -}
    1.93 -
    1.94 -void PromotionInfo::track(PromotedObject* trackOop) {
    1.95 -  track(trackOop, oop(trackOop)->klass());
    1.96 -}
    1.97 -
    1.98 -void PromotionInfo::track(PromotedObject* trackOop, klassOop klassOfOop) {
    1.99 -  // make a copy of header as it may need to be spooled
   1.100 -  markOop mark = oop(trackOop)->mark();
   1.101 -  trackOop->clearNext();
   1.102 -  if (mark->must_be_preserved_for_cms_scavenge(klassOfOop)) {
   1.103 -    // save non-prototypical header, and mark oop
   1.104 -    saveDisplacedHeader(mark);
   1.105 -    trackOop->setDisplacedMark();
   1.106 -  } else {
   1.107 -    // we'd like to assert something like the following:
   1.108 -    // assert(mark == markOopDesc::prototype(), "consistency check");
   1.109 -    // ... but the above won't work because the age bits have not (yet) been
   1.110 -    // cleared. The remainder of the check would be identical to the
   1.111 -    // condition checked in must_be_preserved() above, so we don't really
   1.112 -    // have anything useful to check here!
   1.113 -  }
   1.114 -  if (_promoTail != NULL) {
   1.115 -    assert(_promoHead != NULL, "List consistency");
   1.116 -    _promoTail->setNext(trackOop);
   1.117 -    _promoTail = trackOop;
   1.118 -  } else {
   1.119 -    assert(_promoHead == NULL, "List consistency");
   1.120 -    _promoHead = _promoTail = trackOop;
   1.121 -  }
   1.122 -  // Mask as newly promoted, so we can skip over such objects
   1.123 -  // when scanning dirty cards
   1.124 -  assert(!trackOop->hasPromotedMark(), "Should not have been marked");
   1.125 -  trackOop->setPromotedMark();
   1.126 -}
   1.127 -
   1.128 -// Save the given displaced header, incrementing the pointer and
   1.129 -// obtaining more spool area as necessary.
   1.130 -void PromotionInfo::saveDisplacedHeader(markOop hdr) {
   1.131 -  assert(_spoolHead != NULL && _spoolTail != NULL,
   1.132 -         "promotionInfo inconsistency");
   1.133 -  assert(_spoolTail->bufferSize > _nextIndex, "Off by one error at tail?");
   1.134 -  _spoolTail->displacedHdr[_nextIndex] = hdr;
   1.135 -  // Spool forward
   1.136 -  if (++_nextIndex == _spoolTail->bufferSize) { // last location in this block
   1.137 -    // get a new spooling block
   1.138 -    assert(_spoolTail->nextSpoolBlock == NULL, "tail should terminate spool list");
   1.139 -    _splice_point = _spoolTail;                   // save for splicing
   1.140 -    _spoolTail->nextSpoolBlock = getSpoolBlock(); // might fail
   1.141 -    _spoolTail = _spoolTail->nextSpoolBlock;      // might become NULL ...
   1.142 -    // ... but will attempt filling before next promotion attempt
   1.143 -    _nextIndex = 1;
   1.144 -  }
   1.145 -}
   1.146 -
   1.147 -// Ensure that spooling space exists. Return false if spooling space
   1.148 -// could not be obtained.
   1.149 -bool PromotionInfo::ensure_spooling_space_work() {
   1.150 -  assert(!has_spooling_space(), "Only call when there is no spooling space");
   1.151 -  // Try and obtain more spooling space
   1.152 -  SpoolBlock* newSpool = getSpoolBlock();
   1.153 -  assert(newSpool == NULL ||
   1.154 -         (newSpool->bufferSize != 0 && newSpool->nextSpoolBlock == NULL),
   1.155 -        "getSpoolBlock() sanity check");
   1.156 -  if (newSpool == NULL) {
   1.157 -    return false;
   1.158 -  }
   1.159 -  _nextIndex = 1;
   1.160 -  if (_spoolTail == NULL) {
   1.161 -    _spoolTail = newSpool;
   1.162 -    if (_spoolHead == NULL) {
   1.163 -      _spoolHead = newSpool;
   1.164 -      _firstIndex = 1;
   1.165 -    } else {
   1.166 -      assert(_splice_point != NULL && _splice_point->nextSpoolBlock == NULL,
   1.167 -             "Splice point invariant");
   1.168 -      // Extra check that _splice_point is connected to list
   1.169 -      #ifdef ASSERT
   1.170 -      {
   1.171 -        SpoolBlock* blk = _spoolHead;
   1.172 -        for (; blk->nextSpoolBlock != NULL;
   1.173 -             blk = blk->nextSpoolBlock);
   1.174 -        assert(blk != NULL && blk == _splice_point,
   1.175 -               "Splice point incorrect");
   1.176 -      }
   1.177 -      #endif // ASSERT
   1.178 -      _splice_point->nextSpoolBlock = newSpool;
   1.179 -    }
   1.180 -  } else {
   1.181 -    assert(_spoolHead != NULL, "spool list consistency");
   1.182 -    _spoolTail->nextSpoolBlock = newSpool;
   1.183 -    _spoolTail = newSpool;
   1.184 -  }
   1.185 -  return true;
   1.186 -}
   1.187 -
   1.188 -// Get a free spool buffer from the free pool, getting a new block
   1.189 -// from the heap if necessary.
   1.190 -SpoolBlock* PromotionInfo::getSpoolBlock() {
   1.191 -  SpoolBlock* res;
   1.192 -  if ((res = _spareSpool) != NULL) {
   1.193 -    _spareSpool = _spareSpool->nextSpoolBlock;
   1.194 -    res->nextSpoolBlock = NULL;
   1.195 -  } else {  // spare spool exhausted, get some from heap
   1.196 -    res = (SpoolBlock*)(space()->allocateScratch(refillSize()));
   1.197 -    if (res != NULL) {
   1.198 -      res->init();
   1.199 -    }
   1.200 -  }
   1.201 -  assert(res == NULL || res->nextSpoolBlock == NULL, "postcondition");
   1.202 -  return res;
   1.203 -}
   1.204 -
   1.205 -void PromotionInfo::startTrackingPromotions() {
   1.206 -  assert(_spoolHead == _spoolTail && _firstIndex == _nextIndex,
   1.207 -         "spooling inconsistency?");
   1.208 -  _firstIndex = _nextIndex = 1;
   1.209 -  _tracking = true;
   1.210 -}
   1.211 -
   1.212 -#define CMSPrintPromoBlockInfo 1
   1.213 -
   1.214 -void PromotionInfo::stopTrackingPromotions(uint worker_id) {
   1.215 -  assert(_spoolHead == _spoolTail && _firstIndex == _nextIndex,
   1.216 -         "spooling inconsistency?");
   1.217 -  _firstIndex = _nextIndex = 1;
   1.218 -  _tracking = false;
   1.219 -  if (CMSPrintPromoBlockInfo > 1) {
   1.220 -    print_statistics(worker_id);
   1.221 -  }
   1.222 -}
   1.223 -
   1.224 -void PromotionInfo::print_statistics(uint worker_id) const {
   1.225 -  assert(_spoolHead == _spoolTail && _firstIndex == _nextIndex,
   1.226 -         "Else will undercount");
   1.227 -  assert(CMSPrintPromoBlockInfo > 0, "Else unnecessary call");
   1.228 -  // Count the number of blocks and slots in the free pool
   1.229 -  size_t slots  = 0;
   1.230 -  size_t blocks = 0;
   1.231 -  for (SpoolBlock* cur_spool = _spareSpool;
   1.232 -       cur_spool != NULL;
   1.233 -       cur_spool = cur_spool->nextSpoolBlock) {
   1.234 -    // the first entry is just a self-pointer; indices 1 through
   1.235 -    // bufferSize - 1 are occupied (thus, bufferSize - 1 slots).
   1.236 -    guarantee((void*)cur_spool->displacedHdr == (void*)&cur_spool->displacedHdr,
   1.237 -              "first entry of displacedHdr should be self-referential");
   1.238 -    slots += cur_spool->bufferSize - 1;
   1.239 -    blocks++;
   1.240 -  }
   1.241 -  if (_spoolHead != NULL) {
   1.242 -    slots += _spoolHead->bufferSize - 1;
   1.243 -    blocks++;
   1.244 -  }
   1.245 -  gclog_or_tty->print_cr(" [worker %d] promo_blocks = %d, promo_slots = %d ",
   1.246 -                         worker_id, blocks, slots);
   1.247 -}
   1.248 -
   1.249 -// When _spoolTail is not NULL, then the slot <_spoolTail, _nextIndex>
   1.250 -// points to the next slot available for filling.
   1.251 -// The set of slots holding displaced headers are then all those in the
   1.252 -// right-open interval denoted by:
   1.253 -//
   1.254 -//    [ <_spoolHead, _firstIndex>, <_spoolTail, _nextIndex> )
   1.255 -//
   1.256 -// When _spoolTail is NULL, then the set of slots with displaced headers
   1.257 -// is all those starting at the slot <_spoolHead, _firstIndex> and
   1.258 -// going up to the last slot of last block in the linked list.
   1.259 -// In this lartter case, _splice_point points to the tail block of
   1.260 -// this linked list of blocks holding displaced headers.
   1.261 -void PromotionInfo::verify() const {
   1.262 -  // Verify the following:
   1.263 -  // 1. the number of displaced headers matches the number of promoted
   1.264 -  //    objects that have displaced headers
   1.265 -  // 2. each promoted object lies in this space
   1.266 -  debug_only(
   1.267 -    PromotedObject* junk = NULL;
   1.268 -    assert(junk->next_addr() == (void*)(oop(junk)->mark_addr()),
   1.269 -           "Offset of PromotedObject::_next is expected to align with "
   1.270 -           "  the OopDesc::_mark within OopDesc");
   1.271 -  )
   1.272 -  // FIXME: guarantee????
   1.273 -  guarantee(_spoolHead == NULL || _spoolTail != NULL ||
   1.274 -            _splice_point != NULL, "list consistency");
   1.275 -  guarantee(_promoHead == NULL || _promoTail != NULL, "list consistency");
   1.276 -  // count the number of objects with displaced headers
   1.277 -  size_t numObjsWithDisplacedHdrs = 0;
   1.278 -  for (PromotedObject* curObj = _promoHead; curObj != NULL; curObj = curObj->next()) {
   1.279 -    guarantee(space()->is_in_reserved((HeapWord*)curObj), "Containment");
   1.280 -    // the last promoted object may fail the mark() != NULL test of is_oop().
   1.281 -    guarantee(curObj->next() == NULL || oop(curObj)->is_oop(), "must be an oop");
   1.282 -    if (curObj->hasDisplacedMark()) {
   1.283 -      numObjsWithDisplacedHdrs++;
   1.284 -    }
   1.285 -  }
   1.286 -  // Count the number of displaced headers
   1.287 -  size_t numDisplacedHdrs = 0;
   1.288 -  for (SpoolBlock* curSpool = _spoolHead;
   1.289 -       curSpool != _spoolTail && curSpool != NULL;
   1.290 -       curSpool = curSpool->nextSpoolBlock) {
   1.291 -    // the first entry is just a self-pointer; indices 1 through
   1.292 -    // bufferSize - 1 are occupied (thus, bufferSize - 1 slots).
   1.293 -    guarantee((void*)curSpool->displacedHdr == (void*)&curSpool->displacedHdr,
   1.294 -              "first entry of displacedHdr should be self-referential");
   1.295 -    numDisplacedHdrs += curSpool->bufferSize - 1;
   1.296 -  }
   1.297 -  guarantee((_spoolHead == _spoolTail) == (numDisplacedHdrs == 0),
   1.298 -            "internal consistency");
   1.299 -  guarantee(_spoolTail != NULL || _nextIndex == 1,
   1.300 -            "Inconsistency between _spoolTail and _nextIndex");
   1.301 -  // We overcounted (_firstIndex-1) worth of slots in block
   1.302 -  // _spoolHead and we undercounted (_nextIndex-1) worth of
   1.303 -  // slots in block _spoolTail. We make an appropriate
   1.304 -  // adjustment by subtracting the first and adding the
   1.305 -  // second:  - (_firstIndex - 1) + (_nextIndex - 1)
   1.306 -  numDisplacedHdrs += (_nextIndex - _firstIndex);
   1.307 -  guarantee(numDisplacedHdrs == numObjsWithDisplacedHdrs, "Displaced hdr count");
   1.308 -}
   1.309 -
   1.310 -void PromotionInfo::print_on(outputStream* st) const {
   1.311 -  SpoolBlock* curSpool = NULL;
   1.312 -  size_t i = 0;
   1.313 -  st->print_cr("start & end indices: [" SIZE_FORMAT ", " SIZE_FORMAT ")",
   1.314 -               _firstIndex, _nextIndex);
   1.315 -  for (curSpool = _spoolHead; curSpool != _spoolTail && curSpool != NULL;
   1.316 -       curSpool = curSpool->nextSpoolBlock) {
   1.317 -    curSpool->print_on(st);
   1.318 -    st->print_cr(" active ");
   1.319 -    i++;
   1.320 -  }
   1.321 -  for (curSpool = _spoolTail; curSpool != NULL;
   1.322 -       curSpool = curSpool->nextSpoolBlock) {
   1.323 -    curSpool->print_on(st);
   1.324 -    st->print_cr(" inactive ");
   1.325 -    i++;
   1.326 -  }
   1.327 -  for (curSpool = _spareSpool; curSpool != NULL;
   1.328 -       curSpool = curSpool->nextSpoolBlock) {
   1.329 -    curSpool->print_on(st);
   1.330 -    st->print_cr(" free ");
   1.331 -    i++;
   1.332 -  }
   1.333 -  st->print_cr(SIZE_FORMAT " header spooling blocks", i);
   1.334 -}
   1.335 -
   1.336 -void SpoolBlock::print_on(outputStream* st) const {
   1.337 -  st->print("[" PTR_FORMAT "," PTR_FORMAT "), " SIZE_FORMAT " HeapWords -> " PTR_FORMAT,
   1.338 -            this, (HeapWord*)displacedHdr + bufferSize,
   1.339 -            bufferSize, nextSpoolBlock);
   1.340 -}
   1.341 -
   1.342  ///////////////////////////////////////////////////////////////////////////
   1.343  // CFLS_LAB
   1.344  ///////////////////////////////////////////////////////////////////////////

mercurial