Wed, 25 Mar 2009 14:19:20 -0400
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
1.1 --- a/src/os/linux/vm/os_linux.cpp Mon Mar 23 10:42:20 2009 -0400 1.2 +++ b/src/os/linux/vm/os_linux.cpp Wed Mar 25 14:19:20 2009 -0400 1.3 @@ -2269,15 +2269,16 @@ 1.4 // All it does is to check if there are enough free pages 1.5 // left at the time of mmap(). This could be a potential 1.6 // problem. 1.7 -bool os::commit_memory(char* addr, size_t size) { 1.8 - uintptr_t res = (uintptr_t) ::mmap(addr, size, 1.9 - PROT_READ|PROT_WRITE|PROT_EXEC, 1.10 +bool os::commit_memory(char* addr, size_t size, bool exec) { 1.11 + int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE; 1.12 + uintptr_t res = (uintptr_t) ::mmap(addr, size, prot, 1.13 MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0); 1.14 return res != (uintptr_t) MAP_FAILED; 1.15 } 1.16 1.17 -bool os::commit_memory(char* addr, size_t size, size_t alignment_hint) { 1.18 - return commit_memory(addr, size); 1.19 +bool os::commit_memory(char* addr, size_t size, size_t alignment_hint, 1.20 + bool exec) { 1.21 + return commit_memory(addr, size, exec); 1.22 } 1.23 1.24 void os::realign_memory(char *addr, size_t bytes, size_t alignment_hint) { } 1.25 @@ -2417,8 +2418,7 @@ 1.26 unsigned long* os::Linux::_numa_all_nodes; 1.27 1.28 bool os::uncommit_memory(char* addr, size_t size) { 1.29 - return ::mmap(addr, size, 1.30 - PROT_READ|PROT_WRITE|PROT_EXEC, 1.31 + return ::mmap(addr, size, PROT_NONE, 1.32 MAP_PRIVATE|MAP_FIXED|MAP_NORESERVE|MAP_ANONYMOUS, -1, 0) 1.33 != MAP_FAILED; 1.34 } 1.35 @@ -2441,7 +2441,9 @@ 1.36 flags |= MAP_FIXED; 1.37 } 1.38 1.39 - addr = (char*)::mmap(requested_addr, bytes, PROT_READ|PROT_WRITE|PROT_EXEC, 1.40 + // Map uncommitted pages PROT_READ and PROT_WRITE, change access 1.41 + // to PROT_EXEC if executable when we commit the page. 1.42 + addr = (char*)::mmap(requested_addr, bytes, PROT_READ|PROT_WRITE, 1.43 flags, -1, 0); 1.44 1.45 if (addr != MAP_FAILED) { 1.46 @@ -2582,7 +2584,9 @@ 1.47 #define SHM_HUGETLB 04000 1.48 #endif 1.49 1.50 -char* os::reserve_memory_special(size_t bytes, char* req_addr) { 1.51 +char* os::reserve_memory_special(size_t bytes, char* req_addr, bool exec) { 1.52 + // "exec" is passed in but not used. Creating the shared image for 1.53 + // the code cache doesn't have an SHM_X executable permission to check. 1.54 assert(UseLargePages, "only for large pages"); 1.55 1.56 key_t key = IPC_PRIVATE;
2.1 --- a/src/os/solaris/vm/os_solaris.cpp Mon Mar 23 10:42:20 2009 -0400 2.2 +++ b/src/os/solaris/vm/os_solaris.cpp Wed Mar 25 14:19:20 2009 -0400 2.3 @@ -2623,15 +2623,16 @@ 2.4 return page_size; 2.5 } 2.6 2.7 -bool os::commit_memory(char* addr, size_t bytes) { 2.8 +bool os::commit_memory(char* addr, size_t bytes, bool exec) { 2.9 + int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE; 2.10 size_t size = bytes; 2.11 return 2.12 - NULL != Solaris::mmap_chunk(addr, size, MAP_PRIVATE|MAP_FIXED, 2.13 - PROT_READ | PROT_WRITE | PROT_EXEC); 2.14 -} 2.15 - 2.16 -bool os::commit_memory(char* addr, size_t bytes, size_t alignment_hint) { 2.17 - if (commit_memory(addr, bytes)) { 2.18 + NULL != Solaris::mmap_chunk(addr, size, MAP_PRIVATE|MAP_FIXED, prot); 2.19 +} 2.20 + 2.21 +bool os::commit_memory(char* addr, size_t bytes, size_t alignment_hint, 2.22 + bool exec) { 2.23 + if (commit_memory(addr, bytes, exec)) { 2.24 if (UseMPSS && alignment_hint > (size_t)vm_page_size()) { 2.25 // If the large page size has been set and the VM 2.26 // is using large pages, use the large page size 2.27 @@ -3220,7 +3221,9 @@ 2.28 return true; 2.29 } 2.30 2.31 -char* os::reserve_memory_special(size_t bytes, char* addr) { 2.32 +char* os::reserve_memory_special(size_t bytes, char* addr, bool exec) { 2.33 + // "exec" is passed in but not used. Creating the shared image for 2.34 + // the code cache doesn't have an SHM_X executable permission to check. 2.35 assert(UseLargePages && UseISM, "only for ISM large pages"); 2.36 2.37 size_t size = bytes;
3.1 --- a/src/os/windows/vm/os_windows.cpp Mon Mar 23 10:42:20 2009 -0400 3.2 +++ b/src/os/windows/vm/os_windows.cpp Wed Mar 25 14:19:20 2009 -0400 3.3 @@ -2189,7 +2189,8 @@ 3.4 if (addr > thread->stack_yellow_zone_base() && addr < thread->stack_base() ) { 3.5 addr = (address)((uintptr_t)addr & 3.6 (~((uintptr_t)os::vm_page_size() - (uintptr_t)1))); 3.7 - os::commit_memory( (char *)addr, thread->stack_base() - addr ); 3.8 + os::commit_memory((char *)addr, thread->stack_base() - addr, 3.9 + false ); 3.10 return EXCEPTION_CONTINUE_EXECUTION; 3.11 } 3.12 else 3.13 @@ -2565,8 +2566,7 @@ 3.14 assert((size_t)addr % os::vm_allocation_granularity() == 0, 3.15 "reserve alignment"); 3.16 assert(bytes % os::vm_allocation_granularity() == 0, "reserve block size"); 3.17 - char* res = (char*)VirtualAlloc(addr, bytes, MEM_RESERVE, 3.18 - PAGE_EXECUTE_READWRITE); 3.19 + char* res = (char*)VirtualAlloc(addr, bytes, MEM_RESERVE, PAGE_READWRITE); 3.20 assert(res == NULL || addr == NULL || addr == res, 3.21 "Unexpected address from reserve."); 3.22 return res; 3.23 @@ -2595,7 +2595,7 @@ 3.24 return true; 3.25 } 3.26 3.27 -char* os::reserve_memory_special(size_t bytes, char* addr) { 3.28 +char* os::reserve_memory_special(size_t bytes, char* addr, bool exec) { 3.29 3.30 if (UseLargePagesIndividualAllocation) { 3.31 if (TracePageSizes && Verbose) { 3.32 @@ -2618,7 +2618,7 @@ 3.33 p_buf = (char *) VirtualAlloc(addr, 3.34 size_of_reserve, // size of Reserve 3.35 MEM_RESERVE, 3.36 - PAGE_EXECUTE_READWRITE); 3.37 + PAGE_READWRITE); 3.38 // If reservation failed, return NULL 3.39 if (p_buf == NULL) return NULL; 3.40 3.41 @@ -2659,7 +2659,13 @@ 3.42 p_new = (char *) VirtualAlloc(next_alloc_addr, 3.43 bytes_to_rq, 3.44 MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES, 3.45 - PAGE_EXECUTE_READWRITE); 3.46 + PAGE_READWRITE); 3.47 + if (p_new != NULL && exec) { 3.48 + DWORD oldprot; 3.49 + // Windows doc says to use VirtualProtect to get execute permissions 3.50 + VirtualProtect(next_alloc_addr, bytes_to_rq, 3.51 + PAGE_EXECUTE_READWRITE, &oldprot); 3.52 + } 3.53 } 3.54 3.55 if (p_new == NULL) { 3.56 @@ -2688,10 +2694,12 @@ 3.57 } else { 3.58 // normal policy just allocate it all at once 3.59 DWORD flag = MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES; 3.60 - char * res = (char *)VirtualAlloc(NULL, 3.61 - bytes, 3.62 - flag, 3.63 - PAGE_EXECUTE_READWRITE); 3.64 + char * res = (char *)VirtualAlloc(NULL, bytes, flag, PAGE_READWRITE); 3.65 + if (res != NULL && exec) { 3.66 + DWORD oldprot; 3.67 + // Windows doc says to use VirtualProtect to get execute permissions 3.68 + VirtualProtect(res, bytes, PAGE_EXECUTE_READWRITE, &oldprot); 3.69 + } 3.70 return res; 3.71 } 3.72 } 3.73 @@ -2703,7 +2711,7 @@ 3.74 void os::print_statistics() { 3.75 } 3.76 3.77 -bool os::commit_memory(char* addr, size_t bytes) { 3.78 +bool os::commit_memory(char* addr, size_t bytes, bool exec) { 3.79 if (bytes == 0) { 3.80 // Don't bother the OS with noops. 3.81 return true; 3.82 @@ -2712,11 +2720,19 @@ 3.83 assert(bytes % os::vm_page_size() == 0, "commit in page-sized chunks"); 3.84 // Don't attempt to print anything if the OS call fails. We're 3.85 // probably low on resources, so the print itself may cause crashes. 3.86 - return VirtualAlloc(addr, bytes, MEM_COMMIT, PAGE_EXECUTE_READWRITE) != NULL; 3.87 + bool result = VirtualAlloc(addr, bytes, MEM_COMMIT, PAGE_READWRITE) != 0; 3.88 + if (result != NULL && exec) { 3.89 + DWORD oldprot; 3.90 + // Windows doc says to use VirtualProtect to get execute permissions 3.91 + return VirtualProtect(addr, bytes, PAGE_EXECUTE_READWRITE, &oldprot) != 0; 3.92 + } else { 3.93 + return result; 3.94 + } 3.95 } 3.96 3.97 -bool os::commit_memory(char* addr, size_t size, size_t alignment_hint) { 3.98 - return commit_memory(addr, size); 3.99 +bool os::commit_memory(char* addr, size_t size, size_t alignment_hint, 3.100 + bool exec) { 3.101 + return commit_memory(addr, size, exec); 3.102 } 3.103 3.104 bool os::uncommit_memory(char* addr, size_t bytes) { 3.105 @@ -2750,7 +2766,7 @@ 3.106 3.107 // Strange enough, but on Win32 one can change protection only for committed 3.108 // memory, not a big deal anyway, as bytes less or equal than 64K 3.109 - if (!is_committed && !commit_memory(addr, bytes)) { 3.110 + if (!is_committed && !commit_memory(addr, bytes, prot == MEM_PROT_RWX)) { 3.111 fatal("cannot commit protection page"); 3.112 } 3.113 // One cannot use os::guard_memory() here, as on Win32 guard page 3.114 @@ -3248,10 +3264,10 @@ 3.115 #endif 3.116 3.117 if (!UseMembar) { 3.118 - address mem_serialize_page = (address)VirtualAlloc(NULL, os::vm_page_size(), MEM_RESERVE, PAGE_EXECUTE_READWRITE); 3.119 + address mem_serialize_page = (address)VirtualAlloc(NULL, os::vm_page_size(), MEM_RESERVE, PAGE_READWRITE); 3.120 guarantee( mem_serialize_page != NULL, "Reserve Failed for memory serialize page"); 3.121 3.122 - return_page = (address)VirtualAlloc(mem_serialize_page, os::vm_page_size(), MEM_COMMIT, PAGE_EXECUTE_READWRITE); 3.123 + return_page = (address)VirtualAlloc(mem_serialize_page, os::vm_page_size(), MEM_COMMIT, PAGE_READWRITE); 3.124 guarantee( return_page != NULL, "Commit Failed for memory serialize page"); 3.125 3.126 os::set_memory_serialize_page( mem_serialize_page );
4.1 --- a/src/share/vm/memory/heap.cpp Mon Mar 23 10:42:20 2009 -0400 4.2 +++ b/src/share/vm/memory/heap.cpp Wed Mar 25 14:19:20 2009 -0400 4.3 @@ -112,7 +112,7 @@ 4.4 4.5 const size_t rs_align = page_size == (size_t) os::vm_page_size() ? 0 : 4.6 MAX2(page_size, granularity); 4.7 - ReservedSpace rs(r_size, rs_align, rs_align > 0); 4.8 + ReservedCodeSpace rs(r_size, rs_align, rs_align > 0); 4.9 os::trace_page_sizes("code heap", committed_size, reserved_size, page_size, 4.10 rs.base(), rs.size()); 4.11 if (!_memory.initialize(rs, c_size)) {
5.1 --- a/src/share/vm/runtime/os.hpp Mon Mar 23 10:42:20 2009 -0400 5.2 +++ b/src/share/vm/runtime/os.hpp Wed Mar 25 14:19:20 2009 -0400 5.3 @@ -202,8 +202,10 @@ 5.4 static char* attempt_reserve_memory_at(size_t bytes, char* addr); 5.5 static void split_reserved_memory(char *base, size_t size, 5.6 size_t split, bool realloc); 5.7 - static bool commit_memory(char* addr, size_t bytes); 5.8 - static bool commit_memory(char* addr, size_t size, size_t alignment_hint); 5.9 + static bool commit_memory(char* addr, size_t bytes, 5.10 + bool executable = false); 5.11 + static bool commit_memory(char* addr, size_t size, size_t alignment_hint, 5.12 + bool executable = false); 5.13 static bool uncommit_memory(char* addr, size_t bytes); 5.14 static bool release_memory(char* addr, size_t bytes); 5.15 5.16 @@ -243,7 +245,8 @@ 5.17 5.18 static char* non_memory_address_word(); 5.19 // reserve, commit and pin the entire memory region 5.20 - static char* reserve_memory_special(size_t size, char* addr = NULL); 5.21 + static char* reserve_memory_special(size_t size, char* addr = NULL, 5.22 + bool executable = false); 5.23 static bool release_memory_special(char* addr, size_t bytes); 5.24 static bool large_page_init(); 5.25 static size_t large_page_size();
6.1 --- a/src/share/vm/runtime/virtualspace.cpp Mon Mar 23 10:42:20 2009 -0400 6.2 +++ b/src/share/vm/runtime/virtualspace.cpp Wed Mar 25 14:19:20 2009 -0400 6.3 @@ -28,7 +28,7 @@ 6.4 6.5 // ReservedSpace 6.6 ReservedSpace::ReservedSpace(size_t size) { 6.7 - initialize(size, 0, false, NULL, 0); 6.8 + initialize(size, 0, false, NULL, 0, false); 6.9 } 6.10 6.11 ReservedSpace::ReservedSpace(size_t size, size_t alignment, 6.12 @@ -36,7 +36,13 @@ 6.13 char* requested_address, 6.14 const size_t noaccess_prefix) { 6.15 initialize(size+noaccess_prefix, alignment, large, requested_address, 6.16 - noaccess_prefix); 6.17 + noaccess_prefix, false); 6.18 +} 6.19 + 6.20 +ReservedSpace::ReservedSpace(size_t size, size_t alignment, 6.21 + bool large, 6.22 + bool executable) { 6.23 + initialize(size, alignment, large, NULL, 0, executable); 6.24 } 6.25 6.26 char * 6.27 @@ -132,7 +138,8 @@ 6.28 const bool try_reserve_special = UseLargePages && 6.29 prefix_align == os::large_page_size(); 6.30 if (!os::can_commit_large_page_memory() && try_reserve_special) { 6.31 - initialize(size, prefix_align, true, requested_address, noaccess_prefix); 6.32 + initialize(size, prefix_align, true, requested_address, noaccess_prefix, 6.33 + false); 6.34 return; 6.35 } 6.36 6.37 @@ -141,6 +148,7 @@ 6.38 _alignment = 0; 6.39 _special = false; 6.40 _noaccess_prefix = 0; 6.41 + _executable = false; 6.42 6.43 // Assert that if noaccess_prefix is used, it is the same as prefix_align. 6.44 assert(noaccess_prefix == 0 || 6.45 @@ -189,7 +197,8 @@ 6.46 6.47 void ReservedSpace::initialize(size_t size, size_t alignment, bool large, 6.48 char* requested_address, 6.49 - const size_t noaccess_prefix) { 6.50 + const size_t noaccess_prefix, 6.51 + bool executable) { 6.52 const size_t granularity = os::vm_allocation_granularity(); 6.53 assert((size & granularity - 1) == 0, 6.54 "size not aligned to os::vm_allocation_granularity()"); 6.55 @@ -201,6 +210,7 @@ 6.56 _base = NULL; 6.57 _size = 0; 6.58 _special = false; 6.59 + _executable = executable; 6.60 _alignment = 0; 6.61 _noaccess_prefix = 0; 6.62 if (size == 0) { 6.63 @@ -214,7 +224,7 @@ 6.64 6.65 if (special) { 6.66 6.67 - base = os::reserve_memory_special(size, requested_address); 6.68 + base = os::reserve_memory_special(size, requested_address, executable); 6.69 6.70 if (base != NULL) { 6.71 // Check alignment constraints 6.72 @@ -284,7 +294,7 @@ 6.73 6.74 6.75 ReservedSpace::ReservedSpace(char* base, size_t size, size_t alignment, 6.76 - bool special) { 6.77 + bool special, bool executable) { 6.78 assert((size % os::vm_allocation_granularity()) == 0, 6.79 "size not allocation aligned"); 6.80 _base = base; 6.81 @@ -292,6 +302,7 @@ 6.82 _alignment = alignment; 6.83 _noaccess_prefix = 0; 6.84 _special = special; 6.85 + _executable = executable; 6.86 } 6.87 6.88 6.89 @@ -299,9 +310,10 @@ 6.90 bool split, bool realloc) { 6.91 assert(partition_size <= size(), "partition failed"); 6.92 if (split) { 6.93 - os::split_reserved_memory(_base, _size, partition_size, realloc); 6.94 + os::split_reserved_memory(base(), size(), partition_size, realloc); 6.95 } 6.96 - ReservedSpace result(base(), partition_size, alignment, special()); 6.97 + ReservedSpace result(base(), partition_size, alignment, special(), 6.98 + executable()); 6.99 return result; 6.100 } 6.101 6.102 @@ -310,7 +322,7 @@ 6.103 ReservedSpace::last_part(size_t partition_size, size_t alignment) { 6.104 assert(partition_size <= size(), "partition failed"); 6.105 ReservedSpace result(base() + partition_size, size() - partition_size, 6.106 - alignment, special()); 6.107 + alignment, special(), executable()); 6.108 return result; 6.109 } 6.110 6.111 @@ -348,6 +360,7 @@ 6.112 _size = 0; 6.113 _noaccess_prefix = 0; 6.114 _special = false; 6.115 + _executable = false; 6.116 } 6.117 } 6.118 6.119 @@ -396,6 +409,14 @@ 6.120 protect_noaccess_prefix(prefix_size+suffix_size); 6.121 } 6.122 6.123 +// Reserve space for code segment. Same as Java heap only we mark this as 6.124 +// executable. 6.125 +ReservedCodeSpace::ReservedCodeSpace(size_t r_size, 6.126 + size_t rs_align, 6.127 + bool large) : 6.128 + ReservedSpace(r_size, rs_align, large, /*executable*/ true) { 6.129 +} 6.130 + 6.131 // VirtualSpace 6.132 6.133 VirtualSpace::VirtualSpace() { 6.134 @@ -413,6 +434,7 @@ 6.135 _middle_alignment = 0; 6.136 _upper_alignment = 0; 6.137 _special = false; 6.138 + _executable = false; 6.139 } 6.140 6.141 6.142 @@ -426,6 +448,7 @@ 6.143 _high = low(); 6.144 6.145 _special = rs.special(); 6.146 + _executable = rs.executable(); 6.147 6.148 // When a VirtualSpace begins life at a large size, make all future expansion 6.149 // and shrinking occur aligned to a granularity of large pages. This avoids 6.150 @@ -483,6 +506,7 @@ 6.151 _middle_alignment = 0; 6.152 _upper_alignment = 0; 6.153 _special = false; 6.154 + _executable = false; 6.155 } 6.156 6.157 6.158 @@ -592,7 +616,7 @@ 6.159 assert(low_boundary() <= lower_high() && 6.160 lower_high() + lower_needs <= lower_high_boundary(), 6.161 "must not expand beyond region"); 6.162 - if (!os::commit_memory(lower_high(), lower_needs)) { 6.163 + if (!os::commit_memory(lower_high(), lower_needs, _executable)) { 6.164 debug_only(warning("os::commit_memory failed")); 6.165 return false; 6.166 } else { 6.167 @@ -603,7 +627,8 @@ 6.168 assert(lower_high_boundary() <= middle_high() && 6.169 middle_high() + middle_needs <= middle_high_boundary(), 6.170 "must not expand beyond region"); 6.171 - if (!os::commit_memory(middle_high(), middle_needs, middle_alignment())) { 6.172 + if (!os::commit_memory(middle_high(), middle_needs, middle_alignment(), 6.173 + _executable)) { 6.174 debug_only(warning("os::commit_memory failed")); 6.175 return false; 6.176 } 6.177 @@ -613,7 +638,7 @@ 6.178 assert(middle_high_boundary() <= upper_high() && 6.179 upper_high() + upper_needs <= upper_high_boundary(), 6.180 "must not expand beyond region"); 6.181 - if (!os::commit_memory(upper_high(), upper_needs)) { 6.182 + if (!os::commit_memory(upper_high(), upper_needs, _executable)) { 6.183 debug_only(warning("os::commit_memory failed")); 6.184 return false; 6.185 } else {
7.1 --- a/src/share/vm/runtime/virtualspace.hpp Mon Mar 23 10:42:20 2009 -0400 7.2 +++ b/src/share/vm/runtime/virtualspace.hpp Wed Mar 25 14:19:20 2009 -0400 7.3 @@ -32,12 +32,15 @@ 7.4 size_t _noaccess_prefix; 7.5 size_t _alignment; 7.6 bool _special; 7.7 + bool _executable; 7.8 7.9 // ReservedSpace 7.10 - ReservedSpace(char* base, size_t size, size_t alignment, bool special); 7.11 + ReservedSpace(char* base, size_t size, size_t alignment, bool special, 7.12 + bool executable); 7.13 void initialize(size_t size, size_t alignment, bool large, 7.14 char* requested_address, 7.15 - const size_t noaccess_prefix); 7.16 + const size_t noaccess_prefix, 7.17 + bool executable); 7.18 7.19 // Release parts of an already-reserved memory region [addr, addr + len) to 7.20 // get a new region that has "compound alignment." Return the start of the 7.21 @@ -75,16 +78,16 @@ 7.22 const size_t suffix_size, const size_t suffix_align, 7.23 char* requested_address, 7.24 const size_t noaccess_prefix = 0); 7.25 + ReservedSpace(size_t size, size_t alignment, bool large, bool executable); 7.26 7.27 // Accessors 7.28 - char* base() const { return _base; } 7.29 - size_t size() const { return _size; } 7.30 - size_t alignment() const { return _alignment; } 7.31 - bool special() const { return _special; } 7.32 - 7.33 - size_t noaccess_prefix() const { return _noaccess_prefix; } 7.34 - 7.35 - bool is_reserved() const { return _base != NULL; } 7.36 + char* base() const { return _base; } 7.37 + size_t size() const { return _size; } 7.38 + size_t alignment() const { return _alignment; } 7.39 + bool special() const { return _special; } 7.40 + bool executable() const { return _executable; } 7.41 + size_t noaccess_prefix() const { return _noaccess_prefix; } 7.42 + bool is_reserved() const { return _base != NULL; } 7.43 void release(); 7.44 7.45 // Splitting 7.46 @@ -126,6 +129,13 @@ 7.47 char* requested_address); 7.48 }; 7.49 7.50 +// Class encapsulating behavior specific memory space for Code 7.51 +class ReservedCodeSpace : public ReservedSpace { 7.52 + public: 7.53 + // Constructor 7.54 + ReservedCodeSpace(size_t r_size, size_t rs_align, bool large); 7.55 +}; 7.56 + 7.57 // VirtualSpace is data structure for committing a previously reserved address range in smaller chunks. 7.58 7.59 class VirtualSpace VALUE_OBJ_CLASS_SPEC { 7.60 @@ -143,6 +153,9 @@ 7.61 // os::commit_memory() or os::uncommit_memory(). 7.62 bool _special; 7.63 7.64 + // Need to know if commit should be executable. 7.65 + bool _executable; 7.66 + 7.67 // MPSS Support 7.68 // Each virtualspace region has a lower, middle, and upper region. 7.69 // Each region has an end boundary and a high pointer which is the