Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/share/vm/gc_implementation/shenandoah/shenandoahCodeRoots.hpp
38920 views
/*1* Copyright (c) 2017, 2019, Red Hat, Inc. All rights reserved.2*3* This code is free software; you can redistribute it and/or modify it4* under the terms of the GNU General Public License version 2 only, as5* published by the Free Software Foundation.6*7* This code is distributed in the hope that it will be useful, but WITHOUT8* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or9* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License10* version 2 for more details (a copy is included in the LICENSE file that11* accompanied this code).12*13* You should have received a copy of the GNU General Public License version14* 2 along with this work; if not, write to the Free Software Foundation,15* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.16*17* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA18* or visit www.oracle.com if you need additional information or have any19* questions.20*21*/2223#ifndef SHARE_VM_GC_SHENANDOAH_SHENANDOAHCODEROOTS_HPP24#define SHARE_VM_GC_SHENANDOAH_SHENANDOAHCODEROOTS_HPP2526#include "code/codeCache.hpp"27#include "gc_implementation/shenandoah/shenandoahSharedVariables.hpp"28#include "gc_implementation/shenandoah/shenandoahPadding.hpp"29#include "memory/allocation.hpp"30#include "memory/iterator.hpp"3132class ShenandoahHeap;33class ShenandoahHeapRegion;34class ShenandoahCodeRootsLock;3536class ShenandoahParallelCodeCacheIterator VALUE_OBJ_CLASS_SPEC {37friend class CodeCache;38private:39shenandoah_padding(0);40volatile int _claimed_idx;41volatile bool _finished;42shenandoah_padding(1);4344// Noncopyable.45ShenandoahParallelCodeCacheIterator(const ShenandoahParallelCodeCacheIterator& o);46ShenandoahParallelCodeCacheIterator& operator=(const ShenandoahParallelCodeCacheIterator& o);47public:48ShenandoahParallelCodeCacheIterator();49void parallel_blobs_do(CodeBlobClosure* f);50};5152// ShenandoahNMethod tuple records the internal locations of oop slots within the nmethod.53// This allows us to quickly scan the oops without doing the nmethod-internal scans, that54// sometimes involves parsing the machine code. Note it does not record the oops themselves,55// because it would then require handling these tuples as the new class of roots.56class ShenandoahNMethod : public CHeapObj<mtGC> {57private:58nmethod* _nm;59oop** _oops;60int _oops_count;6162public:63ShenandoahNMethod(nmethod *nm, GrowableArray<oop*>* oops);64~ShenandoahNMethod();6566nmethod* nm() {67return _nm;68}6970bool has_cset_oops(ShenandoahHeap* heap);7172void assert_alive_and_correct() NOT_DEBUG_RETURN;73void assert_same_oops(GrowableArray<oop*>* oops) NOT_DEBUG_RETURN;7475static bool find_with_nmethod(void* nm, ShenandoahNMethod* other) {76return other->_nm == nm;77}78};7980class ShenandoahCodeRootsIterator VALUE_OBJ_CLASS_SPEC {81friend class ShenandoahCodeRoots;82protected:83ShenandoahHeap* _heap;84ShenandoahParallelCodeCacheIterator _par_iterator;85ShenandoahSharedFlag _seq_claimed;86char _pad0[DEFAULT_CACHE_LINE_SIZE];87volatile jlong _claimed;88char _pad1[DEFAULT_CACHE_LINE_SIZE];89protected:90ShenandoahCodeRootsIterator();91~ShenandoahCodeRootsIterator();9293template<bool CSET_FILTER>94void dispatch_parallel_blobs_do(CodeBlobClosure *f);9596template<bool CSET_FILTER>97void fast_parallel_blobs_do(CodeBlobClosure *f);98};99100class ShenandoahAllCodeRootsIterator : public ShenandoahCodeRootsIterator {101public:102ShenandoahAllCodeRootsIterator() : ShenandoahCodeRootsIterator() {};103void possibly_parallel_blobs_do(CodeBlobClosure *f);104};105106class ShenandoahCsetCodeRootsIterator : public ShenandoahCodeRootsIterator {107public:108ShenandoahCsetCodeRootsIterator() : ShenandoahCodeRootsIterator() {};109void possibly_parallel_blobs_do(CodeBlobClosure* f);110};111112class ShenandoahCodeRoots : public AllStatic {113friend class ShenandoahHeap;114friend class ShenandoahCodeRootsLock;115friend class ShenandoahCodeRootsIterator;116117public:118static void initialize();119static void add_nmethod(nmethod* nm);120static void remove_nmethod(nmethod* nm);121122private:123struct PaddedLock {124char _pad0[DEFAULT_CACHE_LINE_SIZE];125volatile int _lock;126char _pad1[DEFAULT_CACHE_LINE_SIZE];127};128129static PaddedLock _recorded_nms_lock;130static GrowableArray<ShenandoahNMethod*>* _recorded_nms;131132static void acquire_lock(bool write) {133volatile int* loc = &_recorded_nms_lock._lock;134if (write) {135while ((OrderAccess::load_acquire(loc) != 0) ||136Atomic::cmpxchg(-1, loc, 0) != 0) {137SpinPause();138}139assert (*loc == -1, "acquired for write");140} else {141while (true) {142jint cur = OrderAccess::load_acquire(loc);143if (cur >= 0) {144if (Atomic::cmpxchg(cur + 1, loc, cur) == cur) {145// Success!146assert (*loc > 0, "acquired for read");147return;148}149}150SpinPause();151}152}153}154155static void release_lock(bool write) {156volatile int* loc = &ShenandoahCodeRoots::_recorded_nms_lock._lock;157if (write) {158OrderAccess::release_store_fence(loc, 0);159} else {160Atomic::dec(loc);161}162}163};164165// Very simple unranked read-write lock166class ShenandoahCodeRootsLock : public StackObj {167friend class ShenandoahCodeRoots;168private:169const bool _write;170public:171ShenandoahCodeRootsLock(bool write) : _write(write) {172ShenandoahCodeRoots::acquire_lock(write);173}174175~ShenandoahCodeRootsLock() {176ShenandoahCodeRoots::release_lock(_write);177}178};179180#endif //SHARE_VM_GC_SHENANDOAH_SHENANDOAHCODEROOTS_HPP181182183