< prev index next >

src/hotspot/share/runtime/sharedRuntime.cpp

Print this page
rev 63603 : Micro-optimize SharedRuntime::get_referenced_objects

@@ -41,13 +41,15 @@
 #include "gc/shared/gcLocker.inline.hpp"
 #include "interpreter/interpreter.hpp"
 #include "interpreter/interpreterRuntime.hpp"
 #include "jfr/jfrEvents.hpp"
 #include "logging/log.hpp"
+#include "memory/iterator.inline.hpp"
 #include "memory/metaspaceShared.hpp"
 #include "memory/resourceArea.hpp"
 #include "memory/universe.hpp"
+#include "oops/instanceKlass.inline.hpp"
 #include "oops/klass.hpp"
 #include "oops/method.inline.hpp"
 #include "oops/objArrayKlass.hpp"
 #include "oops/oop.inline.hpp"
 #include "prims/forte.hpp"

@@ -61,10 +63,11 @@
 #include "runtime/handles.inline.hpp"
 #include "runtime/init.hpp"
 #include "runtime/interfaceSupport.inline.hpp"
 #include "runtime/java.hpp"
 #include "runtime/javaCalls.hpp"
+#include "runtime/jniHandles.inline.hpp"
 #include "runtime/sharedRuntime.hpp"
 #include "runtime/stubRoutines.hpp"
 #include "runtime/synchronizer.hpp"
 #include "runtime/vframe.inline.hpp"
 #include "runtime/vframeArray.hpp"

@@ -3215,5 +3218,65 @@
   if (new_obj == NULL) return;
 
   BarrierSet *bs = BarrierSet::barrier_set();
   bs->on_slowpath_allocation_exit(thread, new_obj);
 }
+
+class GetReferencedObjectsClosure : public BasicOopIterateClosure {
+private:
+  objArrayOopDesc* const _result;
+  int _count;
+public:
+  GetReferencedObjectsClosure(objArrayOopDesc* result) : _result(result), _count(0) {}
+
+  template <typename T> void do_oop_nv(T* p) {
+    oop o = HeapAccess<>::oop_load(p);
+    if (!CompressedOops::is_null(o)) {
+      _result->obj_at_put(_count++, o);
+    }
+  }
+
+  int count() { return _count; }
+
+  virtual void do_oop(oop* p)       { do_oop_nv(p); }
+  virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
+
+  // Don't use the oop verification code in the oop_oop_iterate framework.
+  debug_only(virtual bool should_verify_oops() { return false; })
+};
+
+JRT_LEAF(jint, SharedRuntime::get_referenced_objects(oopDesc* obj, objArrayOopDesc* ref_buf))
+  assert(Universe::heap()->is_in(obj), "object should be in heap: " PTR_FORMAT, p2i(obj));
+  assert(Universe::heap()->is_in(ref_buf), "ref buf should be in heap: " PTR_FORMAT, p2i(ref_buf));
+
+  InstanceKlass* k = InstanceKlass::cast(obj->klass());
+
+  int count = 0;
+  {
+    InstanceKlass* ik = k;
+    while (ik != NULL) {
+      count += ik->nonstatic_oop_field_count();
+      ik = ik->superklass();
+    }
+  }
+
+  if (count == 0) {
+    return 0;
+  }
+
+  if (count > ref_buf->length()) {
+    return -1;
+  }
+
+  GetReferencedObjectsClosure cl(ref_buf);
+
+#ifdef _LP64
+  if (UseCompressedOops) {
+    k->oop_oop_iterate<narrowOop>(obj, &cl);
+  } else
+#endif
+  {
+    k->oop_oop_iterate<oop>(obj, &cl);
+  }
+
+  return cl.count();
+JRT_END
< prev index next >