97 } |
97 } |
98 // Return a youngergen_card_value that is not currently in use. |
98 // Return a youngergen_card_value that is not currently in use. |
99 jbyte find_unused_youngergenP_card_value(); |
99 jbyte find_unused_youngergenP_card_value(); |
100 |
100 |
101 public: |
101 public: |
102 CardTableRS(MemRegion whole_heap); |
102 CardTableRS(MemRegion whole_heap, bool scanned_concurrently); |
103 ~CardTableRS(); |
103 ~CardTableRS(); |
104 |
104 |
105 CLDRemSet* cld_rem_set() { return &_cld_rem_set; } |
105 CLDRemSet* cld_rem_set() { return &_cld_rem_set; } |
106 |
106 |
107 void younger_refs_in_space_iterate(Space* sp, OopsInGenClosure* cl, uint n_threads); |
107 void younger_refs_in_space_iterate(Space* sp, OopsInGenClosure* cl, uint n_threads); |
|
108 |
|
109 virtual void verify_used_region_at_save_marks(Space* sp) const NOT_DEBUG_RETURN; |
108 |
110 |
109 // Override. |
111 // Override. |
110 void prepare_for_younger_refs_iterate(bool parallel); |
112 void prepare_for_younger_refs_iterate(bool parallel); |
111 |
113 |
112 // Card table entries are cleared before application; "blk" is |
114 // Card table entries are cleared before application; "blk" is |
172 OopsInGenClosure* cl, CardTableRS* ct, |
174 OopsInGenClosure* cl, CardTableRS* ct, |
173 uint n_threads); |
175 uint n_threads); |
174 |
176 |
175 // Work method used to implement non_clean_card_iterate_possibly_parallel() |
177 // Work method used to implement non_clean_card_iterate_possibly_parallel() |
176 // above in the parallel case. |
178 // above in the parallel case. |
177 void non_clean_card_iterate_parallel_work(Space* sp, MemRegion mr, |
179 virtual void non_clean_card_iterate_parallel_work(Space* sp, MemRegion mr, |
178 OopsInGenClosure* cl, CardTableRS* ct, |
180 OopsInGenClosure* cl, CardTableRS* ct, |
179 uint n_threads); |
181 uint n_threads); |
180 |
182 |
181 // This is an array, one element per covered region of the card table. |
183 // This is an array, one element per covered region of the card table. |
182 // Each entry is itself an array, with one element per chunk in the |
184 // Each entry is itself an array, with one element per chunk in the |
183 // covered region. Each entry of these arrays is the lowest non-clean |
185 // covered region. Each entry of these arrays is the lowest non-clean |
184 // card of the corresponding chunk containing part of an object from the |
186 // card of the corresponding chunk containing part of an object from the |
188 CardArr* _lowest_non_clean; |
190 CardArr* _lowest_non_clean; |
189 size_t* _lowest_non_clean_chunk_size; |
191 size_t* _lowest_non_clean_chunk_size; |
190 uintptr_t* _lowest_non_clean_base_chunk_index; |
192 uintptr_t* _lowest_non_clean_base_chunk_index; |
191 volatile int* _last_LNC_resizing_collection; |
193 volatile int* _last_LNC_resizing_collection; |
192 |
194 |
193 // Initializes "lowest_non_clean" to point to the array for the region |
|
194 // covering "sp", and "lowest_non_clean_base_chunk_index" to the chunk |
|
195 // index of the corresponding to the first element of that array. |
|
196 // Ensures that these arrays are of sufficient size, allocating if necessary. |
|
197 // May be called by several threads concurrently. |
|
198 void get_LNC_array_for_space(Space* sp, |
|
199 jbyte**& lowest_non_clean, |
|
200 uintptr_t& lowest_non_clean_base_chunk_index, |
|
201 size_t& lowest_non_clean_chunk_size); |
|
202 |
|
203 // Returns the number of chunks necessary to cover "mr". |
|
204 size_t chunks_to_cover(MemRegion mr) { |
|
205 return (size_t)(addr_to_chunk_index(mr.last()) - |
|
206 addr_to_chunk_index(mr.start()) + 1); |
|
207 } |
|
208 |
|
209 // Returns the index of the chunk in a stride which |
|
210 // covers the given address. |
|
211 uintptr_t addr_to_chunk_index(const void* addr) { |
|
212 uintptr_t card = (uintptr_t) byte_for(addr); |
|
213 return card / ParGCCardsPerStrideChunk; |
|
214 } |
|
215 |
|
216 // Apply cl, which must either itself apply dcto_cl or be dcto_cl, |
|
217 // to the cards in the stride (of n_strides) within the given space. |
|
218 void process_stride(Space* sp, |
|
219 MemRegion used, |
|
220 jint stride, int n_strides, |
|
221 OopsInGenClosure* cl, |
|
222 CardTableRS* ct, |
|
223 jbyte** lowest_non_clean, |
|
224 uintptr_t lowest_non_clean_base_chunk_index, |
|
225 size_t lowest_non_clean_chunk_size); |
|
226 |
|
227 // Makes sure that chunk boundaries are handled appropriately, by |
|
228 // adjusting the min_done of dcto_cl, and by using a special card-table |
|
229 // value to indicate how min_done should be set. |
|
230 void process_chunk_boundaries(Space* sp, |
|
231 DirtyCardToOopClosure* dcto_cl, |
|
232 MemRegion chunk_mr, |
|
233 MemRegion used, |
|
234 jbyte** lowest_non_clean, |
|
235 uintptr_t lowest_non_clean_base_chunk_index, |
|
236 size_t lowest_non_clean_chunk_size); |
|
237 |
|
238 virtual bool is_in_young(oop obj) const; |
195 virtual bool is_in_young(oop obj) const; |
239 |
|
240 }; |
196 }; |
241 |
197 |
242 class ClearNoncleanCardWrapper: public MemRegionClosure { |
198 class ClearNoncleanCardWrapper: public MemRegionClosure { |
243 DirtyCardToOopClosure* _dirty_card_closure; |
199 DirtyCardToOopClosure* _dirty_card_closure; |
244 CardTableRS* _ct; |
200 CardTableRS* _ct; |