oop.inline.hpp revision 642:660978a2a31a
1296415Sdes/*
2296415Sdes * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
3296415Sdes * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4238106Sdes *
5296415Sdes * This code is free software; you can redistribute it and/or modify it
6296415Sdes * under the terms of the GNU General Public License version 2 only, as
7238106Sdes * published by the Free Software Foundation.
8238106Sdes *
9296415Sdes * This code is distributed in the hope that it will be useful, but WITHOUT
10238106Sdes * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11238106Sdes * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12238106Sdes * version 2 for more details (a copy is included in the LICENSE file that
13238106Sdes * accompanied this code).
14238106Sdes *
15238106Sdes * You should have received a copy of the GNU General Public License version
16238106Sdes * 2 along with this work; if not, write to the Free Software Foundation,
17238106Sdes * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18238106Sdes *
19238106Sdes * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20238106Sdes * CA 95054 USA or visit www.sun.com if you need additional information or
21238106Sdes * have any questions.
22238106Sdes *
23238106Sdes */
24238106Sdes
25238106Sdes// Implementation of all inlined member functions defined in oop.hpp
26238106Sdes// We need a separate file to avoid circular references
27238106Sdes
28238106Sdesinline void oopDesc::release_set_mark(markOop m) {
29296415Sdes  OrderAccess::release_store_ptr(&_mark, m);
30238106Sdes}
31238106Sdes
32238106Sdesinline markOop oopDesc::cas_set_mark(markOop new_mark, markOop old_mark) {
33238106Sdes  return (markOop) Atomic::cmpxchg_ptr(new_mark, &_mark, old_mark);
34296415Sdes}
35296415Sdes
36238106Sdesinline klassOop oopDesc::klass() const {
37296415Sdes  if (UseCompressedOops) {
38296415Sdes    return (klassOop)decode_heap_oop_not_null(_metadata._compressed_klass);
39296415Sdes  } else {
40296415Sdes    return _metadata._klass;
41296415Sdes  }
42296415Sdes}
43296415Sdes
44296415Sdesinline klassOop oopDesc::klass_or_null() const volatile {
45296415Sdes  // can be NULL in CMS
46296415Sdes  if (UseCompressedOops) {
47296415Sdes    return (klassOop)decode_heap_oop(_metadata._compressed_klass);
48296415Sdes  } else {
49296415Sdes    return _metadata._klass;
50296415Sdes  }
51296415Sdes}
52296415Sdes
53296415Sdesinline int oopDesc::klass_gap_offset_in_bytes() {
54296415Sdes  assert(UseCompressedOops, "only applicable to compressed headers");
55296415Sdes  return oopDesc::klass_offset_in_bytes() + sizeof(narrowOop);
56296415Sdes}
57296415Sdes
58296415Sdesinline oop* oopDesc::klass_addr() {
59296415Sdes  // Only used internally and with CMS and will not work with
60296415Sdes  // UseCompressedOops
61296415Sdes  assert(!UseCompressedOops, "only supported with uncompressed oops");
62296415Sdes  return (oop*) &_metadata._klass;
63296415Sdes}
64296415Sdes
65296415Sdesinline narrowOop* oopDesc::compressed_klass_addr() {
66296415Sdes  assert(UseCompressedOops, "only called by compressed oops");
67296415Sdes  return (narrowOop*) &_metadata._compressed_klass;
68296415Sdes}
69296415Sdes
70296415Sdesinline void oopDesc::set_klass(klassOop k) {
71296415Sdes  // since klasses are promoted no store check is needed
72296415Sdes  assert(Universe::is_bootstrapping() || k != NULL, "must be a real klassOop");
73296415Sdes  assert(Universe::is_bootstrapping() || k->is_klass(), "not a klassOop");
74296415Sdes  if (UseCompressedOops) {
75296415Sdes    oop_store_without_check(compressed_klass_addr(), (oop)k);
76296415Sdes  } else {
77296415Sdes    oop_store_without_check(klass_addr(), (oop) k);
78296415Sdes  }
79296415Sdes}
80296415Sdes
81296415Sdesinline int oopDesc::klass_gap() const {
82296415Sdes  return *(int*)(((intptr_t)this) + klass_gap_offset_in_bytes());
83296415Sdes}
84296415Sdes
85296415Sdesinline void oopDesc::set_klass_gap(int v) {
86296415Sdes  if (UseCompressedOops) {
87296415Sdes    *(int*)(((intptr_t)this) + klass_gap_offset_in_bytes()) = v;
88296415Sdes  }
89296415Sdes}
90296415Sdes
91296415Sdesinline void oopDesc::set_klass_to_list_ptr(oop k) {
92296415Sdes  // This is only to be used during GC, for from-space objects, so no
93296415Sdes  // barrier is needed.
94296415Sdes  if (UseCompressedOops) {
95296415Sdes    _metadata._compressed_klass = encode_heap_oop(k);  // may be null (parnew overflow handling)
96296415Sdes  } else {
97296415Sdes    _metadata._klass = (klassOop)k;
98296415Sdes  }
99296415Sdes}
100296415Sdes
101296415Sdesinline void   oopDesc::init_mark()                 { set_mark(markOopDesc::prototype_for_object(this)); }
102296415Sdesinline Klass* oopDesc::blueprint()           const { return klass()->klass_part(); }
103296415Sdes
104296415Sdesinline bool oopDesc::is_a(klassOop k)        const { return blueprint()->is_subtype_of(k); }
105296415Sdes
106296415Sdesinline bool oopDesc::is_instance()           const { return blueprint()->oop_is_instance(); }
107296415Sdesinline bool oopDesc::is_instanceRef()        const { return blueprint()->oop_is_instanceRef(); }
108296415Sdesinline bool oopDesc::is_array()              const { return blueprint()->oop_is_array(); }
109296415Sdesinline bool oopDesc::is_objArray()           const { return blueprint()->oop_is_objArray(); }
110296415Sdesinline bool oopDesc::is_typeArray()          const { return blueprint()->oop_is_typeArray(); }
111296415Sdesinline bool oopDesc::is_javaArray()          const { return blueprint()->oop_is_javaArray(); }
112296415Sdesinline bool oopDesc::is_symbol()             const { return blueprint()->oop_is_symbol(); }
113296415Sdesinline bool oopDesc::is_klass()              const { return blueprint()->oop_is_klass(); }
114296415Sdesinline bool oopDesc::is_thread()             const { return blueprint()->oop_is_thread(); }
115296415Sdesinline bool oopDesc::is_method()             const { return blueprint()->oop_is_method(); }
116296415Sdesinline bool oopDesc::is_constMethod()        const { return blueprint()->oop_is_constMethod(); }
117296415Sdesinline bool oopDesc::is_methodData()         const { return blueprint()->oop_is_methodData(); }
118296415Sdesinline bool oopDesc::is_constantPool()       const { return blueprint()->oop_is_constantPool(); }
119238106Sdesinline bool oopDesc::is_constantPoolCache()  const { return blueprint()->oop_is_constantPoolCache(); }
120238106Sdesinline bool oopDesc::is_compiledICHolder()   const { return blueprint()->oop_is_compiledICHolder(); }
121296415Sdes
122238106Sdesinline void*     oopDesc::field_base(int offset)        const { return (void*)&((char*)this)[offset]; }
123238106Sdes
124238106Sdestemplate <class T> inline T* oopDesc::obj_field_addr(int offset) const { return (T*)field_base(offset); }
125238106Sdesinline jbyte*    oopDesc::byte_field_addr(int offset)   const { return (jbyte*)   field_base(offset); }
126296415Sdesinline jchar*    oopDesc::char_field_addr(int offset)   const { return (jchar*)   field_base(offset); }
127238106Sdesinline jboolean* oopDesc::bool_field_addr(int offset)   const { return (jboolean*)field_base(offset); }
128238106Sdesinline jint*     oopDesc::int_field_addr(int offset)    const { return (jint*)    field_base(offset); }
129296415Sdesinline jshort*   oopDesc::short_field_addr(int offset)  const { return (jshort*)  field_base(offset); }
130296415Sdesinline jlong*    oopDesc::long_field_addr(int offset)   const { return (jlong*)   field_base(offset); }
131296415Sdesinline jfloat*   oopDesc::float_field_addr(int offset)  const { return (jfloat*)  field_base(offset); }
132296415Sdesinline jdouble*  oopDesc::double_field_addr(int offset) const { return (jdouble*) field_base(offset); }
133238106Sdesinline address*  oopDesc::address_field_addr(int offset) const { return (address*) field_base(offset); }
134296415Sdes
135296415Sdes
136296415Sdes// Functions for getting and setting oops within instance objects.
137296415Sdes// If the oops are compressed, the type passed to these overloaded functions
138296415Sdes// is narrowOop.  All functions are overloaded so they can be called by
139296415Sdes// template functions without conditionals (the compiler instantiates via
140238106Sdes// the right type and inlines the appopriate code).
141238106Sdes
142238106Sdesinline bool oopDesc::is_null(oop obj)       { return obj == NULL; }
143296415Sdesinline bool oopDesc::is_null(narrowOop obj) { return obj == 0; }
144296415Sdes
145238106Sdes// Algorithm for encoding and decoding oops from 64 bit pointers to 32 bit
146296415Sdes// offset from the heap base.  Saving the check for null can save instructions
147296415Sdes// in inner GC loops so these are separated.
148296415Sdes
149296415Sdesinline narrowOop oopDesc::encode_heap_oop_not_null(oop v) {
150296415Sdes  assert(!is_null(v), "oop value can never be zero");
151238106Sdes  address base = Universe::narrow_oop_base();
152296415Sdes  int    shift = Universe::narrow_oop_shift();
153296415Sdes  uint64_t  pd = (uint64_t)(pointer_delta((void*)v, (void*)base, 1));
154296415Sdes  assert(OopEncodingHeapMax > pd, "change encoding max if new encoding");
155296415Sdes  uint64_t result = pd >> shift;
156296415Sdes  assert((result & CONST64(0xffffffff00000000)) == 0, "narrow oop overflow");
157296415Sdes  return (narrowOop)result;
158296415Sdes}
159296415Sdes
160238106Sdesinline narrowOop oopDesc::encode_heap_oop(oop v) {
161238106Sdes  return (is_null(v)) ? (narrowOop)0 : encode_heap_oop_not_null(v);
162238106Sdes}
163296415Sdes
164296415Sdesinline oop oopDesc::decode_heap_oop_not_null(narrowOop v) {
165296415Sdes  assert(!is_null(v), "narrow oop value can never be zero");
166296415Sdes  address base = Universe::narrow_oop_base();
167296415Sdes  int    shift = Universe::narrow_oop_shift();
168296415Sdes  return (oop)(void*)((uintptr_t)base + ((uintptr_t)v << shift));
169296415Sdes}
170296415Sdes
171296415Sdesinline oop oopDesc::decode_heap_oop(narrowOop v) {
172296415Sdes  return is_null(v) ? (oop)NULL : decode_heap_oop_not_null(v);
173296415Sdes}
174296415Sdes
175296415Sdesinline oop oopDesc::decode_heap_oop_not_null(oop v) { return v; }
176296415Sdesinline oop oopDesc::decode_heap_oop(oop v)  { return v; }
177296415Sdes
178296415Sdes// Load an oop out of the Java heap as is without decoding.
179296415Sdes// Called by GC to check for null before decoding.
180296415Sdesinline oop       oopDesc::load_heap_oop(oop* p)          { return *p; }
181296415Sdesinline narrowOop oopDesc::load_heap_oop(narrowOop* p)    { return *p; }
182296415Sdes
183296415Sdes// Load and decode an oop out of the Java heap into a wide oop.
184296415Sdesinline oop oopDesc::load_decode_heap_oop_not_null(oop* p)       { return *p; }
185296415Sdesinline oop oopDesc::load_decode_heap_oop_not_null(narrowOop* p) {
186296415Sdes  return decode_heap_oop_not_null(*p);
187296415Sdes}
188296415Sdes
189296415Sdes// Load and decode an oop out of the heap accepting null
190296415Sdesinline oop oopDesc::load_decode_heap_oop(oop* p) { return *p; }
191296415Sdesinline oop oopDesc::load_decode_heap_oop(narrowOop* p) {
192296415Sdes  return decode_heap_oop(*p);
193296415Sdes}
194296415Sdes
195296415Sdes// Store already encoded heap oop into the heap.
196296415Sdesinline void oopDesc::store_heap_oop(oop* p, oop v)                 { *p = v; }
197296415Sdesinline void oopDesc::store_heap_oop(narrowOop* p, narrowOop v)     { *p = v; }
198296415Sdes
199296415Sdes// Encode and store a heap oop.
200296415Sdesinline void oopDesc::encode_store_heap_oop_not_null(narrowOop* p, oop v) {
201296415Sdes  *p = encode_heap_oop_not_null(v);
202296415Sdes}
203296415Sdesinline void oopDesc::encode_store_heap_oop_not_null(oop* p, oop v) { *p = v; }
204296415Sdes
205296415Sdes// Encode and store a heap oop allowing for null.
206296415Sdesinline void oopDesc::encode_store_heap_oop(narrowOop* p, oop v) {
207296415Sdes  *p = encode_heap_oop(v);
208296415Sdes}
209296415Sdesinline void oopDesc::encode_store_heap_oop(oop* p, oop v) { *p = v; }
210296415Sdes
211296415Sdes// Store heap oop as is for volatile fields.
212296415Sdesinline void oopDesc::release_store_heap_oop(volatile oop* p, oop v) {
213296415Sdes  OrderAccess::release_store_ptr(p, v);
214296415Sdes}
215296415Sdesinline void oopDesc::release_store_heap_oop(volatile narrowOop* p,
216296415Sdes                                            narrowOop v) {
217296415Sdes  OrderAccess::release_store(p, v);
218296415Sdes}
219296415Sdes
220296415Sdesinline void oopDesc::release_encode_store_heap_oop_not_null(
221296415Sdes                                                volatile narrowOop* p, oop v) {
222296415Sdes  // heap oop is not pointer sized.
223296415Sdes  OrderAccess::release_store(p, encode_heap_oop_not_null(v));
224296415Sdes}
225296415Sdes
226296415Sdesinline void oopDesc::release_encode_store_heap_oop_not_null(
227296415Sdes                                                      volatile oop* p, oop v) {
228296415Sdes  OrderAccess::release_store_ptr(p, v);
229296415Sdes}
230296415Sdes
231296415Sdesinline void oopDesc::release_encode_store_heap_oop(volatile oop* p,
232296415Sdes                                                           oop v) {
233296415Sdes  OrderAccess::release_store_ptr(p, v);
234296415Sdes}
235296415Sdesinline void oopDesc::release_encode_store_heap_oop(
236296415Sdes                                                volatile narrowOop* p, oop v) {
237296415Sdes  OrderAccess::release_store(p, encode_heap_oop(v));
238296415Sdes}
239296415Sdes
240296415Sdes
241296415Sdes// These functions are only used to exchange oop fields in instances,
242296415Sdes// not headers.
243296415Sdesinline oop oopDesc::atomic_exchange_oop(oop exchange_value, volatile HeapWord *dest) {
244296415Sdes  if (UseCompressedOops) {
245296415Sdes    // encode exchange value from oop to T
246296415Sdes    narrowOop val = encode_heap_oop(exchange_value);
247296415Sdes    narrowOop old = (narrowOop)Atomic::xchg(val, (narrowOop*)dest);
248296415Sdes    // decode old from T to oop
249296415Sdes    return decode_heap_oop(old);
250296415Sdes  } else {
251296415Sdes    return (oop)Atomic::xchg_ptr(exchange_value, (oop*)dest);
252296415Sdes  }
253296415Sdes}
254296415Sdes
255296415Sdesinline oop oopDesc::atomic_compare_exchange_oop(oop exchange_value,
256296415Sdes                                                volatile HeapWord *dest,
257296415Sdes                                                oop compare_value) {
258296415Sdes  if (UseCompressedOops) {
259296415Sdes    // encode exchange and compare value from oop to T
260296415Sdes    narrowOop val = encode_heap_oop(exchange_value);
261296415Sdes    narrowOop cmp = encode_heap_oop(compare_value);
262296415Sdes
263296415Sdes    narrowOop old = (narrowOop) Atomic::cmpxchg(val, (narrowOop*)dest, cmp);
264296415Sdes    // decode old from T to oop
265296415Sdes    return decode_heap_oop(old);
266296415Sdes  } else {
267296415Sdes    return (oop)Atomic::cmpxchg_ptr(exchange_value, (oop*)dest, compare_value);
268296415Sdes  }
269296415Sdes}
270296415Sdes
271296415Sdes// In order to put or get a field out of an instance, must first check
272296415Sdes// if the field has been compressed and uncompress it.
273296415Sdesinline oop oopDesc::obj_field(int offset) const {
274296415Sdes  return UseCompressedOops ?
275296415Sdes    load_decode_heap_oop(obj_field_addr<narrowOop>(offset)) :
276296415Sdes    load_decode_heap_oop(obj_field_addr<oop>(offset));
277296415Sdes}
278296415Sdesinline void oopDesc::obj_field_put(int offset, oop value) {
279296415Sdes  UseCompressedOops ? oop_store(obj_field_addr<narrowOop>(offset), value) :
280296415Sdes                      oop_store(obj_field_addr<oop>(offset),       value);
281296415Sdes}
282296415Sdesinline void oopDesc::obj_field_raw_put(int offset, oop value) {
283296415Sdes  UseCompressedOops ?
284296415Sdes    encode_store_heap_oop(obj_field_addr<narrowOop>(offset), value) :
285296415Sdes    encode_store_heap_oop(obj_field_addr<oop>(offset),       value);
286296415Sdes}
287296415Sdes
288296415Sdesinline jbyte oopDesc::byte_field(int offset) const                  { return (jbyte) *byte_field_addr(offset);    }
289296415Sdesinline void oopDesc::byte_field_put(int offset, jbyte contents)     { *byte_field_addr(offset) = (jint) contents; }
290296415Sdes
291296415Sdesinline jboolean oopDesc::bool_field(int offset) const               { return (jboolean) *bool_field_addr(offset); }
292296415Sdesinline void oopDesc::bool_field_put(int offset, jboolean contents)  { *bool_field_addr(offset) = (jint) contents; }
293296415Sdes
294296415Sdesinline jchar oopDesc::char_field(int offset) const                  { return (jchar) *char_field_addr(offset);    }
295296415Sdesinline void oopDesc::char_field_put(int offset, jchar contents)     { *char_field_addr(offset) = (jint) contents; }
296296415Sdes
297296415Sdesinline jint oopDesc::int_field(int offset) const                    { return *int_field_addr(offset);        }
298296415Sdesinline void oopDesc::int_field_put(int offset, jint contents)       { *int_field_addr(offset) = contents;    }
299296415Sdes
300296415Sdesinline jshort oopDesc::short_field(int offset) const                { return (jshort) *short_field_addr(offset);  }
301296415Sdesinline void oopDesc::short_field_put(int offset, jshort contents)   { *short_field_addr(offset) = (jint) contents;}
302296415Sdes
303296415Sdesinline jlong oopDesc::long_field(int offset) const                  { return *long_field_addr(offset);       }
304296415Sdesinline void oopDesc::long_field_put(int offset, jlong contents)     { *long_field_addr(offset) = contents;   }
305296415Sdes
306296415Sdesinline jfloat oopDesc::float_field(int offset) const                { return *float_field_addr(offset);      }
307296415Sdesinline void oopDesc::float_field_put(int offset, jfloat contents)   { *float_field_addr(offset) = contents;  }
308296415Sdes
309296415Sdesinline jdouble oopDesc::double_field(int offset) const              { return *double_field_addr(offset);     }
310296415Sdesinline void oopDesc::double_field_put(int offset, jdouble contents) { *double_field_addr(offset) = contents; }
311296415Sdes
312238106Sdesinline address oopDesc::address_field(int offset) const              { return *address_field_addr(offset);     }
313296415Sdesinline void oopDesc::address_field_put(int offset, address contents) { *address_field_addr(offset) = contents; }
314296415Sdes
315296415Sdesinline oop oopDesc::obj_field_acquire(int offset) const {
316296415Sdes  return UseCompressedOops ?
317238106Sdes             decode_heap_oop((narrowOop)
318238106Sdes               OrderAccess::load_acquire(obj_field_addr<narrowOop>(offset)))
319238106Sdes           : decode_heap_oop((oop)
320238106Sdes               OrderAccess::load_ptr_acquire(obj_field_addr<oop>(offset)));
321238106Sdes}
322238106Sdesinline void oopDesc::release_obj_field_put(int offset, oop value) {
323238106Sdes  UseCompressedOops ?
324296415Sdes    oop_store((volatile narrowOop*)obj_field_addr<narrowOop>(offset), value) :
325296415Sdes    oop_store((volatile oop*)      obj_field_addr<oop>(offset),       value);
326296415Sdes}
327238106Sdes
328296415Sdesinline jbyte oopDesc::byte_field_acquire(int offset) const                  { return OrderAccess::load_acquire(byte_field_addr(offset));     }
329296415Sdesinline void oopDesc::release_byte_field_put(int offset, jbyte contents)     { OrderAccess::release_store(byte_field_addr(offset), contents); }
330238106Sdes
331296415Sdesinline jboolean oopDesc::bool_field_acquire(int offset) const               { return OrderAccess::load_acquire(bool_field_addr(offset));     }
332296415Sdesinline void oopDesc::release_bool_field_put(int offset, jboolean contents)  { OrderAccess::release_store(bool_field_addr(offset), contents); }
333296415Sdes
334238106Sdesinline jchar oopDesc::char_field_acquire(int offset) const                  { return OrderAccess::load_acquire(char_field_addr(offset));     }
335296415Sdesinline void oopDesc::release_char_field_put(int offset, jchar contents)     { OrderAccess::release_store(char_field_addr(offset), contents); }
336296415Sdes
337238106Sdesinline jint oopDesc::int_field_acquire(int offset) const                    { return OrderAccess::load_acquire(int_field_addr(offset));      }
338296415Sdesinline void oopDesc::release_int_field_put(int offset, jint contents)       { OrderAccess::release_store(int_field_addr(offset), contents);  }
339296415Sdes
340296415Sdesinline jshort oopDesc::short_field_acquire(int offset) const                { return (jshort)OrderAccess::load_acquire(short_field_addr(offset)); }
341238106Sdesinline void oopDesc::release_short_field_put(int offset, jshort contents)   { OrderAccess::release_store(short_field_addr(offset), contents);     }
342296415Sdes
343296415Sdesinline jlong oopDesc::long_field_acquire(int offset) const                  { return OrderAccess::load_acquire(long_field_addr(offset));       }
344296415Sdesinline void oopDesc::release_long_field_put(int offset, jlong contents)     { OrderAccess::release_store(long_field_addr(offset), contents);   }
345296415Sdes
346238106Sdesinline jfloat oopDesc::float_field_acquire(int offset) const                { return OrderAccess::load_acquire(float_field_addr(offset));      }
347296415Sdesinline void oopDesc::release_float_field_put(int offset, jfloat contents)   { OrderAccess::release_store(float_field_addr(offset), contents);  }
348296415Sdes
349296415Sdesinline jdouble oopDesc::double_field_acquire(int offset) const              { return OrderAccess::load_acquire(double_field_addr(offset));     }
350296415Sdesinline void oopDesc::release_double_field_put(int offset, jdouble contents) { OrderAccess::release_store(double_field_addr(offset), contents); }
351296415Sdes
352296415Sdesinline int oopDesc::size_given_klass(Klass* klass)  {
353296415Sdes  int lh = klass->layout_helper();
354296415Sdes  int s  = lh >> LogHeapWordSize;  // deliver size scaled by wordSize
355296415Sdes
356296415Sdes  // lh is now a value computed at class initialization that may hint
357296415Sdes  // at the size.  For instances, this is positive and equal to the
358296415Sdes  // size.  For arrays, this is negative and provides log2 of the
359296415Sdes  // array element size.  For other oops, it is zero and thus requires
360296415Sdes  // a virtual call.
361296415Sdes  //
362238106Sdes  // We go to all this trouble because the size computation is at the
363238106Sdes  // heart of phase 2 of mark-compaction, and called for every object,
364296415Sdes  // alive or dead.  So the speed here is equal in importance to the
365296415Sdes  // speed of allocation.
366296415Sdes
367238106Sdes  if (lh <= Klass::_lh_neutral_value) {
368296415Sdes    // The most common case is instances; fall through if so.
369296415Sdes    if (lh < Klass::_lh_neutral_value) {
370296415Sdes      // Second most common case is arrays.  We have to fetch the
371296415Sdes      // length of the array, shift (multiply) it appropriately,
372296415Sdes      // up to wordSize, add the header, and align to object size.
373296415Sdes      size_t size_in_bytes;
374296415Sdes#ifdef _M_IA64
375296415Sdes      // The Windows Itanium Aug 2002 SDK hoists this load above
376296415Sdes      // the check for s < 0.  An oop at the end of the heap will
377296415Sdes      // cause an access violation if this load is performed on a non
378296415Sdes      // array oop.  Making the reference volatile prohibits this.
379296415Sdes      // (%%% please explain by what magic the length is actually fetched!)
380238106Sdes      volatile int *array_length;
381296415Sdes      array_length = (volatile int *)( (intptr_t)this +
382296415Sdes                          arrayOopDesc::length_offset_in_bytes() );
383296415Sdes      assert(array_length > 0, "Integer arithmetic problem somewhere");
384296415Sdes      // Put into size_t to avoid overflow.
385238106Sdes      size_in_bytes = (size_t) array_length;
386296415Sdes      size_in_bytes = size_in_bytes << Klass::layout_helper_log2_element_size(lh);
387296415Sdes#else
388296415Sdes      size_t array_length = (size_t) ((arrayOop)this)->length();
389296415Sdes      size_in_bytes = array_length << Klass::layout_helper_log2_element_size(lh);
390296415Sdes#endif
391296415Sdes      size_in_bytes += Klass::layout_helper_header_size(lh);
392296415Sdes
393238106Sdes      // This code could be simplified, but by keeping array_header_in_bytes
394296415Sdes      // in units of bytes and doing it this way we can round up just once,
395296415Sdes      // skipping the intermediate round to HeapWordSize.  Cast the result
396296415Sdes      // of round_to to size_t to guarantee unsigned division == right shift.
397296415Sdes      s = (int)((size_t)round_to(size_in_bytes, MinObjAlignmentInBytes) /
398296415Sdes        HeapWordSize);
399296415Sdes
400296415Sdes      // UseParNewGC, UseParallelGC and UseG1GC can change the length field
401296415Sdes      // of an "old copy" of an object array in the young gen so it indicates
402238106Sdes      // the grey portion of an already copied array. This will cause the first
403296415Sdes      // disjunct below to fail if the two comparands are computed across such
404296415Sdes      // a concurrent change.
405296415Sdes      // UseParNewGC also runs with promotion labs (which look like int
406296415Sdes      // filler arrays) which are subject to changing their declared size
407296415Sdes      // when finally retiring a PLAB; this also can cause the first disjunct
408296415Sdes      // to fail for another worker thread that is concurrently walking the block
409238106Sdes      // offset table. Both these invariant failures are benign for their
410296415Sdes      // current uses; we relax the assertion checking to cover these two cases below:
411296415Sdes      //     is_objArray() && is_forwarded()   // covers first scenario above
412238106Sdes      //  || is_typeArray()                    // covers second scenario above
413296415Sdes      // If and when UseParallelGC uses the same obj array oop stealing/chunking
414238106Sdes      // technique, we will need to suitably modify the assertion.
415238106Sdes      assert((s == klass->oop_size(this)) ||
416238106Sdes             (Universe::heap()->is_gc_active() &&
417296415Sdes              ((is_typeArray() && UseParNewGC) ||
418238106Sdes               (is_objArray()  && is_forwarded() && (UseParNewGC || UseParallelGC || UseG1GC)))),
419296415Sdes             "wrong array object size");
420238106Sdes    } else {
421238106Sdes      // Must be zero, so bite the bullet and take the virtual call.
422296415Sdes      s = klass->oop_size(this);
423249141Sdes    }
424238106Sdes  }
425296415Sdes
426238106Sdes  assert(s % MinObjAlignment == 0, "alignment check");
427238106Sdes  assert(s > 0, "Bad size calculated");
428296415Sdes  return s;
429238106Sdes}
430296415Sdes
431238106Sdes
432238106Sdesinline int oopDesc::size()  {
433238106Sdes  return size_given_klass(blueprint());
434238106Sdes}
435296415Sdes
436296415Sdesinline bool oopDesc::is_parsable() {
437296415Sdes  return blueprint()->oop_is_parsable(this);
438238106Sdes}
439296415Sdes
440296415Sdesinline bool oopDesc::is_conc_safe() {
441296415Sdes  return blueprint()->oop_is_conc_safe(this);
442238106Sdes}
443238106Sdes
444238106Sdesinline void update_barrier_set(void* p, oop v) {
445238106Sdes  assert(oopDesc::bs() != NULL, "Uninitialized bs in oop!");
446238106Sdes  oopDesc::bs()->write_ref_field(p, v);
447296415Sdes}
448296415Sdes
449296415Sdesinline void update_barrier_set_pre(void* p, oop v) {
450296415Sdes  oopDesc::bs()->write_ref_field_pre(p, v);
451296415Sdes}
452296415Sdes
453296415Sdestemplate <class T> inline void oop_store(T* p, oop v) {
454296415Sdes  if (always_do_update_barrier) {
455296415Sdes    oop_store((volatile T*)p, v);
456296415Sdes  } else {
457296415Sdes    update_barrier_set_pre(p, v);
458296415Sdes    oopDesc::encode_store_heap_oop(p, v);
459296415Sdes    update_barrier_set(p, v);
460296415Sdes  }
461296415Sdes}
462296415Sdes
463296415Sdestemplate <class T> inline void oop_store(volatile T* p, oop v) {
464296415Sdes  update_barrier_set_pre((void*)p, v);
465296415Sdes  // Used by release_obj_field_put, so use release_store_ptr.
466296415Sdes  oopDesc::release_encode_store_heap_oop(p, v);
467296415Sdes  update_barrier_set((void*)p, v);
468296415Sdes}
469296415Sdes
470296415Sdestemplate <class T> inline void oop_store_without_check(T* p, oop v) {
471296415Sdes  // XXX YSR FIX ME!!!
472296415Sdes  if (always_do_update_barrier) {
473296415Sdes    oop_store(p, v);
474296415Sdes  } else {
475296415Sdes    assert(!Universe::heap()->barrier_set()->write_ref_needs_barrier(p, v),
476296415Sdes           "oop store without store check failed");
477296415Sdes    oopDesc::encode_store_heap_oop(p, v);
478296415Sdes  }
479296415Sdes}
480296415Sdes
481296415Sdes// When it absolutely has to get there.
482296415Sdestemplate <class T> inline void oop_store_without_check(volatile T* p, oop v) {
483296415Sdes  // XXX YSR FIX ME!!!
484238106Sdes  if (always_do_update_barrier) {
485296415Sdes    oop_store(p, v);
486296415Sdes  } else {
487296415Sdes    assert(!Universe::heap()->barrier_set()->write_ref_needs_barrier((T*)p, v),
488296415Sdes           "oop store without store check failed");
489296415Sdes    oopDesc::release_encode_store_heap_oop(p, v);
490296415Sdes  }
491296415Sdes}
492296415Sdes
493296415Sdes// Should replace *addr = oop assignments where addr type depends on UseCompressedOops
494296415Sdes// (without having to remember the function name this calls).
495296415Sdesinline void oop_store_raw(HeapWord* addr, oop value) {
496296415Sdes  if (UseCompressedOops) {
497296415Sdes    oopDesc::encode_store_heap_oop((narrowOop*)addr, value);
498296415Sdes  } else {
499296415Sdes    oopDesc::encode_store_heap_oop((oop*)addr, value);
500296415Sdes  }
501296415Sdes}
502296415Sdes
503296415Sdes// Used only for markSweep, scavenging
504296415Sdesinline bool oopDesc::is_gc_marked() const {
505296415Sdes  return mark()->is_marked();
506296415Sdes}
507296415Sdes
508296415Sdesinline bool oopDesc::is_locked() const {
509296415Sdes  return mark()->is_locked();
510296415Sdes}
511296415Sdes
512296415Sdesinline bool oopDesc::is_unlocked() const {
513296415Sdes  return mark()->is_unlocked();
514296415Sdes}
515238106Sdes
516238106Sdesinline bool oopDesc::has_bias_pattern() const {
517296415Sdes  return mark()->has_bias_pattern();
518296415Sdes}
519296415Sdes
520296415Sdesinline bool check_obj_alignment(oop obj) {
521296415Sdes  return (intptr_t)obj % MinObjAlignmentInBytes == 0;
522296415Sdes}
523296415Sdes
524296415Sdes
525296415Sdes// used only for asserts
526296415Sdesinline bool oopDesc::is_oop(bool ignore_mark_word) const {
527296415Sdes  oop obj = (oop) this;
528296415Sdes  if (!check_obj_alignment(obj)) return false;
529296415Sdes  if (!Universe::heap()->is_in_reserved(obj)) return false;
530296415Sdes  // obj is aligned and accessible in heap
531296415Sdes  // try to find metaclass cycle safely without seg faulting on bad input
532296415Sdes  // we should reach klassKlassObj by following klass link at most 3 times
533296415Sdes  for (int i = 0; i < 3; i++) {
534296415Sdes    obj = obj->klass_or_null();
535296415Sdes    // klass should be aligned and in permspace
536296415Sdes    if (!check_obj_alignment(obj)) return false;
537296415Sdes    if (!Universe::heap()->is_in_permanent(obj)) return false;
538296415Sdes  }
539296415Sdes  if (obj != Universe::klassKlassObj()) {
540296415Sdes    // During a dump, the _klassKlassObj moved to a shared space.
541296415Sdes    if (DumpSharedSpaces && Universe::klassKlassObj()->is_shared()) {
542296415Sdes      return true;
543296415Sdes    }
544296415Sdes    return false;
545296415Sdes  }
546296415Sdes
547296415Sdes  // Header verification: the mark is typically non-NULL. If we're
548296415Sdes  // at a safepoint, it must not be null.
549296415Sdes  // Outside of a safepoint, the header could be changing (for example,
550296415Sdes  // another thread could be inflating a lock on this object).
551296415Sdes  if (ignore_mark_word) {
552296415Sdes    return true;
553296415Sdes  }
554296415Sdes  if (mark() != NULL) {
555296415Sdes    return true;
556296415Sdes  }
557296415Sdes  return !SafepointSynchronize::is_at_safepoint();
558296415Sdes}
559296415Sdes
560296415Sdes
561296415Sdes// used only for asserts
562296415Sdesinline bool oopDesc::is_oop_or_null(bool ignore_mark_word) const {
563296415Sdes  return this == NULL ? true : is_oop(ignore_mark_word);
564296415Sdes}
565296415Sdes
566296415Sdes#ifndef PRODUCT
567296415Sdes// used only for asserts
568296415Sdesinline bool oopDesc::is_unlocked_oop() const {
569296415Sdes  if (!Universe::heap()->is_in_reserved(this)) return false;
570296415Sdes  return mark()->is_unlocked();
571296415Sdes}
572296415Sdes#endif // PRODUCT
573296415Sdes
574296415Sdesinline void oopDesc::follow_header() {
575296415Sdes  if (UseCompressedOops) {
576296415Sdes    MarkSweep::mark_and_push(compressed_klass_addr());
577296415Sdes  } else {
578296415Sdes    MarkSweep::mark_and_push(klass_addr());
579296415Sdes  }
580296415Sdes}
581296415Sdes
582296415Sdesinline void oopDesc::follow_contents(void) {
583296415Sdes  assert (is_gc_marked(), "should be marked");
584296415Sdes  blueprint()->oop_follow_contents(this);
585296415Sdes}
586296415Sdes
587296415Sdes
588296415Sdes// Used by scavengers
589296415Sdes
590296415Sdesinline bool oopDesc::is_forwarded() const {
591296415Sdes  // The extra heap check is needed since the obj might be locked, in which case the
592296415Sdes  // mark would point to a stack location and have the sentinel bit cleared
593296415Sdes  return mark()->is_marked();
594296415Sdes}
595296415Sdes
596296415Sdes// Used by scavengers
597296415Sdesinline void oopDesc::forward_to(oop p) {
598296415Sdes  assert(Universe::heap()->is_in_reserved(p),
599296415Sdes         "forwarding to something not in heap");
600296415Sdes  markOop m = markOopDesc::encode_pointer_as_mark(p);
601296415Sdes  assert(m->decode_pointer() == p, "encoding must be reversable");
602296415Sdes  set_mark(m);
603296415Sdes}
604296415Sdes
605296415Sdes// Used by parallel scavengers
606296415Sdesinline bool oopDesc::cas_forward_to(oop p, markOop compare) {
607296415Sdes  assert(Universe::heap()->is_in_reserved(p),
608238106Sdes         "forwarding to something not in heap");
609296415Sdes  markOop m = markOopDesc::encode_pointer_as_mark(p);
610238106Sdes  assert(m->decode_pointer() == p, "encoding must be reversable");
611296415Sdes  return cas_set_mark(m, compare) == compare;
612296415Sdes}
613296415Sdes
614296415Sdes// Note that the forwardee is not the same thing as the displaced_mark.
615296415Sdes// The forwardee is used when copying during scavenge and mark-sweep.
616296415Sdes// It does need to clear the low two locking- and GC-related bits.
617296415Sdesinline oop oopDesc::forwardee() const {
618238106Sdes  return (oop) mark()->decode_pointer();
619238106Sdes}
620296415Sdes
621296415Sdesinline bool oopDesc::has_displaced_mark() const {
622296415Sdes  return mark()->has_displaced_mark_helper();
623296415Sdes}
624296415Sdes
625296415Sdesinline markOop oopDesc::displaced_mark() const {
626296415Sdes  return mark()->displaced_mark_helper();
627296415Sdes}
628296415Sdes
629296415Sdesinline void oopDesc::set_displaced_mark(markOop m) {
630296415Sdes  mark()->set_displaced_mark_helper(m);
631296415Sdes}
632296415Sdes
633296415Sdes// The following method needs to be MT safe.
634296415Sdesinline int oopDesc::age() const {
635296415Sdes  assert(!is_forwarded(), "Attempt to read age from forwarded mark");
636296415Sdes  if (has_displaced_mark()) {
637296415Sdes    return displaced_mark()->age();
638296415Sdes  } else {
639296415Sdes    return mark()->age();
640296415Sdes  }
641296415Sdes}
642296415Sdes
643296415Sdesinline void oopDesc::incr_age() {
644296415Sdes  assert(!is_forwarded(), "Attempt to increment age of forwarded mark");
645296415Sdes  if (has_displaced_mark()) {
646296415Sdes    set_displaced_mark(displaced_mark()->incr_age());
647296415Sdes  } else {
648296415Sdes    set_mark(mark()->incr_age());
649296415Sdes  }
650296415Sdes}
651296415Sdes
652296415Sdes
653296415Sdesinline intptr_t oopDesc::identity_hash() {
654296415Sdes  // Fast case; if the object is unlocked and the hash value is set, no locking is needed
655296415Sdes  // Note: The mark must be read into local variable to avoid concurrent updates.
656296415Sdes  markOop mrk = mark();
657296415Sdes  if (mrk->is_unlocked() && !mrk->has_no_hash()) {
658296415Sdes    return mrk->hash();
659296415Sdes  } else if (mrk->is_marked()) {
660296415Sdes    return mrk->hash();
661296415Sdes  } else {
662296415Sdes    return slow_identity_hash();
663296415Sdes  }
664296415Sdes}
665296415Sdes
666296415Sdesinline void oopDesc::oop_iterate_header(OopClosure* blk) {
667296415Sdes  if (UseCompressedOops) {
668296415Sdes    blk->do_oop(compressed_klass_addr());
669296415Sdes  } else {
670296415Sdes    blk->do_oop(klass_addr());
671296415Sdes  }
672296415Sdes}
673296415Sdes
674296415Sdesinline void oopDesc::oop_iterate_header(OopClosure* blk, MemRegion mr) {
675296415Sdes  if (UseCompressedOops) {
676296415Sdes    if (mr.contains(compressed_klass_addr())) {
677296415Sdes      blk->do_oop(compressed_klass_addr());
678296415Sdes    }
679296415Sdes  } else {
680296415Sdes    if (mr.contains(klass_addr())) blk->do_oop(klass_addr());
681296415Sdes  }
682296415Sdes}
683296415Sdes
684296415Sdesinline int oopDesc::adjust_pointers() {
685296415Sdes  debug_only(int check_size = size());
686296415Sdes  int s = blueprint()->oop_adjust_pointers(this);
687296415Sdes  assert(s == check_size, "should be the same");
688296415Sdes  return s;
689296415Sdes}
690296415Sdes
691296415Sdesinline void oopDesc::adjust_header() {
692296415Sdes  if (UseCompressedOops) {
693296415Sdes    MarkSweep::adjust_pointer(compressed_klass_addr());
694296415Sdes  } else {
695296415Sdes    MarkSweep::adjust_pointer(klass_addr());
696296415Sdes  }
697296415Sdes}
698296415Sdes
699296415Sdes#define OOP_ITERATE_DEFN(OopClosureType, nv_suffix)                        \
700296415Sdes                                                                           \
701296415Sdesinline int oopDesc::oop_iterate(OopClosureType* blk) {                     \
702296415Sdes  SpecializationStats::record_call();                                      \
703296415Sdes  return blueprint()->oop_oop_iterate##nv_suffix(this, blk);               \
704296415Sdes}                                                                          \
705296415Sdes                                                                           \
706296415Sdesinline int oopDesc::oop_iterate(OopClosureType* blk, MemRegion mr) {       \
707296415Sdes  SpecializationStats::record_call();                                      \
708296415Sdes  return blueprint()->oop_oop_iterate##nv_suffix##_m(this, blk, mr);       \
709296415Sdes}
710296415Sdes
711296415SdesALL_OOP_OOP_ITERATE_CLOSURES_1(OOP_ITERATE_DEFN)
712296415SdesALL_OOP_OOP_ITERATE_CLOSURES_2(OOP_ITERATE_DEFN)
713296415Sdes
714296415Sdes#ifndef SERIALGC
715296415Sdes#define OOP_ITERATE_BACKWARDS_DEFN(OopClosureType, nv_suffix)              \
716296415Sdes                                                                           \
717296415Sdesinline int oopDesc::oop_iterate_backwards(OopClosureType* blk) {           \
718296415Sdes  SpecializationStats::record_call();                                      \
719296415Sdes  return blueprint()->oop_oop_iterate_backwards##nv_suffix(this, blk);     \
720296415Sdes}
721296415Sdes
722296415SdesALL_OOP_OOP_ITERATE_CLOSURES_1(OOP_ITERATE_BACKWARDS_DEFN)
723296415SdesALL_OOP_OOP_ITERATE_CLOSURES_2(OOP_ITERATE_BACKWARDS_DEFN)
724296415Sdes#endif // !SERIALGC
725296415Sdes
726296415Sdesinline bool oopDesc::is_shared() const {
727296415Sdes  return CompactingPermGenGen::is_shared(this);
728296415Sdes}
729296415Sdes
730296415Sdesinline bool oopDesc::is_shared_readonly() const {
731296415Sdes  return CompactingPermGenGen::is_shared_readonly(this);
732238106Sdes}
733238106Sdes
734238106Sdesinline bool oopDesc::is_shared_readwrite() const {
735238106Sdes  return CompactingPermGenGen::is_shared_readwrite(this);
736238106Sdes}
737238106Sdes