diff src/share/vm/code/oopRecorder.cpp @ 17375:44b83285b645

Deduplicate constant oops during code installation
author Tom Rodriguez <tom.rodriguez@oracle.com>
date Wed, 08 Oct 2014 11:50:00 -0700
parents 9928ad27a80e
children 50942f016967
line wrap: on
line diff
--- a/src/share/vm/code/oopRecorder.cpp	Wed Oct 08 11:48:00 2014 -0700
+++ b/src/share/vm/code/oopRecorder.cpp	Wed Oct 08 11:50:00 2014 -0700
@@ -165,3 +165,49 @@
 // Explicitly instantiate these types
 template class ValueRecorder<Metadata*>;
 template class ValueRecorder<jobject>;
+
+oop ObjectLookup::ObjectEntry::oop_value() { return JNIHandles::resolve(_value); }
+
+ObjectLookup::ObjectLookup(): _gc_count(Universe::heap()->total_collections()), _values(4) {}
+
+void ObjectLookup::maybe_resort() {
+  // The values are kept sorted by address which may be invalidated
+  // after a GC, so resort if a GC has occurred since last time.
+  if (_gc_count != Universe::heap()->total_collections()) {
+    _gc_count = Universe::heap()->total_collections();
+    _values.sort(sort_by_address);
+  }
+}
+
+int ObjectLookup::sort_by_address(oop a, oop b) {
+  if (b > a) return 1;
+  if (a > b) return -1;
+  return 0;
+}
+
+int ObjectLookup::sort_by_address(ObjectEntry* a, ObjectEntry* b) {
+  return sort_by_address(a->oop_value(), b->oop_value());
+}
+
+int ObjectLookup::sort_oop_by_address(oop a, ObjectEntry b) {
+  return sort_by_address(a, b.oop_value());
+}
+  
+int ObjectLookup::find_index(jobject handle, OopRecorder* oop_recorder) {
+  if (handle == NULL) {
+    return 0;
+  }
+  oop object = JNIHandles::resolve(handle);
+  maybe_resort();
+  bool found;
+  int location = _values.find_binary<oop, sort_oop_by_address>(object, found);
+  if (!found) {
+    assert(location <= _values.length(), "out of range");
+    jobject handle = JNIHandles::make_local(object);
+    ObjectEntry r(handle, oop_recorder->allocate_oop_index(handle));
+    _values.insert_binary(location, r);
+    return r.index();
+  }
+  return _values.at(location).index();
+}
+