< prev index next >

src/hotspot/share/oops/oop.inline.hpp

Print this page

 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_INLINE_HPP
 26 #define SHARE_OOPS_OOP_INLINE_HPP
 27 
 28 #include "oops/oop.hpp"
 29 
 30 #include "memory/universe.hpp"
 31 #include "oops/access.inline.hpp"
 32 #include "oops/arrayKlass.hpp"
 33 #include "oops/arrayOop.hpp"
 34 #include "oops/compressedOops.inline.hpp"

 35 #include "oops/markWord.hpp"
 36 #include "oops/oopsHierarchy.hpp"
 37 #include "runtime/atomic.hpp"
 38 #include "runtime/globals.hpp"
 39 #include "utilities/align.hpp"

 40 #include "utilities/debug.hpp"
 41 #include "utilities/macros.hpp"
 42 #include "utilities/globalDefinitions.hpp"
 43 
 44 // Implementation of all inlined member functions defined in oop.hpp
 45 // We need a separate file to avoid circular references
 46 
 47 markWord oopDesc::mark() const {
 48   return Atomic::load(&_mark);
 49 }
 50 
 51 markWord oopDesc::mark_acquire() const {
 52   return Atomic::load_acquire(&_mark);
 53 }
 54 
 55 markWord* oopDesc::mark_addr() const {
 56   return (markWord*) &_mark;
 57 }
 58 
 59 void oopDesc::set_mark(markWord m) {

 73 }
 74 
 75 markWord oopDesc::cas_set_mark(markWord new_mark, markWord old_mark, atomic_memory_order order) {
 76   return Atomic::cmpxchg(&_mark, old_mark, new_mark, order);
 77 }
 78 
 79 void oopDesc::init_mark() {
 80   set_mark(markWord::prototype());
 81 }
 82 
 83 Klass* oopDesc::klass() const {
 84   if (UseCompressedClassPointers) {
 85     return CompressedKlassPointers::decode_not_null(_metadata._compressed_klass);
 86   } else {
 87     return _metadata._klass;
 88   }
 89 }
 90 
 91 Klass* oopDesc::klass_or_null() const {
 92   if (UseCompressedClassPointers) {








 93     return CompressedKlassPointers::decode(_metadata._compressed_klass);
 94   } else {
 95     return _metadata._klass;
 96   }
 97 }
 98 
 99 Klass* oopDesc::klass_or_null_acquire() const {
100   if (UseCompressedClassPointers) {
101     narrowKlass nklass = Atomic::load_acquire(&_metadata._compressed_klass);
102     return CompressedKlassPointers::decode(nklass);
103   } else {
104     return Atomic::load_acquire(&_metadata._klass);
105   }
106 }
107 
108 void oopDesc::set_klass(Klass* k) {
109   assert(Universe::is_bootstrapping() || (k != NULL && k->is_klass()), "incorrect Klass");
110   if (UseCompressedClassPointers) {
111     _metadata._compressed_klass = CompressedKlassPointers::encode_not_null(k);
112   } else {

167       s = lh >> LogHeapWordSize;  // deliver size scaled by wordSize
168     } else {
169       s = klass->oop_size(this);
170     }
171   } else if (lh <= Klass::_lh_neutral_value) {
172     // The most common case is instances; fall through if so.
173     if (lh < Klass::_lh_neutral_value) {
174       // Second most common case is arrays.  We have to fetch the
175       // length of the array, shift (multiply) it appropriately,
176       // up to wordSize, add the header, and align to object size.
177       size_t size_in_bytes;
178       size_t array_length = (size_t) ((arrayOop)this)->length();
179       size_in_bytes = array_length << Klass::layout_helper_log2_element_size(lh);
180       size_in_bytes += Klass::layout_helper_header_size(lh);
181 
182       // This code could be simplified, but by keeping array_header_in_bytes
183       // in units of bytes and doing it this way we can round up just once,
184       // skipping the intermediate round to HeapWordSize.
185       s = (int)(align_up(size_in_bytes, MinObjAlignmentInBytes) / HeapWordSize);
186 
187       // UseParallelGC and UseG1GC can change the length field
188       // of an "old copy" of an object array in the young gen so it indicates
189       // the grey portion of an already copied array. This will cause the first
190       // disjunct below to fail if the two comparands are computed across such
191       // a concurrent change.
192       assert((s == klass->oop_size(this)) ||
193              (Universe::is_gc_active() && is_objArray() && is_forwarded() && (get_UseParallelGC() || get_UseG1GC())),
194              "wrong array object size");
195     } else {
196       // Must be zero, so bite the bullet and take the virtual call.
197       s = klass->oop_size(this);
198     }
199   }
200 
201   assert(s > 0, "Oop size must be greater than zero, not %d", s);
202   assert(is_object_aligned(s), "Oop size is not properly aligned: %d", s);
203   return s;
204 }
205 

























206 bool oopDesc::is_instance()  const { return klass()->is_instance_klass();  }
207 bool oopDesc::is_array()     const { return klass()->is_array_klass();     }
208 bool oopDesc::is_objArray()  const { return klass()->is_objArray_klass();  }
209 bool oopDesc::is_typeArray() const { return klass()->is_typeArray_klass(); }

210 
211 template<typename T>
212 T*       oopDesc::field_addr(int offset)     const { return reinterpret_cast<T*>(cast_from_oop<intptr_t>(as_oop()) + offset); }
213 
214 template <typename T>
215 size_t   oopDesc::field_offset(T* p) const { return pointer_delta((void*)p, (void*)this, 1); }
216 
217 template <DecoratorSet decorators>
218 inline oop  oopDesc::obj_field_access(int offset) const             { return HeapAccess<decorators>::oop_load_at(as_oop(), offset); }
219 inline oop  oopDesc::obj_field(int offset) const                    { return HeapAccess<>::oop_load_at(as_oop(), offset);  }
220 
221 inline void oopDesc::obj_field_put(int offset, oop value)           { HeapAccess<>::oop_store_at(as_oop(), offset, value); }
222 
223 inline jbyte oopDesc::byte_field(int offset) const                  { return *field_addr<jbyte>(offset);  }
224 inline void  oopDesc::byte_field_put(int offset, jbyte value)       { *field_addr<jbyte>(offset) = value; }
225 
226 inline jchar oopDesc::char_field(int offset) const                  { return *field_addr<jchar>(offset);  }
227 inline void  oopDesc::char_field_put(int offset, jchar value)       { *field_addr<jchar>(offset) = value; }
228 
229 inline jboolean oopDesc::bool_field(int offset) const               { return *field_addr<jboolean>(offset); }

368 bool oopDesc::has_displaced_mark() const {
369   return mark().has_displaced_mark_helper();
370 }
371 
372 markWord oopDesc::displaced_mark() const {
373   return mark().displaced_mark_helper();
374 }
375 
376 void oopDesc::set_displaced_mark(markWord m) {
377   mark().set_displaced_mark_helper(m);
378 }
379 
380 bool oopDesc::mark_must_be_preserved() const {
381   return mark_must_be_preserved(mark());
382 }
383 
384 bool oopDesc::mark_must_be_preserved(markWord m) const {
385   return m.must_be_preserved(this);
386 }
387 
































































388 #endif // SHARE_OOPS_OOP_INLINE_HPP

 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_INLINE_HPP
 26 #define SHARE_OOPS_OOP_INLINE_HPP
 27 
 28 #include "oops/oop.hpp"
 29 
 30 #include "memory/universe.hpp"
 31 #include "oops/access.inline.hpp"
 32 #include "oops/arrayKlass.hpp"
 33 #include "oops/arrayOop.hpp"
 34 #include "oops/compressedOops.inline.hpp"
 35 #include "oops/instanceKlass.hpp"
 36 #include "oops/markWord.hpp"
 37 #include "oops/oopsHierarchy.hpp"
 38 #include "runtime/atomic.hpp"
 39 #include "runtime/globals.hpp"
 40 #include "utilities/align.hpp"
 41 #include "utilities/copy.hpp"
 42 #include "utilities/debug.hpp"
 43 #include "utilities/macros.hpp"
 44 #include "utilities/globalDefinitions.hpp"
 45 
 46 // Implementation of all inlined member functions defined in oop.hpp
 47 // We need a separate file to avoid circular references
 48 
 49 markWord oopDesc::mark() const {
 50   return Atomic::load(&_mark);
 51 }
 52 
 53 markWord oopDesc::mark_acquire() const {
 54   return Atomic::load_acquire(&_mark);
 55 }
 56 
 57 markWord* oopDesc::mark_addr() const {
 58   return (markWord*) &_mark;
 59 }
 60 
 61 void oopDesc::set_mark(markWord m) {

 75 }
 76 
 77 markWord oopDesc::cas_set_mark(markWord new_mark, markWord old_mark, atomic_memory_order order) {
 78   return Atomic::cmpxchg(&_mark, old_mark, new_mark, order);
 79 }
 80 
 81 void oopDesc::init_mark() {
 82   set_mark(markWord::prototype());
 83 }
 84 
 85 Klass* oopDesc::klass() const {
 86   if (UseCompressedClassPointers) {
 87     return CompressedKlassPointers::decode_not_null(_metadata._compressed_klass);
 88   } else {
 89     return _metadata._klass;
 90   }
 91 }
 92 
 93 Klass* oopDesc::klass_or_null() const {
 94   if (UseCompressedClassPointers) {
 95     // narrowKlass v = _metadata._compressed_klass;
 96     // if (!CompressedKlassPointers::is_null(v)) {
 97     //   Klass* result = CompressedKlassPointers::decode_raw(v);
 98     //   if(!check_alignment(result)) {
 99     //     tty->print_cr("oop klass unaligned: %p oop: %p",  (void*) result, this);
100     //     return NULL;
101     //   }
102     // }
103     return CompressedKlassPointers::decode(_metadata._compressed_klass);
104   } else {
105     return _metadata._klass;
106   }
107 }
108 
109 Klass* oopDesc::klass_or_null_acquire() const {
110   if (UseCompressedClassPointers) {
111     narrowKlass nklass = Atomic::load_acquire(&_metadata._compressed_klass);
112     return CompressedKlassPointers::decode(nklass);
113   } else {
114     return Atomic::load_acquire(&_metadata._klass);
115   }
116 }
117 
118 void oopDesc::set_klass(Klass* k) {
119   assert(Universe::is_bootstrapping() || (k != NULL && k->is_klass()), "incorrect Klass");
120   if (UseCompressedClassPointers) {
121     _metadata._compressed_klass = CompressedKlassPointers::encode_not_null(k);
122   } else {

177       s = lh >> LogHeapWordSize;  // deliver size scaled by wordSize
178     } else {
179       s = klass->oop_size(this);
180     }
181   } else if (lh <= Klass::_lh_neutral_value) {
182     // The most common case is instances; fall through if so.
183     if (lh < Klass::_lh_neutral_value) {
184       // Second most common case is arrays.  We have to fetch the
185       // length of the array, shift (multiply) it appropriately,
186       // up to wordSize, add the header, and align to object size.
187       size_t size_in_bytes;
188       size_t array_length = (size_t) ((arrayOop)this)->length();
189       size_in_bytes = array_length << Klass::layout_helper_log2_element_size(lh);
190       size_in_bytes += Klass::layout_helper_header_size(lh);
191 
192       // This code could be simplified, but by keeping array_header_in_bytes
193       // in units of bytes and doing it this way we can round up just once,
194       // skipping the intermediate round to HeapWordSize.
195       s = (int)(align_up(size_in_bytes, MinObjAlignmentInBytes) / HeapWordSize);
196 
197 
198       assert(s == klass->oop_size(this) || size_might_change(), "wrong array object size");






199     } else {
200       // Must be zero, so bite the bullet and take the virtual call.
201       s = klass->oop_size(this);
202     }
203   }
204 
205   assert(s > 0, "Oop size must be greater than zero, not %d", s);
206   assert(is_object_aligned(s), "Oop size is not properly aligned: %d", s);
207   return s;
208 }
209 
210 int oopDesc::compact_size()  {
211   return compact_size_given_klass(klass());
212 }
213 
214 int oopDesc::compact_size(int size)  {
215   return compact_size_given_klass(klass(), size);
216 }
217 
218 int oopDesc::compact_size_given_klass(Klass* klass) {
219   int lh = klass->layout_helper();
220   if (lh > Klass::_lh_neutral_value && Klass::layout_helper_needs_slow_path(lh) && TrimContinuationChunksInGC) {
221     return klass->compact_oop_size(this);
222   }
223   return size_given_klass(klass);
224 }
225 
226 int oopDesc::compact_size_given_klass(Klass* klass, int size) {
227   int lh = klass->layout_helper();
228   if (lh > Klass::_lh_neutral_value && Klass::layout_helper_needs_slow_path(lh) && TrimContinuationChunksInGC) {
229     return klass->compact_oop_size(this);
230   }
231   assert (size == size_given_klass(klass), "");
232   return size;
233 }
234 
235 bool oopDesc::is_instance()  const { return klass()->is_instance_klass();  }
236 bool oopDesc::is_array()     const { return klass()->is_array_klass();     }
237 bool oopDesc::is_objArray()  const { return klass()->is_objArray_klass();  }
238 bool oopDesc::is_typeArray() const { return klass()->is_typeArray_klass(); }
239 bool oopDesc::is_stackChunk()const { return klass()->is_instance_klass() && InstanceKlass::cast(klass())->is_stack_chunk_instance_klass(); }
240 
241 template<typename T>
242 T*       oopDesc::field_addr(int offset)     const { return reinterpret_cast<T*>(cast_from_oop<intptr_t>(as_oop()) + offset); }
243 
244 template <typename T>
245 size_t   oopDesc::field_offset(T* p) const { return pointer_delta((void*)p, (void*)this, 1); }
246 
247 template <DecoratorSet decorators>
248 inline oop  oopDesc::obj_field_access(int offset) const             { return HeapAccess<decorators>::oop_load_at(as_oop(), offset); }
249 inline oop  oopDesc::obj_field(int offset) const                    { return HeapAccess<>::oop_load_at(as_oop(), offset);  }
250 
251 inline void oopDesc::obj_field_put(int offset, oop value)           { HeapAccess<>::oop_store_at(as_oop(), offset, value); }
252 
253 inline jbyte oopDesc::byte_field(int offset) const                  { return *field_addr<jbyte>(offset);  }
254 inline void  oopDesc::byte_field_put(int offset, jbyte value)       { *field_addr<jbyte>(offset) = value; }
255 
256 inline jchar oopDesc::char_field(int offset) const                  { return *field_addr<jchar>(offset);  }
257 inline void  oopDesc::char_field_put(int offset, jchar value)       { *field_addr<jchar>(offset) = value; }
258 
259 inline jboolean oopDesc::bool_field(int offset) const               { return *field_addr<jboolean>(offset); }

398 bool oopDesc::has_displaced_mark() const {
399   return mark().has_displaced_mark_helper();
400 }
401 
402 markWord oopDesc::displaced_mark() const {
403   return mark().displaced_mark_helper();
404 }
405 
406 void oopDesc::set_displaced_mark(markWord m) {
407   mark().set_displaced_mark_helper(m);
408 }
409 
410 bool oopDesc::mark_must_be_preserved() const {
411   return mark_must_be_preserved(mark());
412 }
413 
414 bool oopDesc::mark_must_be_preserved(markWord m) const {
415   return m.must_be_preserved(this);
416 }
417 
418 size_t oopDesc::copy_disjoint(HeapWord* to) { 
419   return copy_disjoint(to, size()); 
420 }
421 
422 size_t oopDesc::copy_conjoint(HeapWord* to) { 
423   return copy_conjoint(to, size()); 
424 }
425 
426 size_t oopDesc::copy_disjoint_compact(HeapWord* to) { 
427   return copy_disjoint_compact(to, compact_size()); 
428 }
429 
430 size_t oopDesc::copy_conjoint_compact(HeapWord* to) { 
431   return copy_conjoint_compact(to, compact_size()); 
432 }
433 
434 size_t oopDesc::copy_disjoint(HeapWord* to, size_t word_size) {
435   // if (is_stackChunk()) tty->print_cr(">>> copy_disjoint from: %p - %p to: %p - %p (word_size: %zu)", cast_from_oop<HeapWord*>(this), cast_from_oop<HeapWord*>(this) + word_size, to, to + word_size, word_size);
436   assert(word_size == (size_t)size() || size_might_change(), "");
437   int lh = klass()->layout_helper();
438   if (UNLIKELY(lh > Klass::_lh_neutral_value && Klass::layout_helper_needs_slow_path(lh))) {
439     size_t res = klass()->copy_disjoint(this, to, word_size);
440     assert (word_size == res, "");
441     return res;
442   }
443   Copy::aligned_disjoint_words(cast_from_oop<HeapWord*>(this), to, word_size);
444   return word_size;
445 }
446 
447 size_t oopDesc::copy_disjoint_compact(HeapWord* to, size_t word_size) {
448   assert(word_size == (size_t)compact_size() || size_might_change(), "");
449   int lh = klass()->layout_helper();
450   if (UNLIKELY(lh > Klass::_lh_neutral_value && Klass::layout_helper_needs_slow_path(lh) && TrimContinuationChunksInGC)) {
451     size_t res = klass()->copy_disjoint_compact(this, to);
452     assert (word_size == res, "");
453     return res;
454   }
455   return copy_disjoint(to, word_size);
456 }
457 
458 size_t oopDesc::copy_conjoint(HeapWord* to, size_t word_size) {
459   // if (is_stackChunk()) tty->print_cr(">>> copy_conjoint from: %p - %p to: %p - %p (word_size: %zu)", cast_from_oop<HeapWord*>(this), cast_from_oop<HeapWord*>(this) + word_size, to, to + word_size, word_size);
460   assert(word_size == (size_t)size() || size_might_change(), "");
461   int lh = klass()->layout_helper();
462   if (UNLIKELY(lh > Klass::_lh_neutral_value && Klass::layout_helper_needs_slow_path(lh))) {
463     size_t res = klass()->copy_conjoint(this, to, word_size);
464     assert (word_size == res, "");
465     return res;
466   }
467   Copy::aligned_conjoint_words(cast_from_oop<HeapWord*>(this), to, word_size);
468   return word_size;
469 }
470 
471 size_t oopDesc::copy_conjoint_compact(HeapWord* to, size_t word_size) {
472   assert(word_size == (size_t)compact_size() || size_might_change(), "");
473   int lh = klass()->layout_helper();
474   if (UNLIKELY(lh > Klass::_lh_neutral_value && Klass::layout_helper_needs_slow_path(lh) && TrimContinuationChunksInGC)) {
475     size_t res = klass()->copy_conjoint_compact(this, to);
476     assert (word_size == res, "");
477     return res;
478   }
479   return copy_conjoint(to, word_size);
480 }
481 
482 #endif // SHARE_OOPS_OOP_INLINE_HPP
< prev index next >