changeset 9762:57e5211846f9

Added class unloading support to the method profiling infrastructure.
author Christian Haeubl <haeubl@ssw.jku.at>
date Fri, 17 May 2013 17:24:03 +0200
parents b1e4aebbd19e
children 4a8b9117327a
files src/share/vm/oops/methodData.cpp src/share/vm/oops/methodData.hpp
diffstat 2 files changed, 70 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/vm/oops/methodData.cpp	Fri May 17 15:40:06 2013 +0200
+++ b/src/share/vm/oops/methodData.cpp	Fri May 17 17:24:03 2013 +0200
@@ -198,6 +198,18 @@
   print_shared(st, "VirtualCallData");
   print_receiver_data_on(st);
 }
+
+#ifdef GRAAL
+void VirtualCallData::clean_weak_klass_links(BoolObjectClosure* is_alive_cl) {
+  ReceiverTypeData::clean_weak_klass_links(is_alive_cl);
+  for (uint row = 0; row < method_row_limit(); row++) {
+    Method* p = method(row);
+    if (p != NULL && !p->method_holder()->is_loader_alive(is_alive_cl)) {
+      clear_method_row(row);
+    }
+  }
+}
+#endif // GRAAL
 #endif // !PRODUCT
 
 // ==================================================================
--- a/src/share/vm/oops/methodData.hpp	Fri May 17 15:40:06 2013 +0200
+++ b/src/share/vm/oops/methodData.hpp	Fri May 17 17:24:03 2013 +0200
@@ -635,9 +635,17 @@
 protected:
   enum {
 #ifdef GRAAL
-    // Graal is interested in knowing the percentage of type checks
-    // involving a type not explicitly in the profile
-    nonprofiled_receiver_count_off_set = counter_cell_count,
+    // Description of the different counters
+    // ReceiverTypeData for instanceof/checkcast/aastore:
+    //   C1/C2: count is incremented on type overflow and decremented for failed type checks
+    //   Graal: count decremented for failed type checks and nonprofiled_count is incremented on type overflow
+    //          TODO (chaeubl): in fact, Graal should also increment the count for failed type checks to mimic the C1/C2 behavior
+    // VirtualCallData for invokevirtual/invokeinterface:
+    //   C1/C2: count is incremented on type overflow
+    //   Graal: count is incremented on type overflow, nonprofiled_count is increment on method overflow
+
+    // Graal is interested in knowing the percentage of type checks involving a type not explicitly in the profile
+    nonprofiled_count_off_set = counter_cell_count,
     receiver0_offset,
 #else
     receiver0_offset = counter_cell_count,
@@ -717,6 +725,13 @@
     set_count(0);
     set_receiver(row, NULL);
     set_receiver_count(row, 0);
+#ifdef GRAAL
+    if (!this->is_VirtualCallData()) {
+      // if this is a ReceiverTypeData for Graal, the nonprofiled_count
+      // must also be reset (see "Description of the different counters" above)
+      set_nonprofiled_count(0);
+    }
+#endif
   }
 
   // Code generation support
@@ -728,7 +743,10 @@
   }
 #ifdef GRAAL
   static ByteSize nonprofiled_receiver_count_offset() {
-    return cell_offset(nonprofiled_receiver_count_off_set);
+    return cell_offset(nonprofiled_count_off_set);
+  }
+  void set_nonprofiled_count(uint count) {
+    set_uint_at(nonprofiled_count_off_set, count);
   }
 #endif
   static ByteSize receiver_type_data_size() {
@@ -766,6 +784,11 @@
     return static_cell_count();
   }
 
+  // Direct accessors
+  static ByteSize virtual_call_data_size() {
+    return cell_offset(static_cell_count());
+  }
+
 #ifdef GRAAL
   static ByteSize method_offset(uint row) {
     return cell_offset(method_cell_index(row));
@@ -779,13 +802,40 @@
   static int method_count_cell_index(uint row) {
     return count0_offset + (row + TypeProfileWidth) * receiver_type_row_cell_count;
   }
-#endif
+  static uint method_row_limit() {
+    return MethodProfileWidth;
+  }
+
+  Method* method(uint row) {
+    assert(row < method_row_limit(), "oob");
+
+    Method* method = (Method*)intptr_at(method_cell_index(row));
+    assert(method == NULL || method->is_method(), "must be");
+    return method;
+  }
+
+  void set_method(uint row, Method* m) {
+    assert((uint)row < method_row_limit(), "oob");
+    set_intptr_at(method_cell_index(row), (uintptr_t)m);
+  }
 
-  // Direct accessors
-  static ByteSize virtual_call_data_size() {
-    return cell_offset(static_cell_count());
+  void set_method_count(uint row, uint count) {
+    assert(row < method_row_limit(), "oob");
+    set_uint_at(method_count_cell_index(row), count);
   }
 
+  void clear_method_row(uint row) {
+    assert(row < method_row_limit(), "oob");
+    // Clear total count - indicator of polymorphic call site (see comment for clear_row() in ReceiverTypeData).
+    set_nonprofiled_count(0);
+    set_method(row, NULL);
+    set_method_count(row, 0);
+  }
+
+  // GC support
+  virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure);
+#endif
+
 #ifndef PRODUCT
   void print_data_on(outputStream* st);
 #endif