mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-18 01:54:47 +02:00
308 lines
11 KiB
C++
308 lines
11 KiB
C++
/*
|
|
* Copyright (c) 2014, 2022, 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_MEMORY_ITERATOR_INLINE_HPP
|
|
#define SHARE_MEMORY_ITERATOR_INLINE_HPP
|
|
|
|
#include "memory/iterator.hpp"
|
|
|
|
#include "classfile/classLoaderData.hpp"
|
|
#include "code/nmethod.hpp"
|
|
#include "oops/access.inline.hpp"
|
|
#include "oops/compressedOops.inline.hpp"
|
|
#include "oops/klass.hpp"
|
|
#include "oops/instanceKlass.inline.hpp"
|
|
#include "oops/instanceMirrorKlass.inline.hpp"
|
|
#include "oops/instanceClassLoaderKlass.inline.hpp"
|
|
#include "oops/instanceRefKlass.inline.hpp"
|
|
#include "oops/instanceStackChunkKlass.inline.hpp"
|
|
#include "oops/objArrayKlass.inline.hpp"
|
|
#include "oops/typeArrayKlass.inline.hpp"
|
|
#include "utilities/debug.hpp"
|
|
|
|
// Defaults to strong claiming.
|
|
inline MetadataVisitingOopIterateClosure::MetadataVisitingOopIterateClosure(ReferenceDiscoverer* rd) :
|
|
ClaimMetadataVisitingOopIterateClosure(ClassLoaderData::_claim_strong, rd) {}
|
|
|
|
inline void ClaimMetadataVisitingOopIterateClosure::do_cld(ClassLoaderData* cld) {
|
|
cld->oops_do(this, _claim);
|
|
}
|
|
|
|
inline void ClaimMetadataVisitingOopIterateClosure::do_klass(Klass* k) {
|
|
ClassLoaderData* cld = k->class_loader_data();
|
|
ClaimMetadataVisitingOopIterateClosure::do_cld(cld);
|
|
}
|
|
|
|
inline void ClaimMetadataVisitingOopIterateClosure::do_nmethod(nmethod* nm) {
|
|
nm->follow_nmethod(this);
|
|
}
|
|
|
|
inline void ClaimMetadataVisitingOopIterateClosure::do_method(Method* m) {
|
|
// Mark interpreted frames for class redefinition
|
|
m->record_gc_epoch();
|
|
}
|
|
|
|
// Dispatch table implementation for *Klass::oop_oop_iterate
|
|
//
|
|
// It allows for a single call to do a multi-dispatch to an optimized version
|
|
// of oop_oop_iterate that statically know all these types:
|
|
// - OopClosureType : static type give at call site
|
|
// - Klass* : dynamic to static type through Klass::kind() -> table index
|
|
// - UseCompressedOops : dynamic to static value determined once
|
|
//
|
|
// when users call obj->oop_iterate(&cl).
|
|
//
|
|
// oopDesc::oop_iterate() calls OopOopIterateDispatch::function(klass)(cl, obj, klass),
|
|
// which dispatches to an optimized version of
|
|
// [Instance, ObjArry, etc]Klass::oop_oop_iterate(oop, OopClosureType)
|
|
//
|
|
// OopClosureType :
|
|
// If OopClosureType has an implementation of do_oop (and do_metadata et.al.),
|
|
// then the static type of OopClosureType will be used to allow inlining of
|
|
// do_oop (even though do_oop is virtual). Otherwise, a virtual call will be
|
|
// used when calling do_oop.
|
|
//
|
|
// Klass* :
|
|
// A table mapping from *Klass::Kind to function is setup. This happens once
|
|
// when the program starts, when the static _table instance is initialized for
|
|
// the OopOopIterateDispatch specialized with the OopClosureType.
|
|
//
|
|
// UseCompressedOops :
|
|
// Initially the table is populated with an init function, and not the actual
|
|
// oop_oop_iterate function. This is done, so that the first time we dispatch
|
|
// through the init function we check what the value of UseCompressedOops
|
|
// became, and use that to determine if we should install an optimized
|
|
// narrowOop version or optimized oop version of oop_oop_iterate. The appropriate
|
|
// oop_oop_iterate function replaces the init function in the table, and
|
|
// succeeding calls will jump directly to oop_oop_iterate.
|
|
|
|
|
|
template <typename OopClosureType>
|
|
class OopOopIterateDispatch : public AllStatic {
|
|
private:
|
|
typedef void (*FunctionType)(OopClosureType*, oop, Klass*);
|
|
|
|
class Table {
|
|
private:
|
|
template <typename KlassType, typename T>
|
|
static void oop_oop_iterate(OopClosureType* cl, oop obj, Klass* k) {
|
|
((KlassType*)k)->KlassType::template oop_oop_iterate<T>(obj, cl);
|
|
}
|
|
|
|
template <typename KlassType>
|
|
static void init(OopClosureType* cl, oop obj, Klass* k) {
|
|
OopOopIterateDispatch<OopClosureType>::_table.set_resolve_function_and_execute<KlassType>(cl, obj, k);
|
|
}
|
|
|
|
template <typename KlassType>
|
|
void set_init_function() {
|
|
_function[KlassType::Kind] = &init<KlassType>;
|
|
}
|
|
|
|
template <typename KlassType>
|
|
void set_resolve_function() {
|
|
// Size requirement to prevent word tearing
|
|
// when functions pointers are updated.
|
|
STATIC_ASSERT(sizeof(_function[0]) == sizeof(void*));
|
|
if (UseCompressedOops) {
|
|
_function[KlassType::Kind] = &oop_oop_iterate<KlassType, narrowOop>;
|
|
} else {
|
|
_function[KlassType::Kind] = &oop_oop_iterate<KlassType, oop>;
|
|
}
|
|
}
|
|
|
|
template <typename KlassType>
|
|
void set_resolve_function_and_execute(OopClosureType* cl, oop obj, Klass* k) {
|
|
set_resolve_function<KlassType>();
|
|
_function[KlassType::Kind](cl, obj, k);
|
|
}
|
|
|
|
public:
|
|
FunctionType _function[KLASS_KIND_COUNT];
|
|
|
|
Table(){
|
|
set_init_function<InstanceKlass>();
|
|
set_init_function<InstanceRefKlass>();
|
|
set_init_function<InstanceMirrorKlass>();
|
|
set_init_function<InstanceClassLoaderKlass>();
|
|
set_init_function<InstanceStackChunkKlass>();
|
|
set_init_function<ObjArrayKlass>();
|
|
set_init_function<TypeArrayKlass>();
|
|
}
|
|
};
|
|
|
|
static Table _table;
|
|
public:
|
|
|
|
static FunctionType function(Klass* klass) {
|
|
return _table._function[klass->kind()];
|
|
}
|
|
};
|
|
|
|
template <typename OopClosureType>
|
|
typename OopOopIterateDispatch<OopClosureType>::Table OopOopIterateDispatch<OopClosureType>::_table;
|
|
|
|
|
|
template <typename OopClosureType>
|
|
class OopOopIterateBoundedDispatch {
|
|
private:
|
|
typedef void (*FunctionType)(OopClosureType*, oop, Klass*, MemRegion);
|
|
|
|
class Table {
|
|
private:
|
|
template <typename KlassType, typename T>
|
|
static void oop_oop_iterate_bounded(OopClosureType* cl, oop obj, Klass* k, MemRegion mr) {
|
|
((KlassType*)k)->KlassType::template oop_oop_iterate_bounded<T>(obj, cl, mr);
|
|
}
|
|
|
|
template <typename KlassType>
|
|
static void init(OopClosureType* cl, oop obj, Klass* k, MemRegion mr) {
|
|
OopOopIterateBoundedDispatch<OopClosureType>::_table.set_resolve_function_and_execute<KlassType>(cl, obj, k, mr);
|
|
}
|
|
|
|
template <typename KlassType>
|
|
void set_init_function() {
|
|
_function[KlassType::Kind] = &init<KlassType>;
|
|
}
|
|
|
|
template <typename KlassType>
|
|
void set_resolve_function() {
|
|
if (UseCompressedOops) {
|
|
_function[KlassType::Kind] = &oop_oop_iterate_bounded<KlassType, narrowOop>;
|
|
} else {
|
|
_function[KlassType::Kind] = &oop_oop_iterate_bounded<KlassType, oop>;
|
|
}
|
|
}
|
|
|
|
template <typename KlassType>
|
|
void set_resolve_function_and_execute(OopClosureType* cl, oop obj, Klass* k, MemRegion mr) {
|
|
set_resolve_function<KlassType>();
|
|
_function[KlassType::Kind](cl, obj, k, mr);
|
|
}
|
|
|
|
public:
|
|
FunctionType _function[KLASS_KIND_COUNT];
|
|
|
|
Table(){
|
|
set_init_function<InstanceKlass>();
|
|
set_init_function<InstanceRefKlass>();
|
|
set_init_function<InstanceMirrorKlass>();
|
|
set_init_function<InstanceClassLoaderKlass>();
|
|
set_init_function<InstanceStackChunkKlass>();
|
|
set_init_function<ObjArrayKlass>();
|
|
set_init_function<TypeArrayKlass>();
|
|
}
|
|
};
|
|
|
|
static Table _table;
|
|
public:
|
|
|
|
static FunctionType function(Klass* klass) {
|
|
return _table._function[klass->kind()];
|
|
}
|
|
};
|
|
|
|
template <typename OopClosureType>
|
|
typename OopOopIterateBoundedDispatch<OopClosureType>::Table OopOopIterateBoundedDispatch<OopClosureType>::_table;
|
|
|
|
|
|
template <typename OopClosureType>
|
|
class OopOopIterateBackwardsDispatch {
|
|
private:
|
|
typedef void (*FunctionType)(OopClosureType*, oop, Klass*);
|
|
|
|
class Table {
|
|
private:
|
|
template <typename KlassType, typename T>
|
|
static void oop_oop_iterate_backwards(OopClosureType* cl, oop obj, Klass* k) {
|
|
((KlassType*)k)->KlassType::template oop_oop_iterate_reverse<T>(obj, cl);
|
|
}
|
|
|
|
template <typename KlassType>
|
|
static void init(OopClosureType* cl, oop obj, Klass* k) {
|
|
OopOopIterateBackwardsDispatch<OopClosureType>::_table.set_resolve_function_and_execute<KlassType>(cl, obj, k);
|
|
}
|
|
|
|
template <typename KlassType>
|
|
void set_init_function() {
|
|
_function[KlassType::Kind] = &init<KlassType>;
|
|
}
|
|
|
|
template <typename KlassType>
|
|
void set_resolve_function() {
|
|
if (UseCompressedOops) {
|
|
_function[KlassType::Kind] = &oop_oop_iterate_backwards<KlassType, narrowOop>;
|
|
} else {
|
|
_function[KlassType::Kind] = &oop_oop_iterate_backwards<KlassType, oop>;
|
|
}
|
|
}
|
|
|
|
template <typename KlassType>
|
|
void set_resolve_function_and_execute(OopClosureType* cl, oop obj, Klass* k) {
|
|
set_resolve_function<KlassType>();
|
|
_function[KlassType::Kind](cl, obj, k);
|
|
}
|
|
|
|
public:
|
|
FunctionType _function[KLASS_KIND_COUNT];
|
|
|
|
Table(){
|
|
set_init_function<InstanceKlass>();
|
|
set_init_function<InstanceRefKlass>();
|
|
set_init_function<InstanceMirrorKlass>();
|
|
set_init_function<InstanceClassLoaderKlass>();
|
|
set_init_function<InstanceStackChunkKlass>();
|
|
set_init_function<ObjArrayKlass>();
|
|
set_init_function<TypeArrayKlass>();
|
|
}
|
|
};
|
|
|
|
static Table _table;
|
|
public:
|
|
|
|
static FunctionType function(Klass* klass) {
|
|
return _table._function[klass->kind()];
|
|
}
|
|
};
|
|
|
|
template <typename OopClosureType>
|
|
typename OopOopIterateBackwardsDispatch<OopClosureType>::Table OopOopIterateBackwardsDispatch<OopClosureType>::_table;
|
|
|
|
|
|
template <typename OopClosureType>
|
|
void OopIteratorClosureDispatch::oop_oop_iterate(OopClosureType* cl, oop obj, Klass* klass) {
|
|
OopOopIterateDispatch<OopClosureType>::function(klass)(cl, obj, klass);
|
|
}
|
|
|
|
template <typename OopClosureType>
|
|
void OopIteratorClosureDispatch::oop_oop_iterate(OopClosureType* cl, oop obj, Klass* klass, MemRegion mr) {
|
|
OopOopIterateBoundedDispatch<OopClosureType>::function(klass)(cl, obj, klass, mr);
|
|
}
|
|
|
|
template <typename OopClosureType>
|
|
void OopIteratorClosureDispatch::oop_oop_iterate_backwards(OopClosureType* cl, oop obj, Klass* klass) {
|
|
OopOopIterateBackwardsDispatch<OopClosureType>::function(klass)(cl, obj, klass);
|
|
}
|
|
|
|
#endif // SHARE_MEMORY_ITERATOR_INLINE_HPP
|