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_VM_OOPS_OOP_INLINE_HPP 26 #define SHARE_VM_OOPS_OOP_INLINE_HPP 27 28 #include "gc_implementation/shared/ageTable.hpp" 29 #include "gc_implementation/shared/markSweep.inline.hpp" 30 #include "gc_interface/collectedHeap.inline.hpp" 31 #include "memory/barrierSet.inline.hpp" 32 #include "memory/cardTableModRefBS.hpp" 33 #include "memory/genCollectedHeap.hpp" 34 #include "memory/generation.hpp" 35 #include "memory/specialized_oop_closures.hpp" 36 #include "oops/arrayKlass.hpp" 37 #include "oops/arrayOop.hpp" 38 #include "oops/klass.hpp" 39 #include "oops/markOop.inline.hpp" 40 #include "oops/oop.hpp" 41 #include "runtime/atomic.hpp" 42 #include "runtime/os.hpp" 43 #include "utilities/macros.hpp" 44 #ifdef TARGET_ARCH_x86 45 # include "bytes_x86.hpp" 46 #endif 47 #ifdef TARGET_ARCH_sparc 48 # include "bytes_sparc.hpp" 49 #endif 50 #ifdef TARGET_ARCH_zero 51 # include "bytes_zero.hpp" 52 #endif 53 #ifdef TARGET_ARCH_arm 54 # include "bytes_arm.hpp" 55 #endif 56 #ifdef TARGET_ARCH_ppc 57 # include "bytes_ppc.hpp" 58 #endif 59 60 // Implementation of all inlined member functions defined in oop.hpp 61 // We need a separate file to avoid circular references 62 63 inline void oopDesc::release_set_mark(markOop m) { 64 OrderAccess::release_store_ptr(&_mark, m); 65 } 66 67 inline markOop oopDesc::cas_set_mark(markOop new_mark, markOop old_mark) { 68 return (markOop) Atomic::cmpxchg_ptr(new_mark, &_mark, old_mark); 69 } 70 71 inline Klass* oopDesc::klass() const { 72 if (UseCompressedKlassPointers) { 73 return decode_klass_not_null(_metadata._compressed_klass); 74 } else { 75 return _metadata._klass; 76 } 77 } 78 79 inline Klass* oopDesc::klass_or_null() const volatile { 80 // can be NULL in CMS 81 if (UseCompressedKlassPointers) { 82 return decode_klass(_metadata._compressed_klass); 83 } else { 84 return _metadata._klass; 85 } 86 } 87 88 inline int oopDesc::klass_gap_offset_in_bytes() { 89 assert(UseCompressedKlassPointers, "only applicable to compressed klass pointers"); 90 return oopDesc::klass_offset_in_bytes() + sizeof(narrowOop); 91 } 92 93 inline Klass** oopDesc::klass_addr() { 94 // Only used internally and with CMS and will not work with 95 // UseCompressedOops 96 assert(!UseCompressedKlassPointers, "only supported with uncompressed klass pointers"); 97 return (Klass**) &_metadata._klass; 98 } 99 100 inline narrowOop* oopDesc::compressed_klass_addr() { 101 assert(UseCompressedKlassPointers, "only called by compressed klass pointers"); 102 return (narrowOop*) &_metadata._compressed_klass; 103 } 104 105 inline void oopDesc::set_klass(Klass* k) { 106 // since klasses are promoted no store check is needed 107 assert(Universe::is_bootstrapping() || k != NULL, "must be a real Klass*"); 108 assert(Universe::is_bootstrapping() || k->is_klass(), "not a Klass*"); 109 if (UseCompressedKlassPointers) { 110 *compressed_klass_addr() = encode_klass_not_null(k); 111 } else { 112 *klass_addr() = k; 113 } 114 } 115 116 inline int oopDesc::klass_gap() const { 117 return *(int*)(((intptr_t)this) + klass_gap_offset_in_bytes()); 118 } 119 120 inline void oopDesc::set_klass_gap(int v) { 121 if (UseCompressedKlassPointers) { 122 *(int*)(((intptr_t)this) + klass_gap_offset_in_bytes()) = v; 123 } 124 } 125 126 inline void oopDesc::set_klass_to_list_ptr(oop k) { 127 // This is only to be used during GC, for from-space objects, so no 128 // barrier is needed. 129 if (UseCompressedKlassPointers) { 130 _metadata._compressed_klass = encode_heap_oop(k); // may be null (parnew overflow handling) 131 } else { 132 _metadata._klass = (Klass*)(address)k; 133 } 134 } 135 136 inline oop oopDesc::list_ptr_from_klass() { 137 // This is only to be used during GC, for from-space objects. 138 if (UseCompressedKlassPointers) { 139 return decode_heap_oop(_metadata._compressed_klass); 140 } else { 141 // Special case for GC 142 return (oop)(address)_metadata._klass; 143 } 144 } 145 146 inline void oopDesc::init_mark() { set_mark(markOopDesc::prototype_for_object(this)); } 147 148 inline bool oopDesc::is_a(Klass* k) const { return klass()->is_subtype_of(k); } 149 150 inline bool oopDesc::is_instance() const { return klass()->oop_is_instance(); } 151 inline bool oopDesc::is_instanceMirror() const { return klass()->oop_is_instanceMirror(); } 152 inline bool oopDesc::is_instanceRef() const { return klass()->oop_is_instanceRef(); } 153 inline bool oopDesc::is_array() const { return klass()->oop_is_array(); } 154 inline bool oopDesc::is_objArray() const { return klass()->oop_is_objArray(); } 155 inline bool oopDesc::is_typeArray() const { return klass()->oop_is_typeArray(); } 156 157 inline void* oopDesc::field_base(int offset) const { return (void*)&((char*)this)[offset]; } 158 159 template <class T> inline T* oopDesc::obj_field_addr(int offset) const { return (T*)field_base(offset); } 160 inline Metadata** oopDesc::metadata_field_addr(int offset) const { return (Metadata**)field_base(offset); } 161 inline jbyte* oopDesc::byte_field_addr(int offset) const { return (jbyte*) field_base(offset); } 162 inline jchar* oopDesc::char_field_addr(int offset) const { return (jchar*) field_base(offset); } 163 inline jboolean* oopDesc::bool_field_addr(int offset) const { return (jboolean*)field_base(offset); } 164 inline jint* oopDesc::int_field_addr(int offset) const { return (jint*) field_base(offset); } 165 inline jshort* oopDesc::short_field_addr(int offset) const { return (jshort*) field_base(offset); } 166 inline jlong* oopDesc::long_field_addr(int offset) const { return (jlong*) field_base(offset); } 167 inline jfloat* oopDesc::float_field_addr(int offset) const { return (jfloat*) field_base(offset); } 168 inline jdouble* oopDesc::double_field_addr(int offset) const { return (jdouble*) field_base(offset); } 169 inline address* oopDesc::address_field_addr(int offset) const { return (address*) field_base(offset); } 170 171 172 // Functions for getting and setting oops within instance objects. 173 // If the oops are compressed, the type passed to these overloaded functions 174 // is narrowOop. All functions are overloaded so they can be called by 175 // template functions without conditionals (the compiler instantiates via 176 // the right type and inlines the appopriate code). 177 178 inline bool oopDesc::is_null(oop obj) { return obj == NULL; } 179 inline bool oopDesc::is_null(Klass* obj) { return obj == NULL; } 180 inline bool oopDesc::is_null(narrowOop obj) { return obj == 0; } 181 182 // Algorithm for encoding and decoding oops from 64 bit pointers to 32 bit 183 // offset from the heap base. Saving the check for null can save instructions 184 // in inner GC loops so these are separated. 185 186 inline bool check_obj_alignment(oop obj) { 187 return (intptr_t)obj % MinObjAlignmentInBytes == 0; 188 } 189 inline bool check_klass_alignment(Klass* obj) { 190 return (intptr_t)obj % KlassAlignmentInBytes == 0; 191 } 192 193 inline narrowOop oopDesc::encode_heap_oop_not_null(oop v) { 194 assert(!is_null(v), "oop value can never be zero"); 195 assert(check_obj_alignment(v), "Address not aligned"); 196 assert(Universe::heap()->is_in_reserved(v), "Address not in heap"); 197 address base = Universe::narrow_oop_base(); 198 int shift = Universe::narrow_oop_shift(); 199 uint64_t pd = (uint64_t)(pointer_delta((void*)v, (void*)base, 1)); 200 assert(OopEncodingHeapMax > pd, "change encoding max if new encoding"); 201 uint64_t result = pd >> shift; 202 assert((result & CONST64(0xffffffff00000000)) == 0, "narrow oop overflow"); 203 assert(decode_heap_oop(result) == v, "reversibility"); 204 return (narrowOop)result; 205 } 206 207 inline narrowOop oopDesc::encode_heap_oop(oop v) { 208 return (is_null(v)) ? (narrowOop)0 : encode_heap_oop_not_null(v); 209 } 210 211 inline oop oopDesc::decode_heap_oop_not_null(narrowOop v) { 212 assert(!is_null(v), "narrow oop value can never be zero"); 213 address base = Universe::narrow_oop_base(); 214 int shift = Universe::narrow_oop_shift(); 215 oop result = (oop)(void*)((uintptr_t)base + ((uintptr_t)v << shift)); 216 assert(check_obj_alignment(result), err_msg("address not aligned: " PTR_FORMAT, (void*) result)); 217 return result; 218 } 219 220 inline oop oopDesc::decode_heap_oop(narrowOop v) { 221 return is_null(v) ? (oop)NULL : decode_heap_oop_not_null(v); 222 } 223 224 inline oop oopDesc::decode_heap_oop_not_null(oop v) { return v; } 225 inline oop oopDesc::decode_heap_oop(oop v) { return v; } 226 227 // Encoding and decoding for klass field. It is copied code, but someday 228 // might not be the same as oop. 229 230 inline narrowOop oopDesc::encode_klass_not_null(Klass* v) { 231 assert(!is_null(v), "klass value can never be zero"); 232 assert(check_klass_alignment(v), "Address not aligned"); 233 address base = Universe::narrow_klass_base(); 234 int shift = Universe::narrow_klass_shift(); 235 uint64_t pd = (uint64_t)(pointer_delta((void*)v, (void*)base, 1)); 236 assert(KlassEncodingMetaspaceMax > pd, "change encoding max if new encoding"); 237 uint64_t result = pd >> shift; 238 assert((result & CONST64(0xffffffff00000000)) == 0, "narrow klass pointer overflow"); 239 assert(decode_klass(result) == v, "reversibility"); 240 return (narrowOop)result; 241 } 242 243 inline narrowOop oopDesc::encode_klass(Klass* v) { 244 return (is_null(v)) ? (narrowOop)0 : encode_klass_not_null(v); 245 } 246 247 inline Klass* oopDesc::decode_klass_not_null(narrowOop v) { 248 assert(!is_null(v), "narrow oop value can never be zero"); 249 address base = Universe::narrow_klass_base(); 250 int shift = Universe::narrow_klass_shift(); 251 Klass* result = (Klass*)(void*)((uintptr_t)base + ((uintptr_t)v << shift)); 252 assert(check_klass_alignment(result), err_msg("address not aligned: " PTR_FORMAT, (void*) result)); 253 return result; 254 } 255 256 inline Klass* oopDesc::decode_klass(narrowOop v) { 257 return is_null(v) ? (Klass*)NULL : decode_klass_not_null(v); 258 } 259 260 // Load an oop out of the Java heap as is without decoding. 261 // Called by GC to check for null before decoding. 262 inline oop oopDesc::load_heap_oop(oop* p) { return *p; } 263 inline narrowOop oopDesc::load_heap_oop(narrowOop* p) { return *p; } 264 265 // Load and decode an oop out of the Java heap into a wide oop. 266 inline oop oopDesc::load_decode_heap_oop_not_null(oop* p) { return *p; } 267 inline oop oopDesc::load_decode_heap_oop_not_null(narrowOop* p) { 268 return decode_heap_oop_not_null(*p); 269 } 270 271 // Load and decode an oop out of the heap accepting null 272 inline oop oopDesc::load_decode_heap_oop(oop* p) { return *p; } 273 inline oop oopDesc::load_decode_heap_oop(narrowOop* p) { 274 return decode_heap_oop(*p); 275 } 276 277 // Store already encoded heap oop into the heap. 278 inline void oopDesc::store_heap_oop(oop* p, oop v) { *p = v; } 279 inline void oopDesc::store_heap_oop(narrowOop* p, narrowOop v) { *p = v; } | 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_VM_OOPS_OOP_INLINE_HPP 26 #define SHARE_VM_OOPS_OOP_INLINE_HPP 27 28 #include "gc_implementation/shared/ageTable.hpp" 29 #include "gc_implementation/shared/markSweep.inline.hpp" 30 #include "gc_interface/collectedHeap.inline.hpp" 31 #include "memory/barrierSet.inline.hpp" 32 #include "memory/cardTableModRefBS.hpp" 33 #include "memory/genCollectedHeap.hpp" 34 #include "memory/generation.hpp" 35 #include "memory/specialized_oop_closures.hpp" 36 #include "oops/arrayKlass.hpp" 37 #include "oops/arrayOop.hpp" 38 #include "oops/klass.inline.hpp" 39 #include "oops/markOop.inline.hpp" 40 #include "oops/oop.hpp" 41 #include "runtime/atomic.hpp" 42 #include "runtime/os.hpp" 43 #include "utilities/macros.hpp" 44 #ifdef TARGET_ARCH_x86 45 # include "bytes_x86.hpp" 46 #endif 47 #ifdef TARGET_ARCH_sparc 48 # include "bytes_sparc.hpp" 49 #endif 50 #ifdef TARGET_ARCH_zero 51 # include "bytes_zero.hpp" 52 #endif 53 #ifdef TARGET_ARCH_arm 54 # include "bytes_arm.hpp" 55 #endif 56 #ifdef TARGET_ARCH_ppc 57 # include "bytes_ppc.hpp" 58 #endif 59 60 // Implementation of all inlined member functions defined in oop.hpp 61 // We need a separate file to avoid circular references 62 63 inline void oopDesc::release_set_mark(markOop m) { 64 OrderAccess::release_store_ptr(&_mark, m); 65 } 66 67 inline markOop oopDesc::cas_set_mark(markOop new_mark, markOop old_mark) { 68 return (markOop) Atomic::cmpxchg_ptr(new_mark, &_mark, old_mark); 69 } 70 71 inline Klass* oopDesc::klass() const { 72 if (UseCompressedKlassPointers) { 73 return Klass::decode_klass_not_null(_metadata._compressed_klass); 74 } else { 75 return _metadata._klass; 76 } 77 } 78 79 inline Klass* oopDesc::klass_or_null() const volatile { 80 // can be NULL in CMS 81 if (UseCompressedKlassPointers) { 82 return Klass::decode_klass(_metadata._compressed_klass); 83 } else { 84 return _metadata._klass; 85 } 86 } 87 88 inline int oopDesc::klass_gap_offset_in_bytes() { 89 assert(UseCompressedKlassPointers, "only applicable to compressed klass pointers"); 90 return oopDesc::klass_offset_in_bytes() + sizeof(narrowKlass); 91 } 92 93 inline Klass** oopDesc::klass_addr() { 94 // Only used internally and with CMS and will not work with 95 // UseCompressedOops 96 assert(!UseCompressedKlassPointers, "only supported with uncompressed klass pointers"); 97 return (Klass**) &_metadata._klass; 98 } 99 100 inline narrowKlass* oopDesc::compressed_klass_addr() { 101 assert(UseCompressedKlassPointers, "only called by compressed klass pointers"); 102 return &_metadata._compressed_klass; 103 } 104 105 inline void oopDesc::set_klass(Klass* k) { 106 // since klasses are promoted no store check is needed 107 assert(Universe::is_bootstrapping() || k != NULL, "must be a real Klass*"); 108 assert(Universe::is_bootstrapping() || k->is_klass(), "not a Klass*"); 109 if (UseCompressedKlassPointers) { 110 *compressed_klass_addr() = Klass::encode_klass_not_null(k); 111 } else { 112 *klass_addr() = k; 113 } 114 } 115 116 inline int oopDesc::klass_gap() const { 117 return *(int*)(((intptr_t)this) + klass_gap_offset_in_bytes()); 118 } 119 120 inline void oopDesc::set_klass_gap(int v) { 121 if (UseCompressedKlassPointers) { 122 *(int*)(((intptr_t)this) + klass_gap_offset_in_bytes()) = v; 123 } 124 } 125 126 inline void oopDesc::set_klass_to_list_ptr(oop k) { 127 // This is only to be used during GC, for from-space objects, so no 128 // barrier is needed. 129 if (UseCompressedKlassPointers) { 130 _metadata._compressed_klass = (narrowKlass)encode_heap_oop(k); // may be null (parnew overflow handling) 131 } else { 132 _metadata._klass = (Klass*)(address)k; 133 } 134 } 135 136 inline oop oopDesc::list_ptr_from_klass() { 137 // This is only to be used during GC, for from-space objects. 138 if (UseCompressedKlassPointers) { 139 return decode_heap_oop((narrowOop)_metadata._compressed_klass); 140 } else { 141 // Special case for GC 142 return (oop)(address)_metadata._klass; 143 } 144 } 145 146 inline void oopDesc::init_mark() { set_mark(markOopDesc::prototype_for_object(this)); } 147 148 inline bool oopDesc::is_a(Klass* k) const { return klass()->is_subtype_of(k); } 149 150 inline bool oopDesc::is_instance() const { return klass()->oop_is_instance(); } 151 inline bool oopDesc::is_instanceMirror() const { return klass()->oop_is_instanceMirror(); } 152 inline bool oopDesc::is_instanceRef() const { return klass()->oop_is_instanceRef(); } 153 inline bool oopDesc::is_array() const { return klass()->oop_is_array(); } 154 inline bool oopDesc::is_objArray() const { return klass()->oop_is_objArray(); } 155 inline bool oopDesc::is_typeArray() const { return klass()->oop_is_typeArray(); } 156 157 inline void* oopDesc::field_base(int offset) const { return (void*)&((char*)this)[offset]; } 158 159 template <class T> inline T* oopDesc::obj_field_addr(int offset) const { return (T*)field_base(offset); } 160 inline Metadata** oopDesc::metadata_field_addr(int offset) const { return (Metadata**)field_base(offset); } 161 inline jbyte* oopDesc::byte_field_addr(int offset) const { return (jbyte*) field_base(offset); } 162 inline jchar* oopDesc::char_field_addr(int offset) const { return (jchar*) field_base(offset); } 163 inline jboolean* oopDesc::bool_field_addr(int offset) const { return (jboolean*)field_base(offset); } 164 inline jint* oopDesc::int_field_addr(int offset) const { return (jint*) field_base(offset); } 165 inline jshort* oopDesc::short_field_addr(int offset) const { return (jshort*) field_base(offset); } 166 inline jlong* oopDesc::long_field_addr(int offset) const { return (jlong*) field_base(offset); } 167 inline jfloat* oopDesc::float_field_addr(int offset) const { return (jfloat*) field_base(offset); } 168 inline jdouble* oopDesc::double_field_addr(int offset) const { return (jdouble*) field_base(offset); } 169 inline address* oopDesc::address_field_addr(int offset) const { return (address*) field_base(offset); } 170 171 172 // Functions for getting and setting oops within instance objects. 173 // If the oops are compressed, the type passed to these overloaded functions 174 // is narrowOop. All functions are overloaded so they can be called by 175 // template functions without conditionals (the compiler instantiates via 176 // the right type and inlines the appopriate code). 177 178 inline bool oopDesc::is_null(oop obj) { return obj == NULL; } 179 inline bool oopDesc::is_null(narrowOop obj) { return obj == 0; } 180 181 // Algorithm for encoding and decoding oops from 64 bit pointers to 32 bit 182 // offset from the heap base. Saving the check for null can save instructions 183 // in inner GC loops so these are separated. 184 185 inline bool check_obj_alignment(oop obj) { 186 return (intptr_t)obj % MinObjAlignmentInBytes == 0; 187 } 188 189 inline narrowOop oopDesc::encode_heap_oop_not_null(oop v) { 190 assert(!is_null(v), "oop value can never be zero"); 191 assert(check_obj_alignment(v), "Address not aligned"); 192 assert(Universe::heap()->is_in_reserved(v), "Address not in heap"); 193 address base = Universe::narrow_oop_base(); 194 int shift = Universe::narrow_oop_shift(); 195 uint64_t pd = (uint64_t)(pointer_delta((void*)v, (void*)base, 1)); 196 assert(OopEncodingHeapMax > pd, "change encoding max if new encoding"); 197 uint64_t result = pd >> shift; 198 assert((result & CONST64(0xffffffff00000000)) == 0, "narrow oop overflow"); 199 assert(decode_heap_oop(result) == v, "reversibility"); 200 return (narrowOop)result; 201 } 202 203 inline narrowOop oopDesc::encode_heap_oop(oop v) { 204 return (is_null(v)) ? (narrowOop)0 : encode_heap_oop_not_null(v); 205 } 206 207 inline oop oopDesc::decode_heap_oop_not_null(narrowOop v) { 208 assert(!is_null(v), "narrow oop value can never be zero"); 209 address base = Universe::narrow_oop_base(); 210 int shift = Universe::narrow_oop_shift(); 211 oop result = (oop)(void*)((uintptr_t)base + ((uintptr_t)v << shift)); 212 assert(check_obj_alignment(result), err_msg("address not aligned: " PTR_FORMAT, (void*) result)); 213 return result; 214 } 215 216 inline oop oopDesc::decode_heap_oop(narrowOop v) { 217 return is_null(v) ? (oop)NULL : decode_heap_oop_not_null(v); 218 } 219 220 inline oop oopDesc::decode_heap_oop_not_null(oop v) { return v; } 221 inline oop oopDesc::decode_heap_oop(oop v) { return v; } 222 223 // Load an oop out of the Java heap as is without decoding. 224 // Called by GC to check for null before decoding. 225 inline oop oopDesc::load_heap_oop(oop* p) { return *p; } 226 inline narrowOop oopDesc::load_heap_oop(narrowOop* p) { return *p; } 227 228 // Load and decode an oop out of the Java heap into a wide oop. 229 inline oop oopDesc::load_decode_heap_oop_not_null(oop* p) { return *p; } 230 inline oop oopDesc::load_decode_heap_oop_not_null(narrowOop* p) { 231 return decode_heap_oop_not_null(*p); 232 } 233 234 // Load and decode an oop out of the heap accepting null 235 inline oop oopDesc::load_decode_heap_oop(oop* p) { return *p; } 236 inline oop oopDesc::load_decode_heap_oop(narrowOop* p) { 237 return decode_heap_oop(*p); 238 } 239 240 // Store already encoded heap oop into the heap. 241 inline void oopDesc::store_heap_oop(oop* p, oop v) { *p = v; } 242 inline void oopDesc::store_heap_oop(narrowOop* p, narrowOop v) { *p = v; } |