提交 c4091c5a 编写于 作者: J jcoomes

Merge

/* /*
* Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -407,6 +407,11 @@ class CompactibleFreeListSpace: public CompactibleSpace { ...@@ -407,6 +407,11 @@ class CompactibleFreeListSpace: public CompactibleSpace {
void save_sweep_limit() { void save_sweep_limit() {
_sweep_limit = BlockOffsetArrayUseUnallocatedBlock ? _sweep_limit = BlockOffsetArrayUseUnallocatedBlock ?
unallocated_block() : end(); unallocated_block() : end();
if (CMSTraceSweeper) {
gclog_or_tty->print_cr(">>>>> Saving sweep limit " PTR_FORMAT
" for space [" PTR_FORMAT "," PTR_FORMAT ") <<<<<<",
_sweep_limit, bottom(), end());
}
} }
NOT_PRODUCT( NOT_PRODUCT(
void clear_sweep_limit() { _sweep_limit = NULL; } void clear_sweep_limit() { _sweep_limit = NULL; }
......
...@@ -7888,40 +7888,45 @@ SweepClosure::SweepClosure(CMSCollector* collector, ...@@ -7888,40 +7888,45 @@ SweepClosure::SweepClosure(CMSCollector* collector,
assert(_limit >= _sp->bottom() && _limit <= _sp->end(), assert(_limit >= _sp->bottom() && _limit <= _sp->end(),
"sweep _limit out of bounds"); "sweep _limit out of bounds");
if (CMSTraceSweeper) { if (CMSTraceSweeper) {
gclog_or_tty->print("\n====================\nStarting new sweep\n"); gclog_or_tty->print_cr("\n====================\nStarting new sweep with limit " PTR_FORMAT,
_limit);
} }
} }
// We need this destructor to reclaim any space at the end void SweepClosure::print_on(outputStream* st) const {
// of the space, which do_blk below may not yet have added back to tty->print_cr("_sp = [" PTR_FORMAT "," PTR_FORMAT ")",
// the free lists. _sp->bottom(), _sp->end());
tty->print_cr("_limit = " PTR_FORMAT, _limit);
tty->print_cr("_freeFinger = " PTR_FORMAT, _freeFinger);
NOT_PRODUCT(tty->print_cr("_last_fc = " PTR_FORMAT, _last_fc);)
tty->print_cr("_inFreeRange = %d, _freeRangeInFreeLists = %d, _lastFreeRangeCoalesced = %d",
_inFreeRange, _freeRangeInFreeLists, _lastFreeRangeCoalesced);
}
#ifndef PRODUCT
// Assertion checking only: no useful work in product mode --
// however, if any of the flags below become product flags,
// you may need to review this code to see if it needs to be
// enabled in product mode.
SweepClosure::~SweepClosure() { SweepClosure::~SweepClosure() {
assert_lock_strong(_freelistLock); assert_lock_strong(_freelistLock);
assert(_limit >= _sp->bottom() && _limit <= _sp->end(), assert(_limit >= _sp->bottom() && _limit <= _sp->end(),
"sweep _limit out of bounds"); "sweep _limit out of bounds");
// Flush any remaining coterminal free run as a single
// coalesced chunk to the appropriate free list.
if (inFreeRange()) { if (inFreeRange()) {
assert(freeFinger() < _limit, "freeFinger points too high"); warning("inFreeRange() should have been reset; dumping state of SweepClosure");
flush_cur_free_chunk(freeFinger(), pointer_delta(_limit, freeFinger())); print();
if (CMSTraceSweeper) { ShouldNotReachHere();
gclog_or_tty->print("Sweep: last chunk: ");
gclog_or_tty->print("put_free_blk 0x%x ("SIZE_FORMAT") [coalesced:"SIZE_FORMAT"]\n",
freeFinger(), pointer_delta(_limit, freeFinger()), lastFreeRangeCoalesced());
} }
} // else nothing to flush
NOT_PRODUCT(
if (Verbose && PrintGC) { if (Verbose && PrintGC) {
gclog_or_tty->print("Collected "SIZE_FORMAT" objects, " gclog_or_tty->print("Collected "SIZE_FORMAT" objects, " SIZE_FORMAT " bytes",
SIZE_FORMAT " bytes",
_numObjectsFreed, _numWordsFreed*sizeof(HeapWord)); _numObjectsFreed, _numWordsFreed*sizeof(HeapWord));
gclog_or_tty->print_cr("\nLive "SIZE_FORMAT" objects, " gclog_or_tty->print_cr("\nLive "SIZE_FORMAT" objects, "
SIZE_FORMAT" bytes " SIZE_FORMAT" bytes "
"Already free "SIZE_FORMAT" objects, "SIZE_FORMAT" bytes", "Already free "SIZE_FORMAT" objects, "SIZE_FORMAT" bytes",
_numObjectsLive, _numWordsLive*sizeof(HeapWord), _numObjectsLive, _numWordsLive*sizeof(HeapWord),
_numObjectsAlreadyFree, _numWordsAlreadyFree*sizeof(HeapWord)); _numObjectsAlreadyFree, _numWordsAlreadyFree*sizeof(HeapWord));
size_t totalBytes = (_numWordsFreed + _numWordsLive + _numWordsAlreadyFree) * size_t totalBytes = (_numWordsFreed + _numWordsLive + _numWordsAlreadyFree)
sizeof(HeapWord); * sizeof(HeapWord);
gclog_or_tty->print_cr("Total sweep: "SIZE_FORMAT" bytes", totalBytes); gclog_or_tty->print_cr("Total sweep: "SIZE_FORMAT" bytes", totalBytes);
if (PrintCMSStatistics && CMSVerifyReturnedBytes) { if (PrintCMSStatistics && CMSVerifyReturnedBytes) {
...@@ -7935,13 +7940,12 @@ SweepClosure::~SweepClosure() { ...@@ -7935,13 +7940,12 @@ SweepClosure::~SweepClosure() {
dictReturnedBytes); dictReturnedBytes);
} }
} }
)
// Now, in debug mode, just null out the sweep_limit
NOT_PRODUCT(_sp->clear_sweep_limit();)
if (CMSTraceSweeper) { if (CMSTraceSweeper) {
gclog_or_tty->print("end of sweep\n================\n"); gclog_or_tty->print_cr("end of sweep with _limit = " PTR_FORMAT "\n================",
_limit);
} }
} }
#endif // PRODUCT
void SweepClosure::initialize_free_range(HeapWord* freeFinger, void SweepClosure::initialize_free_range(HeapWord* freeFinger,
bool freeRangeInFreeLists) { bool freeRangeInFreeLists) {
...@@ -8001,15 +8005,17 @@ size_t SweepClosure::do_blk_careful(HeapWord* addr) { ...@@ -8001,15 +8005,17 @@ size_t SweepClosure::do_blk_careful(HeapWord* addr) {
// we started the sweep, it may no longer be one because heap expansion // we started the sweep, it may no longer be one because heap expansion
// may have caused us to coalesce the block ending at the address _limit // may have caused us to coalesce the block ending at the address _limit
// with a newly expanded chunk (this happens when _limit was set to the // with a newly expanded chunk (this happens when _limit was set to the
// previous _end of the space), so we may have stepped past _limit; see CR 6977970. // previous _end of the space), so we may have stepped past _limit:
// see the following Zeno-like trail of CRs 6977970, 7008136, 7042740.
if (addr >= _limit) { // we have swept up to or past the limit: finish up if (addr >= _limit) { // we have swept up to or past the limit: finish up
assert(_limit >= _sp->bottom() && _limit <= _sp->end(), assert(_limit >= _sp->bottom() && _limit <= _sp->end(),
"sweep _limit out of bounds"); "sweep _limit out of bounds");
assert(addr < _sp->end(), "addr out of bounds"); assert(addr < _sp->end(), "addr out of bounds");
// Flush any remaining coterminal free run as a single // Flush any free range we might be holding as a single
// coalesced chunk to the appropriate free list. // coalesced chunk to the appropriate free list.
if (inFreeRange()) { if (inFreeRange()) {
assert(freeFinger() < _limit, "finger points too high"); assert(freeFinger() >= _sp->bottom() && freeFinger() < _limit,
err_msg("freeFinger() " PTR_FORMAT" is out-of-bounds", freeFinger()));
flush_cur_free_chunk(freeFinger(), flush_cur_free_chunk(freeFinger(),
pointer_delta(addr, freeFinger())); pointer_delta(addr, freeFinger()));
if (CMSTraceSweeper) { if (CMSTraceSweeper) {
...@@ -8033,7 +8039,16 @@ size_t SweepClosure::do_blk_careful(HeapWord* addr) { ...@@ -8033,7 +8039,16 @@ size_t SweepClosure::do_blk_careful(HeapWord* addr) {
res = fc->size(); res = fc->size();
do_already_free_chunk(fc); do_already_free_chunk(fc);
debug_only(_sp->verifyFreeLists()); debug_only(_sp->verifyFreeLists());
assert(res == fc->size(), "Don't expect the size to change"); // If we flush the chunk at hand in lookahead_and_flush()
// and it's coalesced with a preceding chunk, then the
// process of "mangling" the payload of the coalesced block
// will cause erasure of the size information from the
// (erstwhile) header of all the coalesced blocks but the
// first, so the first disjunct in the assert will not hold
// in that specific case (in which case the second disjunct
// will hold).
assert(res == fc->size() || ((HeapWord*)fc) + res >= _limit,
"Otherwise the size info doesn't change at this step");
NOT_PRODUCT( NOT_PRODUCT(
_numObjectsAlreadyFree++; _numObjectsAlreadyFree++;
_numWordsAlreadyFree += res; _numWordsAlreadyFree += res;
...@@ -8103,7 +8118,7 @@ size_t SweepClosure::do_blk_careful(HeapWord* addr) { ...@@ -8103,7 +8118,7 @@ size_t SweepClosure::do_blk_careful(HeapWord* addr) {
// //
void SweepClosure::do_already_free_chunk(FreeChunk* fc) { void SweepClosure::do_already_free_chunk(FreeChunk* fc) {
size_t size = fc->size(); const size_t size = fc->size();
// Chunks that cannot be coalesced are not in the // Chunks that cannot be coalesced are not in the
// free lists. // free lists.
if (CMSTestInFreeList && !fc->cantCoalesce()) { if (CMSTestInFreeList && !fc->cantCoalesce()) {
...@@ -8112,7 +8127,7 @@ void SweepClosure::do_already_free_chunk(FreeChunk* fc) { ...@@ -8112,7 +8127,7 @@ void SweepClosure::do_already_free_chunk(FreeChunk* fc) {
} }
// a chunk that is already free, should not have been // a chunk that is already free, should not have been
// marked in the bit map // marked in the bit map
HeapWord* addr = (HeapWord*) fc; HeapWord* const addr = (HeapWord*) fc;
assert(!_bitMap->isMarked(addr), "free chunk should be unmarked"); assert(!_bitMap->isMarked(addr), "free chunk should be unmarked");
// Verify that the bit map has no bits marked between // Verify that the bit map has no bits marked between
// addr and purported end of this block. // addr and purported end of this block.
...@@ -8149,7 +8164,7 @@ void SweepClosure::do_already_free_chunk(FreeChunk* fc) { ...@@ -8149,7 +8164,7 @@ void SweepClosure::do_already_free_chunk(FreeChunk* fc) {
} }
} else { } else {
// the midst of a free range, we are coalescing // the midst of a free range, we are coalescing
debug_only(record_free_block_coalesced(fc);) print_free_block_coalesced(fc);
if (CMSTraceSweeper) { if (CMSTraceSweeper) {
gclog_or_tty->print(" -- pick up free block 0x%x (%d)\n", fc, size); gclog_or_tty->print(" -- pick up free block 0x%x (%d)\n", fc, size);
} }
...@@ -8173,6 +8188,10 @@ void SweepClosure::do_already_free_chunk(FreeChunk* fc) { ...@@ -8173,6 +8188,10 @@ void SweepClosure::do_already_free_chunk(FreeChunk* fc) {
} }
} }
} }
// Note that if the chunk is not coalescable (the else arm
// below), we unconditionally flush, without needing to do
// a "lookahead," as we do below.
if (inFreeRange()) lookahead_and_flush(fc, size);
} else { } else {
// Code path common to both original and adaptive free lists. // Code path common to both original and adaptive free lists.
...@@ -8191,8 +8210,8 @@ size_t SweepClosure::do_garbage_chunk(FreeChunk* fc) { ...@@ -8191,8 +8210,8 @@ size_t SweepClosure::do_garbage_chunk(FreeChunk* fc) {
// This is a chunk of garbage. It is not in any free list. // This is a chunk of garbage. It is not in any free list.
// Add it to a free list or let it possibly be coalesced into // Add it to a free list or let it possibly be coalesced into
// a larger chunk. // a larger chunk.
HeapWord* addr = (HeapWord*) fc; HeapWord* const addr = (HeapWord*) fc;
size_t size = CompactibleFreeListSpace::adjustObjectSize(oop(addr)->size()); const size_t size = CompactibleFreeListSpace::adjustObjectSize(oop(addr)->size());
if (_sp->adaptive_freelists()) { if (_sp->adaptive_freelists()) {
// Verify that the bit map has no bits marked between // Verify that the bit map has no bits marked between
...@@ -8205,7 +8224,6 @@ size_t SweepClosure::do_garbage_chunk(FreeChunk* fc) { ...@@ -8205,7 +8224,6 @@ size_t SweepClosure::do_garbage_chunk(FreeChunk* fc) {
// start of a new free range // start of a new free range
assert(size > 0, "A free range should have a size"); assert(size > 0, "A free range should have a size");
initialize_free_range(addr, false); initialize_free_range(addr, false);
} else { } else {
// this will be swept up when we hit the end of the // this will be swept up when we hit the end of the
// free range // free range
...@@ -8235,6 +8253,9 @@ size_t SweepClosure::do_garbage_chunk(FreeChunk* fc) { ...@@ -8235,6 +8253,9 @@ size_t SweepClosure::do_garbage_chunk(FreeChunk* fc) {
// addr and purported end of just dead object. // addr and purported end of just dead object.
_bitMap->verifyNoOneBitsInRange(addr + 1, addr + size); _bitMap->verifyNoOneBitsInRange(addr + 1, addr + size);
} }
assert(_limit >= addr + size,
"A freshly garbage chunk can't possibly straddle over _limit");
if (inFreeRange()) lookahead_and_flush(fc, size);
return size; return size;
} }
...@@ -8284,8 +8305,8 @@ size_t SweepClosure::do_live_chunk(FreeChunk* fc) { ...@@ -8284,8 +8305,8 @@ size_t SweepClosure::do_live_chunk(FreeChunk* fc) {
(!_collector->should_unload_classes() (!_collector->should_unload_classes()
|| oop(addr)->is_parsable()), || oop(addr)->is_parsable()),
"Should be an initialized object"); "Should be an initialized object");
// Note that there are objects used during class redefinition // Note that there are objects used during class redefinition,
// (e.g., merge_cp in VM_RedefineClasses::merge_cp_and_rewrite() // e.g. merge_cp in VM_RedefineClasses::merge_cp_and_rewrite(),
// which are discarded with their is_conc_safe state still // which are discarded with their is_conc_safe state still
// false. These object may be floating garbage so may be // false. These object may be floating garbage so may be
// seen here. If they are floating garbage their size // seen here. If they are floating garbage their size
...@@ -8307,7 +8328,7 @@ void SweepClosure::do_post_free_or_garbage_chunk(FreeChunk* fc, ...@@ -8307,7 +8328,7 @@ void SweepClosure::do_post_free_or_garbage_chunk(FreeChunk* fc,
size_t chunkSize) { size_t chunkSize) {
// do_post_free_or_garbage_chunk() should only be called in the case // do_post_free_or_garbage_chunk() should only be called in the case
// of the adaptive free list allocator. // of the adaptive free list allocator.
bool fcInFreeLists = fc->isFree(); const bool fcInFreeLists = fc->isFree();
assert(_sp->adaptive_freelists(), "Should only be used in this case."); assert(_sp->adaptive_freelists(), "Should only be used in this case.");
assert((HeapWord*)fc <= _limit, "sweep invariant"); assert((HeapWord*)fc <= _limit, "sweep invariant");
if (CMSTestInFreeList && fcInFreeLists) { if (CMSTestInFreeList && fcInFreeLists) {
...@@ -8318,11 +8339,11 @@ void SweepClosure::do_post_free_or_garbage_chunk(FreeChunk* fc, ...@@ -8318,11 +8339,11 @@ void SweepClosure::do_post_free_or_garbage_chunk(FreeChunk* fc,
gclog_or_tty->print_cr(" -- pick up another chunk at 0x%x (%d)", fc, chunkSize); gclog_or_tty->print_cr(" -- pick up another chunk at 0x%x (%d)", fc, chunkSize);
} }
HeapWord* addr = (HeapWord*) fc; HeapWord* const fc_addr = (HeapWord*) fc;
bool coalesce; bool coalesce;
size_t left = pointer_delta(addr, freeFinger()); const size_t left = pointer_delta(fc_addr, freeFinger());
size_t right = chunkSize; const size_t right = chunkSize;
switch (FLSCoalescePolicy) { switch (FLSCoalescePolicy) {
// numeric value forms a coalition aggressiveness metric // numeric value forms a coalition aggressiveness metric
case 0: { // never coalesce case 0: { // never coalesce
...@@ -8355,15 +8376,15 @@ void SweepClosure::do_post_free_or_garbage_chunk(FreeChunk* fc, ...@@ -8355,15 +8376,15 @@ void SweepClosure::do_post_free_or_garbage_chunk(FreeChunk* fc,
// If the chunk is in a free range and either we decided to coalesce above // If the chunk is in a free range and either we decided to coalesce above
// or the chunk is near the large block at the end of the heap // or the chunk is near the large block at the end of the heap
// (isNearLargestChunk() returns true), then coalesce this chunk. // (isNearLargestChunk() returns true), then coalesce this chunk.
bool doCoalesce = inFreeRange() && const bool doCoalesce = inFreeRange()
(coalesce || _g->isNearLargestChunk((HeapWord*)fc)); && (coalesce || _g->isNearLargestChunk(fc_addr));
if (doCoalesce) { if (doCoalesce) {
// Coalesce the current free range on the left with the new // Coalesce the current free range on the left with the new
// chunk on the right. If either is on a free list, // chunk on the right. If either is on a free list,
// it must be removed from the list and stashed in the closure. // it must be removed from the list and stashed in the closure.
if (freeRangeInFreeLists()) { if (freeRangeInFreeLists()) {
FreeChunk* ffc = (FreeChunk*)freeFinger(); FreeChunk* const ffc = (FreeChunk*)freeFinger();
assert(ffc->size() == pointer_delta(addr, freeFinger()), assert(ffc->size() == pointer_delta(fc_addr, freeFinger()),
"Size of free range is inconsistent with chunk size."); "Size of free range is inconsistent with chunk size.");
if (CMSTestInFreeList) { if (CMSTestInFreeList) {
assert(_sp->verifyChunkInFreeLists(ffc), assert(_sp->verifyChunkInFreeLists(ffc),
...@@ -8380,13 +8401,14 @@ void SweepClosure::do_post_free_or_garbage_chunk(FreeChunk* fc, ...@@ -8380,13 +8401,14 @@ void SweepClosure::do_post_free_or_garbage_chunk(FreeChunk* fc,
_sp->removeFreeChunkFromFreeLists(fc); _sp->removeFreeChunkFromFreeLists(fc);
} }
set_lastFreeRangeCoalesced(true); set_lastFreeRangeCoalesced(true);
print_free_block_coalesced(fc);
} else { // not in a free range and/or should not coalesce } else { // not in a free range and/or should not coalesce
// Return the current free range and start a new one. // Return the current free range and start a new one.
if (inFreeRange()) { if (inFreeRange()) {
// In a free range but cannot coalesce with the right hand chunk. // In a free range but cannot coalesce with the right hand chunk.
// Put the current free range into the free lists. // Put the current free range into the free lists.
flush_cur_free_chunk(freeFinger(), flush_cur_free_chunk(freeFinger(),
pointer_delta(addr, freeFinger())); pointer_delta(fc_addr, freeFinger()));
} }
// Set up for new free range. Pass along whether the right hand // Set up for new free range. Pass along whether the right hand
// chunk is in the free lists. // chunk is in the free lists.
...@@ -8394,6 +8416,42 @@ void SweepClosure::do_post_free_or_garbage_chunk(FreeChunk* fc, ...@@ -8394,6 +8416,42 @@ void SweepClosure::do_post_free_or_garbage_chunk(FreeChunk* fc,
} }
} }
// Lookahead flush:
// If we are tracking a free range, and this is the last chunk that
// we'll look at because its end crosses past _limit, we'll preemptively
// flush it along with any free range we may be holding on to. Note that
// this can be the case only for an already free or freshly garbage
// chunk. If this block is an object, it can never straddle
// over _limit. The "straddling" occurs when _limit is set at
// the previous end of the space when this cycle started, and
// a subsequent heap expansion caused the previously co-terminal
// free block to be coalesced with the newly expanded portion,
// thus rendering _limit a non-block-boundary making it dangerous
// for the sweeper to step over and examine.
void SweepClosure::lookahead_and_flush(FreeChunk* fc, size_t chunk_size) {
assert(inFreeRange(), "Should only be called if currently in a free range.");
HeapWord* const eob = ((HeapWord*)fc) + chunk_size;
assert(_sp->used_region().contains(eob - 1),
err_msg("eob = " PTR_FORMAT " out of bounds wrt _sp = [" PTR_FORMAT "," PTR_FORMAT ")"
" when examining fc = " PTR_FORMAT "(" SIZE_FORMAT ")",
_limit, _sp->bottom(), _sp->end(), fc, chunk_size));
if (eob >= _limit) {
assert(eob == _limit || fc->isFree(), "Only a free chunk should allow us to cross over the limit");
if (CMSTraceSweeper) {
gclog_or_tty->print_cr("_limit " PTR_FORMAT " reached or crossed by block "
"[" PTR_FORMAT "," PTR_FORMAT ") in space "
"[" PTR_FORMAT "," PTR_FORMAT ")",
_limit, fc, eob, _sp->bottom(), _sp->end());
}
// Return the storage we are tracking back into the free lists.
if (CMSTraceSweeper) {
gclog_or_tty->print_cr("Flushing ... ");
}
assert(freeFinger() < eob, "Error");
flush_cur_free_chunk( freeFinger(), pointer_delta(eob, freeFinger()));
}
}
void SweepClosure::flush_cur_free_chunk(HeapWord* chunk, size_t size) { void SweepClosure::flush_cur_free_chunk(HeapWord* chunk, size_t size) {
assert(inFreeRange(), "Should only be called if currently in a free range."); assert(inFreeRange(), "Should only be called if currently in a free range.");
assert(size > 0, assert(size > 0,
...@@ -8419,6 +8477,8 @@ void SweepClosure::flush_cur_free_chunk(HeapWord* chunk, size_t size) { ...@@ -8419,6 +8477,8 @@ void SweepClosure::flush_cur_free_chunk(HeapWord* chunk, size_t size) {
} }
_sp->addChunkAndRepairOffsetTable(chunk, size, _sp->addChunkAndRepairOffsetTable(chunk, size,
lastFreeRangeCoalesced()); lastFreeRangeCoalesced());
} else if (CMSTraceSweeper) {
gclog_or_tty->print_cr("Already in free list: nothing to flush");
} }
set_inFreeRange(false); set_inFreeRange(false);
set_freeRangeInFreeLists(false); set_freeRangeInFreeLists(false);
...@@ -8477,13 +8537,14 @@ void SweepClosure::do_yield_work(HeapWord* addr) { ...@@ -8477,13 +8537,14 @@ void SweepClosure::do_yield_work(HeapWord* addr) {
bool debug_verifyChunkInFreeLists(FreeChunk* fc) { bool debug_verifyChunkInFreeLists(FreeChunk* fc) {
return debug_cms_space->verifyChunkInFreeLists(fc); return debug_cms_space->verifyChunkInFreeLists(fc);
} }
#endif
void SweepClosure::record_free_block_coalesced(FreeChunk* fc) const { void SweepClosure::print_free_block_coalesced(FreeChunk* fc) const {
if (CMSTraceSweeper) { if (CMSTraceSweeper) {
gclog_or_tty->print("Sweep:coal_free_blk 0x%x (%d)\n", fc, fc->size()); gclog_or_tty->print_cr("Sweep:coal_free_blk " PTR_FORMAT " (" SIZE_FORMAT ")",
fc, fc->size());
} }
} }
#endif
// CMSIsAliveClosure // CMSIsAliveClosure
bool CMSIsAliveClosure::do_object_b(oop obj) { bool CMSIsAliveClosure::do_object_b(oop obj) {
......
...@@ -1701,9 +1701,9 @@ class SweepClosure: public BlkClosureCareful { ...@@ -1701,9 +1701,9 @@ class SweepClosure: public BlkClosureCareful {
CMSCollector* _collector; // collector doing the work CMSCollector* _collector; // collector doing the work
ConcurrentMarkSweepGeneration* _g; // Generation being swept ConcurrentMarkSweepGeneration* _g; // Generation being swept
CompactibleFreeListSpace* _sp; // Space being swept CompactibleFreeListSpace* _sp; // Space being swept
HeapWord* _limit;// the address at which the sweep should stop because HeapWord* _limit;// the address at or above which the sweep should stop
// we do not expect blocks eligible for sweeping past // because we do not expect newly garbage blocks
// that address. // eligible for sweeping past that address.
Mutex* _freelistLock; // Free list lock (in space) Mutex* _freelistLock; // Free list lock (in space)
CMSBitMap* _bitMap; // Marking bit map (in CMSBitMap* _bitMap; // Marking bit map (in
// generation) // generation)
...@@ -1750,6 +1750,10 @@ class SweepClosure: public BlkClosureCareful { ...@@ -1750,6 +1750,10 @@ class SweepClosure: public BlkClosureCareful {
void do_post_free_or_garbage_chunk(FreeChunk *fc, size_t chunkSize); void do_post_free_or_garbage_chunk(FreeChunk *fc, size_t chunkSize);
// Process a free chunk during sweeping. // Process a free chunk during sweeping.
void do_already_free_chunk(FreeChunk *fc); void do_already_free_chunk(FreeChunk *fc);
// Work method called when processing an already free or a
// freshly garbage chunk to do a lookahead and possibly a
// premptive flush if crossing over _limit.
void lookahead_and_flush(FreeChunk* fc, size_t chunkSize);
// Process a garbage chunk during sweeping. // Process a garbage chunk during sweeping.
size_t do_garbage_chunk(FreeChunk *fc); size_t do_garbage_chunk(FreeChunk *fc);
// Process a live chunk during sweeping. // Process a live chunk during sweeping.
...@@ -1758,8 +1762,6 @@ class SweepClosure: public BlkClosureCareful { ...@@ -1758,8 +1762,6 @@ class SweepClosure: public BlkClosureCareful {
// Accessors. // Accessors.
HeapWord* freeFinger() const { return _freeFinger; } HeapWord* freeFinger() const { return _freeFinger; }
void set_freeFinger(HeapWord* v) { _freeFinger = v; } void set_freeFinger(HeapWord* v) { _freeFinger = v; }
size_t freeRangeSize() const { return _freeRangeSize; }
void set_freeRangeSize(size_t v) { _freeRangeSize = v; }
bool inFreeRange() const { return _inFreeRange; } bool inFreeRange() const { return _inFreeRange; }
void set_inFreeRange(bool v) { _inFreeRange = v; } void set_inFreeRange(bool v) { _inFreeRange = v; }
bool lastFreeRangeCoalesced() const { return _lastFreeRangeCoalesced; } bool lastFreeRangeCoalesced() const { return _lastFreeRangeCoalesced; }
...@@ -1779,14 +1781,16 @@ class SweepClosure: public BlkClosureCareful { ...@@ -1779,14 +1781,16 @@ class SweepClosure: public BlkClosureCareful {
void do_yield_work(HeapWord* addr); void do_yield_work(HeapWord* addr);
// Debugging/Printing // Debugging/Printing
void record_free_block_coalesced(FreeChunk* fc) const PRODUCT_RETURN; void print_free_block_coalesced(FreeChunk* fc) const;
public: public:
SweepClosure(CMSCollector* collector, ConcurrentMarkSweepGeneration* g, SweepClosure(CMSCollector* collector, ConcurrentMarkSweepGeneration* g,
CMSBitMap* bitMap, bool should_yield); CMSBitMap* bitMap, bool should_yield);
~SweepClosure(); ~SweepClosure() PRODUCT_RETURN;
size_t do_blk_careful(HeapWord* addr); size_t do_blk_careful(HeapWord* addr);
void print() const { print_on(tty); }
void print_on(outputStream *st) const;
}; };
// Closures related to weak references processing // Closures related to weak references processing
......
/* /*
* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -566,11 +566,17 @@ HeapWord* BlockOffsetArrayNonContigSpace::block_start_unsafe( ...@@ -566,11 +566,17 @@ HeapWord* BlockOffsetArrayNonContigSpace::block_start_unsafe(
q = n; q = n;
n += _sp->block_size(n); n += _sp->block_size(n);
assert(n > q, assert(n > q,
err_msg("Looping at n = " PTR_FORMAT " with last = " PTR_FORMAT " _sp = [" PTR_FORMAT "," PTR_FORMAT ")", err_msg("Looping at n = " PTR_FORMAT " with last = " PTR_FORMAT","
n, last, _sp->bottom(), _sp->end())); " while querying blk_start(" PTR_FORMAT ")"
} " on _sp = [" PTR_FORMAT "," PTR_FORMAT ")",
assert(q <= addr, err_msg("wrong order for current (" INTPTR_FORMAT ") <= arg (" INTPTR_FORMAT ")", q, addr)); n, last, addr, _sp->bottom(), _sp->end()));
assert(addr <= n, err_msg("wrong order for arg (" INTPTR_FORMAT ") <= next (" INTPTR_FORMAT ")", addr, n)); }
assert(q <= addr,
err_msg("wrong order for current (" INTPTR_FORMAT ")" " <= arg (" INTPTR_FORMAT ")",
q, addr));
assert(addr <= n,
err_msg("wrong order for arg (" INTPTR_FORMAT ") <= next (" INTPTR_FORMAT ")",
addr, n));
return q; return q;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册