8288537: Move Devirtualizer out of hotspot/share/memory/iterator.hpp
Reviewed-by: stefank, coleenp
This commit is contained in:
parent
f080430440
commit
9f8bfab290
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2001, 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
|
||||
@ -32,6 +32,7 @@
|
||||
#include "gc/shared/genOopClosures.inline.hpp"
|
||||
#include "gc/shared/space.inline.hpp"
|
||||
#include "oops/access.inline.hpp"
|
||||
#include "utilities/devirtualizer.inline.hpp"
|
||||
|
||||
// Methods of protected closure types
|
||||
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "gc/shenandoah/shenandoahMarkingContext.inline.hpp"
|
||||
#include "gc/shenandoah/shenandoahHeap.inline.hpp"
|
||||
#include "gc/shenandoah/shenandoahNMethod.inline.hpp"
|
||||
#include "memory/iterator.inline.hpp"
|
||||
#include "oops/compressedOops.inline.hpp"
|
||||
#include "runtime/atomic.hpp"
|
||||
#include "runtime/thread.hpp"
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include "oops/compressedOops.inline.hpp"
|
||||
#include "oops/oop.inline.hpp"
|
||||
#include "runtime/prefetch.inline.hpp"
|
||||
#include "utilities/devirtualizer.inline.hpp"
|
||||
#include "utilities/powerOfTwo.hpp"
|
||||
|
||||
template <StringDedupMode STRING_DEDUP>
|
||||
|
@ -28,7 +28,6 @@
|
||||
#include "memory/allocation.hpp"
|
||||
#include "memory/memRegion.hpp"
|
||||
#include "oops/oopsHierarchy.hpp"
|
||||
#include "utilities/bitMap.hpp"
|
||||
|
||||
class CodeBlob;
|
||||
class nmethod;
|
||||
@ -370,18 +369,6 @@ public:
|
||||
virtual int do_compare(const E&, const E&) = 0;
|
||||
};
|
||||
|
||||
// Dispatches to the non-virtual functions if OopClosureType has
|
||||
// a concrete implementation, otherwise a virtual call is taken.
|
||||
class Devirtualizer {
|
||||
public:
|
||||
template <typename OopClosureType, typename T> static void do_oop(OopClosureType* closure, T* p);
|
||||
template <typename OopClosureType> static void do_klass(OopClosureType* closure, Klass* k);
|
||||
template <typename OopClosureType> static void do_cld(OopClosureType* closure, ClassLoaderData* cld);
|
||||
template <typename OopClosureType> static bool do_metadata(OopClosureType* closure);
|
||||
template <typename DerivedOopClosureType> static void do_derived_oop(DerivedOopClosureType* closure, oop* base, derived_pointer* derived);
|
||||
template <typename BitMapClosureType> static bool do_bit(BitMapClosureType* closure, BitMap::idx_t index);
|
||||
};
|
||||
|
||||
class OopIteratorClosureDispatch {
|
||||
public:
|
||||
template <typename OopClosureType> static void oop_oop_iterate(OopClosureType* cl, oop obj, Klass* klass);
|
||||
|
@ -63,142 +63,6 @@ inline void ClaimMetadataVisitingOopIterateClosure::do_method(Method* m) {
|
||||
m->record_gc_epoch();
|
||||
}
|
||||
|
||||
// Implementation of the non-virtual do_oop dispatch.
|
||||
//
|
||||
// The same implementation is used for do_metadata, do_klass, and do_cld.
|
||||
//
|
||||
// Preconditions:
|
||||
// - Base has a pure virtual do_oop
|
||||
// - Only one of the classes in the inheritance chain from OopClosureType to
|
||||
// Base implements do_oop.
|
||||
//
|
||||
// Given the preconditions:
|
||||
// - If &OopClosureType::do_oop is resolved to &Base::do_oop, then there is no
|
||||
// implementation of do_oop between Base and OopClosureType. However, there
|
||||
// must be one implementation in one of the subclasses of OopClosureType.
|
||||
// In this case we take the virtual call.
|
||||
//
|
||||
// - Conversely, if &OopClosureType::do_oop is not resolved to &Base::do_oop,
|
||||
// then we've found the one and only concrete implementation. In this case we
|
||||
// take a non-virtual call.
|
||||
//
|
||||
// Because of this it's clear when we should call the virtual call and
|
||||
// when the non-virtual call should be made.
|
||||
//
|
||||
// The way we find if &OopClosureType::do_oop is resolved to &Base::do_oop is to
|
||||
// check if the resulting type of the class of a member-function pointer to
|
||||
// &OopClosureType::do_oop is equal to the type of the class of a
|
||||
// &Base::do_oop member-function pointer. Template parameter deduction is used
|
||||
// to find these types, and then the IsSame trait is used to check if they are
|
||||
// equal. Finally, SFINAE is used to select the appropriate implementation.
|
||||
//
|
||||
// Template parameters:
|
||||
// T - narrowOop or oop
|
||||
// Receiver - the resolved type of the class of the
|
||||
// &OopClosureType::do_oop member-function pointer. That is,
|
||||
// the klass with the do_oop member function.
|
||||
// Base - klass with the pure virtual do_oop member function.
|
||||
// OopClosureType - The dynamic closure type
|
||||
//
|
||||
// Parameters:
|
||||
// closure - The closure to call
|
||||
// p - The oop (or narrowOop) field to pass to the closure
|
||||
|
||||
template <typename T, typename Receiver, typename Base, typename OopClosureType>
|
||||
static typename EnableIf<IsSame<Receiver, Base>::value, void>::type
|
||||
call_do_oop(void (Receiver::*)(T*), void (Base::*)(T*), OopClosureType* closure, T* p) {
|
||||
closure->do_oop(p);
|
||||
}
|
||||
|
||||
template <typename T, typename Receiver, typename Base, typename OopClosureType>
|
||||
static typename EnableIf<!IsSame<Receiver, Base>::value, void>::type
|
||||
call_do_oop(void (Receiver::*)(T*), void (Base::*)(T*), OopClosureType* closure, T* p) {
|
||||
// Sanity check
|
||||
STATIC_ASSERT((!IsSame<OopClosureType, OopIterateClosure>::value));
|
||||
closure->OopClosureType::do_oop(p);
|
||||
}
|
||||
|
||||
template <typename OopClosureType, typename T>
|
||||
inline void Devirtualizer::do_oop(OopClosureType* closure, T* p) {
|
||||
call_do_oop<T>(&OopClosureType::do_oop, &OopClosure::do_oop, closure, p);
|
||||
}
|
||||
|
||||
// Implementation of the non-virtual do_metadata dispatch.
|
||||
|
||||
template <typename Receiver, typename Base, typename OopClosureType>
|
||||
static typename EnableIf<IsSame<Receiver, Base>::value, bool>::type
|
||||
call_do_metadata(bool (Receiver::*)(), bool (Base::*)(), OopClosureType* closure) {
|
||||
return closure->do_metadata();
|
||||
}
|
||||
|
||||
template <typename Receiver, typename Base, typename OopClosureType>
|
||||
static typename EnableIf<!IsSame<Receiver, Base>::value, bool>::type
|
||||
call_do_metadata(bool (Receiver::*)(), bool (Base::*)(), OopClosureType* closure) {
|
||||
return closure->OopClosureType::do_metadata();
|
||||
}
|
||||
|
||||
template <typename OopClosureType>
|
||||
inline bool Devirtualizer::do_metadata(OopClosureType* closure) {
|
||||
return call_do_metadata(&OopClosureType::do_metadata, &OopIterateClosure::do_metadata, closure);
|
||||
}
|
||||
|
||||
// Implementation of the non-virtual do_klass dispatch.
|
||||
|
||||
template <typename Receiver, typename Base, typename OopClosureType>
|
||||
static typename EnableIf<IsSame<Receiver, Base>::value, void>::type
|
||||
call_do_klass(void (Receiver::*)(Klass*), void (Base::*)(Klass*), OopClosureType* closure, Klass* k) {
|
||||
closure->do_klass(k);
|
||||
}
|
||||
|
||||
template <typename Receiver, typename Base, typename OopClosureType>
|
||||
static typename EnableIf<!IsSame<Receiver, Base>::value, void>::type
|
||||
call_do_klass(void (Receiver::*)(Klass*), void (Base::*)(Klass*), OopClosureType* closure, Klass* k) {
|
||||
closure->OopClosureType::do_klass(k);
|
||||
}
|
||||
|
||||
template <typename OopClosureType>
|
||||
inline void Devirtualizer::do_klass(OopClosureType* closure, Klass* k) {
|
||||
call_do_klass(&OopClosureType::do_klass, &OopIterateClosure::do_klass, closure, k);
|
||||
}
|
||||
|
||||
// Implementation of the non-virtual do_cld dispatch.
|
||||
|
||||
template <typename Receiver, typename Base, typename OopClosureType>
|
||||
static typename EnableIf<IsSame<Receiver, Base>::value, void>::type
|
||||
call_do_cld(void (Receiver::*)(ClassLoaderData*), void (Base::*)(ClassLoaderData*), OopClosureType* closure, ClassLoaderData* cld) {
|
||||
closure->do_cld(cld);
|
||||
}
|
||||
|
||||
template <typename Receiver, typename Base, typename OopClosureType>
|
||||
static typename EnableIf<!IsSame<Receiver, Base>::value, void>::type
|
||||
call_do_cld(void (Receiver::*)(ClassLoaderData*), void (Base::*)(ClassLoaderData*), OopClosureType* closure, ClassLoaderData* cld) {
|
||||
closure->OopClosureType::do_cld(cld);
|
||||
}
|
||||
|
||||
template <typename OopClosureType>
|
||||
void Devirtualizer::do_cld(OopClosureType* closure, ClassLoaderData* cld) {
|
||||
call_do_cld(&OopClosureType::do_cld, &OopIterateClosure::do_cld, closure, cld);
|
||||
}
|
||||
|
||||
// Implementation of the non-virtual do_derived_oop dispatch.
|
||||
|
||||
template <typename Receiver, typename Base, typename DerivedOopClosureType>
|
||||
static typename EnableIf<IsSame<Receiver, Base>::value, void>::type
|
||||
call_do_derived_oop(void (Receiver::*)(oop*, derived_pointer*), void (Base::*)(oop*, derived_pointer*), DerivedOopClosureType* closure, oop* base, derived_pointer* derived) {
|
||||
closure->do_derived_oop(base, derived);
|
||||
}
|
||||
|
||||
template <typename Receiver, typename Base, typename DerivedOopClosureType>
|
||||
static typename EnableIf<!IsSame<Receiver, Base>::value, void>::type
|
||||
call_do_derived_oop(void (Receiver::*)(oop*, derived_pointer*), void (Base::*)(oop*, derived_pointer*), DerivedOopClosureType* closure, oop* base, derived_pointer* derived) {
|
||||
closure->DerivedOopClosureType::do_derived_oop(base, derived);
|
||||
}
|
||||
|
||||
template <typename DerivedOopClosureType>
|
||||
inline void Devirtualizer::do_derived_oop(DerivedOopClosureType* closure, oop* base, derived_pointer* derived) {
|
||||
call_do_derived_oop(&DerivedOopClosureType::do_derived_oop, &DerivedOopClosure::do_derived_oop, closure, base, derived);
|
||||
}
|
||||
|
||||
// Dispatch table implementation for *Klass::oop_oop_iterate
|
||||
//
|
||||
// It allows for a single call to do a multi-dispatch to an optimized version
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 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
|
||||
@ -28,10 +28,10 @@
|
||||
#include "oops/instanceClassLoaderKlass.hpp"
|
||||
|
||||
#include "classfile/javaClasses.hpp"
|
||||
#include "memory/iterator.hpp"
|
||||
#include "oops/instanceKlass.inline.hpp"
|
||||
#include "oops/oop.inline.hpp"
|
||||
#include "utilities/debug.hpp"
|
||||
#include "utilities/devirtualizer.inline.hpp"
|
||||
#include "utilities/globalDefinitions.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 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
|
||||
@ -29,12 +29,12 @@
|
||||
|
||||
#include "classfile/javaClasses.hpp"
|
||||
#include "classfile/vmSymbols.hpp"
|
||||
#include "memory/iterator.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "oops/klass.inline.hpp"
|
||||
#include "oops/oop.inline.hpp"
|
||||
#include "runtime/atomic.hpp"
|
||||
#include "utilities/debug.hpp"
|
||||
#include "utilities/devirtualizer.inline.hpp"
|
||||
#include "utilities/globalDefinitions.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 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
|
||||
@ -32,6 +32,7 @@
|
||||
#include "oops/klass.hpp"
|
||||
#include "oops/oop.inline.hpp"
|
||||
#include "utilities/debug.hpp"
|
||||
#include "utilities/devirtualizer.inline.hpp"
|
||||
#include "utilities/globalDefinitions.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 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
|
||||
@ -34,6 +34,7 @@
|
||||
#include "oops/instanceKlass.inline.hpp"
|
||||
#include "oops/oop.inline.hpp"
|
||||
#include "utilities/debug.hpp"
|
||||
#include "utilities/devirtualizer.inline.hpp"
|
||||
#include "utilities/globalDefinitions.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
|
||||
|
@ -26,7 +26,6 @@
|
||||
#include "classfile/javaClasses.inline.hpp"
|
||||
#include "classfile/vmClasses.hpp"
|
||||
#include "compiler/oopMap.inline.hpp"
|
||||
#include "memory/iterator.inline.hpp"
|
||||
#include "memory/oopFactory.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "oops/instanceStackChunkKlass.inline.hpp"
|
||||
@ -37,6 +36,7 @@
|
||||
#include "runtime/registerMap.hpp"
|
||||
#include "runtime/smallRegisterMap.inline.hpp"
|
||||
#include "runtime/stackChunkFrameStream.inline.hpp"
|
||||
#include "utilities/devirtualizer.inline.hpp"
|
||||
#include "utilities/globalDefinitions.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
#include "utilities/ostream.hpp"
|
||||
|
@ -35,7 +35,6 @@
|
||||
#include "gc/shared/collectedHeap.hpp"
|
||||
#include "gc/shared/gc_globals.hpp"
|
||||
#include "logging/log.hpp"
|
||||
#include "memory/iterator.inline.hpp"
|
||||
#include "oops/instanceKlass.inline.hpp"
|
||||
#include "oops/klass.hpp"
|
||||
#include "oops/oop.inline.hpp"
|
||||
@ -47,6 +46,7 @@
|
||||
#include "runtime/stackChunkFrameStream.inline.hpp"
|
||||
#include "utilities/bitMap.inline.hpp"
|
||||
#include "utilities/debug.hpp"
|
||||
#include "utilities/devirtualizer.inline.hpp"
|
||||
#include "utilities/globalDefinitions.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2010, 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
|
||||
@ -28,12 +28,12 @@
|
||||
#include "oops/objArrayKlass.hpp"
|
||||
|
||||
#include "memory/memRegion.hpp"
|
||||
#include "memory/iterator.hpp"
|
||||
#include "oops/arrayKlass.hpp"
|
||||
#include "oops/arrayOop.hpp"
|
||||
#include "oops/klass.hpp"
|
||||
#include "oops/objArrayOop.inline.hpp"
|
||||
#include "oops/oop.inline.hpp"
|
||||
#include "utilities/devirtualizer.inline.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
|
||||
template <typename T, class OopClosureType>
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include "oops/instanceStackChunkKlass.inline.hpp"
|
||||
#include "runtime/frame.inline.hpp"
|
||||
#include "utilities/debug.hpp"
|
||||
#include "utilities/devirtualizer.inline.hpp"
|
||||
#include "utilities/globalDefinitions.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
#include CPU_HEADER_INLINE(stackChunkFrameStream)
|
||||
|
45
src/hotspot/share/utilities/devirtualizer.hpp
Normal file
45
src/hotspot/share/utilities/devirtualizer.hpp
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2018, 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_UTILITIES_DEVIRTUALIZER_HPP
|
||||
#define SHARE_UTILITIES_DEVIRTUALIZER_HPP
|
||||
|
||||
#include "oops/oopsHierarchy.hpp"
|
||||
#include "utilities/bitMap.hpp"
|
||||
|
||||
class ClassLoaderData;
|
||||
|
||||
// Dispatches to the non-virtual functions if OopClosureType has
|
||||
// a concrete implementation, otherwise a virtual call is taken.
|
||||
class Devirtualizer {
|
||||
public:
|
||||
template <typename OopClosureType, typename T> static void do_oop(OopClosureType* closure, T* p);
|
||||
template <typename OopClosureType> static void do_klass(OopClosureType* closure, Klass* k);
|
||||
template <typename OopClosureType> static void do_cld(OopClosureType* closure, ClassLoaderData* cld);
|
||||
template <typename OopClosureType> static bool do_metadata(OopClosureType* closure);
|
||||
template <typename DerivedOopClosureType> static void do_derived_oop(DerivedOopClosureType* closure, oop* base, derived_pointer* derived);
|
||||
template <typename BitMapClosureType> static bool do_bit(BitMapClosureType* closure, BitMap::idx_t index);
|
||||
};
|
||||
|
||||
#endif // SHARE_UTILITIES_DEVIRTUALIZER_HPP
|
171
src/hotspot/share/utilities/devirtualizer.inline.hpp
Normal file
171
src/hotspot/share/utilities/devirtualizer.inline.hpp
Normal file
@ -0,0 +1,171 @@
|
||||
/*
|
||||
* Copyright (c) 2018, 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_UTILITIES_DEVIRTUALIZER_INLINE_HPP
|
||||
#define SHARE_UTILITIES_DEVIRTUALIZER_INLINE_HPP
|
||||
|
||||
#include "utilities/devirtualizer.hpp"
|
||||
|
||||
#include "classfile/classLoaderData.hpp"
|
||||
#include "oops/access.inline.hpp"
|
||||
#include "utilities/debug.hpp"
|
||||
|
||||
// Implementation of the non-virtual do_oop dispatch.
|
||||
//
|
||||
// The same implementation is used for do_metadata, do_klass, and do_cld.
|
||||
//
|
||||
// Preconditions:
|
||||
// - Base has a pure virtual do_oop
|
||||
// - Only one of the classes in the inheritance chain from OopClosureType to
|
||||
// Base implements do_oop.
|
||||
//
|
||||
// Given the preconditions:
|
||||
// - If &OopClosureType::do_oop is resolved to &Base::do_oop, then there is no
|
||||
// implementation of do_oop between Base and OopClosureType. However, there
|
||||
// must be one implementation in one of the subclasses of OopClosureType.
|
||||
// In this case we take the virtual call.
|
||||
//
|
||||
// - Conversely, if &OopClosureType::do_oop is not resolved to &Base::do_oop,
|
||||
// then we've found the one and only concrete implementation. In this case we
|
||||
// take a non-virtual call.
|
||||
//
|
||||
// Because of this it's clear when we should call the virtual call and
|
||||
// when the non-virtual call should be made.
|
||||
//
|
||||
// The way we find if &OopClosureType::do_oop is resolved to &Base::do_oop is to
|
||||
// check if the resulting type of the class of a member-function pointer to
|
||||
// &OopClosureType::do_oop is equal to the type of the class of a
|
||||
// &Base::do_oop member-function pointer. Template parameter deduction is used
|
||||
// to find these types, and then the IsSame trait is used to check if they are
|
||||
// equal. Finally, SFINAE is used to select the appropriate implementation.
|
||||
//
|
||||
// Template parameters:
|
||||
// T - narrowOop or oop
|
||||
// Receiver - the resolved type of the class of the
|
||||
// &OopClosureType::do_oop member-function pointer. That is,
|
||||
// the klass with the do_oop member function.
|
||||
// Base - klass with the pure virtual do_oop member function.
|
||||
// OopClosureType - The dynamic closure type
|
||||
//
|
||||
// Parameters:
|
||||
// closure - The closure to call
|
||||
// p - The oop (or narrowOop) field to pass to the closure
|
||||
|
||||
template <typename T, typename Receiver, typename Base, typename OopClosureType>
|
||||
static typename EnableIf<IsSame<Receiver, Base>::value, void>::type
|
||||
call_do_oop(void (Receiver::*)(T*), void (Base::*)(T*), OopClosureType* closure, T* p) {
|
||||
closure->do_oop(p);
|
||||
}
|
||||
|
||||
template <typename T, typename Receiver, typename Base, typename OopClosureType>
|
||||
static typename EnableIf<!IsSame<Receiver, Base>::value, void>::type
|
||||
call_do_oop(void (Receiver::*)(T*), void (Base::*)(T*), OopClosureType* closure, T* p) {
|
||||
// Sanity check
|
||||
STATIC_ASSERT((!IsSame<OopClosureType, OopIterateClosure>::value));
|
||||
closure->OopClosureType::do_oop(p);
|
||||
}
|
||||
|
||||
template <typename OopClosureType, typename T>
|
||||
inline void Devirtualizer::do_oop(OopClosureType* closure, T* p) {
|
||||
call_do_oop<T>(&OopClosureType::do_oop, &OopClosure::do_oop, closure, p);
|
||||
}
|
||||
|
||||
// Implementation of the non-virtual do_metadata dispatch.
|
||||
|
||||
template <typename Receiver, typename Base, typename OopClosureType>
|
||||
static typename EnableIf<IsSame<Receiver, Base>::value, bool>::type
|
||||
call_do_metadata(bool (Receiver::*)(), bool (Base::*)(), OopClosureType* closure) {
|
||||
return closure->do_metadata();
|
||||
}
|
||||
|
||||
template <typename Receiver, typename Base, typename OopClosureType>
|
||||
static typename EnableIf<!IsSame<Receiver, Base>::value, bool>::type
|
||||
call_do_metadata(bool (Receiver::*)(), bool (Base::*)(), OopClosureType* closure) {
|
||||
return closure->OopClosureType::do_metadata();
|
||||
}
|
||||
|
||||
template <typename OopClosureType>
|
||||
inline bool Devirtualizer::do_metadata(OopClosureType* closure) {
|
||||
return call_do_metadata(&OopClosureType::do_metadata, &OopIterateClosure::do_metadata, closure);
|
||||
}
|
||||
|
||||
// Implementation of the non-virtual do_klass dispatch.
|
||||
|
||||
template <typename Receiver, typename Base, typename OopClosureType>
|
||||
static typename EnableIf<IsSame<Receiver, Base>::value, void>::type
|
||||
call_do_klass(void (Receiver::*)(Klass*), void (Base::*)(Klass*), OopClosureType* closure, Klass* k) {
|
||||
closure->do_klass(k);
|
||||
}
|
||||
|
||||
template <typename Receiver, typename Base, typename OopClosureType>
|
||||
static typename EnableIf<!IsSame<Receiver, Base>::value, void>::type
|
||||
call_do_klass(void (Receiver::*)(Klass*), void (Base::*)(Klass*), OopClosureType* closure, Klass* k) {
|
||||
closure->OopClosureType::do_klass(k);
|
||||
}
|
||||
|
||||
template <typename OopClosureType>
|
||||
inline void Devirtualizer::do_klass(OopClosureType* closure, Klass* k) {
|
||||
call_do_klass(&OopClosureType::do_klass, &OopIterateClosure::do_klass, closure, k);
|
||||
}
|
||||
|
||||
// Implementation of the non-virtual do_cld dispatch.
|
||||
|
||||
template <typename Receiver, typename Base, typename OopClosureType>
|
||||
static typename EnableIf<IsSame<Receiver, Base>::value, void>::type
|
||||
call_do_cld(void (Receiver::*)(ClassLoaderData*), void (Base::*)(ClassLoaderData*), OopClosureType* closure, ClassLoaderData* cld) {
|
||||
closure->do_cld(cld);
|
||||
}
|
||||
|
||||
template <typename Receiver, typename Base, typename OopClosureType>
|
||||
static typename EnableIf<!IsSame<Receiver, Base>::value, void>::type
|
||||
call_do_cld(void (Receiver::*)(ClassLoaderData*), void (Base::*)(ClassLoaderData*), OopClosureType* closure, ClassLoaderData* cld) {
|
||||
closure->OopClosureType::do_cld(cld);
|
||||
}
|
||||
|
||||
template <typename OopClosureType>
|
||||
void Devirtualizer::do_cld(OopClosureType* closure, ClassLoaderData* cld) {
|
||||
call_do_cld(&OopClosureType::do_cld, &OopIterateClosure::do_cld, closure, cld);
|
||||
}
|
||||
|
||||
// Implementation of the non-virtual do_derived_oop dispatch.
|
||||
|
||||
template <typename Receiver, typename Base, typename DerivedOopClosureType>
|
||||
static typename EnableIf<IsSame<Receiver, Base>::value, void>::type
|
||||
call_do_derived_oop(void (Receiver::*)(oop*, derived_pointer*), void (Base::*)(oop*, derived_pointer*), DerivedOopClosureType* closure, oop* base, derived_pointer* derived) {
|
||||
closure->do_derived_oop(base, derived);
|
||||
}
|
||||
|
||||
template <typename Receiver, typename Base, typename DerivedOopClosureType>
|
||||
static typename EnableIf<!IsSame<Receiver, Base>::value, void>::type
|
||||
call_do_derived_oop(void (Receiver::*)(oop*, derived_pointer*), void (Base::*)(oop*, derived_pointer*), DerivedOopClosureType* closure, oop* base, derived_pointer* derived) {
|
||||
closure->DerivedOopClosureType::do_derived_oop(base, derived);
|
||||
}
|
||||
|
||||
template <typename DerivedOopClosureType>
|
||||
inline void Devirtualizer::do_derived_oop(DerivedOopClosureType* closure, oop* base, derived_pointer* derived) {
|
||||
call_do_derived_oop(&DerivedOopClosureType::do_derived_oop, &DerivedOopClosure::do_derived_oop, closure, base, derived);
|
||||
}
|
||||
|
||||
#endif // SHARE_UTILITIES_DEVIRTUALIZER_INLINE_HPP
|
||||
|
Loading…
Reference in New Issue
Block a user