< 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 >