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) :