59 int _yellow_zone; |
61 int _yellow_zone; |
60 int _red_zone; |
62 int _red_zone; |
61 |
63 |
62 int _thread_threshold_step; |
64 int _thread_threshold_step; |
63 |
65 |
|
66 // We delay the refinement of 'hot' cards using the hot card cache. |
|
67 G1HotCardCache _hot_card_cache; |
|
68 |
64 // Reset the threshold step value based of the current zone boundaries. |
69 // Reset the threshold step value based of the current zone boundaries. |
65 void reset_threshold_step(); |
70 void reset_threshold_step(); |
66 |
71 |
67 // The cache for card refinement. |
|
68 bool _use_cache; |
|
69 bool _def_use_cache; |
|
70 |
|
71 size_t _n_periods; // Used as clearing epoch |
|
72 |
|
73 // An evicting cache of the number of times each card |
|
74 // is accessed. Reduces, but does not eliminate, the amount |
|
75 // of duplicated processing of dirty cards. |
|
76 |
|
77 enum SomePrivateConstants { |
|
78 epoch_bits = 32, |
|
79 card_num_shift = epoch_bits, |
|
80 epoch_mask = AllBits, |
|
81 card_num_mask = AllBits, |
|
82 |
|
83 // The initial cache size is approximately this fraction |
|
84 // of a maximal cache (i.e. the size needed for all cards |
|
85 // in the heap) |
|
86 InitialCacheFraction = 512 |
|
87 }; |
|
88 |
|
89 const static julong card_num_mask_in_place = |
|
90 (julong) card_num_mask << card_num_shift; |
|
91 |
|
92 typedef struct { |
|
93 julong _value; // | card_num | epoch | |
|
94 } CardEpochCacheEntry; |
|
95 |
|
96 julong make_epoch_entry(unsigned int card_num, unsigned int epoch) { |
|
97 assert(0 <= card_num && card_num < _max_cards, "Bounds"); |
|
98 assert(0 <= epoch && epoch <= _n_periods, "must be"); |
|
99 |
|
100 return ((julong) card_num << card_num_shift) | epoch; |
|
101 } |
|
102 |
|
103 unsigned int extract_epoch(julong v) { |
|
104 return (v & epoch_mask); |
|
105 } |
|
106 |
|
107 unsigned int extract_card_num(julong v) { |
|
108 return (v & card_num_mask_in_place) >> card_num_shift; |
|
109 } |
|
110 |
|
111 typedef struct { |
|
112 unsigned char _count; |
|
113 unsigned char _evict_count; |
|
114 } CardCountCacheEntry; |
|
115 |
|
116 CardCountCacheEntry* _card_counts; |
|
117 CardEpochCacheEntry* _card_epochs; |
|
118 |
|
119 // The current number of buckets in the card count cache |
|
120 size_t _n_card_counts; |
|
121 |
|
122 // The number of cards for the entire reserved heap |
|
123 size_t _max_cards; |
|
124 |
|
125 // The max number of buckets for the card counts and epochs caches. |
|
126 // This is the maximum that the counts and epochs will grow to. |
|
127 // It is specified as a fraction or percentage of _max_cards using |
|
128 // G1MaxHotCardCountSizePercent. |
|
129 size_t _max_n_card_counts; |
|
130 |
|
131 // Possible sizes of the cache: odd primes that roughly double in size. |
|
132 // (See jvmtiTagMap.cpp). |
|
133 enum { |
|
134 MAX_CC_CACHE_INDEX = 15 // maximum index into the cache size array. |
|
135 }; |
|
136 |
|
137 static size_t _cc_cache_sizes[MAX_CC_CACHE_INDEX]; |
|
138 |
|
139 // The index in _cc_cache_sizes corresponding to the size of |
|
140 // _card_counts. |
|
141 int _cache_size_index; |
|
142 |
|
143 bool _expand_card_counts; |
|
144 |
|
145 const jbyte* _ct_bot; |
|
146 |
|
147 jbyte** _hot_cache; |
|
148 int _hot_cache_size; |
|
149 int _n_hot; |
|
150 int _hot_cache_idx; |
|
151 |
|
152 int _hot_cache_par_chunk_size; |
|
153 volatile int _hot_cache_par_claimed_idx; |
|
154 |
|
155 // Needed to workaround 6817995 |
|
156 CardTableModRefBS* _ct_bs; |
|
157 G1CollectedHeap* _g1h; |
|
158 |
|
159 // Helper routine for expand_card_count_cache(). |
|
160 // The arrays used to hold the card counts and the epochs must have |
|
161 // a 1:1 correspondence. Hence they are allocated and freed together. |
|
162 // Returns true if the allocations of both the counts and epochs |
|
163 // were successful; false otherwise. |
|
164 bool allocate_card_count_cache(size_t n, |
|
165 CardCountCacheEntry** counts, |
|
166 CardEpochCacheEntry** epochs); |
|
167 |
|
168 // Expands the arrays that hold the card counts and epochs |
|
169 // to the cache size at index. Returns true if the expansion/ |
|
170 // allocation was successful; false otherwise. |
|
171 bool expand_card_count_cache(int index); |
|
172 |
|
173 // hash a given key (index of card_ptr) with the specified size |
|
174 static unsigned int hash(size_t key, size_t size) { |
|
175 return (unsigned int) (key % size); |
|
176 } |
|
177 |
|
178 // hash a given key (index of card_ptr) |
|
179 unsigned int hash(size_t key) { |
|
180 return hash(key, _n_card_counts); |
|
181 } |
|
182 |
|
183 unsigned int ptr_2_card_num(jbyte* card_ptr) { |
|
184 return (unsigned int) (card_ptr - _ct_bot); |
|
185 } |
|
186 |
|
187 jbyte* card_num_2_ptr(unsigned int card_num) { |
|
188 return (jbyte*) (_ct_bot + card_num); |
|
189 } |
|
190 |
|
191 // Returns the count of this card after incrementing it. |
|
192 jbyte* add_card_count(jbyte* card_ptr, int* count, bool* defer); |
|
193 |
|
194 // Returns true if this card is in a young region |
|
195 bool is_young_card(jbyte* card_ptr); |
|
196 |
|
197 public: |
72 public: |
198 ConcurrentG1Refine(); |
73 ConcurrentG1Refine(G1CollectedHeap* g1h); |
199 ~ConcurrentG1Refine(); |
74 ~ConcurrentG1Refine(); |
200 |
75 |
201 void init(); // Accomplish some initialization that has to wait. |
76 void init(); // Accomplish some initialization that has to wait. |
202 void stop(); |
77 void stop(); |
203 |
78 |
204 void reinitialize_threads(); |
79 void reinitialize_threads(); |
205 |
80 |
206 // Iterate over the conc refine threads |
81 // Iterate over the conc refine threads |
207 void threads_do(ThreadClosure *tc); |
82 void threads_do(ThreadClosure *tc); |
208 |
|
209 // If this is the first entry for the slot, writes into the cache and |
|
210 // returns NULL. If it causes an eviction, returns the evicted pointer. |
|
211 // Otherwise, its a cache hit, and returns NULL. |
|
212 jbyte* cache_insert(jbyte* card_ptr, bool* defer); |
|
213 |
|
214 // Process the cached entries. |
|
215 void clean_up_cache(int worker_i, G1RemSet* g1rs, DirtyCardQueue* into_cset_dcq); |
|
216 |
|
217 // Set up for parallel processing of the cards in the hot cache |
|
218 void clear_hot_cache_claimed_index() { |
|
219 _hot_cache_par_claimed_idx = 0; |
|
220 } |
|
221 |
|
222 // Discard entries in the hot cache. |
|
223 void clear_hot_cache() { |
|
224 _hot_cache_idx = 0; _n_hot = 0; |
|
225 } |
|
226 |
|
227 bool hot_cache_is_empty() { return _n_hot == 0; } |
|
228 |
|
229 bool use_cache() { return _use_cache; } |
|
230 void set_use_cache(bool b) { |
|
231 if (b) _use_cache = _def_use_cache; |
|
232 else _use_cache = false; |
|
233 } |
|
234 |
|
235 void clear_and_record_card_counts(); |
|
236 |
83 |
237 static int thread_num(); |
84 static int thread_num(); |
238 |
85 |
239 void print_worker_threads_on(outputStream* st) const; |
86 void print_worker_threads_on(outputStream* st) const; |
240 |
87 |