src/hotspot/share/oops/oop.inline.hpp
changeset 47998 fb0275c320a0
parent 47634 6a0c42c40cd1
child 48618 688e5cbd0b91
equal deleted inserted replaced
47997:55c43e677ded 47998:fb0275c320a0
    24 
    24 
    25 #ifndef SHARE_VM_OOPS_OOP_INLINE_HPP
    25 #ifndef SHARE_VM_OOPS_OOP_INLINE_HPP
    26 #define SHARE_VM_OOPS_OOP_INLINE_HPP
    26 #define SHARE_VM_OOPS_OOP_INLINE_HPP
    27 
    27 
    28 #include "gc/shared/ageTable.hpp"
    28 #include "gc/shared/ageTable.hpp"
    29 #include "gc/shared/barrierSet.inline.hpp"
       
    30 #include "gc/shared/cardTableModRefBS.hpp"
       
    31 #include "gc/shared/collectedHeap.inline.hpp"
    29 #include "gc/shared/collectedHeap.inline.hpp"
    32 #include "gc/shared/genCollectedHeap.hpp"
    30 #include "gc/shared/genCollectedHeap.hpp"
    33 #include "gc/shared/generation.hpp"
    31 #include "gc/shared/generation.hpp"
       
    32 #include "oops/access.inline.hpp"
    34 #include "oops/arrayKlass.hpp"
    33 #include "oops/arrayKlass.hpp"
    35 #include "oops/arrayOop.hpp"
    34 #include "oops/arrayOop.hpp"
    36 #include "oops/klass.inline.hpp"
    35 #include "oops/klass.inline.hpp"
    37 #include "oops/markOop.inline.hpp"
    36 #include "oops/markOop.inline.hpp"
    38 #include "oops/oop.hpp"
    37 #include "oops/oop.hpp"
    39 #include "runtime/atomic.hpp"
    38 #include "runtime/atomic.hpp"
    40 #include "runtime/orderAccess.inline.hpp"
    39 #include "runtime/orderAccess.inline.hpp"
    41 #include "runtime/os.hpp"
    40 #include "runtime/os.hpp"
    42 #include "utilities/align.hpp"
    41 #include "utilities/align.hpp"
    43 #include "utilities/macros.hpp"
    42 #include "utilities/macros.hpp"
    44 
       
    45 inline void update_barrier_set(void* p, oop v, bool release = false) {
       
    46   assert(oopDesc::bs() != NULL, "Uninitialized bs in oop!");
       
    47   oopDesc::bs()->write_ref_field(p, v, release);
       
    48 }
       
    49 
       
    50 template <class T> inline void update_barrier_set_pre(T* p, oop v) {
       
    51   oopDesc::bs()->write_ref_field_pre(p, v);
       
    52 }
       
    53 
       
    54 template <class T> void oop_store(T* p, oop v) {
       
    55   if (always_do_update_barrier) {
       
    56     oop_store((volatile T*)p, v);
       
    57   } else {
       
    58     update_barrier_set_pre(p, v);
       
    59     oopDesc::encode_store_heap_oop(p, v);
       
    60     // always_do_update_barrier == false =>
       
    61     // Either we are at a safepoint (in GC) or CMS is not used. In both
       
    62     // cases it's unnecessary to mark the card as dirty with release sematics.
       
    63     update_barrier_set((void*)p, v, false /* release */);  // cast away type
       
    64   }
       
    65 }
       
    66 
       
    67 template <class T> void oop_store(volatile T* p, oop v) {
       
    68   update_barrier_set_pre((T*)p, v);   // cast away volatile
       
    69   // Used by release_obj_field_put, so use release_store.
       
    70   oopDesc::release_encode_store_heap_oop(p, v);
       
    71   // When using CMS we must mark the card corresponding to p as dirty
       
    72   // with release sematics to prevent that CMS sees the dirty card but
       
    73   // not the new value v at p due to reordering of the two
       
    74   // stores. Note that CMS has a concurrent precleaning phase, where
       
    75   // it reads the card table while the Java threads are running.
       
    76   update_barrier_set((void*)p, v, true /* release */);    // cast away type
       
    77 }
       
    78 
       
    79 // Should replace *addr = oop assignments where addr type depends on UseCompressedOops
       
    80 // (without having to remember the function name this calls).
       
    81 inline void oop_store_raw(HeapWord* addr, oop value) {
       
    82   if (UseCompressedOops) {
       
    83     oopDesc::encode_store_heap_oop((narrowOop*)addr, value);
       
    84   } else {
       
    85     oopDesc::encode_store_heap_oop((oop*)addr, value);
       
    86   }
       
    87 }
       
    88 
    43 
    89 // Implementation of all inlined member functions defined in oop.hpp
    44 // Implementation of all inlined member functions defined in oop.hpp
    90 // We need a separate file to avoid circular references
    45 // We need a separate file to avoid circular references
    91 
    46 
    92 void oopDesc::release_set_mark(markOop m) {
    47 void oopDesc::release_set_mark(markOop m) {
   337 
   292 
   338 narrowOop oopDesc::encode_heap_oop(oop v) {
   293 narrowOop oopDesc::encode_heap_oop(oop v) {
   339   return (is_null(v)) ? (narrowOop)0 : encode_heap_oop_not_null(v);
   294   return (is_null(v)) ? (narrowOop)0 : encode_heap_oop_not_null(v);
   340 }
   295 }
   341 
   296 
       
   297 narrowOop oopDesc::load_heap_oop(narrowOop* p) { return *p; }
       
   298 oop       oopDesc::load_heap_oop(oop* p)       { return *p; }
       
   299 
       
   300 void oopDesc::store_heap_oop(narrowOop* p, narrowOop v) { *p = v; }
       
   301 void oopDesc::store_heap_oop(oop* p, oop v)             { *p = v; }
       
   302 
   342 // Load and decode an oop out of the Java heap into a wide oop.
   303 // Load and decode an oop out of the Java heap into a wide oop.
   343 oop oopDesc::load_decode_heap_oop_not_null(narrowOop* p) {
   304 oop oopDesc::load_decode_heap_oop_not_null(narrowOop* p) {
   344   return decode_heap_oop_not_null(*p);
   305   return decode_heap_oop_not_null(load_heap_oop(p));
   345 }
   306 }
   346 
   307 
   347 // Load and decode an oop out of the heap accepting null
   308 // Load and decode an oop out of the heap accepting null
   348 oop oopDesc::load_decode_heap_oop(narrowOop* p) {
   309 oop oopDesc::load_decode_heap_oop(narrowOop* p) {
   349   return decode_heap_oop(*p);
   310   return decode_heap_oop(load_heap_oop(p));
   350 }
   311 }
       
   312 
       
   313 oop oopDesc::load_decode_heap_oop_not_null(oop* p) { return *p; }
       
   314 oop oopDesc::load_decode_heap_oop(oop* p)          { return *p; }
       
   315 
       
   316 void oopDesc::encode_store_heap_oop_not_null(oop* p, oop v) { *p = v; }
       
   317 void oopDesc::encode_store_heap_oop(oop* p, oop v)          { *p = v; }
   351 
   318 
   352 // Encode and store a heap oop.
   319 // Encode and store a heap oop.
   353 void oopDesc::encode_store_heap_oop_not_null(narrowOop* p, oop v) {
   320 void oopDesc::encode_store_heap_oop_not_null(narrowOop* p, oop v) {
   354   *p = encode_heap_oop_not_null(v);
   321   *p = encode_heap_oop_not_null(v);
   355 }
   322 }
   357 // Encode and store a heap oop allowing for null.
   324 // Encode and store a heap oop allowing for null.
   358 void oopDesc::encode_store_heap_oop(narrowOop* p, oop v) {
   325 void oopDesc::encode_store_heap_oop(narrowOop* p, oop v) {
   359   *p = encode_heap_oop(v);
   326   *p = encode_heap_oop(v);
   360 }
   327 }
   361 
   328 
   362 // Store heap oop as is for volatile fields.
   329 inline oop  oopDesc::obj_field(int offset) const                    { return HeapAccess<>::oop_load_at(as_oop(), offset);  }
   363 void oopDesc::release_store_heap_oop(volatile oop* p, oop v) {
   330 inline void oopDesc::obj_field_put(int offset, oop value)           { HeapAccess<>::oop_store_at(as_oop(), offset, value); }
   364   OrderAccess::release_store(p, v);
   331 
   365 }
   332 inline jbyte oopDesc::byte_field(int offset) const                  { return HeapAccess<>::load_at(as_oop(), offset);  }
   366 void oopDesc::release_store_heap_oop(volatile narrowOop* p, narrowOop v) {
   333 inline void  oopDesc::byte_field_put(int offset, jbyte value)       { HeapAccess<>::store_at(as_oop(), offset, value); }
   367   OrderAccess::release_store(p, v);
   334 
   368 }
   335 inline jchar oopDesc::char_field(int offset) const                  { return HeapAccess<>::load_at(as_oop(), offset);  }
   369 
   336 inline void  oopDesc::char_field_put(int offset, jchar value)       { HeapAccess<>::store_at(as_oop(), offset, value); }
   370 void oopDesc::release_encode_store_heap_oop_not_null(volatile narrowOop* p, oop v) {
   337 
   371   // heap oop is not pointer sized.
   338 inline jboolean oopDesc::bool_field(int offset) const               { return HeapAccess<>::load_at(as_oop(), offset);                }
   372   OrderAccess::release_store(p, encode_heap_oop_not_null(v));
   339 inline void     oopDesc::bool_field_put(int offset, jboolean value) { HeapAccess<>::store_at(as_oop(), offset, jboolean(value & 1)); }
   373 }
   340 
   374 void oopDesc::release_encode_store_heap_oop_not_null(volatile oop* p, oop v) {
   341 inline jshort oopDesc::short_field(int offset) const                { return HeapAccess<>::load_at(as_oop(), offset);  }
   375   OrderAccess::release_store(p, v);
   342 inline void   oopDesc::short_field_put(int offset, jshort value)    { HeapAccess<>::store_at(as_oop(), offset, value); }
   376 }
   343 
   377 
   344 inline jint oopDesc::int_field(int offset) const                    { return HeapAccess<>::load_at(as_oop(), offset);  }
   378 void oopDesc::release_encode_store_heap_oop(volatile oop* p, oop v) {
   345 inline void oopDesc::int_field_put(int offset, jint value)          { HeapAccess<>::store_at(as_oop(), offset, value); }
   379   OrderAccess::release_store(p, v);
   346 
   380 }
   347 inline jlong oopDesc::long_field(int offset) const                  { return HeapAccess<>::load_at(as_oop(), offset);  }
   381 void oopDesc::release_encode_store_heap_oop(volatile narrowOop* p, oop v) {
   348 inline void  oopDesc::long_field_put(int offset, jlong value)       { HeapAccess<>::store_at(as_oop(), offset, value); }
   382   OrderAccess::release_store(p, encode_heap_oop(v));
   349 
   383 }
   350 inline jfloat oopDesc::float_field(int offset) const                { return HeapAccess<>::load_at(as_oop(), offset);  }
   384 
   351 inline void   oopDesc::float_field_put(int offset, jfloat value)    { HeapAccess<>::store_at(as_oop(), offset, value); }
   385 // These functions are only used to exchange oop fields in instances,
   352 
   386 // not headers.
   353 inline jdouble oopDesc::double_field(int offset) const              { return HeapAccess<>::load_at(as_oop(), offset);  }
   387 oop oopDesc::atomic_exchange_oop(oop exchange_value, volatile HeapWord *dest) {
   354 inline void    oopDesc::double_field_put(int offset, jdouble value) { HeapAccess<>::store_at(as_oop(), offset, value); }
   388   if (UseCompressedOops) {
       
   389     // encode exchange value from oop to T
       
   390     narrowOop val = encode_heap_oop(exchange_value);
       
   391     narrowOop old = Atomic::xchg(val, (narrowOop*)dest);
       
   392     // decode old from T to oop
       
   393     return decode_heap_oop(old);
       
   394   } else {
       
   395     return Atomic::xchg(exchange_value, (oop*)dest);
       
   396   }
       
   397 }
       
   398 
       
   399 oop oopDesc::atomic_compare_exchange_oop(oop exchange_value,
       
   400                                          volatile HeapWord *dest,
       
   401                                          oop compare_value,
       
   402                                          bool prebarrier) {
       
   403   if (UseCompressedOops) {
       
   404     if (prebarrier) {
       
   405       update_barrier_set_pre((narrowOop*)dest, exchange_value);
       
   406     }
       
   407     // encode exchange and compare value from oop to T
       
   408     narrowOop val = encode_heap_oop(exchange_value);
       
   409     narrowOop cmp = encode_heap_oop(compare_value);
       
   410 
       
   411     narrowOop old = Atomic::cmpxchg(val, (narrowOop*)dest, cmp);
       
   412     // decode old from T to oop
       
   413     return decode_heap_oop(old);
       
   414   } else {
       
   415     if (prebarrier) {
       
   416       update_barrier_set_pre((oop*)dest, exchange_value);
       
   417     }
       
   418     return Atomic::cmpxchg(exchange_value, (oop*)dest, compare_value);
       
   419   }
       
   420 }
       
   421 
       
   422 // In order to put or get a field out of an instance, must first check
       
   423 // if the field has been compressed and uncompress it.
       
   424 oop oopDesc::obj_field(int offset) const {
       
   425   return UseCompressedOops ?
       
   426     load_decode_heap_oop(obj_field_addr<narrowOop>(offset)) :
       
   427     load_decode_heap_oop(obj_field_addr<oop>(offset));
       
   428 }
       
   429 
       
   430 void oopDesc::obj_field_put(int offset, oop value) {
       
   431   UseCompressedOops ? oop_store(obj_field_addr<narrowOop>(offset), value) :
       
   432                       oop_store(obj_field_addr<oop>(offset),       value);
       
   433 }
       
   434 
       
   435 void oopDesc::obj_field_put_raw(int offset, oop value) {
       
   436   UseCompressedOops ?
       
   437     encode_store_heap_oop(obj_field_addr<narrowOop>(offset), value) :
       
   438     encode_store_heap_oop(obj_field_addr<oop>(offset),       value);
       
   439 }
       
   440 void oopDesc::obj_field_put_volatile(int offset, oop value) {
       
   441   OrderAccess::release();
       
   442   obj_field_put(offset, value);
       
   443   OrderAccess::fence();
       
   444 }
       
   445 
       
   446 Metadata* oopDesc::metadata_field(int offset) const           { return *metadata_field_addr(offset);   }
       
   447 void oopDesc::metadata_field_put(int offset, Metadata* value) { *metadata_field_addr(offset) = value;  }
       
   448 
       
   449 Metadata* oopDesc::metadata_field_acquire(int offset) const   {
       
   450   return OrderAccess::load_acquire(metadata_field_addr(offset));
       
   451 }
       
   452 
       
   453 void oopDesc::release_metadata_field_put(int offset, Metadata* value) {
       
   454   OrderAccess::release_store(metadata_field_addr(offset), value);
       
   455 }
       
   456 
       
   457 jbyte oopDesc::byte_field(int offset) const                   { return (jbyte) *byte_field_addr(offset);    }
       
   458 void oopDesc::byte_field_put(int offset, jbyte contents)      { *byte_field_addr(offset) = (jint) contents; }
       
   459 
       
   460 jchar oopDesc::char_field(int offset) const                   { return (jchar) *char_field_addr(offset);    }
       
   461 void oopDesc::char_field_put(int offset, jchar contents)      { *char_field_addr(offset) = (jint) contents; }
       
   462 
       
   463 jboolean oopDesc::bool_field(int offset) const                { return (jboolean) *bool_field_addr(offset); }
       
   464 void oopDesc::bool_field_put(int offset, jboolean contents)   { *bool_field_addr(offset) = (((jint) contents) & 1); }
       
   465 
       
   466 jint oopDesc::int_field(int offset) const                     { return *int_field_addr(offset);        }
       
   467 void oopDesc::int_field_put(int offset, jint contents)        { *int_field_addr(offset) = contents;    }
       
   468 
       
   469 jshort oopDesc::short_field(int offset) const                 { return (jshort) *short_field_addr(offset);  }
       
   470 void oopDesc::short_field_put(int offset, jshort contents)    { *short_field_addr(offset) = (jint) contents;}
       
   471 
       
   472 jlong oopDesc::long_field(int offset) const                   { return *long_field_addr(offset);       }
       
   473 void oopDesc::long_field_put(int offset, jlong contents)      { *long_field_addr(offset) = contents;   }
       
   474 
       
   475 jfloat oopDesc::float_field(int offset) const                 { return *float_field_addr(offset);      }
       
   476 void oopDesc::float_field_put(int offset, jfloat contents)    { *float_field_addr(offset) = contents;  }
       
   477 
       
   478 jdouble oopDesc::double_field(int offset) const               { return *double_field_addr(offset);     }
       
   479 void oopDesc::double_field_put(int offset, jdouble contents)  { *double_field_addr(offset) = contents; }
       
   480 
       
   481 address oopDesc::address_field(int offset) const              { return *address_field_addr(offset);     }
       
   482 void oopDesc::address_field_put(int offset, address contents) { *address_field_addr(offset) = contents; }
       
   483 
       
   484 oop oopDesc::obj_field_acquire(int offset) const {
       
   485   return UseCompressedOops ?
       
   486              decode_heap_oop((narrowOop)
       
   487                OrderAccess::load_acquire(obj_field_addr<narrowOop>(offset)))
       
   488            : decode_heap_oop(
       
   489                 OrderAccess::load_acquire(obj_field_addr<oop>(offset)));
       
   490 }
       
   491 void oopDesc::release_obj_field_put(int offset, oop value) {
       
   492   UseCompressedOops ?
       
   493     oop_store((volatile narrowOop*)obj_field_addr<narrowOop>(offset), value) :
       
   494     oop_store((volatile oop*)      obj_field_addr<oop>(offset),       value);
       
   495 }
       
   496 
       
   497 jbyte oopDesc::byte_field_acquire(int offset) const                   { return OrderAccess::load_acquire(byte_field_addr(offset));     }
       
   498 void oopDesc::release_byte_field_put(int offset, jbyte contents)      { OrderAccess::release_store(byte_field_addr(offset), contents); }
       
   499 
       
   500 jchar oopDesc::char_field_acquire(int offset) const                   { return OrderAccess::load_acquire(char_field_addr(offset));     }
       
   501 void oopDesc::release_char_field_put(int offset, jchar contents)      { OrderAccess::release_store(char_field_addr(offset), contents); }
       
   502 
       
   503 jboolean oopDesc::bool_field_acquire(int offset) const                { return OrderAccess::load_acquire(bool_field_addr(offset));     }
       
   504 void oopDesc::release_bool_field_put(int offset, jboolean contents)   { OrderAccess::release_store(bool_field_addr(offset), jboolean(contents & 1)); }
       
   505 
       
   506 jint oopDesc::int_field_acquire(int offset) const                     { return OrderAccess::load_acquire(int_field_addr(offset));      }
       
   507 void oopDesc::release_int_field_put(int offset, jint contents)        { OrderAccess::release_store(int_field_addr(offset), contents);  }
       
   508 
       
   509 jshort oopDesc::short_field_acquire(int offset) const                 { return (jshort)OrderAccess::load_acquire(short_field_addr(offset)); }
       
   510 void oopDesc::release_short_field_put(int offset, jshort contents)    { OrderAccess::release_store(short_field_addr(offset), contents);     }
       
   511 
       
   512 jlong oopDesc::long_field_acquire(int offset) const                   { return OrderAccess::load_acquire(long_field_addr(offset));       }
       
   513 void oopDesc::release_long_field_put(int offset, jlong contents)      { OrderAccess::release_store(long_field_addr(offset), contents);   }
       
   514 
       
   515 jfloat oopDesc::float_field_acquire(int offset) const                 { return OrderAccess::load_acquire(float_field_addr(offset));      }
       
   516 void oopDesc::release_float_field_put(int offset, jfloat contents)    { OrderAccess::release_store(float_field_addr(offset), contents);  }
       
   517 
       
   518 jdouble oopDesc::double_field_acquire(int offset) const               { return OrderAccess::load_acquire(double_field_addr(offset));     }
       
   519 void oopDesc::release_double_field_put(int offset, jdouble contents)  { OrderAccess::release_store(double_field_addr(offset), contents); }
       
   520 
       
   521 address oopDesc::address_field_acquire(int offset) const              { return OrderAccess::load_acquire(address_field_addr(offset)); }
       
   522 void oopDesc::release_address_field_put(int offset, address contents) { OrderAccess::release_store(address_field_addr(offset), contents); }
       
   523 
   355 
   524 bool oopDesc::is_locked() const {
   356 bool oopDesc::is_locked() const {
   525   return mark()->is_locked();
   357   return mark()->is_locked();
   526 }
   358 }
   527 
   359