Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsOopClosures.hpp
38920 views
/*1* Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#ifndef SHARE_VM_GC_IMPLEMENTATION_CONCURRENTMARKSWEEP_CMSOOPCLOSURES_HPP25#define SHARE_VM_GC_IMPLEMENTATION_CONCURRENTMARKSWEEP_CMSOOPCLOSURES_HPP2627#include "memory/genOopClosures.hpp"28#include "memory/iterator.hpp"2930/////////////////////////////////////////////////////////////////31// Closures used by ConcurrentMarkSweepGeneration's collector32/////////////////////////////////////////////////////////////////33class ConcurrentMarkSweepGeneration;34class CMSBitMap;35class CMSMarkStack;36class CMSCollector;37class MarkFromRootsClosure;38class Par_MarkFromRootsClosure;3940// Decode the oop and call do_oop on it.41#define DO_OOP_WORK_DEFN \42void do_oop(oop obj); \43template <class T> inline void do_oop_work(T* p) { \44T heap_oop = oopDesc::load_heap_oop(p); \45if (!oopDesc::is_null(heap_oop)) { \46oop obj = oopDesc::decode_heap_oop_not_null(heap_oop); \47do_oop(obj); \48} \49}5051// TODO: This duplication of the MetadataAwareOopClosure class is only needed52// because some CMS OopClosures derive from OopsInGenClosure. It would be53// good to get rid of them completely.54class MetadataAwareOopsInGenClosure: public OopsInGenClosure {55KlassToOopClosure _klass_closure;56public:57MetadataAwareOopsInGenClosure() {58_klass_closure.initialize(this);59}6061virtual bool do_metadata() { return do_metadata_nv(); }62inline bool do_metadata_nv() { return true; }6364virtual void do_klass(Klass* k);65void do_klass_nv(Klass* k);6667virtual void do_class_loader_data(ClassLoaderData* cld);68};6970class MarkRefsIntoClosure: public MetadataAwareOopsInGenClosure {71private:72const MemRegion _span;73CMSBitMap* _bitMap;74protected:75DO_OOP_WORK_DEFN76public:77MarkRefsIntoClosure(MemRegion span, CMSBitMap* bitMap);78virtual void do_oop(oop* p);79virtual void do_oop(narrowOop* p);8081Prefetch::style prefetch_style() {82return Prefetch::do_read;83}84};8586class Par_MarkRefsIntoClosure: public MetadataAwareOopsInGenClosure {87private:88const MemRegion _span;89CMSBitMap* _bitMap;90protected:91DO_OOP_WORK_DEFN92public:93Par_MarkRefsIntoClosure(MemRegion span, CMSBitMap* bitMap);94virtual void do_oop(oop* p);95virtual void do_oop(narrowOop* p);9697Prefetch::style prefetch_style() {98return Prefetch::do_read;99}100};101102// A variant of the above used in certain kinds of CMS103// marking verification.104class MarkRefsIntoVerifyClosure: public MetadataAwareOopsInGenClosure {105private:106const MemRegion _span;107CMSBitMap* _verification_bm;108CMSBitMap* _cms_bm;109protected:110DO_OOP_WORK_DEFN111public:112MarkRefsIntoVerifyClosure(MemRegion span, CMSBitMap* verification_bm,113CMSBitMap* cms_bm);114virtual void do_oop(oop* p);115virtual void do_oop(narrowOop* p);116117Prefetch::style prefetch_style() {118return Prefetch::do_read;119}120};121122// The non-parallel version (the parallel version appears further below).123class PushAndMarkClosure: public MetadataAwareOopClosure {124private:125CMSCollector* _collector;126MemRegion _span;127CMSBitMap* _bit_map;128CMSBitMap* _mod_union_table;129CMSMarkStack* _mark_stack;130bool _concurrent_precleaning;131protected:132DO_OOP_WORK_DEFN133public:134PushAndMarkClosure(CMSCollector* collector,135MemRegion span,136ReferenceProcessor* rp,137CMSBitMap* bit_map,138CMSBitMap* mod_union_table,139CMSMarkStack* mark_stack,140bool concurrent_precleaning);141virtual void do_oop(oop* p);142virtual void do_oop(narrowOop* p);143inline void do_oop_nv(oop* p) { PushAndMarkClosure::do_oop_work(p); }144inline void do_oop_nv(narrowOop* p) { PushAndMarkClosure::do_oop_work(p); }145146Prefetch::style prefetch_style() {147return Prefetch::do_read;148}149};150151// In the parallel case, the bit map and the152// reference processor are currently all shared. Access to153// these shared mutable structures must use appropriate154// synchronization (for instance, via CAS). The marking stack155// used in the non-parallel case above is here replaced with156// an OopTaskQueue structure to allow efficient work stealing.157class Par_PushAndMarkClosure: public MetadataAwareOopClosure {158private:159CMSCollector* _collector;160MemRegion _span;161CMSBitMap* _bit_map;162OopTaskQueue* _work_queue;163protected:164DO_OOP_WORK_DEFN165public:166Par_PushAndMarkClosure(CMSCollector* collector,167MemRegion span,168ReferenceProcessor* rp,169CMSBitMap* bit_map,170OopTaskQueue* work_queue);171virtual void do_oop(oop* p);172virtual void do_oop(narrowOop* p);173inline void do_oop_nv(oop* p) { Par_PushAndMarkClosure::do_oop_work(p); }174inline void do_oop_nv(narrowOop* p) { Par_PushAndMarkClosure::do_oop_work(p); }175176Prefetch::style prefetch_style() {177return Prefetch::do_read;178}179};180181// The non-parallel version (the parallel version appears further below).182class MarkRefsIntoAndScanClosure: public MetadataAwareOopsInGenClosure {183private:184MemRegion _span;185CMSBitMap* _bit_map;186CMSMarkStack* _mark_stack;187PushAndMarkClosure _pushAndMarkClosure;188CMSCollector* _collector;189Mutex* _freelistLock;190bool _yield;191// Whether closure is being used for concurrent precleaning192bool _concurrent_precleaning;193protected:194DO_OOP_WORK_DEFN195public:196MarkRefsIntoAndScanClosure(MemRegion span,197ReferenceProcessor* rp,198CMSBitMap* bit_map,199CMSBitMap* mod_union_table,200CMSMarkStack* mark_stack,201CMSCollector* collector,202bool should_yield,203bool concurrent_precleaning);204virtual void do_oop(oop* p);205virtual void do_oop(narrowOop* p);206inline void do_oop_nv(oop* p) { MarkRefsIntoAndScanClosure::do_oop_work(p); }207inline void do_oop_nv(narrowOop* p) { MarkRefsIntoAndScanClosure::do_oop_work(p); }208209Prefetch::style prefetch_style() {210return Prefetch::do_read;211}212void set_freelistLock(Mutex* m) {213_freelistLock = m;214}215216private:217inline void do_yield_check();218void do_yield_work();219bool take_from_overflow_list();220};221222// Tn this, the parallel avatar of MarkRefsIntoAndScanClosure, the revisit223// stack and the bitMap are shared, so access needs to be suitably224// sycnhronized. An OopTaskQueue structure, supporting efficient225// workstealing, replaces a CMSMarkStack for storing grey objects.226class Par_MarkRefsIntoAndScanClosure: public MetadataAwareOopsInGenClosure {227private:228MemRegion _span;229CMSBitMap* _bit_map;230OopTaskQueue* _work_queue;231const uint _low_water_mark;232Par_PushAndMarkClosure _par_pushAndMarkClosure;233protected:234DO_OOP_WORK_DEFN235public:236Par_MarkRefsIntoAndScanClosure(CMSCollector* collector,237MemRegion span,238ReferenceProcessor* rp,239CMSBitMap* bit_map,240OopTaskQueue* work_queue);241virtual void do_oop(oop* p);242virtual void do_oop(narrowOop* p);243inline void do_oop_nv(oop* p) { Par_MarkRefsIntoAndScanClosure::do_oop_work(p); }244inline void do_oop_nv(narrowOop* p) { Par_MarkRefsIntoAndScanClosure::do_oop_work(p); }245246Prefetch::style prefetch_style() {247return Prefetch::do_read;248}249void trim_queue(uint size);250};251252// This closure is used during the concurrent marking phase253// following the first checkpoint. Its use is buried in254// the closure MarkFromRootsClosure.255class PushOrMarkClosure: public MetadataAwareOopClosure {256private:257CMSCollector* _collector;258MemRegion _span;259CMSBitMap* _bitMap;260CMSMarkStack* _markStack;261HeapWord* const _finger;262MarkFromRootsClosure* const263_parent;264protected:265DO_OOP_WORK_DEFN266public:267PushOrMarkClosure(CMSCollector* cms_collector,268MemRegion span,269CMSBitMap* bitMap,270CMSMarkStack* markStack,271HeapWord* finger,272MarkFromRootsClosure* parent);273virtual void do_oop(oop* p);274virtual void do_oop(narrowOop* p);275inline void do_oop_nv(oop* p) { PushOrMarkClosure::do_oop_work(p); }276inline void do_oop_nv(narrowOop* p) { PushOrMarkClosure::do_oop_work(p); }277278// Deal with a stack overflow condition279void handle_stack_overflow(HeapWord* lost);280private:281inline void do_yield_check();282};283284// A parallel (MT) version of the above.285// This closure is used during the concurrent marking phase286// following the first checkpoint. Its use is buried in287// the closure Par_MarkFromRootsClosure.288class Par_PushOrMarkClosure: public MetadataAwareOopClosure {289private:290CMSCollector* _collector;291MemRegion _whole_span;292MemRegion _span; // local chunk293CMSBitMap* _bit_map;294OopTaskQueue* _work_queue;295CMSMarkStack* _overflow_stack;296HeapWord* const _finger;297HeapWord** const _global_finger_addr;298Par_MarkFromRootsClosure* const299_parent;300protected:301DO_OOP_WORK_DEFN302public:303Par_PushOrMarkClosure(CMSCollector* cms_collector,304MemRegion span,305CMSBitMap* bit_map,306OopTaskQueue* work_queue,307CMSMarkStack* mark_stack,308HeapWord* finger,309HeapWord** global_finger_addr,310Par_MarkFromRootsClosure* parent);311virtual void do_oop(oop* p);312virtual void do_oop(narrowOop* p);313inline void do_oop_nv(oop* p) { Par_PushOrMarkClosure::do_oop_work(p); }314inline void do_oop_nv(narrowOop* p) { Par_PushOrMarkClosure::do_oop_work(p); }315316// Deal with a stack overflow condition317void handle_stack_overflow(HeapWord* lost);318private:319inline void do_yield_check();320};321322// For objects in CMS generation, this closure marks323// given objects (transitively) as being reachable/live.324// This is currently used during the (weak) reference object325// processing phase of the CMS final checkpoint step, as326// well as during the concurrent precleaning of the discovered327// reference lists.328class CMSKeepAliveClosure: public MetadataAwareOopClosure {329private:330CMSCollector* _collector;331const MemRegion _span;332CMSMarkStack* _mark_stack;333CMSBitMap* _bit_map;334bool _concurrent_precleaning;335protected:336DO_OOP_WORK_DEFN337public:338CMSKeepAliveClosure(CMSCollector* collector, MemRegion span,339CMSBitMap* bit_map, CMSMarkStack* mark_stack,340bool cpc);341bool concurrent_precleaning() const { return _concurrent_precleaning; }342virtual void do_oop(oop* p);343virtual void do_oop(narrowOop* p);344inline void do_oop_nv(oop* p) { CMSKeepAliveClosure::do_oop_work(p); }345inline void do_oop_nv(narrowOop* p) { CMSKeepAliveClosure::do_oop_work(p); }346};347348class CMSInnerParMarkAndPushClosure: public MetadataAwareOopClosure {349private:350CMSCollector* _collector;351MemRegion _span;352OopTaskQueue* _work_queue;353CMSBitMap* _bit_map;354protected:355DO_OOP_WORK_DEFN356public:357CMSInnerParMarkAndPushClosure(CMSCollector* collector,358MemRegion span, CMSBitMap* bit_map,359OopTaskQueue* work_queue);360virtual void do_oop(oop* p);361virtual void do_oop(narrowOop* p);362inline void do_oop_nv(oop* p) { CMSInnerParMarkAndPushClosure::do_oop_work(p); }363inline void do_oop_nv(narrowOop* p) { CMSInnerParMarkAndPushClosure::do_oop_work(p); }364};365366// A parallel (MT) version of the above, used when367// reference processing is parallel; the only difference368// is in the do_oop method.369class CMSParKeepAliveClosure: public MetadataAwareOopClosure {370private:371MemRegion _span;372OopTaskQueue* _work_queue;373CMSBitMap* _bit_map;374CMSInnerParMarkAndPushClosure375_mark_and_push;376const uint _low_water_mark;377void trim_queue(uint max);378protected:379DO_OOP_WORK_DEFN380public:381CMSParKeepAliveClosure(CMSCollector* collector, MemRegion span,382CMSBitMap* bit_map, OopTaskQueue* work_queue);383virtual void do_oop(oop* p);384virtual void do_oop(narrowOop* p);385};386387#endif // SHARE_VM_GC_IMPLEMENTATION_CONCURRENTMARKSWEEP_CMSOOPCLOSURES_HPP388389390