Mercurial > hg > truffle
comparison src/share/vm/runtime/virtualspace.cpp @ 10187:b294421fa3c5
8012915: ReservedSpace::align_reserved_region() broken on Windows
Summary: remove unused constructors and helper methods for ReservedHeapSpace and ReservedSpace
Reviewed-by: mgerdin, jmasa, johnc, tschatzl
author | brutisso |
---|---|
date | Fri, 26 Apr 2013 09:53:22 +0200 |
parents | 203f64878aab |
children | a837fa3d3f86 |
comparison
equal
deleted
inserted
replaced
10186:b06ac540229e | 10187:b294421fa3c5 |
---|---|
58 bool large, | 58 bool large, |
59 bool executable) { | 59 bool executable) { |
60 initialize(size, alignment, large, NULL, 0, executable); | 60 initialize(size, alignment, large, NULL, 0, executable); |
61 } | 61 } |
62 | 62 |
63 char * | |
64 ReservedSpace::align_reserved_region(char* addr, const size_t len, | |
65 const size_t prefix_size, | |
66 const size_t prefix_align, | |
67 const size_t suffix_size, | |
68 const size_t suffix_align) | |
69 { | |
70 assert(addr != NULL, "sanity"); | |
71 const size_t required_size = prefix_size + suffix_size; | |
72 assert(len >= required_size, "len too small"); | |
73 | |
74 const size_t s = size_t(addr); | |
75 const size_t beg_ofs = (s + prefix_size) & (suffix_align - 1); | |
76 const size_t beg_delta = beg_ofs == 0 ? 0 : suffix_align - beg_ofs; | |
77 | |
78 if (len < beg_delta + required_size) { | |
79 return NULL; // Cannot do proper alignment. | |
80 } | |
81 const size_t end_delta = len - (beg_delta + required_size); | |
82 | |
83 if (beg_delta != 0) { | |
84 os::release_memory(addr, beg_delta); | |
85 } | |
86 | |
87 if (end_delta != 0) { | |
88 char* release_addr = (char*) (s + beg_delta + required_size); | |
89 os::release_memory(release_addr, end_delta); | |
90 } | |
91 | |
92 return (char*) (s + beg_delta); | |
93 } | |
94 | |
95 char* ReservedSpace::reserve_and_align(const size_t reserve_size, | |
96 const size_t prefix_size, | |
97 const size_t prefix_align, | |
98 const size_t suffix_size, | |
99 const size_t suffix_align) | |
100 { | |
101 assert(reserve_size > prefix_size + suffix_size, "should not be here"); | |
102 | |
103 char* raw_addr = os::reserve_memory(reserve_size, NULL, prefix_align); | |
104 if (raw_addr == NULL) return NULL; | |
105 | |
106 char* result = align_reserved_region(raw_addr, reserve_size, prefix_size, | |
107 prefix_align, suffix_size, | |
108 suffix_align); | |
109 if (result == NULL && !os::release_memory(raw_addr, reserve_size)) { | |
110 fatal("os::release_memory failed"); | |
111 } | |
112 | |
113 #ifdef ASSERT | |
114 if (result != NULL) { | |
115 const size_t raw = size_t(raw_addr); | |
116 const size_t res = size_t(result); | |
117 assert(res >= raw, "alignment decreased start addr"); | |
118 assert(res + prefix_size + suffix_size <= raw + reserve_size, | |
119 "alignment increased end addr"); | |
120 assert((res & (prefix_align - 1)) == 0, "bad alignment of prefix"); | |
121 assert(((res + prefix_size) & (suffix_align - 1)) == 0, | |
122 "bad alignment of suffix"); | |
123 } | |
124 #endif | |
125 | |
126 return result; | |
127 } | |
128 | |
129 // Helper method. | 63 // Helper method. |
130 static bool failed_to_reserve_as_requested(char* base, char* requested_address, | 64 static bool failed_to_reserve_as_requested(char* base, char* requested_address, |
131 const size_t size, bool special) | 65 const size_t size, bool special) |
132 { | 66 { |
133 if (base == requested_address || requested_address == NULL) | 67 if (base == requested_address || requested_address == NULL) |
151 fatal("os::release_memory failed"); | 85 fatal("os::release_memory failed"); |
152 } | 86 } |
153 } | 87 } |
154 } | 88 } |
155 return true; | 89 return true; |
156 } | |
157 | |
158 ReservedSpace::ReservedSpace(const size_t suffix_size, | |
159 const size_t suffix_align, | |
160 char* requested_address, | |
161 const size_t noaccess_prefix) | |
162 { | |
163 assert(suffix_size != 0, "sanity"); | |
164 assert(suffix_align != 0, "sanity"); | |
165 assert((suffix_size & (suffix_align - 1)) == 0, | |
166 "suffix_size not divisible by suffix_align"); | |
167 | |
168 // Assert that if noaccess_prefix is used, it is the same as prefix_align. | |
169 // Add in noaccess_prefix to prefix | |
170 const size_t adjusted_prefix_size = noaccess_prefix; | |
171 const size_t size = adjusted_prefix_size + suffix_size; | |
172 | |
173 // On systems where the entire region has to be reserved and committed up | |
174 // front, the compound alignment normally done by this method is unnecessary. | |
175 const bool try_reserve_special = UseLargePages && | |
176 suffix_align == os::large_page_size(); | |
177 if (!os::can_commit_large_page_memory() && try_reserve_special) { | |
178 initialize(size, suffix_align, true, requested_address, noaccess_prefix, | |
179 false); | |
180 return; | |
181 } | |
182 | |
183 _base = NULL; | |
184 _size = 0; | |
185 _alignment = 0; | |
186 _special = false; | |
187 _noaccess_prefix = 0; | |
188 _executable = false; | |
189 | |
190 // Optimistically try to reserve the exact size needed. | |
191 char* addr; | |
192 if (requested_address != 0) { | |
193 requested_address -= noaccess_prefix; // adjust address | |
194 assert(requested_address != NULL, "huge noaccess prefix?"); | |
195 addr = os::attempt_reserve_memory_at(size, requested_address); | |
196 if (failed_to_reserve_as_requested(addr, requested_address, size, false)) { | |
197 // OS ignored requested address. Try different address. | |
198 addr = NULL; | |
199 } | |
200 } else { | |
201 addr = os::reserve_memory(size, NULL, suffix_align); | |
202 } | |
203 if (addr == NULL) return; | |
204 | |
205 // Check whether the result has the needed alignment | |
206 const size_t ofs = (size_t(addr) + adjusted_prefix_size) & (suffix_align - 1); | |
207 if (ofs != 0) { | |
208 // Wrong alignment. Release, allocate more space and do manual alignment. | |
209 // | |
210 // On most operating systems, another allocation with a somewhat larger size | |
211 // will return an address "close to" that of the previous allocation. The | |
212 // result is often the same address (if the kernel hands out virtual | |
213 // addresses from low to high), or an address that is offset by the increase | |
214 // in size. Exploit that to minimize the amount of extra space requested. | |
215 if (!os::release_memory(addr, size)) { | |
216 fatal("os::release_memory failed"); | |
217 } | |
218 | |
219 const size_t extra = MAX2(ofs, suffix_align - ofs); | |
220 addr = reserve_and_align(size + extra, adjusted_prefix_size, suffix_align, | |
221 suffix_size, suffix_align); | |
222 if (addr == NULL) { | |
223 // Try an even larger region. If this fails, address space is exhausted. | |
224 addr = reserve_and_align(size + suffix_align, adjusted_prefix_size, | |
225 suffix_align, suffix_size, suffix_align); | |
226 } | |
227 | |
228 if (requested_address != 0 && | |
229 failed_to_reserve_as_requested(addr, requested_address, size, false)) { | |
230 // As a result of the alignment constraints, the allocated addr differs | |
231 // from the requested address. Return back to the caller who can | |
232 // take remedial action (like try again without a requested address). | |
233 assert(_base == NULL, "should be"); | |
234 return; | |
235 } | |
236 } | |
237 | |
238 _base = addr; | |
239 _size = size; | |
240 _alignment = suffix_align; | |
241 _noaccess_prefix = noaccess_prefix; | |
242 } | 90 } |
243 | 91 |
244 void ReservedSpace::initialize(size_t size, size_t alignment, bool large, | 92 void ReservedSpace::initialize(size_t size, size_t alignment, bool large, |
245 char* requested_address, | 93 char* requested_address, |
246 const size_t noaccess_prefix, | 94 const size_t noaccess_prefix, |
474 // Only reserved space for the java heap should have a noaccess_prefix | 322 // Only reserved space for the java heap should have a noaccess_prefix |
475 // if using compressed oops. | 323 // if using compressed oops. |
476 protect_noaccess_prefix(size); | 324 protect_noaccess_prefix(size); |
477 } | 325 } |
478 | 326 |
479 ReservedHeapSpace::ReservedHeapSpace(const size_t heap_space_size, | |
480 const size_t alignment, | |
481 char* requested_address) : | |
482 ReservedSpace(heap_space_size, alignment, | |
483 requested_address, | |
484 (UseCompressedOops && (Universe::narrow_oop_base() != NULL) && | |
485 Universe::narrow_oop_use_implicit_null_checks()) ? | |
486 lcm(os::vm_page_size(), alignment) : 0) { | |
487 if (base() > 0) { | |
488 MemTracker::record_virtual_memory_type((address)base(), mtJavaHeap); | |
489 } | |
490 protect_noaccess_prefix(heap_space_size); | |
491 } | |
492 | |
493 // Reserve space for code segment. Same as Java heap only we mark this as | 327 // Reserve space for code segment. Same as Java heap only we mark this as |
494 // executable. | 328 // executable. |
495 ReservedCodeSpace::ReservedCodeSpace(size_t r_size, | 329 ReservedCodeSpace::ReservedCodeSpace(size_t r_size, |
496 size_t rs_align, | 330 size_t rs_align, |
497 bool large) : | 331 bool large) : |