64
65
66 // The card cache table
67 CardValue** _hot_cache;
68
69 size_t _hot_cache_size;
70
71 size_t _hot_cache_par_chunk_size;
72
73 // Avoids false sharing when concurrently updating _hot_cache_idx or
74 // _hot_cache_par_claimed_idx. These are never updated at the same time
75 // thus it's not necessary to separate them as well
76 char _pad_before[DEFAULT_CACHE_LINE_SIZE];
77
78 volatile size_t _hot_cache_idx;
79
80 volatile size_t _hot_cache_par_claimed_idx;
81
82 char _pad_after[DEFAULT_CACHE_LINE_SIZE];
83
84 // The number of cached cards a thread claims when flushing the cache
85 static const int ClaimChunkSize = 32;
86
87 public:
88 static bool default_use_cache() {
89 return (G1ConcRSLogCacheSize > 0);
90 }
91
92 G1HotCardCache(G1CollectedHeap* g1h);
93 ~G1HotCardCache();
94
95 void initialize(G1RegionToSpaceMapper* card_counts_storage);
96
97 bool use_cache() { return _use_cache; }
98
99 void set_use_cache(bool b) {
100 _use_cache = (b ? default_use_cache() : false);
101 }
102
103 // Returns the card to be refined or NULL.
115 // being in the cache.
116 void drain(G1CardTableEntryClosure* cl, uint worker_id);
117
118 // Set up for parallel processing of the cards in the hot cache
119 void reset_hot_cache_claimed_index() {
120 _hot_cache_par_claimed_idx = 0;
121 }
122
123 // Resets the hot card cache and discards the entries.
124 void reset_hot_cache() {
125 assert(SafepointSynchronize::is_at_safepoint(), "Should be at a safepoint");
126 assert(Thread::current()->is_VM_thread(), "Current thread should be the VMthread");
127 if (default_use_cache()) {
128 reset_hot_cache_internal();
129 }
130 }
131
132 // Zeros the values in the card counts table for the given region
133 void reset_card_counts(HeapRegion* hr);
134
135 private:
136 void reset_hot_cache_internal() {
137 assert(_hot_cache != NULL, "Logic");
138 _hot_cache_idx = 0;
139 for (size_t i = 0; i < _hot_cache_size; i++) {
140 _hot_cache[i] = NULL;
141 }
142 }
143 };
144
145 #endif // SHARE_GC_G1_G1HOTCARDCACHE_HPP
|
64
65
66 // The card cache table
67 CardValue** _hot_cache;
68
69 size_t _hot_cache_size;
70
71 size_t _hot_cache_par_chunk_size;
72
73 // Avoids false sharing when concurrently updating _hot_cache_idx or
74 // _hot_cache_par_claimed_idx. These are never updated at the same time
75 // thus it's not necessary to separate them as well
76 char _pad_before[DEFAULT_CACHE_LINE_SIZE];
77
78 volatile size_t _hot_cache_idx;
79
80 volatile size_t _hot_cache_par_claimed_idx;
81
82 char _pad_after[DEFAULT_CACHE_LINE_SIZE];
83
84 // Records whether insertion overflowed the hot card cache at least once. This
85 // avoids the need for a separate atomic counter of how many valid entries are
86 // in the HCC.
87 volatile bool _cache_wrapped_around;
88
89 // The number of cached cards a thread claims when flushing the cache
90 static const int ClaimChunkSize = 32;
91
92 public:
93 static bool default_use_cache() {
94 return (G1ConcRSLogCacheSize > 0);
95 }
96
97 G1HotCardCache(G1CollectedHeap* g1h);
98 ~G1HotCardCache();
99
100 void initialize(G1RegionToSpaceMapper* card_counts_storage);
101
102 bool use_cache() { return _use_cache; }
103
104 void set_use_cache(bool b) {
105 _use_cache = (b ? default_use_cache() : false);
106 }
107
108 // Returns the card to be refined or NULL.
120 // being in the cache.
121 void drain(G1CardTableEntryClosure* cl, uint worker_id);
122
123 // Set up for parallel processing of the cards in the hot cache
124 void reset_hot_cache_claimed_index() {
125 _hot_cache_par_claimed_idx = 0;
126 }
127
128 // Resets the hot card cache and discards the entries.
129 void reset_hot_cache() {
130 assert(SafepointSynchronize::is_at_safepoint(), "Should be at a safepoint");
131 assert(Thread::current()->is_VM_thread(), "Current thread should be the VMthread");
132 if (default_use_cache()) {
133 reset_hot_cache_internal();
134 }
135 }
136
137 // Zeros the values in the card counts table for the given region
138 void reset_card_counts(HeapRegion* hr);
139
140 // Number of entries in the HCC.
141 size_t num_entries() const {
142 return _cache_wrapped_around ? _hot_cache_size : _hot_cache_idx + 1;
143 }
144 private:
145 void reset_hot_cache_internal() {
146 assert(_hot_cache != NULL, "Logic");
147 _hot_cache_idx = 0;
148 for (size_t i = 0; i < _hot_cache_size; i++) {
149 _hot_cache[i] = NULL;
150 }
151 _cache_wrapped_around = false;
152 }
153 };
154
155 #endif // SHARE_GC_G1_G1HOTCARDCACHE_HPP
|