< prev index next >

src/hotspot/share/gc/g1/g1BarrierSetRuntime.cpp

Print this page
rev 55659 : 8225776: Branch profiling for G1's write post-barrier in C2.

@@ -21,16 +21,25 @@
  * questions.
  *
  */
 
 #include "precompiled.hpp"
+#include "gc/g1/heapRegion.hpp"
 #include "gc/g1/g1BarrierSet.inline.hpp"
 #include "gc/g1/g1BarrierSetRuntime.hpp"
 #include "gc/g1/g1ThreadLocalData.hpp"
 #include "runtime/interfaceSupport.inline.hpp"
 #include "utilities/macros.hpp"
 
+PerfCounter* G1BarrierSetRuntime::_total_write_barriers = NULL;
+PerfCounter* G1BarrierSetRuntime::_young_ref_writes = NULL;
+PerfCounter* G1BarrierSetRuntime::_cross_region_ref_writes = NULL;
+PerfCounter* G1BarrierSetRuntime::_young_cross_region_ref_writes = NULL;
+PerfCounter* G1BarrierSetRuntime::_old_cross_region_ref_writes = NULL;
+PerfCounter* G1BarrierSetRuntime::_old_dirty_cross_ref_writes = NULL;
+PerfCounter* G1BarrierSetRuntime::_ref_array_writes = NULL;
+
 void G1BarrierSetRuntime::write_ref_array_pre_oop_entry(oop* dst, size_t length) {
   G1BarrierSet *bs = barrier_set_cast<G1BarrierSet>(BarrierSet::barrier_set());
   bs->write_ref_array_pre(dst, length, false);
 }
 

@@ -38,10 +47,13 @@
   G1BarrierSet *bs = barrier_set_cast<G1BarrierSet>(BarrierSet::barrier_set());
   bs->write_ref_array_pre(dst, length, false);
 }
 
 void G1BarrierSetRuntime::write_ref_array_post_entry(HeapWord* dst, size_t length) {
+  if (UsePerfData && G1WriteBarrierStats) {
+    _ref_array_writes->atomic_add((jlong)length);
+  }
   G1BarrierSet *bs = barrier_set_cast<G1BarrierSet>(BarrierSet::barrier_set());
   bs->G1BarrierSet::write_ref_array(dst, length);
 }
 
 // G1 pre write barrier slowpath

@@ -57,5 +69,58 @@
 
 // G1 post write barrier slowpath
 JRT_LEAF(void, G1BarrierSetRuntime::write_ref_field_post_entry(void* card_addr, JavaThread* thread))
   G1ThreadLocalData::dirty_card_queue(thread).enqueue(card_addr);
 JRT_END
+
+JRT_LEAF(void, G1BarrierSetRuntime::write_ref_stats(HeapWord* dst, oopDesc* val))
+  _total_write_barriers->atomic_inc();
+  G1BarrierSet* bs = barrier_set_cast<G1BarrierSet>(BarrierSet::barrier_set());
+  CardTable* ct = bs->card_table();
+  bool is_young = ct->is_in_young(oop(dst));
+  uint64_t xor_result =
+      reinterpret_cast<uint64_t>(dst) ^ reinterpret_cast<uint64_t>(val);
+  bool is_cross_region = (xor_result >> HeapRegion::LogOfHRGrainBytes) != 0;
+  if (is_young) {
+    _young_ref_writes->atomic_inc();
+  }
+  if (is_cross_region) {
+    _cross_region_ref_writes->atomic_inc();
+  }
+  if (is_young && is_cross_region) {
+    _young_cross_region_ref_writes->atomic_inc();
+  }
+  if (!is_young && is_cross_region) {
+    _old_cross_region_ref_writes->atomic_inc();
+    if (*ct->byte_for(dst) == CardTable::dirty_card_val()) {
+      _old_dirty_cross_ref_writes->atomic_inc();
+    }
+  }
+JRT_END
+
+void G1BarrierSetRuntime::initialize() {
+  if (UsePerfData && G1WriteBarrierStats) {
+    EXCEPTION_MARK;
+
+    _total_write_barriers =
+                 PerfDataManager::create_counter(NULL_NS, "total_write_barriers",
+                                                 PerfData::U_Ticks, CHECK);
+    _young_ref_writes =
+                 PerfDataManager::create_counter(NULL_NS, "young_ref_writes",
+                                                 PerfData::U_Ticks, CHECK);
+    _cross_region_ref_writes =
+                 PerfDataManager::create_counter(NULL_NS, "cross_region_ref_writes",
+                                                 PerfData::U_Ticks, CHECK);
+    _young_cross_region_ref_writes =
+                 PerfDataManager::create_counter(NULL_NS, "young_cross_region_ref_writes",
+                                                 PerfData::U_Ticks, CHECK);
+    _old_cross_region_ref_writes =
+                 PerfDataManager::create_counter(NULL_NS, "old_cross_region_ref_writes",
+                                                 PerfData::U_Ticks, CHECK);
+    _old_dirty_cross_ref_writes =
+                 PerfDataManager::create_counter(NULL_NS, "old_dirty_cross_ref_writes",
+                                                 PerfData::U_Ticks, CHECK);
+    _ref_array_writes =
+                 PerfDataManager::create_counter(NULL_NS, "ref_array_writes",
+                                                 PerfData::U_Ticks, CHECK);
+  }
+}
< prev index next >