1 /* 2 * Copyright (c) 1997, 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 25 #ifndef SHARE_OOPS_OOP_HPP 26 #define SHARE_OOPS_OOP_HPP 27 28 #include "memory/iterator.hpp" 29 #include "memory/memRegion.hpp" 30 #include "oops/accessDecorators.hpp" 31 #include "oops/compressedKlass.hpp" 32 #include "oops/markWord.hpp" 33 #include "oops/metadata.hpp" 34 #include "oops/objLayout.hpp" 35 #include "runtime/atomic.hpp" 36 #include "utilities/globalDefinitions.hpp" 37 #include "utilities/macros.hpp" 38 39 #include <type_traits> 40 41 // oopDesc is the top baseclass for objects classes. The {name}Desc classes describe 42 // the format of Java objects so the fields can be accessed from C++. 43 // oopDesc is abstract. 44 // (see oopHierarchy for complete oop class hierarchy) 45 // 46 // no virtual functions allowed 47 // 48 // oopDesc::_mark - the "oop mark word" encoding to be found separately in markWord.hpp 49 // 50 // oopDesc::_metadata - encodes the object's klass pointer, as a raw pointer in "_klass" 51 // or compressed pointer in "_compressed_klass" 52 // 53 // The overall size of the _metadata field is dependent on "UseCompressedClassPointers", 54 // hence the terms "narrow" (32 bits) vs "wide" (64 bits). 55 // 56 57 58 class oopDesc { 59 friend class VMStructs; 60 friend class JVMCIVMStructs; 61 private: 62 volatile markWord _mark; 63 union _metadata { 64 Klass* _klass; 65 narrowKlass _compressed_klass; 66 } _metadata; 67 68 // There may be ordering constraints on the initialization of fields that 69 // make use of the C++ copy/assign incorrect. 70 NONCOPYABLE(oopDesc); 71 72 inline oop cas_set_forwardee(markWord new_mark, markWord old_mark, atomic_memory_order order); 73 74 public: 75 // Must be trivial; see verifying static assert after the class. 76 oopDesc() = default; 77 78 inline markWord mark() const; 79 inline markWord mark_acquire() const; 80 inline markWord* mark_addr() const; 81 82 inline void set_mark(markWord m); 83 static inline void set_mark(HeapWord* mem, markWord m); 84 static inline void release_set_mark(HeapWord* mem, markWord m); 85 86 inline void release_set_mark(markWord m); 87 inline markWord cas_set_mark(markWord new_mark, markWord old_mark); 88 inline markWord cas_set_mark(markWord new_mark, markWord old_mark, atomic_memory_order order); 89 90 // Returns the prototype mark that should be used for this object. 91 inline markWord prototype_mark() const; 92 93 // Used only to re-initialize the mark word (e.g., of promoted 94 // objects during a GC) -- requires a valid klass pointer 95 inline void init_mark(); 96 inline void reinit_mark(); // special for parallelGC 97 98 inline Klass* klass() const; 99 inline Klass* klass_or_null() const; 100 inline Klass* klass_or_null_acquire() const; 101 // Get the klass without running any asserts. 102 inline Klass* klass_without_asserts() const; 103 104 void set_narrow_klass(narrowKlass nk) NOT_CDS_JAVA_HEAP_RETURN; 105 inline narrowKlass narrow_klass() const; 106 inline void set_klass(Klass* k); 107 static inline void release_set_klass(HeapWord* mem, Klass* k); 108 109 // For klass field compression 110 static inline void set_klass_gap(HeapWord* mem, int z); 111 112 // Size of object header, aligned to platform wordSize 113 static int header_size() { 114 if (UseCompactObjectHeaders) { 115 return sizeof(markWord) / HeapWordSize; 116 } else { 117 return sizeof(oopDesc) / HeapWordSize; 118 } 119 } 120 121 // Returns whether this is an instance of k or an instance of a subclass of k 122 inline bool is_a(Klass* k) const; 123 124 // Returns the actual oop size of the object in machine words 125 inline size_t size(); 126 127 // Sometimes (for complicated concurrency-related reasons), it is useful 128 // to be able to figure out the size of an object knowing its klass. 129 inline size_t size_given_klass(Klass* klass); 130 131 // type test operations (inlined in oop.inline.hpp) 132 inline bool is_instance() const; 133 inline bool is_inline_type() const; 134 inline bool is_instanceRef() const; 135 inline bool is_stackChunk() const; 136 inline bool is_array() const; 137 inline bool is_objArray() const; 138 inline bool is_typeArray() const; 139 inline bool is_flatArray() const; 140 inline bool is_refArray() const; 141 inline bool is_null_free_array() const; 142 inline bool is_refined_objArray() const; 143 144 // type test operations that don't require inclusion of oop.inline.hpp. 145 bool is_instance_noinline() const; 146 bool is_instanceRef_noinline() const; 147 bool is_stackChunk_noinline() const; 148 bool is_array_noinline() const; 149 bool is_objArray_noinline() const; 150 bool is_refArray_noinline() const; 151 bool is_typeArray_noinline() const; 152 bool is_flatArray_noinline() const; 153 bool is_null_free_array_noinline() const; 154 155 protected: 156 inline oop as_oop() const { return const_cast<oopDesc*>(this); } 157 158 public: 159 template<typename T> 160 inline T* field_addr(int offset) const; 161 162 template <typename T> inline size_t field_offset(T* p) const; 163 164 // Standard compare function returns negative value if o1 < o2 165 // 0 if o1 == o2 166 // positive value if o1 > o2 167 inline static int compare(oop o1, oop o2) { 168 void* o1_addr = (void*)o1; 169 void* o2_addr = (void*)o2; 170 if (o1_addr < o2_addr) { 171 return -1; 172 } else if (o1_addr > o2_addr) { 173 return 1; 174 } else { 175 return 0; 176 } 177 } 178 179 // Access to fields in a instanceOop through these methods. 180 template<DecoratorSet decorators> 181 oop obj_field_access(int offset) const; 182 oop obj_field(int offset) const; 183 184 void obj_field_put(int offset, oop value); 185 void obj_field_put_raw(int offset, oop value); 186 void obj_field_put_volatile(int offset, oop value); 187 template<DecoratorSet decorators> 188 void obj_field_put_access(int offset, oop value); 189 190 Metadata* metadata_field(int offset) const; 191 void metadata_field_put(int offset, Metadata* value); 192 193 Metadata* metadata_field_acquire(int offset) const; 194 void release_metadata_field_put(int offset, Metadata* value); 195 196 jbyte byte_field(int offset) const; 197 void byte_field_put(int offset, jbyte contents); 198 199 jchar char_field(int offset) const; 200 void char_field_put(int offset, jchar contents); 201 202 jboolean bool_field(int offset) const; 203 void bool_field_put(int offset, jboolean contents); 204 jboolean bool_field_volatile(int offset) const; 205 void bool_field_put_volatile(int offset, jboolean contents); 206 207 jint int_field(int offset) const; 208 void int_field_put(int offset, jint contents); 209 210 jshort short_field(int offset) const; 211 void short_field_put(int offset, jshort contents); 212 213 jlong long_field(int offset) const; 214 void long_field_put(int offset, jlong contents); 215 216 jfloat float_field(int offset) const; 217 void float_field_put(int offset, jfloat contents); 218 219 jdouble double_field(int offset) const; 220 void double_field_put(int offset, jdouble contents); 221 222 address address_field(int offset) const; 223 void address_field_put(int offset, address contents); 224 225 oop obj_field_acquire(int offset) const; 226 void release_obj_field_put(int offset, oop value); 227 228 jbyte byte_field_acquire(int offset) const; 229 void release_byte_field_put(int offset, jbyte contents); 230 231 jchar char_field_acquire(int offset) const; 232 void release_char_field_put(int offset, jchar contents); 233 234 jboolean bool_field_acquire(int offset) const; 235 void release_bool_field_put(int offset, jboolean contents); 236 237 jint int_field_relaxed(int offset) const; 238 void int_field_put_relaxed(int offset, jint contents); 239 jint int_field_acquire(int offset) const; 240 void release_int_field_put(int offset, jint contents); 241 242 jshort short_field_acquire(int offset) const; 243 void release_short_field_put(int offset, jshort contents); 244 245 jlong long_field_acquire(int offset) const; 246 void release_long_field_put(int offset, jlong contents); 247 248 jfloat float_field_acquire(int offset) const; 249 void release_float_field_put(int offset, jfloat contents); 250 251 jdouble double_field_acquire(int offset) const; 252 void release_double_field_put(int offset, jdouble contents); 253 254 address address_field_acquire(int offset) const; 255 void release_address_field_put(int offset, address contents); 256 257 // printing functions for VM debugging 258 void print_on(outputStream* st) const; // First level print 259 void print_value_on(outputStream* st) const; // Second level print. 260 void print_address_on(outputStream* st) const; // Address printing 261 void print_name_on(outputStream* st) const; // External name printing. 262 263 // printing on default output stream 264 void print(); 265 void print_value(); 266 void print_address(); 267 268 // return the print strings 269 char* print_string(); 270 char* print_value_string(); 271 272 // verification operations 273 static void verify_on(outputStream* st, oopDesc* oop_desc); 274 static void verify(oopDesc* oopDesc); 275 276 // locking operations 277 inline bool is_locked() const; 278 inline bool is_unlocked() const; 279 280 // asserts and guarantees 281 static bool is_oop(oop obj, bool ignore_mark_word = false); 282 static bool is_oop_or_null(oop obj, bool ignore_mark_word = false); 283 284 // garbage collection 285 inline bool is_gc_marked() const; 286 287 // Forward pointer operations for scavenge 288 inline bool is_forwarded() const; 289 inline bool is_self_forwarded() const; 290 291 inline void forward_to(oop p); 292 inline void forward_to_self(); 293 294 // Like "forward_to", but inserts the forwarding pointer atomically. 295 // Exactly one thread succeeds in inserting the forwarding pointer, and 296 // this call returns null for that thread; any other thread has the 297 // value of the forwarding pointer returned and does not modify "this". 298 inline oop forward_to_atomic(oop p, markWord compare, atomic_memory_order order = memory_order_conservative); 299 inline oop forward_to_self_atomic(markWord compare, atomic_memory_order order = memory_order_conservative); 300 301 inline oop forwardee() const; 302 inline oop forwardee(markWord header) const; 303 304 inline void unset_self_forwarded(); 305 306 // Age of object during scavenge 307 inline uint age() const; 308 inline void incr_age(); 309 310 template <typename OopClosureType> 311 inline void oop_iterate(OopClosureType* cl); 312 313 template <typename OopClosureType> 314 inline void oop_iterate(OopClosureType* cl, MemRegion mr); 315 316 template <typename OopClosureType> 317 inline size_t oop_iterate_size(OopClosureType* cl); 318 319 template <typename OopClosureType> 320 inline size_t oop_iterate_size(OopClosureType* cl, MemRegion mr); 321 322 template <typename OopClosureType> 323 inline void oop_iterate_backwards(OopClosureType* cl); 324 325 template <typename OopClosureType> 326 inline void oop_iterate_backwards(OopClosureType* cl, Klass* klass); 327 328 inline static bool is_instanceof_or_null(oop obj, Klass* klass); 329 330 // identity hash; returns the identity hash key (computes it if necessary) 331 inline intptr_t identity_hash(); 332 intptr_t slow_identity_hash(); 333 inline bool fast_no_hash_check(); 334 335 // marks are forwarded to stack when object is locked 336 inline bool has_displaced_mark() const; 337 inline markWord displaced_mark() const; 338 inline void set_displaced_mark(markWord m); 339 340 // Checks if the mark word needs to be preserved 341 inline bool mark_must_be_preserved() const; 342 inline bool mark_must_be_preserved(markWord m) const; 343 344 inline static bool has_klass_gap() { 345 return ObjLayout::oop_has_klass_gap(); 346 } 347 348 // for code generation 349 static int mark_offset_in_bytes() { return (int)offset_of(oopDesc, _mark); } 350 static int klass_offset_in_bytes() { 351 #ifdef _LP64 352 if (UseCompactObjectHeaders) { 353 // NOTE: The only places where this is used with compact headers are the C2 354 // compiler and JVMCI. 355 return mark_offset_in_bytes() + markWord::klass_offset_in_bytes; 356 } else 357 #endif 358 { 359 return (int)offset_of(oopDesc, _metadata._klass); 360 } 361 } 362 static int klass_gap_offset_in_bytes() { 363 assert(has_klass_gap(), "only applicable to compressed klass pointers"); 364 return klass_offset_in_bytes() + sizeof(narrowKlass); 365 } 366 367 static int base_offset_in_bytes() { 368 return ObjLayout::oop_base_offset_in_bytes(); 369 } 370 371 // for error reporting 372 static void* load_oop_raw(oop obj, int offset); 373 }; 374 375 // An oopDesc is not initialized via a constructor. Space is allocated in 376 // the Java heap, and static functions provided here on HeapWord* are used 377 // to fill in certain parts of that memory. The allocated memory is then 378 // treated as referring to an oopDesc. For that to be valid, the oopDesc 379 // class must have a trivial default constructor (C++14 3.8/1). 380 static_assert(std::is_trivially_default_constructible<oopDesc>::value, "required"); 381 382 #endif // SHARE_OOPS_OOP_HPP