--- a/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp Fri Oct 04 13:33:02 2013 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp Tue Oct 08 17:35:51 2013 +0200
@@ -70,6 +70,12 @@
if ((val & (clean_card_mask_val() | deferred_card_val())) == deferred_card_val()) {
return false;
}
+
+ if (val == g1_young_gen) {
+ // the card is for a young gen region. We don't need to keep track of all pointers into young
+ return false;
+ }
+
// Cached bit can be installed either on a clean card or on a claimed card.
jbyte new_val = val;
if (val == clean_card_val()) {
@@ -85,6 +91,19 @@
return true;
}
+void G1SATBCardTableModRefBS::g1_mark_as_young(const MemRegion& mr) {
+ jbyte *const first = byte_for(mr.start());
+ jbyte *const last = byte_after(mr.last());
+
+ memset(first, g1_young_gen, last - first);
+}
+
+#ifndef PRODUCT
+void G1SATBCardTableModRefBS::verify_g1_young_region(MemRegion mr) {
+ verify_region(mr, g1_young_gen, true);
+}
+#endif
+
G1SATBCardTableLoggingModRefBS::
G1SATBCardTableLoggingModRefBS(MemRegion whole_heap,
int max_covered_regions) :
@@ -97,7 +116,11 @@
void
G1SATBCardTableLoggingModRefBS::write_ref_field_work(void* field,
oop new_val) {
- jbyte* byte = byte_for(field);
+ volatile jbyte* byte = byte_for(field);
+ if (*byte == g1_young_gen) {
+ return;
+ }
+ OrderAccess::storeload();
if (*byte != dirty_card) {
*byte = dirty_card;
Thread* thr = Thread::current();
@@ -129,7 +152,7 @@
void
G1SATBCardTableLoggingModRefBS::invalidate(MemRegion mr, bool whole_heap) {
- jbyte* byte = byte_for(mr.start());
+ volatile jbyte* byte = byte_for(mr.start());
jbyte* last_byte = byte_for(mr.last());
Thread* thr = Thread::current();
if (whole_heap) {
@@ -138,25 +161,35 @@
byte++;
}
} else {
- // Enqueue if necessary.
- if (thr->is_Java_thread()) {
- JavaThread* jt = (JavaThread*)thr;
- while (byte <= last_byte) {
- if (*byte != dirty_card) {
- *byte = dirty_card;
- jt->dirty_card_queue().enqueue(byte);
+ // skip all consecutive young cards
+ for (; byte <= last_byte && *byte == g1_young_gen; byte++);
+
+ if (byte <= last_byte) {
+ OrderAccess::storeload();
+ // Enqueue if necessary.
+ if (thr->is_Java_thread()) {
+ JavaThread* jt = (JavaThread*)thr;
+ for (; byte <= last_byte; byte++) {
+ if (*byte == g1_young_gen) {
+ continue;
+ }
+ if (*byte != dirty_card) {
+ *byte = dirty_card;
+ jt->dirty_card_queue().enqueue(byte);
+ }
}
- byte++;
- }
- } else {
- MutexLockerEx x(Shared_DirtyCardQ_lock,
- Mutex::_no_safepoint_check_flag);
- while (byte <= last_byte) {
- if (*byte != dirty_card) {
- *byte = dirty_card;
- _dcqs.shared_dirty_card_queue()->enqueue(byte);
+ } else {
+ MutexLockerEx x(Shared_DirtyCardQ_lock,
+ Mutex::_no_safepoint_check_flag);
+ for (; byte <= last_byte; byte++) {
+ if (*byte == g1_young_gen) {
+ continue;
+ }
+ if (*byte != dirty_card) {
+ *byte = dirty_card;
+ _dcqs.shared_dirty_card_queue()->enqueue(byte);
+ }
}
- byte++;
}
}
}