1 /*
  2  * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.
  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 12  * version 2 for more details (a copy is included in the LICENSE file that
 13  * accompanied this code).
 14  *
 15  * You should have received a copy of the GNU General Public License version
 16  * 2 along with this work; if not, write to the Free Software Foundation,
 17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 18  *
 19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  * or visit www.oracle.com if you need additional information or have any
 21  * questions.
 22  *
 23  */
 24 #ifndef SHARE_VM_OOPS_INLINEKLASS_INLINE_HPP
 25 #define SHARE_VM_OOPS_INLINEKLASS_INLINE_HPP
 26 
 27 #include "oops/inlineKlass.hpp"
 28 
 29 #include "oops/valuePayload.inline.hpp"
 30 #include "runtime/handles.hpp"
 31 #include "utilities/debug.hpp"
 32 #include "utilities/devirtualizer.inline.hpp"
 33 
 34 inline bool InlineKlass::layout_has_null_marker(LayoutKind lk) const {
 35   assert(is_layout_supported(lk), "Must be");
 36   return LayoutKindHelper::is_nullable_flat(lk) ||
 37          (lk == LayoutKind::BUFFERED && supports_nullable_layouts());
 38 }
 39 
 40 inline bool InlineKlass::is_layout_supported(LayoutKind lk) const {
 41   switch(lk) {
 42     case LayoutKind::NULL_FREE_NON_ATOMIC_FLAT:
 43       return has_null_free_non_atomic_layout();
 44       break;
 45     case LayoutKind::NULL_FREE_ATOMIC_FLAT:
 46       return has_null_free_atomic_layout();
 47       break;
 48     case LayoutKind::NULLABLE_ATOMIC_FLAT:
 49       return has_nullable_atomic_layout();
 50       break;
 51     case LayoutKind::NULLABLE_NON_ATOMIC_FLAT:
 52       return has_nullable_non_atomic_layout();
 53       break;
 54     case LayoutKind::BUFFERED:
 55       return true;
 56       break;
 57     default:
 58       ShouldNotReachHere();
 59   }
 60 }
 61 
 62 inline int InlineKlass::layout_size_in_bytes(LayoutKind kind) const {
 63   switch(kind) {
 64     case LayoutKind::NULL_FREE_NON_ATOMIC_FLAT:
 65       assert(has_null_free_non_atomic_layout(), "Layout not available");
 66       return null_free_non_atomic_size_in_bytes();
 67       break;
 68     case LayoutKind::NULL_FREE_ATOMIC_FLAT:
 69       assert(has_null_free_atomic_layout(), "Layout not available");
 70       return null_free_atomic_size_in_bytes();
 71       break;
 72     case LayoutKind::NULLABLE_ATOMIC_FLAT:
 73       assert(has_nullable_atomic_layout(), "Layout not available");
 74       return nullable_atomic_size_in_bytes();
 75       break;
 76     case LayoutKind::NULLABLE_NON_ATOMIC_FLAT:
 77       assert(has_nullable_non_atomic_layout(), "Layout not available");
 78       return nullable_non_atomic_size_in_bytes();
 79       break;
 80     case LayoutKind::BUFFERED:
 81       return payload_size_in_bytes();
 82       break;
 83     default:
 84       ShouldNotReachHere();
 85   }
 86 }
 87 
 88 inline int InlineKlass::layout_alignment(LayoutKind kind) const {
 89   switch(kind) {
 90     case LayoutKind::NULL_FREE_NON_ATOMIC_FLAT:
 91       assert(has_null_free_non_atomic_layout(), "Layout not available");
 92       return null_free_non_atomic_alignment();
 93       break;
 94     case LayoutKind::NULL_FREE_ATOMIC_FLAT:
 95       assert(has_null_free_atomic_layout(), "Layout not available");
 96       return null_free_atomic_size_in_bytes();
 97       break;
 98     case LayoutKind::NULLABLE_ATOMIC_FLAT:
 99       assert(has_nullable_atomic_layout(), "Layout not available");
100       return nullable_atomic_size_in_bytes();
101       break;
102     case LayoutKind::NULLABLE_NON_ATOMIC_FLAT:
103       assert(has_nullable_non_atomic_layout(), "Layout not available");
104       return null_free_non_atomic_alignment();
105     break;
106     case LayoutKind::BUFFERED:
107       return payload_alignment();
108       break;
109     default:
110       ShouldNotReachHere();
111   }
112 }
113 
114 inline address InlineKlass::payload_addr(oop o) const {
115   return cast_from_oop<address>(o) + payload_offset();
116 }
117 
118 template <typename T, class OopClosureType>
119 void InlineKlass::oop_iterate_specialized(const address oop_addr, OopClosureType* closure) {
120   OopMapBlock* map = start_of_nonstatic_oop_maps();
121   OopMapBlock* const end_map = map + nonstatic_oop_map_count();
122 
123   for (; map < end_map; map++) {
124     T* p = (T*) (oop_addr + map->offset());
125     T* const end = p + map->count();
126     for (; p < end; ++p) {
127       Devirtualizer::do_oop(closure, p);
128     }
129   }
130 }
131 
132 template <typename T, class OopClosureType>
133 inline void InlineKlass::oop_iterate_specialized_bounded(const address oop_addr, OopClosureType* closure, uintptr_t lo, uintptr_t hi) {
134   OopMapBlock* map = start_of_nonstatic_oop_maps();
135   OopMapBlock* const end_map = map + nonstatic_oop_map_count();
136 
137   T* const l   = (T*) lo;
138   T* const h   = (T*) hi;
139 
140   for (; map < end_map; map++) {
141     T* p = (T*) (oop_addr + map->offset());
142     T* end = p + map->count();
143     if (p < l) {
144       p = l;
145     }
146     if (end > h) {
147       end = h;
148     }
149     for (; p < end; ++p) {
150       Devirtualizer::do_oop(closure, p);
151     }
152   }
153 }
154 
155 #endif // SHARE_VM_OOPS_INLINEKLASS_INLINE_HPP