< prev index next >

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

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

@@ -26,15 +26,19 @@
 #define SHARE_VM_OOPS_OOP_INLINE_HPP
 
 #include "gc_implementation/shared/ageTable.hpp"
 #include "gc_implementation/shared/markSweep.inline.hpp"
 #include "gc_interface/collectedHeap.inline.hpp"
+#include "memory/iterator.inline.hpp"
 #include "memory/barrierSet.inline.hpp"
 #include "memory/cardTableModRefBS.hpp"
 #include "memory/genCollectedHeap.hpp"
 #include "memory/generation.hpp"
-#include "memory/specialized_oop_closures.hpp"
+#include "memory/specialized_oop_closures.inline.hpp"
+#include "oops/instanceMirrorKlass.inline.hpp"
+#include "oops/instanceRefKlass.inline.hpp"
+#include "oops/instanceClassLoaderKlass.inline.hpp"
 #include "oops/arrayKlass.hpp"
 #include "oops/arrayOop.hpp"
 #include "oops/klass.inline.hpp"
 #include "oops/markOop.inline.hpp"
 #include "oops/oop.hpp"

@@ -682,17 +686,103 @@
   } else {
     return slow_identity_hash();
   }
 }
 
+template <class OopClosureType>
+inline typename enable_if<is_kind_of<ExtendedOopClosure, OopClosureType>::value, void>::type
+oopDesc::do_metadata_if_applicable(OopClosureType *cl) {
+  if (OopClosureDispatcher::do_metadata<OopClosureType>(cl)) {
+    OopClosureDispatcher::do_klass<OopClosureType>(cl, klass());
+  }
+}
+
+template <class OopClosureType>
+inline typename enable_if<!is_kind_of<ExtendedOopClosure, OopClosureType>::value, void>::type
+oopDesc::do_metadata_if_applicable(OopClosureType *cl) {}
+
+template <class OopClosureType>
+inline int oopDesc::oop_iterate_dispatch_tag(OopClosureType *blk, DispatchTag tag) {
+  // Closure is not explicitly specialized; determine which klass with a tag and call an inline dispatch method.
+  switch (tag) {
+      case _instance_mirror_klass: return static_cast<InstanceMirrorKlass*>(klass())->oop_iterate_and_dispatch<OopClosureType>(this, blk);
+      case _instance_class_loader_klass: return static_cast<InstanceClassLoaderKlass*>(klass())->InstanceClassLoaderKlass::oop_iterate_and_dispatch<OopClosureType>(this, blk);
+      case _instance_ref_klass: return static_cast<InstanceRefKlass*>(klass())->InstanceRefKlass::oop_iterate_and_dispatch<OopClosureType>(this, blk);
+  }
+  ShouldNotReachHere();
+  return -1;
+}
+
 inline int oopDesc::adjust_pointers() {
   debug_only(int check_size = size());
   int s = klass()->oop_adjust_pointers(this);
   assert(s == check_size, "should be the same");
   return s;
 }
 
+template <class OopClosureType>
+inline int oopDesc::oop_iterate_internal(OopClosureType *blk) {
+  SpecializationStats::record_call();
+  Klass::OopInterval interval;  // Allocate space for an interval for arrays just in case it's needed
+  Klass::OopInterval *current = &interval;
+  int size;
+  int count = klass()->get_linear_oop_intervals(this, current, size);
+  if (count >= 0) {
+    if (UseCompressedOops) {
+      for (int i = 0; i < count; i++) {
+        narrowOop *current_oop = this->obj_field_addr<narrowOop>(current->_offset);
+        for (uint j = 0; j < current->_size; j++) {
+          OopClosureDispatcher::do_oop<OopClosureType, narrowOop>(blk, current_oop);
+          current_oop++;
+        }
+      }
+      current++;
+    } else {
+      for (int i = 0; i < count; i++) {
+        oop *current_oop = this->obj_field_addr<oop>(current->_offset);
+        for (uint j = 0; j < current->_size; j++) {
+          OopClosureDispatcher::do_oop<OopClosureType, oop>(blk, current_oop);
+          current_oop++;
+        }
+      }
+      current++;
+    }
+
+    // The below call uses SFINAE and does nothing if the closure is not an ExtendedOopClosure
+    // Otherwise, if it is, it checks if it should send in metadata into the closure too and then does so
+    do_metadata_if_applicable<OopClosureType>(blk);
+
+    return size;
+  } else {
+    // The Klass is of a slightly more advanced type, falling back to dispatch tag solution.
+    // This fallback parses the returned tag and identifies the klass implementation and calls it.
+    return oop_iterate_dispatch_tag<OopClosureType>(blk, DispatchTag(-count));
+  }
+}
+
+template <class OopClosureType>
+inline typename enable_if<is_kind_of<ExtendedOopClosure, OopClosureType>::value, int>::type
+oopDesc::oop_iterate(OopClosureType *blk) {
+  return oop_iterate_internal<OopClosureType>(blk);
+}
+
+template <class OopClosureType>
+inline typename enable_if<is_kind_of<OopClosure, OopClosureType>::value, int>::type
+oopDesc::oop_iterate_no_header(OopClosureType *blk) {
+  if (is_kind_of<ExtendedOopClosure, OopClosureType>::value) {
+    NoHeaderOopClosure<OopClosureType> cl(blk);
+    return oop_iterate_internal(&cl);
+  } else {
+    return oop_iterate_internal(blk);
+  }
+}
+
+inline int oopDesc::oop_iterate_no_header(OopClosure* blk, MemRegion mr) {
+  NoHeaderExtendedOopClosure cl(blk);
+  return oop_iterate(&cl, mr);
+}
+
 #define OOP_ITERATE_DEFN(OopClosureType, nv_suffix)                        \
                                                                            \
 inline int oopDesc::oop_iterate(OopClosureType* blk) {                     \
   SpecializationStats::record_call();                                      \
   return klass()->oop_oop_iterate##nv_suffix(this, blk);               \

@@ -701,23 +791,10 @@
 inline int oopDesc::oop_iterate(OopClosureType* blk, MemRegion mr) {       \
   SpecializationStats::record_call();                                      \
   return klass()->oop_oop_iterate##nv_suffix##_m(this, blk, mr);       \
 }
 
-
-inline int oopDesc::oop_iterate_no_header(OopClosure* blk) {
-  // The NoHeaderExtendedOopClosure wraps the OopClosure and proxies all
-  // the do_oop calls, but turns off all other features in ExtendedOopClosure.
-  NoHeaderExtendedOopClosure cl(blk);
-  return oop_iterate(&cl);
-}
-
-inline int oopDesc::oop_iterate_no_header(OopClosure* blk, MemRegion mr) {
-  NoHeaderExtendedOopClosure cl(blk);
-  return oop_iterate(&cl, mr);
-}
-
 ALL_OOP_OOP_ITERATE_CLOSURES_1(OOP_ITERATE_DEFN)
 ALL_OOP_OOP_ITERATE_CLOSURES_2(OOP_ITERATE_DEFN)
 
 #if INCLUDE_ALL_GCS
 #define OOP_ITERATE_BACKWARDS_DEFN(OopClosureType, nv_suffix)              \
< prev index next >