29 #include "logging/log.hpp" |
29 #include "logging/log.hpp" |
30 #include "runtime/atomic.hpp" |
30 #include "runtime/atomic.hpp" |
31 #include "runtime/orderAccess.hpp" |
31 #include "runtime/orderAccess.hpp" |
32 |
32 |
33 bool G1CardTable::mark_card_deferred(size_t card_index) { |
33 bool G1CardTable::mark_card_deferred(size_t card_index) { |
34 jbyte val = _byte_map[card_index]; |
34 CardValue val = _byte_map[card_index]; |
35 // It's already processed |
35 // It's already processed |
36 if ((val & (clean_card_mask_val() | deferred_card_val())) == deferred_card_val()) { |
36 if ((val & (clean_card_mask_val() | deferred_card_val())) == deferred_card_val()) { |
37 return false; |
37 return false; |
38 } |
38 } |
39 |
39 |
40 // Cached bit can be installed either on a clean card or on a claimed card. |
40 // Cached bit can be installed either on a clean card or on a claimed card. |
41 jbyte new_val = val; |
41 CardValue new_val = val; |
42 if (val == clean_card_val()) { |
42 if (val == clean_card_val()) { |
43 new_val = (jbyte)deferred_card_val(); |
43 new_val = deferred_card_val(); |
44 } else { |
44 } else { |
45 if (val & claimed_card_val()) { |
45 if (val & claimed_card_val()) { |
46 new_val = val | (jbyte)deferred_card_val(); |
46 new_val = val | deferred_card_val(); |
47 } |
47 } |
48 } |
48 } |
49 if (new_val != val) { |
49 if (new_val != val) { |
50 Atomic::cmpxchg(new_val, &_byte_map[card_index], val); |
50 Atomic::cmpxchg(new_val, &_byte_map[card_index], val); |
51 } |
51 } |
52 return true; |
52 return true; |
53 } |
53 } |
54 |
54 |
55 void G1CardTable::g1_mark_as_young(const MemRegion& mr) { |
55 void G1CardTable::g1_mark_as_young(const MemRegion& mr) { |
56 jbyte *const first = byte_for(mr.start()); |
56 CardValue *const first = byte_for(mr.start()); |
57 jbyte *const last = byte_after(mr.last()); |
57 CardValue *const last = byte_after(mr.last()); |
58 |
58 |
59 memset_with_concurrent_readers(first, g1_young_gen, last - first); |
59 memset_with_concurrent_readers(first, g1_young_gen, last - first); |
60 } |
60 } |
61 |
61 |
62 #ifndef PRODUCT |
62 #ifndef PRODUCT |
83 HeapWord* high_bound = _whole_heap.end(); |
83 HeapWord* high_bound = _whole_heap.end(); |
84 |
84 |
85 _cur_covered_regions = 1; |
85 _cur_covered_regions = 1; |
86 _covered[0] = _whole_heap; |
86 _covered[0] = _whole_heap; |
87 |
87 |
88 _byte_map = (jbyte*) mapper->reserved().start(); |
88 _byte_map = (CardValue*) mapper->reserved().start(); |
89 _byte_map_base = _byte_map - (uintptr_t(low_bound) >> card_shift); |
89 _byte_map_base = _byte_map - (uintptr_t(low_bound) >> card_shift); |
90 assert(byte_for(low_bound) == &_byte_map[0], "Checking start of map"); |
90 assert(byte_for(low_bound) == &_byte_map[0], "Checking start of map"); |
91 assert(byte_for(high_bound-1) <= &_byte_map[_last_valid_index], "Checking end of map"); |
91 assert(byte_for(high_bound-1) <= &_byte_map[_last_valid_index], "Checking end of map"); |
92 |
92 |
93 log_trace(gc, barrier)("G1CardTable::G1CardTable: "); |
93 log_trace(gc, barrier)("G1CardTable::G1CardTable: "); |
95 p2i(&_byte_map[0]), p2i(&_byte_map[_last_valid_index])); |
95 p2i(&_byte_map[0]), p2i(&_byte_map[_last_valid_index])); |
96 log_trace(gc, barrier)(" _byte_map_base: " INTPTR_FORMAT, p2i(_byte_map_base)); |
96 log_trace(gc, barrier)(" _byte_map_base: " INTPTR_FORMAT, p2i(_byte_map_base)); |
97 } |
97 } |
98 |
98 |
99 bool G1CardTable::is_in_young(oop obj) const { |
99 bool G1CardTable::is_in_young(oop obj) const { |
100 volatile jbyte* p = byte_for(obj); |
100 volatile CardValue* p = byte_for(obj); |
101 return *p == G1CardTable::g1_young_card_val(); |
101 return *p == G1CardTable::g1_young_card_val(); |
102 } |
102 } |