Path: blob/master/src/hotspot/share/oops/instanceKlass.inline.hpp
40951 views
/*1* Copyright (c) 2015, 2021, 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_OOPS_INSTANCEKLASS_INLINE_HPP25#define SHARE_OOPS_INSTANCEKLASS_INLINE_HPP2627#include "oops/instanceKlass.hpp"2829#include "classfile/javaClasses.hpp"30#include "classfile/vmSymbols.hpp"31#include "memory/iterator.hpp"32#include "memory/resourceArea.hpp"33#include "oops/klass.inline.hpp"34#include "oops/oop.inline.hpp"35#include "runtime/atomic.hpp"36#include "utilities/debug.hpp"37#include "utilities/globalDefinitions.hpp"38#include "utilities/macros.hpp"3940inline intptr_t* InstanceKlass::start_of_itable() const { return (intptr_t*)start_of_vtable() + vtable_length(); }41inline intptr_t* InstanceKlass::end_of_itable() const { return start_of_itable() + itable_length(); }4243inline int InstanceKlass::itable_offset_in_words() const { return start_of_itable() - (intptr_t*)this; }4445inline oop InstanceKlass::static_field_base_raw() { return java_mirror(); }4647inline OopMapBlock* InstanceKlass::start_of_nonstatic_oop_maps() const {48return (OopMapBlock*)(start_of_itable() + itable_length());49}5051inline Klass** InstanceKlass::end_of_nonstatic_oop_maps() const {52return (Klass**)(start_of_nonstatic_oop_maps() +53nonstatic_oop_map_count());54}5556inline InstanceKlass* volatile* InstanceKlass::adr_implementor() const {57if (is_interface()) {58return (InstanceKlass* volatile*)end_of_nonstatic_oop_maps();59} else {60return NULL;61}62}6364inline ObjArrayKlass* InstanceKlass::array_klasses_acquire() const {65return Atomic::load_acquire(&_array_klasses);66}6768inline void InstanceKlass::release_set_array_klasses(ObjArrayKlass* k) {69Atomic::release_store(&_array_klasses, k);70}7172inline jmethodID* InstanceKlass::methods_jmethod_ids_acquire() const {73return Atomic::load_acquire(&_methods_jmethod_ids);74}7576inline void InstanceKlass::release_set_methods_jmethod_ids(jmethodID* jmeths) {77Atomic::release_store(&_methods_jmethod_ids, jmeths);78}7980// The iteration over the oops in objects is a hot path in the GC code.81// By force inlining the following functions, we get similar GC performance82// as the previous macro based implementation.8384template <typename T, class OopClosureType>85ALWAYSINLINE void InstanceKlass::oop_oop_iterate_oop_map(OopMapBlock* map, oop obj, OopClosureType* closure) {86T* p = (T*)obj->obj_field_addr<T>(map->offset());87T* const end = p + map->count();8889for (; p < end; ++p) {90Devirtualizer::do_oop(closure, p);91}92}9394template <typename T, class OopClosureType>95ALWAYSINLINE void InstanceKlass::oop_oop_iterate_oop_map_reverse(OopMapBlock* map, oop obj, OopClosureType* closure) {96T* const start = (T*)obj->obj_field_addr<T>(map->offset());97T* p = start + map->count();9899while (start < p) {100--p;101Devirtualizer::do_oop(closure, p);102}103}104105template <typename T, class OopClosureType>106ALWAYSINLINE void InstanceKlass::oop_oop_iterate_oop_map_bounded(OopMapBlock* map, oop obj, OopClosureType* closure, MemRegion mr) {107T* p = (T*)obj->obj_field_addr<T>(map->offset());108T* end = p + map->count();109110T* const l = (T*)mr.start();111T* const h = (T*)mr.end();112assert(mask_bits((intptr_t)l, sizeof(T)-1) == 0 &&113mask_bits((intptr_t)h, sizeof(T)-1) == 0,114"bounded region must be properly aligned");115116if (p < l) {117p = l;118}119if (end > h) {120end = h;121}122123for (;p < end; ++p) {124Devirtualizer::do_oop(closure, p);125}126}127128template <typename T, class OopClosureType>129ALWAYSINLINE void InstanceKlass::oop_oop_iterate_oop_maps(oop obj, OopClosureType* closure) {130OopMapBlock* map = start_of_nonstatic_oop_maps();131OopMapBlock* const end_map = map + nonstatic_oop_map_count();132133for (; map < end_map; ++map) {134oop_oop_iterate_oop_map<T>(map, obj, closure);135}136}137138template <typename T, class OopClosureType>139ALWAYSINLINE void InstanceKlass::oop_oop_iterate_oop_maps_reverse(oop obj, OopClosureType* closure) {140OopMapBlock* const start_map = start_of_nonstatic_oop_maps();141OopMapBlock* map = start_map + nonstatic_oop_map_count();142143while (start_map < map) {144--map;145oop_oop_iterate_oop_map_reverse<T>(map, obj, closure);146}147}148149template <typename T, class OopClosureType>150ALWAYSINLINE void InstanceKlass::oop_oop_iterate_oop_maps_bounded(oop obj, OopClosureType* closure, MemRegion mr) {151OopMapBlock* map = start_of_nonstatic_oop_maps();152OopMapBlock* const end_map = map + nonstatic_oop_map_count();153154for (;map < end_map; ++map) {155oop_oop_iterate_oop_map_bounded<T>(map, obj, closure, mr);156}157}158159template <typename T, class OopClosureType>160ALWAYSINLINE void InstanceKlass::oop_oop_iterate(oop obj, OopClosureType* closure) {161if (Devirtualizer::do_metadata(closure)) {162Devirtualizer::do_klass(closure, this);163}164165oop_oop_iterate_oop_maps<T>(obj, closure);166}167168template <typename T, class OopClosureType>169ALWAYSINLINE void InstanceKlass::oop_oop_iterate_reverse(oop obj, OopClosureType* closure) {170assert(!Devirtualizer::do_metadata(closure),171"Code to handle metadata is not implemented");172173oop_oop_iterate_oop_maps_reverse<T>(obj, closure);174}175176template <typename T, class OopClosureType>177ALWAYSINLINE void InstanceKlass::oop_oop_iterate_bounded(oop obj, OopClosureType* closure, MemRegion mr) {178if (Devirtualizer::do_metadata(closure)) {179if (mr.contains(obj)) {180Devirtualizer::do_klass(closure, this);181}182}183184oop_oop_iterate_oop_maps_bounded<T>(obj, closure, mr);185}186187inline instanceOop InstanceKlass::allocate_instance(oop java_class, TRAPS) {188Klass* k = java_lang_Class::as_Klass(java_class);189if (k == NULL) {190ResourceMark rm(THREAD);191THROW_(vmSymbols::java_lang_InstantiationException(), NULL);192}193InstanceKlass* ik = cast(k);194ik->check_valid_for_instantiation(false, CHECK_NULL);195ik->initialize(CHECK_NULL);196return ik->allocate_instance(THREAD);197}198199#endif // SHARE_OOPS_INSTANCEKLASS_INLINE_HPP200201202