84 |
84 |
85 void ShenandoahAssertToSpaceClosure::do_oop(narrowOop* p) { do_oop_work(p); } |
85 void ShenandoahAssertToSpaceClosure::do_oop(narrowOop* p) { do_oop_work(p); } |
86 void ShenandoahAssertToSpaceClosure::do_oop(oop* p) { do_oop_work(p); } |
86 void ShenandoahAssertToSpaceClosure::do_oop(oop* p) { do_oop_work(p); } |
87 #endif |
87 #endif |
88 |
88 |
89 class ShenandoahPretouchTask : public AbstractGangTask { |
89 class ShenandoahPretouchHeapTask : public AbstractGangTask { |
|
90 private: |
|
91 ShenandoahRegionIterator _regions; |
|
92 const size_t _page_size; |
|
93 public: |
|
94 ShenandoahPretouchHeapTask(size_t page_size) : |
|
95 AbstractGangTask("Shenandoah Pretouch Heap"), |
|
96 _page_size(page_size) {} |
|
97 |
|
98 virtual void work(uint worker_id) { |
|
99 ShenandoahHeapRegion* r = _regions.next(); |
|
100 while (r != NULL) { |
|
101 os::pretouch_memory(r->bottom(), r->end(), _page_size); |
|
102 r = _regions.next(); |
|
103 } |
|
104 } |
|
105 }; |
|
106 |
|
107 class ShenandoahPretouchBitmapTask : public AbstractGangTask { |
90 private: |
108 private: |
91 ShenandoahRegionIterator _regions; |
109 ShenandoahRegionIterator _regions; |
92 char* _bitmap_base; |
110 char* _bitmap_base; |
93 const size_t _bitmap_size; |
111 const size_t _bitmap_size; |
94 const size_t _heap_page_size; |
112 const size_t _page_size; |
95 const size_t _bitmap_page_size; |
|
96 public: |
113 public: |
97 ShenandoahPretouchTask(char* bitmap_base, size_t bitmap_size, size_t heap_page_size, size_t bitmap_page_size) : |
114 ShenandoahPretouchBitmapTask(char* bitmap_base, size_t bitmap_size, size_t page_size) : |
98 AbstractGangTask("Shenandoah PreTouch"), |
115 AbstractGangTask("Shenandoah Pretouch Bitmap"), |
99 _bitmap_base(bitmap_base), |
116 _bitmap_base(bitmap_base), |
100 _bitmap_size(bitmap_size), |
117 _bitmap_size(bitmap_size), |
101 _heap_page_size(heap_page_size), |
118 _page_size(page_size) {} |
102 _bitmap_page_size(bitmap_page_size) {} |
|
103 |
119 |
104 virtual void work(uint worker_id) { |
120 virtual void work(uint worker_id) { |
105 ShenandoahHeapRegion* r = _regions.next(); |
121 ShenandoahHeapRegion* r = _regions.next(); |
106 while (r != NULL) { |
122 while (r != NULL) { |
107 os::pretouch_memory(r->bottom(), r->end(), _heap_page_size); |
|
108 |
|
109 size_t start = r->region_number() * ShenandoahHeapRegion::region_size_bytes() / MarkBitMap::heap_map_factor(); |
123 size_t start = r->region_number() * ShenandoahHeapRegion::region_size_bytes() / MarkBitMap::heap_map_factor(); |
110 size_t end = (r->region_number() + 1) * ShenandoahHeapRegion::region_size_bytes() / MarkBitMap::heap_map_factor(); |
124 size_t end = (r->region_number() + 1) * ShenandoahHeapRegion::region_size_bytes() / MarkBitMap::heap_map_factor(); |
111 assert (end <= _bitmap_size, "end is sane: " SIZE_FORMAT " < " SIZE_FORMAT, end, _bitmap_size); |
125 assert (end <= _bitmap_size, "end is sane: " SIZE_FORMAT " < " SIZE_FORMAT, end, _bitmap_size); |
112 |
126 |
113 os::pretouch_memory(_bitmap_base + start, _bitmap_base + end, _bitmap_page_size); |
127 os::pretouch_memory(_bitmap_base + start, _bitmap_base + end, _page_size); |
114 |
128 |
115 r = _regions.next(); |
129 r = _regions.next(); |
116 } |
130 } |
117 } |
131 } |
118 }; |
132 }; |
162 |
176 |
163 assert((((size_t) base()) & ShenandoahHeapRegion::region_size_bytes_mask()) == 0, |
177 assert((((size_t) base()) & ShenandoahHeapRegion::region_size_bytes_mask()) == 0, |
164 "Misaligned heap: " PTR_FORMAT, p2i(base())); |
178 "Misaligned heap: " PTR_FORMAT, p2i(base())); |
165 |
179 |
166 ReservedSpace sh_rs = heap_rs.first_part(max_byte_size); |
180 ReservedSpace sh_rs = heap_rs.first_part(max_byte_size); |
167 os::commit_memory_or_exit(sh_rs.base(), _initial_size, false, |
181 os::commit_memory_or_exit(sh_rs.base(), _initial_size, heap_alignment, false, |
168 "Cannot commit heap memory"); |
182 "Cannot commit heap memory"); |
169 |
183 |
170 // |
184 // |
171 // Reserve and commit memory for bitmap(s) |
185 // Reserve and commit memory for bitmap(s) |
172 // |
186 // |
202 _bitmap_region = MemRegion((HeapWord*) bitmap.base(), bitmap.size() / HeapWordSize); |
216 _bitmap_region = MemRegion((HeapWord*) bitmap.base(), bitmap.size() / HeapWordSize); |
203 |
217 |
204 size_t bitmap_init_commit = _bitmap_bytes_per_slice * |
218 size_t bitmap_init_commit = _bitmap_bytes_per_slice * |
205 align_up(num_committed_regions, _bitmap_regions_per_slice) / _bitmap_regions_per_slice; |
219 align_up(num_committed_regions, _bitmap_regions_per_slice) / _bitmap_regions_per_slice; |
206 bitmap_init_commit = MIN2(_bitmap_size, bitmap_init_commit); |
220 bitmap_init_commit = MIN2(_bitmap_size, bitmap_init_commit); |
207 os::commit_memory_or_exit((char *)_bitmap_region.start(), bitmap_init_commit, false, |
221 os::commit_memory_or_exit((char *)_bitmap_region.start(), bitmap_init_commit, bitmap_page_size, false, |
208 "Cannot commit bitmap memory"); |
222 "Cannot commit bitmap memory"); |
209 |
223 |
210 _marking_context = new ShenandoahMarkingContext(_heap_region, _bitmap_region, _num_regions); |
224 _marking_context = new ShenandoahMarkingContext(_heap_region, _bitmap_region, _num_regions); |
211 |
225 |
212 if (ShenandoahVerify) { |
226 if (ShenandoahVerify) { |
213 ReservedSpace verify_bitmap(_bitmap_size, bitmap_page_size); |
227 ReservedSpace verify_bitmap(_bitmap_size, bitmap_page_size); |
214 os::commit_memory_or_exit(verify_bitmap.base(), verify_bitmap.size(), false, |
228 os::commit_memory_or_exit(verify_bitmap.base(), verify_bitmap.size(), bitmap_page_size, false, |
215 "Cannot commit verification bitmap memory"); |
229 "Cannot commit verification bitmap memory"); |
216 MemTracker::record_virtual_memory_type(verify_bitmap.base(), mtGC); |
230 MemTracker::record_virtual_memory_type(verify_bitmap.base(), mtGC); |
217 MemRegion verify_bitmap_region = MemRegion((HeapWord *) verify_bitmap.base(), verify_bitmap.size() / HeapWordSize); |
231 MemRegion verify_bitmap_region = MemRegion((HeapWord *) verify_bitmap.base(), verify_bitmap.size() / HeapWordSize); |
218 _verification_bit_map.initialize(_heap_region, verify_bitmap_region); |
232 _verification_bit_map.initialize(_heap_region, verify_bitmap_region); |
219 _verifier = new ShenandoahVerifier(this, &_verification_bit_map); |
233 _verifier = new ShenandoahVerifier(this, &_verification_bit_map); |
260 // For NUMA, it is important to pre-touch the storage under bitmaps with worker threads, |
274 // For NUMA, it is important to pre-touch the storage under bitmaps with worker threads, |
261 // before initialize() below zeroes it with initializing thread. For any given region, |
275 // before initialize() below zeroes it with initializing thread. For any given region, |
262 // we touch the region and the corresponding bitmaps from the same thread. |
276 // we touch the region and the corresponding bitmaps from the same thread. |
263 ShenandoahPushWorkerScope scope(workers(), _max_workers, false); |
277 ShenandoahPushWorkerScope scope(workers(), _max_workers, false); |
264 |
278 |
265 log_info(gc, init)("Pretouch " SIZE_FORMAT " regions; page sizes: " SIZE_FORMAT " heap, " SIZE_FORMAT " bitmap", |
279 size_t pretouch_heap_page_size = heap_page_size; |
266 _num_regions, heap_page_size, bitmap_page_size); |
280 size_t pretouch_bitmap_page_size = bitmap_page_size; |
267 ShenandoahPretouchTask cl(bitmap.base(), _bitmap_size, heap_page_size, bitmap_page_size); |
281 |
268 _workers->run_task(&cl); |
282 #ifdef LINUX |
|
283 // UseTransparentHugePages would madvise that backing memory can be coalesced into huge |
|
284 // pages. But, the kernel needs to know that every small page is used, in order to coalesce |
|
285 // them into huge one. Therefore, we need to pretouch with smaller pages. |
|
286 if (UseTransparentHugePages) { |
|
287 pretouch_heap_page_size = (size_t)os::vm_page_size(); |
|
288 pretouch_bitmap_page_size = (size_t)os::vm_page_size(); |
|
289 } |
|
290 #endif |
|
291 |
|
292 // OS memory managers may want to coalesce back-to-back pages. Make their jobs |
|
293 // simpler by pre-touching continuous spaces (heap and bitmap) separately. |
|
294 |
|
295 log_info(gc, init)("Pretouch bitmap: " SIZE_FORMAT " regions, " SIZE_FORMAT " bytes page", |
|
296 _num_regions, pretouch_bitmap_page_size); |
|
297 ShenandoahPretouchBitmapTask bcl(bitmap.base(), _bitmap_size, pretouch_bitmap_page_size); |
|
298 _workers->run_task(&bcl); |
|
299 |
|
300 log_info(gc, init)("Pretouch heap: " SIZE_FORMAT " regions, " SIZE_FORMAT " bytes page", |
|
301 _num_regions, pretouch_heap_page_size); |
|
302 ShenandoahPretouchHeapTask hcl(pretouch_heap_page_size); |
|
303 _workers->run_task(&hcl); |
269 } |
304 } |
270 |
305 |
271 // |
306 // |
272 // Initialize the rest of GC subsystems |
307 // Initialize the rest of GC subsystems |
273 // |
308 // |