src/hotspot/share/gc/g1/g1CardTable.inline.hpp
changeset 55510 3e31a8beaae4
parent 53244 9807daeb47c4
child 59319 9ee940f1de90
--- a/src/hotspot/share/gc/g1/g1CardTable.inline.hpp	Thu Jun 27 03:33:44 2019 +0200
+++ b/src/hotspot/share/gc/g1/g1CardTable.inline.hpp	Thu Jun 27 11:48:32 2019 +0200
@@ -26,15 +26,58 @@
 #define SHARE_GC_G1_G1CARDTABLE_INLINE_HPP
 
 #include "gc/g1/g1CardTable.hpp"
+#include "gc/g1/heapRegion.hpp"
 
-void G1CardTable::set_card_claimed(size_t card_index) {
-  jbyte val = _byte_map[card_index];
-  if (val == clean_card_val()) {
-    val = (jbyte)claimed_card_val();
-  } else {
-    val |= (jbyte)claimed_card_val();
+inline uint G1CardTable::region_idx_for(CardValue* p) {
+  size_t const card_idx = pointer_delta(p, _byte_map, sizeof(CardValue));
+  return (uint)(card_idx >> (HeapRegion::LogOfHRGrainBytes - card_shift));
+}
+
+inline void G1CardTable::mark_clean_as_dirty(size_t card_index) {
+  CardValue value = _byte_map[card_index];
+  if (value == clean_card_val()) {
+    _byte_map[card_index] = dirty_card_val();
   }
-  _byte_map[card_index] = val;
 }
 
-#endif // SHARE_GC_G1_G1CARDTABLE_INLINE_HPP
+inline void G1CardTable::mark_region_dirty(size_t start_card_index, size_t num_cards) {
+  assert(is_aligned(start_card_index, sizeof(size_t)), "Start card index must be aligned.");
+  assert(is_aligned(num_cards, sizeof(size_t)), "Number of cards to change must be evenly divisible.");
+
+  size_t const num_chunks = num_cards / sizeof(size_t);
+
+  size_t* cur_word = (size_t*)&_byte_map[start_card_index];
+  size_t* const end_word_map = cur_word + num_chunks;
+  while (cur_word < end_word_map) {
+    size_t value = *cur_word;
+    if (value == WordAllClean) {
+      *cur_word = WordAllDirty;
+    } else if (value == WordAllDirty) {
+      // do nothing.
+    } else {
+      // There is a mix of cards in there. Tread slowly.
+      CardValue* cur = (CardValue*)cur_word;
+      for (size_t i = 0; i < sizeof(size_t); i++) {
+        CardValue value = *cur;
+        if (value == clean_card_val()) {
+          *cur = dirty_card_val();
+        }
+        cur++;
+      }
+    }
+    cur_word++;
+  }
+}
+
+inline void G1CardTable::mark_as_scanned(size_t start_card_index, size_t num_cards) {
+  CardValue* start = &_byte_map[start_card_index];
+  CardValue* const end = start + num_cards;
+  while (start < end) {
+    CardValue value = *start;
+    assert(value == dirty_card_val(),
+           "Must have been dirty %d start " PTR_FORMAT " " PTR_FORMAT, value, p2i(start), p2i(end));
+    *start++ = g1_card_already_scanned;
+  }
+}
+
+#endif /* SHARE_GC_G1_G1CARDTABLE_INLINE_HPP */