< prev index next >

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

Print this page
rev 7183 : autospecialized oop_iterate using SFINAE and templates


  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #ifndef SHARE_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.inline.hpp"
  42 #include "runtime/orderAccess.inline.hpp"
  43 #include "runtime/os.hpp"
  44 #include "utilities/macros.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 inline void oopDesc::release_set_mark(markOop m) {
  50   OrderAccess::release_store_ptr(&_mark, m);
  51 }
  52 
  53 inline markOop oopDesc::cas_set_mark(markOop new_mark, markOop old_mark) {
  54   return (markOop) Atomic::cmpxchg_ptr(new_mark, &_mark, old_mark);
  55 }


 667     set_displaced_mark(displaced_mark()->incr_age());
 668   } else {
 669     set_mark(mark()->incr_age());
 670   }
 671 }
 672 
 673 
 674 inline intptr_t oopDesc::identity_hash() {
 675   // Fast case; if the object is unlocked and the hash value is set, no locking is needed
 676   // Note: The mark must be read into local variable to avoid concurrent updates.
 677   markOop mrk = mark();
 678   if (mrk->is_unlocked() && !mrk->has_no_hash()) {
 679     return mrk->hash();
 680   } else if (mrk->is_marked()) {
 681     return mrk->hash();
 682   } else {
 683     return slow_identity_hash();
 684   }
 685 }
 686 
























 687 inline int oopDesc::adjust_pointers() {
 688   debug_only(int check_size = size());
 689   int s = klass()->oop_adjust_pointers(this);
 690   assert(s == check_size, "should be the same");
 691   return s;
 692 }
 693 






























































 694 #define OOP_ITERATE_DEFN(OopClosureType, nv_suffix)                        \
 695                                                                            \
 696 inline int oopDesc::oop_iterate(OopClosureType* blk) {                     \
 697   SpecializationStats::record_call();                                      \
 698   return klass()->oop_oop_iterate##nv_suffix(this, blk);               \
 699 }                                                                          \
 700                                                                            \
 701 inline int oopDesc::oop_iterate(OopClosureType* blk, MemRegion mr) {       \
 702   SpecializationStats::record_call();                                      \
 703   return klass()->oop_oop_iterate##nv_suffix##_m(this, blk, mr);       \
 704 }
 705 
 706 
 707 inline int oopDesc::oop_iterate_no_header(OopClosure* blk) {
 708   // The NoHeaderExtendedOopClosure wraps the OopClosure and proxies all
 709   // the do_oop calls, but turns off all other features in ExtendedOopClosure.
 710   NoHeaderExtendedOopClosure cl(blk);
 711   return oop_iterate(&cl);
 712 }
 713 
 714 inline int oopDesc::oop_iterate_no_header(OopClosure* blk, MemRegion mr) {
 715   NoHeaderExtendedOopClosure cl(blk);
 716   return oop_iterate(&cl, mr);
 717 }
 718 
 719 ALL_OOP_OOP_ITERATE_CLOSURES_1(OOP_ITERATE_DEFN)
 720 ALL_OOP_OOP_ITERATE_CLOSURES_2(OOP_ITERATE_DEFN)
 721 
 722 #if INCLUDE_ALL_GCS
 723 #define OOP_ITERATE_BACKWARDS_DEFN(OopClosureType, nv_suffix)              \
 724                                                                            \
 725 inline int oopDesc::oop_iterate_backwards(OopClosureType* blk) {           \
 726   SpecializationStats::record_call();                                      \
 727   return klass()->oop_oop_iterate_backwards##nv_suffix(this, blk);     \
 728 }
 729 
 730 ALL_OOP_OOP_ITERATE_CLOSURES_1(OOP_ITERATE_BACKWARDS_DEFN)
 731 ALL_OOP_OOP_ITERATE_CLOSURES_2(OOP_ITERATE_BACKWARDS_DEFN)
 732 #endif // INCLUDE_ALL_GCS
 733 
 734 #endif // SHARE_VM_OOPS_OOP_INLINE_HPP


  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #ifndef SHARE_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/iterator.inline.hpp"
  32 #include "memory/barrierSet.inline.hpp"
  33 #include "memory/cardTableModRefBS.hpp"
  34 #include "memory/genCollectedHeap.hpp"
  35 #include "memory/generation.hpp"
  36 #include "memory/specialized_oop_closures.inline.hpp"
  37 #include "oops/instanceMirrorKlass.inline.hpp"
  38 #include "oops/instanceRefKlass.inline.hpp"
  39 #include "oops/instanceClassLoaderKlass.inline.hpp"
  40 #include "oops/arrayKlass.hpp"
  41 #include "oops/arrayOop.hpp"
  42 #include "oops/klass.inline.hpp"
  43 #include "oops/markOop.inline.hpp"
  44 #include "oops/oop.hpp"
  45 #include "runtime/atomic.inline.hpp"
  46 #include "runtime/orderAccess.inline.hpp"
  47 #include "runtime/os.hpp"
  48 #include "utilities/macros.hpp"
  49 
  50 // Implementation of all inlined member functions defined in oop.hpp
  51 // We need a separate file to avoid circular references
  52 
  53 inline void oopDesc::release_set_mark(markOop m) {
  54   OrderAccess::release_store_ptr(&_mark, m);
  55 }
  56 
  57 inline markOop oopDesc::cas_set_mark(markOop new_mark, markOop old_mark) {
  58   return (markOop) Atomic::cmpxchg_ptr(new_mark, &_mark, old_mark);
  59 }


 671     set_displaced_mark(displaced_mark()->incr_age());
 672   } else {
 673     set_mark(mark()->incr_age());
 674   }
 675 }
 676 
 677 
 678 inline intptr_t oopDesc::identity_hash() {
 679   // Fast case; if the object is unlocked and the hash value is set, no locking is needed
 680   // Note: The mark must be read into local variable to avoid concurrent updates.
 681   markOop mrk = mark();
 682   if (mrk->is_unlocked() && !mrk->has_no_hash()) {
 683     return mrk->hash();
 684   } else if (mrk->is_marked()) {
 685     return mrk->hash();
 686   } else {
 687     return slow_identity_hash();
 688   }
 689 }
 690 
 691 template <class OopClosureType>
 692 inline typename enable_if<is_kind_of<ExtendedOopClosure, OopClosureType>::value, void>::type
 693 oopDesc::do_metadata_if_applicable(OopClosureType *cl) {
 694   if (OopClosureDispatcher::do_metadata<OopClosureType>(cl)) {
 695     OopClosureDispatcher::do_klass<OopClosureType>(cl, klass());
 696   }
 697 }
 698 
 699 template <class OopClosureType>
 700 inline typename enable_if<!is_kind_of<ExtendedOopClosure, OopClosureType>::value, void>::type
 701 oopDesc::do_metadata_if_applicable(OopClosureType *cl) {}
 702 
 703 template <class OopClosureType>
 704 inline int oopDesc::oop_iterate_dispatch_tag(OopClosureType *blk, DispatchTag tag) {
 705   // Closure is not explicitly specialized; determine which klass with a tag and call an inline dispatch method.
 706   switch (tag) {
 707       case _instance_mirror_klass: return static_cast<InstanceMirrorKlass*>(klass())->oop_iterate_and_dispatch<OopClosureType>(this, blk);
 708       case _instance_class_loader_klass: return static_cast<InstanceClassLoaderKlass*>(klass())->InstanceClassLoaderKlass::oop_iterate_and_dispatch<OopClosureType>(this, blk);
 709       case _instance_ref_klass: return static_cast<InstanceRefKlass*>(klass())->InstanceRefKlass::oop_iterate_and_dispatch<OopClosureType>(this, blk);
 710   }
 711   ShouldNotReachHere();
 712   return -1;
 713 }
 714 
 715 inline int oopDesc::adjust_pointers() {
 716   debug_only(int check_size = size());
 717   int s = klass()->oop_adjust_pointers(this);
 718   assert(s == check_size, "should be the same");
 719   return s;
 720 }
 721 
 722 template <class OopClosureType>
 723 inline int oopDesc::oop_iterate_internal(OopClosureType *blk) {
 724   SpecializationStats::record_call();
 725   Klass::OopInterval interval;  // Allocate space for an interval for arrays just in case it's needed
 726   Klass::OopInterval *current = &interval;
 727   int size;
 728   int count = klass()->get_linear_oop_intervals(this, current, size);
 729   if (count >= 0) {
 730     if (UseCompressedOops) {
 731       for (int i = 0; i < count; i++) {
 732         narrowOop *current_oop = this->obj_field_addr<narrowOop>(current->_offset);
 733         for (uint j = 0; j < current->_size; j++) {
 734           OopClosureDispatcher::do_oop<OopClosureType, narrowOop>(blk, current_oop);
 735           current_oop++;
 736         }
 737       }
 738       current++;
 739     } else {
 740       for (int i = 0; i < count; i++) {
 741         oop *current_oop = this->obj_field_addr<oop>(current->_offset);
 742         for (uint j = 0; j < current->_size; j++) {
 743           OopClosureDispatcher::do_oop<OopClosureType, oop>(blk, current_oop);
 744           current_oop++;
 745         }
 746       }
 747       current++;
 748     }
 749 
 750     // The below call uses SFINAE and does nothing if the closure is not an ExtendedOopClosure
 751     // Otherwise, if it is, it checks if it should send in metadata into the closure too and then does so
 752     do_metadata_if_applicable<OopClosureType>(blk);
 753 
 754     return size;
 755   } else {
 756     // The Klass is of a slightly more advanced type, falling back to dispatch tag solution.
 757     // This fallback parses the returned tag and identifies the klass implementation and calls it.
 758     return oop_iterate_dispatch_tag<OopClosureType>(blk, DispatchTag(-count));
 759   }
 760 }
 761 
 762 template <class OopClosureType>
 763 inline typename enable_if<is_kind_of<ExtendedOopClosure, OopClosureType>::value, int>::type
 764 oopDesc::oop_iterate(OopClosureType *blk) {
 765   return oop_iterate_internal<OopClosureType>(blk);
 766 }
 767 
 768 template <class OopClosureType>
 769 inline typename enable_if<is_kind_of<OopClosure, OopClosureType>::value, int>::type
 770 oopDesc::oop_iterate_no_header(OopClosureType *blk) {
 771   if (is_kind_of<ExtendedOopClosure, OopClosureType>::value) {
 772     NoHeaderOopClosure<OopClosureType> cl(blk);
 773     return oop_iterate_internal(&cl);
 774   } else {
 775     return oop_iterate_internal(blk);
 776   }
 777 }
 778 
 779 inline int oopDesc::oop_iterate_no_header(OopClosure* blk, MemRegion mr) {
 780   NoHeaderExtendedOopClosure cl(blk);
 781   return oop_iterate(&cl, mr);
 782 }
 783 
 784 #define OOP_ITERATE_DEFN(OopClosureType, nv_suffix)                     \
 785                                                                         \
 786 inline int oopDesc::oop_iterate(OopClosureType* blk) {                  \
 787   SpecializationStats::record_call();                                   \
 788   return klass()->oop_oop_iterate##nv_suffix(this, blk);                \
 789 }                                                                       \
 790                                                                         \
 791 inline int oopDesc::oop_iterate(OopClosureType* blk, MemRegion mr) {    \
 792   SpecializationStats::record_call();                                   \
 793   return klass()->oop_oop_iterate##nv_suffix##_m(this, blk, mr);        \
 794 }
 795 













 796 ALL_OOP_OOP_ITERATE_CLOSURES_1(OOP_ITERATE_DEFN)
 797 ALL_OOP_OOP_ITERATE_CLOSURES_2(OOP_ITERATE_DEFN)
 798 
 799 #if INCLUDE_ALL_GCS
 800 #define OOP_ITERATE_BACKWARDS_DEFN(OopClosureType, nv_suffix)           \
 801                                                                         \
 802 inline int oopDesc::oop_iterate_backwards(OopClosureType* blk) {        \
 803   SpecializationStats::record_call();                                   \
 804   return klass()->oop_oop_iterate_backwards##nv_suffix(this, blk);      \
 805 }
 806 
 807 ALL_OOP_OOP_ITERATE_CLOSURES_1(OOP_ITERATE_BACKWARDS_DEFN)
 808 ALL_OOP_OOP_ITERATE_CLOSURES_2(OOP_ITERATE_BACKWARDS_DEFN)
 809 #endif // INCLUDE_ALL_GCS
 810 
 811 #endif // SHARE_VM_OOPS_OOP_INLINE_HPP
< prev index next >