28 |
28 |
29 #ifdef ASSERT |
29 #ifdef ASSERT |
30 int CollectedHeap::_fire_out_of_memory_count = 0; |
30 int CollectedHeap::_fire_out_of_memory_count = 0; |
31 #endif |
31 #endif |
32 |
32 |
|
33 size_t CollectedHeap::_filler_array_max_size = 0; |
|
34 |
33 // Memory state functions. |
35 // Memory state functions. |
34 |
36 |
35 CollectedHeap::CollectedHeap() : |
37 CollectedHeap::CollectedHeap() |
36 _reserved(), _barrier_set(NULL), _is_gc_active(false), |
38 { |
37 _total_collections(0), _total_full_collections(0), |
39 const size_t max_len = size_t(arrayOopDesc::max_array_length(T_INT)); |
38 _gc_cause(GCCause::_no_gc), _gc_lastcause(GCCause::_no_gc) { |
40 const size_t elements_per_word = HeapWordSize / sizeof(jint); |
|
41 _filler_array_max_size = align_object_size(filler_array_hdr_size() + |
|
42 max_len * elements_per_word); |
|
43 |
|
44 _barrier_set = NULL; |
|
45 _is_gc_active = false; |
|
46 _total_collections = _total_full_collections = 0; |
|
47 _gc_cause = _gc_lastcause = GCCause::_no_gc; |
39 NOT_PRODUCT(_promotion_failure_alot_count = 0;) |
48 NOT_PRODUCT(_promotion_failure_alot_count = 0;) |
40 NOT_PRODUCT(_promotion_failure_alot_gc_number = 0;) |
49 NOT_PRODUCT(_promotion_failure_alot_gc_number = 0;) |
41 |
50 |
42 if (UsePerfData) { |
51 if (UsePerfData) { |
43 EXCEPTION_MARK; |
52 EXCEPTION_MARK; |
126 } |
135 } |
127 thread->tlab().fill(obj, obj + size, new_tlab_size); |
136 thread->tlab().fill(obj, obj + size, new_tlab_size); |
128 return obj; |
137 return obj; |
129 } |
138 } |
130 |
139 |
|
140 size_t CollectedHeap::filler_array_hdr_size() { |
|
141 return size_t(arrayOopDesc::header_size(T_INT)); |
|
142 } |
|
143 |
|
144 size_t CollectedHeap::filler_array_min_size() { |
|
145 return align_object_size(filler_array_hdr_size()); |
|
146 } |
|
147 |
|
148 size_t CollectedHeap::filler_array_max_size() { |
|
149 return _filler_array_max_size; |
|
150 } |
|
151 |
|
152 #ifdef ASSERT |
|
153 void CollectedHeap::fill_args_check(HeapWord* start, size_t words) |
|
154 { |
|
155 assert(words >= min_fill_size(), "too small to fill"); |
|
156 assert(words % MinObjAlignment == 0, "unaligned size"); |
|
157 assert(Universe::heap()->is_in_reserved(start), "not in heap"); |
|
158 assert(Universe::heap()->is_in_reserved(start + words - 1), "not in heap"); |
|
159 } |
|
160 |
|
161 void CollectedHeap::zap_filler_array(HeapWord* start, size_t words) |
|
162 { |
|
163 if (ZapFillerObjects) { |
|
164 Copy::fill_to_words(start + filler_array_hdr_size(), |
|
165 words - filler_array_hdr_size(), 0XDEAFBABE); |
|
166 } |
|
167 } |
|
168 #endif // ASSERT |
|
169 |
|
170 void |
|
171 CollectedHeap::fill_with_array(HeapWord* start, size_t words) |
|
172 { |
|
173 assert(words >= filler_array_min_size(), "too small for an array"); |
|
174 assert(words <= filler_array_max_size(), "too big for a single object"); |
|
175 |
|
176 const size_t payload_size = words - filler_array_hdr_size(); |
|
177 const size_t len = payload_size * HeapWordSize / sizeof(jint); |
|
178 |
|
179 // Set the length first for concurrent GC. |
|
180 ((arrayOop)start)->set_length((int)len); |
|
181 post_allocation_setup_common(Universe::fillerArrayKlassObj(), start, |
|
182 words); |
|
183 DEBUG_ONLY(zap_filler_array(start, words);) |
|
184 } |
|
185 |
|
186 void |
|
187 CollectedHeap::fill_with_object_impl(HeapWord* start, size_t words) |
|
188 { |
|
189 assert(words <= filler_array_max_size(), "too big for a single object"); |
|
190 |
|
191 if (words >= filler_array_min_size()) { |
|
192 fill_with_array(start, words); |
|
193 } else if (words > 0) { |
|
194 assert(words == min_fill_size(), "unaligned size"); |
|
195 post_allocation_setup_common(SystemDictionary::object_klass(), start, |
|
196 words); |
|
197 } |
|
198 } |
|
199 |
|
200 void CollectedHeap::fill_with_object(HeapWord* start, size_t words) |
|
201 { |
|
202 DEBUG_ONLY(fill_args_check(start, words);) |
|
203 HandleMark hm; // Free handles before leaving. |
|
204 fill_with_object_impl(start, words); |
|
205 } |
|
206 |
|
207 void CollectedHeap::fill_with_objects(HeapWord* start, size_t words) |
|
208 { |
|
209 DEBUG_ONLY(fill_args_check(start, words);) |
|
210 HandleMark hm; // Free handles before leaving. |
|
211 |
|
212 #ifdef LP64 |
|
213 // A single array can fill ~8G, so multiple objects are needed only in 64-bit. |
|
214 // First fill with arrays, ensuring that any remaining space is big enough to |
|
215 // fill. The remainder is filled with a single object. |
|
216 const size_t min = min_fill_size(); |
|
217 const size_t max = filler_array_max_size(); |
|
218 while (words > max) { |
|
219 const size_t cur = words - max >= min ? max : max - min; |
|
220 fill_with_array(start, cur); |
|
221 start += cur; |
|
222 words -= cur; |
|
223 } |
|
224 #endif |
|
225 |
|
226 fill_with_object_impl(start, words); |
|
227 } |
|
228 |
131 oop CollectedHeap::new_store_barrier(oop new_obj) { |
229 oop CollectedHeap::new_store_barrier(oop new_obj) { |
132 // %%% This needs refactoring. (It was imported from the server compiler.) |
230 // %%% This needs refactoring. (It was imported from the server compiler.) |
133 guarantee(can_elide_tlab_store_barriers(), "store barrier elision not supported"); |
231 guarantee(can_elide_tlab_store_barriers(), "store barrier elision not supported"); |
134 BarrierSet* bs = this->barrier_set(); |
232 BarrierSet* bs = this->barrier_set(); |
135 assert(bs->has_write_region_opt(), "Barrier set does not have write_region"); |
233 assert(bs->has_write_region_opt(), "Barrier set does not have write_region"); |