comparison src/share/vm/runtime/virtualspace.cpp @ 656:6bdd6923ba16

6541756: Reduce executable C-heap Summary: Add executable parameters to reserve_memory and commit_memory to reduce executable memory to only the Code Heap. Reviewed-by: xlu, kvn, acorn
author coleenp
date Wed, 25 Mar 2009 14:19:20 -0400
parents 660978a2a31a
children bd02caa94611
comparison
equal deleted inserted replaced
655:60bfce711da4 656:6bdd6923ba16
26 #include "incls/_virtualspace.cpp.incl" 26 #include "incls/_virtualspace.cpp.incl"
27 27
28 28
29 // ReservedSpace 29 // ReservedSpace
30 ReservedSpace::ReservedSpace(size_t size) { 30 ReservedSpace::ReservedSpace(size_t size) {
31 initialize(size, 0, false, NULL, 0); 31 initialize(size, 0, false, NULL, 0, false);
32 } 32 }
33 33
34 ReservedSpace::ReservedSpace(size_t size, size_t alignment, 34 ReservedSpace::ReservedSpace(size_t size, size_t alignment,
35 bool large, 35 bool large,
36 char* requested_address, 36 char* requested_address,
37 const size_t noaccess_prefix) { 37 const size_t noaccess_prefix) {
38 initialize(size+noaccess_prefix, alignment, large, requested_address, 38 initialize(size+noaccess_prefix, alignment, large, requested_address,
39 noaccess_prefix); 39 noaccess_prefix, false);
40 }
41
42 ReservedSpace::ReservedSpace(size_t size, size_t alignment,
43 bool large,
44 bool executable) {
45 initialize(size, alignment, large, NULL, 0, executable);
40 } 46 }
41 47
42 char * 48 char *
43 ReservedSpace::align_reserved_region(char* addr, const size_t len, 49 ReservedSpace::align_reserved_region(char* addr, const size_t len,
44 const size_t prefix_size, 50 const size_t prefix_size,
130 // On systems where the entire region has to be reserved and committed up 136 // On systems where the entire region has to be reserved and committed up
131 // front, the compound alignment normally done by this method is unnecessary. 137 // front, the compound alignment normally done by this method is unnecessary.
132 const bool try_reserve_special = UseLargePages && 138 const bool try_reserve_special = UseLargePages &&
133 prefix_align == os::large_page_size(); 139 prefix_align == os::large_page_size();
134 if (!os::can_commit_large_page_memory() && try_reserve_special) { 140 if (!os::can_commit_large_page_memory() && try_reserve_special) {
135 initialize(size, prefix_align, true, requested_address, noaccess_prefix); 141 initialize(size, prefix_align, true, requested_address, noaccess_prefix,
142 false);
136 return; 143 return;
137 } 144 }
138 145
139 _base = NULL; 146 _base = NULL;
140 _size = 0; 147 _size = 0;
141 _alignment = 0; 148 _alignment = 0;
142 _special = false; 149 _special = false;
143 _noaccess_prefix = 0; 150 _noaccess_prefix = 0;
151 _executable = false;
144 152
145 // Assert that if noaccess_prefix is used, it is the same as prefix_align. 153 // Assert that if noaccess_prefix is used, it is the same as prefix_align.
146 assert(noaccess_prefix == 0 || 154 assert(noaccess_prefix == 0 ||
147 noaccess_prefix == prefix_align, "noaccess prefix wrong"); 155 noaccess_prefix == prefix_align, "noaccess prefix wrong");
148 156
187 _noaccess_prefix = noaccess_prefix; 195 _noaccess_prefix = noaccess_prefix;
188 } 196 }
189 197
190 void ReservedSpace::initialize(size_t size, size_t alignment, bool large, 198 void ReservedSpace::initialize(size_t size, size_t alignment, bool large,
191 char* requested_address, 199 char* requested_address,
192 const size_t noaccess_prefix) { 200 const size_t noaccess_prefix,
201 bool executable) {
193 const size_t granularity = os::vm_allocation_granularity(); 202 const size_t granularity = os::vm_allocation_granularity();
194 assert((size & granularity - 1) == 0, 203 assert((size & granularity - 1) == 0,
195 "size not aligned to os::vm_allocation_granularity()"); 204 "size not aligned to os::vm_allocation_granularity()");
196 assert((alignment & granularity - 1) == 0, 205 assert((alignment & granularity - 1) == 0,
197 "alignment not aligned to os::vm_allocation_granularity()"); 206 "alignment not aligned to os::vm_allocation_granularity()");
199 "not a power of 2"); 208 "not a power of 2");
200 209
201 _base = NULL; 210 _base = NULL;
202 _size = 0; 211 _size = 0;
203 _special = false; 212 _special = false;
213 _executable = executable;
204 _alignment = 0; 214 _alignment = 0;
205 _noaccess_prefix = 0; 215 _noaccess_prefix = 0;
206 if (size == 0) { 216 if (size == 0) {
207 return; 217 return;
208 } 218 }
212 bool special = large && !os::can_commit_large_page_memory(); 222 bool special = large && !os::can_commit_large_page_memory();
213 char* base = NULL; 223 char* base = NULL;
214 224
215 if (special) { 225 if (special) {
216 226
217 base = os::reserve_memory_special(size, requested_address); 227 base = os::reserve_memory_special(size, requested_address, executable);
218 228
219 if (base != NULL) { 229 if (base != NULL) {
220 // Check alignment constraints 230 // Check alignment constraints
221 if (alignment > 0) { 231 if (alignment > 0) {
222 assert((uintptr_t) base % alignment == 0, 232 assert((uintptr_t) base % alignment == 0,
282 "area must be distinguisable from marks for mark-sweep"); 292 "area must be distinguisable from marks for mark-sweep");
283 } 293 }
284 294
285 295
286 ReservedSpace::ReservedSpace(char* base, size_t size, size_t alignment, 296 ReservedSpace::ReservedSpace(char* base, size_t size, size_t alignment,
287 bool special) { 297 bool special, bool executable) {
288 assert((size % os::vm_allocation_granularity()) == 0, 298 assert((size % os::vm_allocation_granularity()) == 0,
289 "size not allocation aligned"); 299 "size not allocation aligned");
290 _base = base; 300 _base = base;
291 _size = size; 301 _size = size;
292 _alignment = alignment; 302 _alignment = alignment;
293 _noaccess_prefix = 0; 303 _noaccess_prefix = 0;
294 _special = special; 304 _special = special;
305 _executable = executable;
295 } 306 }
296 307
297 308
298 ReservedSpace ReservedSpace::first_part(size_t partition_size, size_t alignment, 309 ReservedSpace ReservedSpace::first_part(size_t partition_size, size_t alignment,
299 bool split, bool realloc) { 310 bool split, bool realloc) {
300 assert(partition_size <= size(), "partition failed"); 311 assert(partition_size <= size(), "partition failed");
301 if (split) { 312 if (split) {
302 os::split_reserved_memory(_base, _size, partition_size, realloc); 313 os::split_reserved_memory(base(), size(), partition_size, realloc);
303 } 314 }
304 ReservedSpace result(base(), partition_size, alignment, special()); 315 ReservedSpace result(base(), partition_size, alignment, special(),
316 executable());
305 return result; 317 return result;
306 } 318 }
307 319
308 320
309 ReservedSpace 321 ReservedSpace
310 ReservedSpace::last_part(size_t partition_size, size_t alignment) { 322 ReservedSpace::last_part(size_t partition_size, size_t alignment) {
311 assert(partition_size <= size(), "partition failed"); 323 assert(partition_size <= size(), "partition failed");
312 ReservedSpace result(base() + partition_size, size() - partition_size, 324 ReservedSpace result(base() + partition_size, size() - partition_size,
313 alignment, special()); 325 alignment, special(), executable());
314 return result; 326 return result;
315 } 327 }
316 328
317 329
318 size_t ReservedSpace::page_align_size_up(size_t size) { 330 size_t ReservedSpace::page_align_size_up(size_t size) {
346 } 358 }
347 _base = NULL; 359 _base = NULL;
348 _size = 0; 360 _size = 0;
349 _noaccess_prefix = 0; 361 _noaccess_prefix = 0;
350 _special = false; 362 _special = false;
363 _executable = false;
351 } 364 }
352 } 365 }
353 366
354 void ReservedSpace::protect_noaccess_prefix(const size_t size) { 367 void ReservedSpace::protect_noaccess_prefix(const size_t size) {
355 // If there is noaccess prefix, return. 368 // If there is noaccess prefix, return.
392 requested_address, 405 requested_address,
393 (UseCompressedOops && (Universe::narrow_oop_base() != NULL) && 406 (UseCompressedOops && (Universe::narrow_oop_base() != NULL) &&
394 Universe::narrow_oop_use_implicit_null_checks()) ? 407 Universe::narrow_oop_use_implicit_null_checks()) ?
395 lcm(os::vm_page_size(), prefix_align) : 0) { 408 lcm(os::vm_page_size(), prefix_align) : 0) {
396 protect_noaccess_prefix(prefix_size+suffix_size); 409 protect_noaccess_prefix(prefix_size+suffix_size);
410 }
411
412 // Reserve space for code segment. Same as Java heap only we mark this as
413 // executable.
414 ReservedCodeSpace::ReservedCodeSpace(size_t r_size,
415 size_t rs_align,
416 bool large) :
417 ReservedSpace(r_size, rs_align, large, /*executable*/ true) {
397 } 418 }
398 419
399 // VirtualSpace 420 // VirtualSpace
400 421
401 VirtualSpace::VirtualSpace() { 422 VirtualSpace::VirtualSpace() {
411 _upper_high_boundary = NULL; 432 _upper_high_boundary = NULL;
412 _lower_alignment = 0; 433 _lower_alignment = 0;
413 _middle_alignment = 0; 434 _middle_alignment = 0;
414 _upper_alignment = 0; 435 _upper_alignment = 0;
415 _special = false; 436 _special = false;
437 _executable = false;
416 } 438 }
417 439
418 440
419 bool VirtualSpace::initialize(ReservedSpace rs, size_t committed_size) { 441 bool VirtualSpace::initialize(ReservedSpace rs, size_t committed_size) {
420 if(!rs.is_reserved()) return false; // allocation failed. 442 if(!rs.is_reserved()) return false; // allocation failed.
424 446
425 _low = low_boundary(); 447 _low = low_boundary();
426 _high = low(); 448 _high = low();
427 449
428 _special = rs.special(); 450 _special = rs.special();
451 _executable = rs.executable();
429 452
430 // When a VirtualSpace begins life at a large size, make all future expansion 453 // When a VirtualSpace begins life at a large size, make all future expansion
431 // and shrinking occur aligned to a granularity of large pages. This avoids 454 // and shrinking occur aligned to a granularity of large pages. This avoids
432 // fragmentation of physical addresses that inhibits the use of large pages 455 // fragmentation of physical addresses that inhibits the use of large pages
433 // by the OS virtual memory system. Empirically, we see that with a 4MB 456 // by the OS virtual memory system. Empirically, we see that with a 4MB
481 _upper_high_boundary = NULL; 504 _upper_high_boundary = NULL;
482 _lower_alignment = 0; 505 _lower_alignment = 0;
483 _middle_alignment = 0; 506 _middle_alignment = 0;
484 _upper_alignment = 0; 507 _upper_alignment = 0;
485 _special = false; 508 _special = false;
509 _executable = false;
486 } 510 }
487 511
488 512
489 size_t VirtualSpace::committed_size() const { 513 size_t VirtualSpace::committed_size() const {
490 return pointer_delta(high(), low(), sizeof(char)); 514 return pointer_delta(high(), low(), sizeof(char));
590 // Commit regions 614 // Commit regions
591 if (lower_needs > 0) { 615 if (lower_needs > 0) {
592 assert(low_boundary() <= lower_high() && 616 assert(low_boundary() <= lower_high() &&
593 lower_high() + lower_needs <= lower_high_boundary(), 617 lower_high() + lower_needs <= lower_high_boundary(),
594 "must not expand beyond region"); 618 "must not expand beyond region");
595 if (!os::commit_memory(lower_high(), lower_needs)) { 619 if (!os::commit_memory(lower_high(), lower_needs, _executable)) {
596 debug_only(warning("os::commit_memory failed")); 620 debug_only(warning("os::commit_memory failed"));
597 return false; 621 return false;
598 } else { 622 } else {
599 _lower_high += lower_needs; 623 _lower_high += lower_needs;
600 } 624 }
601 } 625 }
602 if (middle_needs > 0) { 626 if (middle_needs > 0) {
603 assert(lower_high_boundary() <= middle_high() && 627 assert(lower_high_boundary() <= middle_high() &&
604 middle_high() + middle_needs <= middle_high_boundary(), 628 middle_high() + middle_needs <= middle_high_boundary(),
605 "must not expand beyond region"); 629 "must not expand beyond region");
606 if (!os::commit_memory(middle_high(), middle_needs, middle_alignment())) { 630 if (!os::commit_memory(middle_high(), middle_needs, middle_alignment(),
631 _executable)) {
607 debug_only(warning("os::commit_memory failed")); 632 debug_only(warning("os::commit_memory failed"));
608 return false; 633 return false;
609 } 634 }
610 _middle_high += middle_needs; 635 _middle_high += middle_needs;
611 } 636 }
612 if (upper_needs > 0) { 637 if (upper_needs > 0) {
613 assert(middle_high_boundary() <= upper_high() && 638 assert(middle_high_boundary() <= upper_high() &&
614 upper_high() + upper_needs <= upper_high_boundary(), 639 upper_high() + upper_needs <= upper_high_boundary(),
615 "must not expand beyond region"); 640 "must not expand beyond region");
616 if (!os::commit_memory(upper_high(), upper_needs)) { 641 if (!os::commit_memory(upper_high(), upper_needs, _executable)) {
617 debug_only(warning("os::commit_memory failed")); 642 debug_only(warning("os::commit_memory failed"));
618 return false; 643 return false;
619 } else { 644 } else {
620 _upper_high += upper_needs; 645 _upper_high += upper_needs;
621 } 646 }