82
83 // Number of generations, plus one for lingering PermGen issues in CardTableRS.
84 static const int _regions_to_iterate = 3;
85
86 jbyte cur_youngergen_card_val() {
87 return _cur_youngergen_card_val;
88 }
89 void set_cur_youngergen_card_val(jbyte v) {
90 _cur_youngergen_card_val = v;
91 }
92 bool is_prev_youngergen_card_val(jbyte v) {
93 return
94 youngergen_card <= v &&
95 v < cur_youngergen_and_prev_nonclean_card &&
96 v != _cur_youngergen_card_val;
97 }
98 // Return a youngergen_card_value that is not currently in use.
99 jbyte find_unused_youngergenP_card_value();
100
101 public:
102 CardTableRS(MemRegion whole_heap);
103 ~CardTableRS();
104
105 CLDRemSet* cld_rem_set() { return &_cld_rem_set; }
106
107 void younger_refs_in_space_iterate(Space* sp, OopsInGenClosure* cl, uint n_threads);
108
109 // Override.
110 void prepare_for_younger_refs_iterate(bool parallel);
111
112 // Card table entries are cleared before application; "blk" is
113 // responsible for dirtying if the oop is still older-to-younger after
114 // closure application.
115 void younger_refs_iterate(Generation* g, OopsInGenClosure* blk, uint n_threads);
116
117 void inline_write_ref_field_gc(void* field, oop new_val) {
118 jbyte* byte = byte_for(field);
119 *byte = youngergen_card;
120 }
121 void write_ref_field_gc_work(void* field, oop new_val) {
122 inline_write_ref_field_gc(field, new_val);
123 }
124
125 // Override. Might want to devirtualize this in the same fashion as
126 // above. Ensures that the value of the card for field says that it's
127 // a younger card in the current collection.
128 virtual void write_ref_field_gc_par(void* field, oop new_val);
157 }
158
159 // Returns "true" iff the value "cv" will cause the card containing it
160 // to be scanned in the current traversal. May be overridden by
161 // subtypes.
162 bool card_will_be_scanned(jbyte cv);
163
164 // Returns "true" iff the value "cv" may have represented a dirty card at
165 // some point.
166 bool card_may_have_been_dirty(jbyte cv);
167
168 // Iterate over the portion of the card-table which covers the given
169 // region mr in the given space and apply cl to any dirty sub-regions
170 // of mr. Clears the dirty cards as they are processed.
171 void non_clean_card_iterate_possibly_parallel(Space* sp, MemRegion mr,
172 OopsInGenClosure* cl, CardTableRS* ct,
173 uint n_threads);
174
175 // Work method used to implement non_clean_card_iterate_possibly_parallel()
176 // above in the parallel case.
177 void non_clean_card_iterate_parallel_work(Space* sp, MemRegion mr,
178 OopsInGenClosure* cl, CardTableRS* ct,
179 uint n_threads);
180
181 // 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
183 // 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
185 // previous chunk, or else NULL.
186 typedef jbyte* CardPtr;
187 typedef CardPtr* CardArr;
188 CardArr* _lowest_non_clean;
189 size_t* _lowest_non_clean_chunk_size;
190 uintptr_t* _lowest_non_clean_base_chunk_index;
191 volatile int* _last_LNC_resizing_collection;
192
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;
239
240 };
241
242 class ClearNoncleanCardWrapper: public MemRegionClosure {
243 DirtyCardToOopClosure* _dirty_card_closure;
244 CardTableRS* _ct;
245 bool _is_par;
246 private:
247 // Clears the given card, return true if the corresponding card should be
248 // processed.
249 inline bool clear_card(jbyte* entry);
250 // Work methods called by the clear_card()
251 inline bool clear_card_serial(jbyte* entry);
252 inline bool clear_card_parallel(jbyte* entry);
253 // check alignment of pointer
254 bool is_word_aligned(jbyte* entry);
255
256 public:
257 ClearNoncleanCardWrapper(DirtyCardToOopClosure* dirty_card_closure, CardTableRS* ct, bool is_par);
258 void do_MemRegion(MemRegion mr);
259 };
|
82
83 // Number of generations, plus one for lingering PermGen issues in CardTableRS.
84 static const int _regions_to_iterate = 3;
85
86 jbyte cur_youngergen_card_val() {
87 return _cur_youngergen_card_val;
88 }
89 void set_cur_youngergen_card_val(jbyte v) {
90 _cur_youngergen_card_val = v;
91 }
92 bool is_prev_youngergen_card_val(jbyte v) {
93 return
94 youngergen_card <= v &&
95 v < cur_youngergen_and_prev_nonclean_card &&
96 v != _cur_youngergen_card_val;
97 }
98 // Return a youngergen_card_value that is not currently in use.
99 jbyte find_unused_youngergenP_card_value();
100
101 public:
102 CardTableRS(MemRegion whole_heap, bool scanned_concurrently);
103 ~CardTableRS();
104
105 CLDRemSet* cld_rem_set() { return &_cld_rem_set; }
106
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;
110
111 // Override.
112 void prepare_for_younger_refs_iterate(bool parallel);
113
114 // Card table entries are cleared before application; "blk" is
115 // responsible for dirtying if the oop is still older-to-younger after
116 // closure application.
117 void younger_refs_iterate(Generation* g, OopsInGenClosure* blk, uint n_threads);
118
119 void inline_write_ref_field_gc(void* field, oop new_val) {
120 jbyte* byte = byte_for(field);
121 *byte = youngergen_card;
122 }
123 void write_ref_field_gc_work(void* field, oop new_val) {
124 inline_write_ref_field_gc(field, new_val);
125 }
126
127 // Override. Might want to devirtualize this in the same fashion as
128 // above. Ensures that the value of the card for field says that it's
129 // a younger card in the current collection.
130 virtual void write_ref_field_gc_par(void* field, oop new_val);
159 }
160
161 // Returns "true" iff the value "cv" will cause the card containing it
162 // to be scanned in the current traversal. May be overridden by
163 // subtypes.
164 bool card_will_be_scanned(jbyte cv);
165
166 // Returns "true" iff the value "cv" may have represented a dirty card at
167 // some point.
168 bool card_may_have_been_dirty(jbyte cv);
169
170 // Iterate over the portion of the card-table which covers the given
171 // region mr in the given space and apply cl to any dirty sub-regions
172 // of mr. Clears the dirty cards as they are processed.
173 void non_clean_card_iterate_possibly_parallel(Space* sp, MemRegion mr,
174 OopsInGenClosure* cl, CardTableRS* ct,
175 uint n_threads);
176
177 // Work method used to implement non_clean_card_iterate_possibly_parallel()
178 // above in the parallel case.
179 virtual void non_clean_card_iterate_parallel_work(Space* sp, MemRegion mr,
180 OopsInGenClosure* cl, CardTableRS* ct,
181 uint n_threads);
182
183 // This is an array, one element per covered region of the card table.
184 // Each entry is itself an array, with one element per chunk in the
185 // covered region. Each entry of these arrays is the lowest non-clean
186 // card of the corresponding chunk containing part of an object from the
187 // previous chunk, or else NULL.
188 typedef jbyte* CardPtr;
189 typedef CardPtr* CardArr;
190 CardArr* _lowest_non_clean;
191 size_t* _lowest_non_clean_chunk_size;
192 uintptr_t* _lowest_non_clean_base_chunk_index;
193 volatile int* _last_LNC_resizing_collection;
194
195 virtual bool is_in_young(oop obj) const;
196 };
197
198 class ClearNoncleanCardWrapper: public MemRegionClosure {
199 DirtyCardToOopClosure* _dirty_card_closure;
200 CardTableRS* _ct;
201 bool _is_par;
202 private:
203 // Clears the given card, return true if the corresponding card should be
204 // processed.
205 inline bool clear_card(jbyte* entry);
206 // Work methods called by the clear_card()
207 inline bool clear_card_serial(jbyte* entry);
208 inline bool clear_card_parallel(jbyte* entry);
209 // check alignment of pointer
210 bool is_word_aligned(jbyte* entry);
211
212 public:
213 ClearNoncleanCardWrapper(DirtyCardToOopClosure* dirty_card_closure, CardTableRS* ct, bool is_par);
214 void do_MemRegion(MemRegion mr);
215 };
|