8202641: Replace OOP_SINCE_SAVE_MARKS with templates

Reviewed-by: eosterlund, sjohanss
This commit is contained in:
Stefan Karlsson 2018-05-07 14:42:08 +02:00
parent 2e1bd03bad
commit 1dd85fe2f4
31 changed files with 297 additions and 276 deletions

@ -104,6 +104,14 @@ public:
return static_cast<ConcurrentMarkSweepGeneration*>(_old_gen);
}
// Apply "cur->do_oop" or "older->do_oop" to all the oops in objects
// allocated since the last call to save_marks in the young generation.
// The "cur" closure is applied to references in the younger generation
// at "level", and the "older" closure to older generations.
template <typename OopClosureType1, typename OopClosureType2>
void oop_since_save_marks_iterate(OopClosureType1* cur,
OopClosureType2* older);
private:
WorkGang* _workers;
MemoryPool* _eden_pool;

@ -0,0 +1,39 @@
/*
* Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef SHARE_GC_CMS_CMSHEAP_INLINE_HPP
#define SHARE_GC_CMS_CMSHEAP_INLINE_HPP
#include "gc/cms/cmsHeap.hpp"
#include "gc/cms/concurrentMarkSweepGeneration.inline.hpp"
#include "gc/serial/defNewGeneration.inline.hpp"
template <typename OopClosureType1, typename OopClosureType2>
void CMSHeap::oop_since_save_marks_iterate(OopClosureType1* cur,
OopClosureType2* older) {
young_gen()->oop_since_save_marks_iterate(cur);
old_gen()->oop_since_save_marks_iterate(older);
}
#endif // SHARE_GC_CMS_CMSHEAP_INLINE_HPP

@ -66,8 +66,4 @@ class CMSInnerParMarkAndPushClosure;
f(ParMarkRefsIntoAndScanClosure,_nv) \
f(ParPushAndMarkClosure,_nv)
#define SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES_YOUNG_P(f) \
f(ParScanWithBarrierClosure,_nv) \
f(ParScanWithoutBarrierClosure,_nv)
#endif // SHARE_GC_CMS_CMS_SPECIALIZED_OOP_CLOSURES_HPP

@ -2103,22 +2103,6 @@ bool CompactibleFreeListSpace::no_allocs_since_save_marks() {
return _promoInfo.noPromotions();
}
#define CFLS_OOP_SINCE_SAVE_MARKS_DEFN(OopClosureType, nv_suffix) \
\
void CompactibleFreeListSpace:: \
oop_since_save_marks_iterate##nv_suffix(OopClosureType* blk) { \
_promoInfo.promoted_oops_iterate##nv_suffix(blk); \
/* \
* This also restores any displaced headers and removes the elements from \
* the iteration set as they are processed, so that we have a clean slate \
* at the end of the iteration. Note, thus, that if new objects are \
* promoted as a result of the iteration they are iterated over as well. \
*/ \
assert(_promoInfo.noPromotions(), "_promoInfo inconsistency"); \
}
ALL_SINCE_SAVE_MARKS_CLOSURES(CFLS_OOP_SINCE_SAVE_MARKS_DEFN)
bool CompactibleFreeListSpace::linearAllocationWouldFail() const {
return _smallLinearAllocBlock._word_size == 0;
}

@ -501,10 +501,8 @@ class CompactibleFreeListSpace: public CompactibleSpace {
// Fields in objects allocated by applications of the closure
// *are* included in the iteration. Thus, when the iteration completes
// there should be no further such objects remaining.
#define CFLS_OOP_SINCE_SAVE_MARKS_DECL(OopClosureType, nv_suffix) \
void oop_since_save_marks_iterate##nv_suffix(OopClosureType* blk);
ALL_SINCE_SAVE_MARKS_CLOSURES(CFLS_OOP_SINCE_SAVE_MARKS_DECL)
#undef CFLS_OOP_SINCE_SAVE_MARKS_DECL
template <typename OopClosureType>
void oop_since_save_marks_iterate(OopClosureType* blk);
// Allocation support
HeapWord* allocate(size_t size);

@ -0,0 +1,42 @@
/*
* Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef SHARE_GC_CMS_COMPACTIBLEFREELISTSPACE_INLINE_HPP
#define SHARE_GC_CMS_COMPACTIBLEFREELISTSPACE_INLINE_HPP
#include "gc/cms/compactibleFreeListSpace.hpp"
#include "gc/cms/promotionInfo.inline.hpp"
template <typename OopClosureType>
void CompactibleFreeListSpace::oop_since_save_marks_iterate(OopClosureType* blk) {
_promoInfo.promoted_oops_iterate(blk);
// This also restores any displaced headers and removes the elements from
// the iteration set as they are processed, so that we have a clean slate
// at the end of the iteration. Note, thus, that if new objects are
// promoted as a result of the iteration they are iterated over as well.
assert(_promoInfo.noPromotions(), "_promoInfo inconsistency");
}
#endif // SHARE_GC_CMS_COMPACTIBLEFREELISTSPACE_INLINE_HPP

@ -36,6 +36,7 @@
#include "gc/cms/concurrentMarkSweepGeneration.inline.hpp"
#include "gc/cms/concurrentMarkSweepThread.hpp"
#include "gc/cms/parNewGeneration.hpp"
#include "gc/cms/promotionInfo.inline.hpp"
#include "gc/cms/vmCMSOperations.hpp"
#include "gc/serial/genMarkSweep.hpp"
#include "gc/serial/tenuredGeneration.hpp"
@ -1099,7 +1100,7 @@ ConcurrentMarkSweepGeneration::
par_oop_since_save_marks_iterate_done(int thread_num) {
CMSParGCThreadState* ps = _par_gc_thread_states[thread_num];
ParScanWithoutBarrierClosure* dummy_cl = NULL;
ps->promo.promoted_oops_iterate_nv(dummy_cl);
ps->promo.promoted_oops_iterate(dummy_cl);
// Because card-scanning has been completed, subsequent phases
// (e.g., reference processing) will not need to recognize which
@ -2461,18 +2462,6 @@ bool ConcurrentMarkSweepGeneration::no_allocs_since_save_marks() {
return cmsSpace()->no_allocs_since_save_marks();
}
#define CMS_SINCE_SAVE_MARKS_DEFN(OopClosureType, nv_suffix) \
\
void ConcurrentMarkSweepGeneration:: \
oop_since_save_marks_iterate##nv_suffix(OopClosureType* cl) { \
cl->set_generation(this); \
cmsSpace()->oop_since_save_marks_iterate##nv_suffix(cl); \
cl->reset_generation(); \
save_marks(); \
}
ALL_SINCE_SAVE_MARKS_CLOSURES(CMS_SINCE_SAVE_MARKS_DEFN)
void
ConcurrentMarkSweepGeneration::oop_iterate(ExtendedOopClosure* cl) {
if (freelistLock()->owned_by_self()) {

@ -1195,12 +1195,8 @@ class ConcurrentMarkSweepGeneration: public CardGeneration {
virtual void safe_object_iterate(ObjectClosure* cl);
virtual void object_iterate(ObjectClosure* cl);
// Need to declare the full complement of closures, whether we'll
// override them or not, or get message from the compiler:
// oop_since_save_marks_iterate_nv hides virtual function...
#define CMS_SINCE_SAVE_MARKS_DECL(OopClosureType, nv_suffix) \
void oop_since_save_marks_iterate##nv_suffix(OopClosureType* cl);
ALL_SINCE_SAVE_MARKS_CLOSURES(CMS_SINCE_SAVE_MARKS_DECL)
template <typename OopClosureType>
void oop_since_save_marks_iterate(OopClosureType* cl);
// Smart allocation XXX -- move to CFLSpace?
void setNearLargestChunk();

@ -27,7 +27,7 @@
#include "gc/cms/cmsHeap.hpp"
#include "gc/cms/cmsLockVerifier.hpp"
#include "gc/cms/compactibleFreeListSpace.hpp"
#include "gc/cms/compactibleFreeListSpace.inline.hpp"
#include "gc/cms/concurrentMarkSweepGeneration.hpp"
#include "gc/cms/concurrentMarkSweepThread.hpp"
#include "gc/cms/parNewGeneration.hpp"
@ -375,6 +375,14 @@ inline MemRegion ConcurrentMarkSweepGeneration::used_region_at_save_marks() cons
return _cmsSpace->used_region_at_save_marks();
}
template <typename OopClosureType>
void ConcurrentMarkSweepGeneration::oop_since_save_marks_iterate(OopClosureType* cl) {
cl->set_generation(this);
cmsSpace()->oop_since_save_marks_iterate(cl);
cl->reset_generation();
save_marks();
}
inline void MarkFromRootsClosure::do_yield_check() {
if (ConcurrentMarkSweepThread::should_yield() &&
!_collector->foregroundGCIsActive() &&

@ -23,7 +23,7 @@
*/
#include "precompiled.hpp"
#include "gc/cms/cmsHeap.hpp"
#include "gc/cms/cmsHeap.inline.hpp"
#include "gc/cms/compactibleFreeListSpace.hpp"
#include "gc/cms/concurrentMarkSweepGeneration.hpp"
#include "gc/cms/parNewGeneration.inline.hpp"
@ -36,7 +36,6 @@
#include "gc/shared/gcTimer.hpp"
#include "gc/shared/gcTrace.hpp"
#include "gc/shared/gcTraceTime.inline.hpp"
#include "gc/shared/genCollectedHeap.hpp"
#include "gc/shared/genOopClosures.inline.hpp"
#include "gc/shared/generation.hpp"
#include "gc/shared/plab.inline.hpp"
@ -836,20 +835,19 @@ ScanClosureWithParBarrier(ParNewGeneration* g, bool gc_barrier) :
ScanClosure(g, gc_barrier)
{ }
EvacuateFollowersClosureGeneral::
template <typename OopClosureType1, typename OopClosureType2>
EvacuateFollowersClosureGeneral<OopClosureType1, OopClosureType2>::
EvacuateFollowersClosureGeneral(CMSHeap* heap,
OopsInGenClosure* cur,
OopsInGenClosure* older) :
OopClosureType1* cur,
OopClosureType2* older) :
_heap(heap),
_scan_cur_or_nonheap(cur), _scan_older(older)
{ }
void EvacuateFollowersClosureGeneral::do_void() {
template <typename OopClosureType1, typename OopClosureType2>
void EvacuateFollowersClosureGeneral<OopClosureType1, OopClosureType2>::do_void() {
do {
// Beware: this call will lead to closure applications via virtual
// calls.
_heap->oop_since_save_marks_iterate(GenCollectedHeap::YoungGen,
_scan_cur_or_nonheap,
_heap->oop_since_save_marks_iterate(_scan_cur_or_nonheap,
_scan_older);
} while (!_heap->no_allocs_since_save_marks());
}
@ -977,8 +975,8 @@ void ParNewGeneration::collect(bool full,
ScanClosure scan_without_gc_barrier(this, false);
ScanClosureWithParBarrier scan_with_gc_barrier(this, true);
set_promo_failure_scan_stack_closure(&scan_without_gc_barrier);
EvacuateFollowersClosureGeneral evacuate_followers(gch,
&scan_without_gc_barrier, &scan_with_gc_barrier);
EvacuateFollowersClosureGeneral<ScanClosure, ScanClosureWithParBarrier> evacuate_followers(
gch, &scan_without_gc_barrier, &scan_with_gc_barrier);
rp->setup_policy(clear_all_soft_refs);
// Can the mt_degree be set later (at run_task() time would be best)?
rp->set_active_mt_degree(active_workers);

@ -258,15 +258,16 @@ class KeepAliveClosure: public DefNewGeneration::KeepAliveClosure {
virtual void do_oop(narrowOop* p);
};
template <typename OopClosureType1, typename OopClosureType2>
class EvacuateFollowersClosureGeneral: public VoidClosure {
private:
CMSHeap* _heap;
OopsInGenClosure* _scan_cur_or_nonheap;
OopsInGenClosure* _scan_older;
OopClosureType1* _scan_cur_or_nonheap;
OopClosureType2* _scan_older;
public:
EvacuateFollowersClosureGeneral(CMSHeap* heap,
OopsInGenClosure* cur,
OopsInGenClosure* older);
OopClosureType1* cur,
OopClosureType2* older);
virtual void do_void();
};

@ -60,60 +60,6 @@ inline void PromotedObject::setNext(PromotedObject* x) {
assert(!((FreeChunk*)this)->is_free(), "Error");
}
//////////////////////////////////////////////////////////////////////////////
// We go over the list of promoted objects, removing each from the list,
// and applying the closure (this may, in turn, add more elements to
// the tail of the promoted list, and these newly added objects will
// also be processed) until the list is empty.
// To aid verification and debugging, in the non-product builds
// we actually forward _promoHead each time we process a promoted oop.
// Note that this is not necessary in general (i.e. when we don't need to
// call PromotionInfo::verify()) because oop_iterate can only add to the
// end of _promoTail, and never needs to look at _promoHead.
#define PROMOTED_OOPS_ITERATE_DEFN(OopClosureType, nv_suffix) \
\
void PromotionInfo::promoted_oops_iterate##nv_suffix(OopClosureType* cl) { \
NOT_PRODUCT(verify()); \
PromotedObject *curObj, *nextObj; \
for (curObj = _promoHead; curObj != NULL; curObj = nextObj) { \
if ((nextObj = curObj->next()) == NULL) { \
/* protect ourselves against additions due to closure application \
below by resetting the list. */ \
assert(_promoTail == curObj, "Should have been the tail"); \
_promoHead = _promoTail = NULL; \
} \
if (curObj->hasDisplacedMark()) { \
/* restore displaced header */ \
oop(curObj)->set_mark_raw(nextDisplacedHeader()); \
} else { \
/* restore prototypical header */ \
oop(curObj)->init_mark_raw(); \
} \
/* The "promoted_mark" should now not be set */ \
assert(!curObj->hasPromotedMark(), \
"Should have been cleared by restoring displaced mark-word"); \
NOT_PRODUCT(_promoHead = nextObj); \
if (cl != NULL) oop(curObj)->oop_iterate(cl); \
if (nextObj == NULL) { /* start at head of list reset above */ \
nextObj = _promoHead; \
} \
} \
assert(noPromotions(), "post-condition violation"); \
assert(_promoHead == NULL && _promoTail == NULL, "emptied promoted list");\
assert(_spoolHead == _spoolTail, "emptied spooling buffers"); \
assert(_firstIndex == _nextIndex, "empty buffer"); \
}
// This should have been ALL_SINCE_...() just like the others,
// but, because the body of the method above is somehwat longer,
// the MSVC compiler cannot cope; as a workaround, we split the
// macro into its 3 constituent parts below (see original macro
// definition in specializedOopClosures.hpp).
SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES_YOUNG(PROMOTED_OOPS_ITERATE_DEFN)
PROMOTED_OOPS_ITERATE_DEFN(OopsInGenClosure,_v)
// Return the next displaced header, incrementing the pointer and
// recycling spool area as necessary.
markOop PromotionInfo::nextDisplacedHeader() {

@ -165,13 +165,10 @@ class PromotionInfo {
bool ensure_spooling_space() {
return has_spooling_space() || ensure_spooling_space_work();
}
#define PROMOTED_OOPS_ITERATE_DECL(OopClosureType, nv_suffix) \
void promoted_oops_iterate##nv_suffix(OopClosureType* cl);
ALL_SINCE_SAVE_MARKS_CLOSURES(PROMOTED_OOPS_ITERATE_DECL)
#undef PROMOTED_OOPS_ITERATE_DECL
void promoted_oops_iterate(OopsInGenClosure* cl) {
promoted_oops_iterate_v(cl);
}
template <typename OopClosureType>
void promoted_oops_iterate(OopClosureType* cl);
void verify() const;
void reset() {
_promoHead = NULL;

@ -0,0 +1,77 @@
/*
* Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef SHARE_GC_CMS_PROMOTIONINFO_INLINE_HPP
#define SHARE_GC_CMS_PROMOTIONINFO_INLINE_HPP
#include "gc/cms/promotionInfo.hpp"
#include "oops/oop.inline.hpp"
#include "utilities/debug.hpp"
#include "utilities/macros.hpp"
//////////////////////////////////////////////////////////////////////////////
// We go over the list of promoted objects, removing each from the list,
// and applying the closure (this may, in turn, add more elements to
// the tail of the promoted list, and these newly added objects will
// also be processed) until the list is empty.
// To aid verification and debugging, in the non-product builds
// we actually forward _promoHead each time we process a promoted oop.
// Note that this is not necessary in general (i.e. when we don't need to
// call PromotionInfo::verify()) because oop_iterate can only add to the
// end of _promoTail, and never needs to look at _promoHead.
template <typename OopClosureType>
void PromotionInfo::promoted_oops_iterate(OopClosureType* cl) {
NOT_PRODUCT(verify());
PromotedObject *curObj, *nextObj;
for (curObj = _promoHead; curObj != NULL; curObj = nextObj) {
if ((nextObj = curObj->next()) == NULL) {
/* protect ourselves against additions due to closure application
below by resetting the list. */
assert(_promoTail == curObj, "Should have been the tail");
_promoHead = _promoTail = NULL;
}
if (curObj->hasDisplacedMark()) {
/* restore displaced header */
oop(curObj)->set_mark_raw(nextDisplacedHeader());
} else {
/* restore prototypical header */
oop(curObj)->init_mark_raw();
}
/* The "promoted_mark" should now not be set */
assert(!curObj->hasPromotedMark(),
"Should have been cleared by restoring displaced mark-word");
NOT_PRODUCT(_promoHead = nextObj);
if (cl != NULL) oop(curObj)->oop_iterate(cl);
if (nextObj == NULL) { /* start at head of list reset above */
nextObj = _promoHead;
}
}
assert(noPromotions(), "post-condition violation");
assert(_promoHead == NULL && _promoTail == NULL, "emptied promoted list");
assert(_spoolHead == _spoolTail, "emptied spooling buffers");
assert(_firstIndex == _nextIndex, "empty buffer");
}
#endif // SHARE_GC_CMS_PROMOTIONINFO_INLINE_HPP

@ -24,7 +24,7 @@
#include "precompiled.hpp"
#include "gc/serial/defNewGeneration.inline.hpp"
#include "gc/serial/serialHeap.hpp"
#include "gc/serial/serialHeap.inline.hpp"
#include "gc/serial/tenuredGeneration.hpp"
#include "gc/shared/adaptiveSizePolicy.hpp"
#include "gc/shared/ageTable.inline.hpp"
@ -57,9 +57,6 @@
#include "utilities/copy.hpp"
#include "utilities/globalDefinitions.hpp"
#include "utilities/stack.inline.hpp"
#if INCLUDE_CMSGC
#include "gc/cms/parOopClosures.hpp"
#endif
//
// DefNewGeneration functions.
@ -103,7 +100,7 @@ FastEvacuateFollowersClosure(SerialHeap* heap,
void DefNewGeneration::FastEvacuateFollowersClosure::do_void() {
do {
_heap->oop_since_save_marks_iterate(GenCollectedHeap::YoungGen, _scan_cur_or_nonheap, _scan_older);
_heap->oop_since_save_marks_iterate(_scan_cur_or_nonheap, _scan_older);
} while (!_heap->no_allocs_since_save_marks());
guarantee(_heap->young_gen()->promo_failure_scan_is_complete(), "Failed to finish scan");
}
@ -814,22 +811,6 @@ bool DefNewGeneration::no_allocs_since_save_marks() {
return to()->saved_mark_at_top();
}
#define DefNew_SINCE_SAVE_MARKS_DEFN(OopClosureType, nv_suffix) \
\
void DefNewGeneration:: \
oop_since_save_marks_iterate##nv_suffix(OopClosureType* cl) { \
cl->set_generation(this); \
eden()->oop_since_save_marks_iterate##nv_suffix(cl); \
to()->oop_since_save_marks_iterate##nv_suffix(cl); \
from()->oop_since_save_marks_iterate##nv_suffix(cl); \
cl->reset_generation(); \
save_marks(); \
}
ALL_SINCE_SAVE_MARKS_CLOSURES(DefNew_SINCE_SAVE_MARKS_DEFN)
#undef DefNew_SINCE_SAVE_MARKS_DEFN
void DefNewGeneration::contribute_scratch(ScratchBlock*& list, Generation* requestor,
size_t max_alloc_words) {
if (requestor == this || _promotion_failed) {

@ -280,12 +280,8 @@ protected:
// Need to declare the full complement of closures, whether we'll
// override them or not, or get message from the compiler:
// oop_since_save_marks_iterate_nv hides virtual function...
#define DefNew_SINCE_SAVE_MARKS_DECL(OopClosureType, nv_suffix) \
void oop_since_save_marks_iterate##nv_suffix(OopClosureType* cl);
ALL_SINCE_SAVE_MARKS_CLOSURES(DefNew_SINCE_SAVE_MARKS_DECL)
#undef DefNew_SINCE_SAVE_MARKS_DECL
template <typename OopClosureType>
void oop_since_save_marks_iterate(OopClosureType* cl);
// For non-youngest collection, the DefNewGeneration can contribute
// "to-space".

@ -29,7 +29,7 @@
#include "gc/shared/cardTableRS.hpp"
#include "gc/shared/genCollectedHeap.hpp"
#include "gc/shared/genOopClosures.inline.hpp"
#include "gc/shared/space.hpp"
#include "gc/shared/space.inline.hpp"
#include "oops/access.inline.hpp"
// Methods of protected closure types
@ -88,4 +88,14 @@ inline void DefNewGeneration::FastKeepAliveClosure::do_oop_work(T* p) {
}
}
template <typename OopClosureType>
void DefNewGeneration::oop_since_save_marks_iterate(OopClosureType* cl) {
cl->set_generation(this);
eden()->oop_since_save_marks_iterate(cl);
to()->oop_since_save_marks_iterate(cl);
from()->oop_since_save_marks_iterate(cl);
cl->reset_generation();
save_marks();
}
#endif // SHARE_VM_GC_SERIAL_DEFNEWGENERATION_INLINE_HPP

@ -23,9 +23,9 @@
*/
#include "precompiled.hpp"
#include "gc/serial/defNewGeneration.hpp"
#include "gc/serial/defNewGeneration.inline.hpp"
#include "gc/serial/serialHeap.hpp"
#include "gc/serial/tenuredGeneration.hpp"
#include "gc/serial/tenuredGeneration.inline.hpp"
#include "gc/shared/genMemoryPools.hpp"
#include "services/memoryManager.hpp"

@ -73,6 +73,14 @@ public:
assert(_old_gen->kind() == Generation::MarkSweepCompact, "Wrong generation type");
return static_cast<TenuredGeneration*>(_old_gen);
}
// Apply "cur->do_oop" or "older->do_oop" to all the oops in objects
// allocated since the last call to save_marks in the young generation.
// The "cur" closure is applied to references in the younger generation
// at "level", and the "older" closure to older generations.
template <typename OopClosureType1, typename OopClosureType2>
void oop_since_save_marks_iterate(OopClosureType1* cur,
OopClosureType2* older);
};
#endif // SHARE_VM_GC_CMS_CMSHEAP_HPP

@ -0,0 +1,39 @@
/*
* Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef SHARE_GC_SERIAL_SERIALHEAP_INLINE_HPP
#define SHARE_GC_SERIAL_SERIALHEAP_INLINE_HPP
#include "gc/serial/defNewGeneration.inline.hpp"
#include "gc/serial/serialHeap.hpp"
#include "gc/serial/tenuredGeneration.inline.hpp"
template <typename OopClosureType1, typename OopClosureType2>
void SerialHeap::oop_since_save_marks_iterate(OopClosureType1* cur,
OopClosureType2* older) {
young_gen()->oop_since_save_marks_iterate(cur);
old_gen()->oop_since_save_marks_iterate(older);
}
#endif // SHARE_GC_SERIAL_SERIALHEAP_INLINE_HPP

@ -50,8 +50,4 @@ class AdjustPointerClosure;
f(MarkAndPushClosure,_nv) \
f(AdjustPointerClosure,_nv)
#define SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES_YOUNG_S(f) \
f(ScanClosure,_nv) \
f(FastScanClosure,_nv)
#endif // SHARE_GC_SERIAL_SERIAL_SPECIALIZED_OOP_CLOSURES_HPP

@ -256,20 +256,6 @@ bool TenuredGeneration::no_allocs_since_save_marks() {
return _the_space->saved_mark_at_top();
}
#define TenuredGen_SINCE_SAVE_MARKS_ITERATE_DEFN(OopClosureType, nv_suffix) \
\
void TenuredGeneration:: \
oop_since_save_marks_iterate##nv_suffix(OopClosureType* blk) { \
blk->set_generation(this); \
_the_space->oop_since_save_marks_iterate##nv_suffix(blk); \
blk->reset_generation(); \
save_marks(); \
}
ALL_SINCE_SAVE_MARKS_CLOSURES(TenuredGen_SINCE_SAVE_MARKS_ITERATE_DEFN)
#undef TenuredGen_SINCE_SAVE_MARKS_ITERATE_DEFN
void TenuredGeneration::gc_epilogue(bool full) {
// update the generation and space performance counters
update_counters();

@ -75,10 +75,8 @@ class TenuredGeneration: public CardGeneration {
virtual inline HeapWord* allocate(size_t word_size, bool is_tlab);
virtual inline HeapWord* par_allocate(size_t word_size, bool is_tlab);
#define TenuredGen_SINCE_SAVE_MARKS_DECL(OopClosureType, nv_suffix) \
void oop_since_save_marks_iterate##nv_suffix(OopClosureType* cl);
TenuredGen_SINCE_SAVE_MARKS_DECL(OopsInGenClosure,_v)
SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES(TenuredGen_SINCE_SAVE_MARKS_DECL)
template <typename OopClosureType>
void oop_since_save_marks_iterate(OopClosureType* cl);
void save_marks();
void reset_saved_marks();

@ -26,7 +26,7 @@
#define SHARE_VM_GC_SERIAL_TENUREDGENERATION_INLINE_HPP
#include "gc/serial/tenuredGeneration.hpp"
#include "gc/shared/space.hpp"
#include "gc/shared/space.inline.hpp"
HeapWord* TenuredGeneration::allocate(size_t word_size,
bool is_tlab) {
@ -53,4 +53,12 @@ bool TenuredGeneration::block_is_obj(const HeapWord* addr) const {
return addr < _the_space ->top();
}
template <typename OopClosureType>
void TenuredGeneration::oop_since_save_marks_iterate(OopClosureType* blk) {
blk->set_generation(this);
_the_space->oop_since_save_marks_iterate(blk);
blk->reset_generation();
save_marks();
}
#endif // SHARE_VM_GC_SERIAL_TENUREDGENERATION_INLINE_HPP

@ -913,23 +913,6 @@ void GenCollectedHeap::gen_process_weak_roots(OopClosure* root_closure) {
_old_gen->ref_processor()->weak_oops_do(root_closure);
}
#define GCH_SINCE_SAVE_MARKS_ITERATE_DEFN(OopClosureType, nv_suffix) \
void GenCollectedHeap:: \
oop_since_save_marks_iterate(GenerationType gen, \
OopClosureType* cur, \
OopClosureType* older) { \
if (gen == YoungGen) { \
_young_gen->oop_since_save_marks_iterate##nv_suffix(cur); \
_old_gen->oop_since_save_marks_iterate##nv_suffix(older); \
} else { \
_old_gen->oop_since_save_marks_iterate##nv_suffix(cur); \
} \
}
ALL_SINCE_SAVE_MARKS_CLOSURES(GCH_SINCE_SAVE_MARKS_ITERATE_DEFN)
#undef GCH_SINCE_SAVE_MARKS_ITERATE_DEFN
bool GenCollectedHeap::no_allocs_since_save_marks() {
return _young_gen->no_allocs_since_save_marks() &&
_old_gen->no_allocs_since_save_marks();

@ -435,20 +435,6 @@ public:
// in other generations, it should call this method.
void save_marks();
// Apply "cur->do_oop" or "older->do_oop" to all the oops in objects
// allocated since the last call to save_marks in generations at or above
// "level". The "cur" closure is
// applied to references in the generation at "level", and the "older"
// closure to older generations.
#define GCH_SINCE_SAVE_MARKS_ITERATE_DECL(OopClosureType, nv_suffix) \
void oop_since_save_marks_iterate(GenerationType start_gen, \
OopClosureType* cur, \
OopClosureType* older);
ALL_SINCE_SAVE_MARKS_CLOSURES(GCH_SINCE_SAVE_MARKS_ITERATE_DECL)
#undef GCH_SINCE_SAVE_MARKS_ITERATE_DECL
// Returns "true" iff no allocations have occurred since the last
// call to "save_marks".
bool no_allocs_since_save_marks();

@ -442,25 +442,6 @@ class Generation: public CHeapObj<mtGC> {
// generation since the last call to "save_marks".
virtual bool no_allocs_since_save_marks() = 0;
// Apply "cl->apply" to (the addresses of) all reference fields in objects
// allocated in the current generation since the last call to "save_marks".
// If more objects are allocated in this generation as a result of applying
// the closure, iterates over reference fields in those objects as well.
// Calls "save_marks" at the end of the iteration.
// General signature...
virtual void oop_since_save_marks_iterate_v(OopsInGenClosure* cl) = 0;
// ...and specializations for de-virtualization. (The general
// implementation of the _nv versions call the virtual version.
// Note that the _nv suffix is not really semantically necessary,
// but it avoids some not-so-useful warnings on Solaris.)
#define Generation_SINCE_SAVE_MARKS_DECL(OopClosureType, nv_suffix) \
virtual void oop_since_save_marks_iterate##nv_suffix(OopClosureType* cl) { \
oop_since_save_marks_iterate_v((OopsInGenClosure*)cl); \
}
SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES(Generation_SINCE_SAVE_MARKS_DECL)
#undef Generation_SINCE_SAVE_MARKS_DECL
// The "requestor" generation is performing some garbage collection
// action for which it would be useful to have scratch space. If
// the target is not the requestor, no gc actions will be required

@ -550,32 +550,6 @@ ContiguousSpace::object_iterate_careful(ObjectClosureCareful* blk) {
return NULL; // all done
}
#define ContigSpace_OOP_SINCE_SAVE_MARKS_DEFN(OopClosureType, nv_suffix) \
\
void ContiguousSpace:: \
oop_since_save_marks_iterate##nv_suffix(OopClosureType* blk) { \
HeapWord* t; \
HeapWord* p = saved_mark_word(); \
assert(p != NULL, "expected saved mark"); \
\
const intx interval = PrefetchScanIntervalInBytes; \
do { \
t = top(); \
while (p < t) { \
Prefetch::write(p, interval); \
debug_only(HeapWord* prev = p); \
oop m = oop(p); \
p += m->oop_iterate_size(blk); \
} \
} while (t < top()); \
\
set_saved_mark_word(p); \
}
ALL_SINCE_SAVE_MARKS_CLOSURES(ContigSpace_OOP_SINCE_SAVE_MARKS_DEFN)
#undef ContigSpace_OOP_SINCE_SAVE_MARKS_DEFN
// Very general, slow implementation.
HeapWord* ContiguousSpace::block_start_const(const void* p) const {
assert(MemRegion(bottom(), end()).contains(p),

@ -639,11 +639,8 @@ class ContiguousSpace: public CompactibleSpace {
// *are* included in the iteration.
// Updates _saved_mark_word to point to just after the last object
// iterated over.
#define ContigSpace_OOP_SINCE_SAVE_MARKS_DECL(OopClosureType, nv_suffix) \
void oop_since_save_marks_iterate##nv_suffix(OopClosureType* blk);
ALL_SINCE_SAVE_MARKS_CLOSURES(ContigSpace_OOP_SINCE_SAVE_MARKS_DECL)
#undef ContigSpace_OOP_SINCE_SAVE_MARKS_DECL
template <typename OopClosureType>
void oop_since_save_marks_iterate(OopClosureType* blk);
// Same as object_iterate, but starting from "mark", which is required
// to denote the start of an object. Objects allocated by

@ -357,4 +357,24 @@ size_t ContiguousSpace::scanned_block_size(const HeapWord* addr) const {
return oop(addr)->size();
}
template <typename OopClosureType>
void ContiguousSpace::oop_since_save_marks_iterate(OopClosureType* blk) {
HeapWord* t;
HeapWord* p = saved_mark_word();
assert(p != NULL, "expected saved mark");
const intx interval = PrefetchScanIntervalInBytes;
do {
t = top();
while (p < t) {
Prefetch::write(p, interval);
debug_only(HeapWord* prev = p);
oop m = oop(p);
p += m->oop_iterate_size(blk);
}
} while (t < top());
set_saved_mark_word(p);
}
#endif // SHARE_VM_GC_SHARED_SPACE_INLINE_HPP

@ -91,25 +91,4 @@ class OopsInGenClosure;
f(ExtendedOopClosure,_v) \
CMSGC_ONLY(SPECIALIZED_PAR_OOP_ITERATE_CLOSURES(f))
// This macro applies an argument macro to all OopClosures for which we
// want specialized bodies of a family of methods related to
// "oops_since_save_marks_do". The arguments to f are the same as above.
// The "root_class" is the most general class to define; this may be
// "OopClosure" in some applications and "OopsInGenClosure" in others.
#define SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES_YOUNG(f) \
SERIALGC_ONLY(SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES_YOUNG_S(f)) \
CMSGC_ONLY(SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES_YOUNG_P(f))
#define SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES(f) \
SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES_YOUNG(f)
// We separate these out, because sometime the general one has
// a different definition from the specialized ones, and sometimes it
// doesn't.
#define ALL_SINCE_SAVE_MARKS_CLOSURES(f) \
f(OopsInGenClosure,_v) \
SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES(f)
#endif // SHARE_VM_GC_SHARED_SPECIALIZED_OOP_CLOSURES_HPP