Mercurial > hg > graal-compiler
annotate src/share/vm/gc_implementation/parallelScavenge/psVirtualspace.cpp @ 10185:d50cc62e94ff
8012715: G1: GraphKit accesses PtrQueue::_index as int but is size_t
Summary: In graphKit INT operations were generated to access PtrQueue::_index which has type size_t. This is 64 bit on 64-bit machines. No problems occur on little endian machines as long as the index fits into 32 bit, but on big endian machines the upper part is read, which is zero. This leads to unnecessary branches to the slow path in the runtime.
Reviewed-by: twisti, johnc
Contributed-by: Martin Doerr <martin.doerr@sap.com>
author | johnc |
---|---|
date | Wed, 24 Apr 2013 14:48:43 -0700 |
parents | f08d439fab8c |
children | a837fa3d3f86 |
rev | line source |
---|---|
0 | 1 /* |
1972 | 2 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
579
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
579
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
579
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "gc_implementation/parallelScavenge/psVirtualspace.hpp" | |
27 #include "runtime/os.hpp" | |
28 #include "runtime/virtualspace.hpp" | |
29 #ifdef TARGET_OS_FAMILY_linux | |
30 # include "os_linux.inline.hpp" | |
31 #endif | |
32 #ifdef TARGET_OS_FAMILY_solaris | |
33 # include "os_solaris.inline.hpp" | |
34 #endif | |
35 #ifdef TARGET_OS_FAMILY_windows | |
36 # include "os_windows.inline.hpp" | |
37 #endif | |
3960 | 38 #ifdef TARGET_OS_FAMILY_bsd |
39 # include "os_bsd.inline.hpp" | |
40 #endif | |
0 | 41 |
42 // PSVirtualSpace | |
43 | |
44 PSVirtualSpace::PSVirtualSpace(ReservedSpace rs, size_t alignment) : | |
45 _alignment(alignment) | |
46 { | |
47 set_reserved(rs); | |
48 set_committed(reserved_low_addr(), reserved_low_addr()); | |
49 DEBUG_ONLY(verify()); | |
50 } | |
51 | |
52 PSVirtualSpace::PSVirtualSpace(ReservedSpace rs) : | |
53 _alignment(os::vm_page_size()) | |
54 { | |
55 set_reserved(rs); | |
56 set_committed(reserved_low_addr(), reserved_low_addr()); | |
57 DEBUG_ONLY(verify()); | |
58 } | |
59 | |
60 // Deprecated. | |
61 PSVirtualSpace::PSVirtualSpace(): _alignment(os::vm_page_size()) { | |
62 } | |
63 | |
64 // Deprecated. | |
65 bool PSVirtualSpace::initialize(ReservedSpace rs, | |
66 size_t commit_size) { | |
67 set_reserved(rs); | |
68 set_committed(reserved_low_addr(), reserved_low_addr()); | |
69 | |
70 // Commit to initial size. | |
71 assert(commit_size <= rs.size(), "commit_size too big"); | |
72 bool result = commit_size > 0 ? expand_by(commit_size) : true; | |
73 DEBUG_ONLY(verify()); | |
74 return result; | |
75 } | |
76 | |
77 PSVirtualSpace::~PSVirtualSpace() { | |
78 release(); | |
79 } | |
80 | |
81 bool PSVirtualSpace::contains(void* p) const { | |
82 char* const cp = (char*)p; | |
83 return cp >= committed_low_addr() && cp < committed_high_addr(); | |
84 } | |
85 | |
86 void PSVirtualSpace::release() { | |
87 DEBUG_ONLY(PSVirtualSpaceVerifier this_verifier(this)); | |
237
1fdb98a17101
6716785: implicit null checks not triggering with CompressedOops
coleenp
parents:
0
diff
changeset
|
88 // This may not release memory it didn't reserve. |
1fdb98a17101
6716785: implicit null checks not triggering with CompressedOops
coleenp
parents:
0
diff
changeset
|
89 // Use rs.release() to release the underlying memory instead. |
0 | 90 _reserved_low_addr = _reserved_high_addr = NULL; |
91 _committed_low_addr = _committed_high_addr = NULL; | |
92 _special = false; | |
93 } | |
94 | |
535
4e400c36026f
6783381: NUMA allocator: don't pretouch eden space with UseNUMA
iveresov
parents:
337
diff
changeset
|
95 bool PSVirtualSpace::expand_by(size_t bytes) { |
0 | 96 assert(is_aligned(bytes), "arg not aligned"); |
97 DEBUG_ONLY(PSVirtualSpaceVerifier this_verifier(this)); | |
98 | |
99 if (uncommitted_size() < bytes) { | |
100 return false; | |
101 } | |
102 | |
103 char* const base_addr = committed_high_addr(); | |
104 bool result = special() || os::commit_memory(base_addr, bytes, alignment()); | |
105 if (result) { | |
106 _committed_high_addr += bytes; | |
107 } | |
108 | |
109 return result; | |
110 } | |
111 | |
112 bool PSVirtualSpace::shrink_by(size_t bytes) { | |
113 assert(is_aligned(bytes), "arg not aligned"); | |
114 DEBUG_ONLY(PSVirtualSpaceVerifier this_verifier(this)); | |
115 | |
116 if (committed_size() < bytes) { | |
117 return false; | |
118 } | |
119 | |
120 char* const base_addr = committed_high_addr() - bytes; | |
121 bool result = special() || os::uncommit_memory(base_addr, bytes); | |
122 if (result) { | |
123 _committed_high_addr -= bytes; | |
124 } | |
125 | |
126 return result; | |
127 } | |
128 | |
129 size_t | |
130 PSVirtualSpace::expand_into(PSVirtualSpace* other_space, size_t bytes) { | |
131 assert(is_aligned(bytes), "arg not aligned"); | |
132 assert(grows_up(), "this space must grow up"); | |
133 assert(other_space->grows_down(), "other space must grow down"); | |
134 assert(reserved_high_addr() == other_space->reserved_low_addr(), | |
135 "spaces not contiguous"); | |
136 assert(special() == other_space->special(), "one space is special, the other is not"); | |
137 DEBUG_ONLY(PSVirtualSpaceVerifier this_verifier(this)); | |
138 DEBUG_ONLY(PSVirtualSpaceVerifier other_verifier(other_space)); | |
139 | |
140 size_t bytes_needed = bytes; | |
141 | |
142 // First use the uncommitted region in this space. | |
143 size_t tmp_bytes = MIN2(uncommitted_size(), bytes_needed); | |
144 if (tmp_bytes > 0) { | |
145 if (expand_by(tmp_bytes)) { | |
146 bytes_needed -= tmp_bytes; | |
147 } else { | |
148 return 0; | |
149 } | |
150 } | |
151 | |
152 // Next take from the uncommitted region in the other space, and commit it. | |
153 tmp_bytes = MIN2(other_space->uncommitted_size(), bytes_needed); | |
154 if (tmp_bytes > 0) { | |
155 char* const commit_base = committed_high_addr(); | |
156 if (other_space->special() || | |
157 os::commit_memory(commit_base, tmp_bytes, alignment())) { | |
158 // Reduce the reserved region in the other space. | |
159 other_space->set_reserved(other_space->reserved_low_addr() + tmp_bytes, | |
160 other_space->reserved_high_addr(), | |
161 other_space->special()); | |
162 | |
163 // Grow both reserved and committed in this space. | |
164 _reserved_high_addr += tmp_bytes; | |
165 _committed_high_addr += tmp_bytes; | |
166 bytes_needed -= tmp_bytes; | |
167 } else { | |
168 return bytes - bytes_needed; | |
169 } | |
170 } | |
171 | |
172 // Finally take from the already committed region in the other space. | |
173 tmp_bytes = bytes_needed; | |
174 if (tmp_bytes > 0) { | |
175 // Reduce both committed and reserved in the other space. | |
176 other_space->set_committed(other_space->committed_low_addr() + tmp_bytes, | |
177 other_space->committed_high_addr()); | |
178 other_space->set_reserved(other_space->reserved_low_addr() + tmp_bytes, | |
179 other_space->reserved_high_addr(), | |
180 other_space->special()); | |
181 | |
182 // Grow both reserved and committed in this space. | |
183 _reserved_high_addr += tmp_bytes; | |
184 _committed_high_addr += tmp_bytes; | |
185 } | |
186 | |
187 return bytes; | |
188 } | |
189 | |
190 #ifndef PRODUCT | |
191 bool PSVirtualSpace::is_aligned(size_t value, size_t align) { | |
192 const size_t tmp_value = value + align - 1; | |
193 const size_t mask = ~(align - 1); | |
194 return (tmp_value & mask) == value; | |
195 } | |
196 | |
197 bool PSVirtualSpace::is_aligned(size_t value) const { | |
198 return is_aligned(value, alignment()); | |
199 } | |
200 | |
201 bool PSVirtualSpace::is_aligned(char* value) const { | |
202 return is_aligned((size_t)value); | |
203 } | |
204 | |
205 void PSVirtualSpace::verify() const { | |
206 assert(is_aligned(alignment(), os::vm_page_size()), "bad alignment"); | |
207 assert(is_aligned(reserved_low_addr()), "bad reserved_low_addr"); | |
208 assert(is_aligned(reserved_high_addr()), "bad reserved_high_addr"); | |
209 assert(is_aligned(committed_low_addr()), "bad committed_low_addr"); | |
210 assert(is_aligned(committed_high_addr()), "bad committed_high_addr"); | |
211 | |
212 // Reserved region must be non-empty or both addrs must be 0. | |
213 assert(reserved_low_addr() < reserved_high_addr() || | |
214 reserved_low_addr() == NULL && reserved_high_addr() == NULL, | |
215 "bad reserved addrs"); | |
216 assert(committed_low_addr() <= committed_high_addr(), "bad committed addrs"); | |
217 | |
218 if (grows_up()) { | |
219 assert(reserved_low_addr() == committed_low_addr(), "bad low addrs"); | |
220 assert(reserved_high_addr() >= committed_high_addr(), "bad high addrs"); | |
221 } else { | |
222 assert(reserved_high_addr() == committed_high_addr(), "bad high addrs"); | |
223 assert(reserved_low_addr() <= committed_low_addr(), "bad low addrs"); | |
224 } | |
225 } | |
226 | |
227 void PSVirtualSpace::print() const { | |
228 gclog_or_tty->print_cr("virtual space [" PTR_FORMAT "]: alignment=" | |
229 SIZE_FORMAT "K grows %s%s", | |
230 this, alignment() / K, grows_up() ? "up" : "down", | |
231 special() ? " (pinned in memory)" : ""); | |
232 gclog_or_tty->print_cr(" reserved=" SIZE_FORMAT "K" | |
233 " [" PTR_FORMAT "," PTR_FORMAT "]" | |
234 " committed=" SIZE_FORMAT "K" | |
235 " [" PTR_FORMAT "," PTR_FORMAT "]", | |
236 reserved_size() / K, | |
237 reserved_low_addr(), reserved_high_addr(), | |
238 committed_size() / K, | |
239 committed_low_addr(), committed_high_addr()); | |
240 } | |
241 #endif // #ifndef PRODUCT | |
242 | |
243 void PSVirtualSpace::print_space_boundaries_on(outputStream* st) const { | |
244 st->print_cr(" [" PTR_FORMAT ", " PTR_FORMAT ", " PTR_FORMAT ")", | |
245 low_boundary(), high(), high_boundary()); | |
246 } | |
247 | |
248 PSVirtualSpaceHighToLow::PSVirtualSpaceHighToLow(ReservedSpace rs, | |
249 size_t alignment) : | |
250 PSVirtualSpace(alignment) | |
251 { | |
252 set_reserved(rs); | |
253 set_committed(reserved_high_addr(), reserved_high_addr()); | |
254 DEBUG_ONLY(verify()); | |
255 } | |
256 | |
257 PSVirtualSpaceHighToLow::PSVirtualSpaceHighToLow(ReservedSpace rs) { | |
258 set_reserved(rs); | |
259 set_committed(reserved_high_addr(), reserved_high_addr()); | |
260 DEBUG_ONLY(verify()); | |
261 } | |
262 | |
535
4e400c36026f
6783381: NUMA allocator: don't pretouch eden space with UseNUMA
iveresov
parents:
337
diff
changeset
|
263 bool PSVirtualSpaceHighToLow::expand_by(size_t bytes) { |
0 | 264 assert(is_aligned(bytes), "arg not aligned"); |
265 DEBUG_ONLY(PSVirtualSpaceVerifier this_verifier(this)); | |
266 | |
267 if (uncommitted_size() < bytes) { | |
268 return false; | |
269 } | |
270 | |
271 char* const base_addr = committed_low_addr() - bytes; | |
272 bool result = special() || os::commit_memory(base_addr, bytes, alignment()); | |
273 if (result) { | |
274 _committed_low_addr -= bytes; | |
275 } | |
276 | |
277 return result; | |
278 } | |
279 | |
280 bool PSVirtualSpaceHighToLow::shrink_by(size_t bytes) { | |
281 assert(is_aligned(bytes), "arg not aligned"); | |
282 DEBUG_ONLY(PSVirtualSpaceVerifier this_verifier(this)); | |
283 | |
284 if (committed_size() < bytes) { | |
285 return false; | |
286 } | |
287 | |
288 char* const base_addr = committed_low_addr(); | |
289 bool result = special() || os::uncommit_memory(base_addr, bytes); | |
290 if (result) { | |
291 _committed_low_addr += bytes; | |
292 } | |
293 | |
294 return result; | |
295 } | |
296 | |
297 size_t PSVirtualSpaceHighToLow::expand_into(PSVirtualSpace* other_space, | |
298 size_t bytes) { | |
299 assert(is_aligned(bytes), "arg not aligned"); | |
300 assert(grows_down(), "this space must grow down"); | |
301 assert(other_space->grows_up(), "other space must grow up"); | |
302 assert(reserved_low_addr() == other_space->reserved_high_addr(), | |
303 "spaces not contiguous"); | |
304 assert(special() == other_space->special(), "one space is special in memory, the other is not"); | |
305 DEBUG_ONLY(PSVirtualSpaceVerifier this_verifier(this)); | |
306 DEBUG_ONLY(PSVirtualSpaceVerifier other_verifier(other_space)); | |
307 | |
308 size_t bytes_needed = bytes; | |
309 | |
310 // First use the uncommitted region in this space. | |
311 size_t tmp_bytes = MIN2(uncommitted_size(), bytes_needed); | |
312 if (tmp_bytes > 0) { | |
313 if (expand_by(tmp_bytes)) { | |
314 bytes_needed -= tmp_bytes; | |
315 } else { | |
316 return 0; | |
317 } | |
318 } | |
319 | |
320 // Next take from the uncommitted region in the other space, and commit it. | |
321 tmp_bytes = MIN2(other_space->uncommitted_size(), bytes_needed); | |
322 if (tmp_bytes > 0) { | |
323 char* const commit_base = committed_low_addr() - tmp_bytes; | |
324 if (other_space->special() || | |
325 os::commit_memory(commit_base, tmp_bytes, alignment())) { | |
326 // Reduce the reserved region in the other space. | |
327 other_space->set_reserved(other_space->reserved_low_addr(), | |
328 other_space->reserved_high_addr() - tmp_bytes, | |
329 other_space->special()); | |
330 | |
331 // Grow both reserved and committed in this space. | |
332 _reserved_low_addr -= tmp_bytes; | |
333 _committed_low_addr -= tmp_bytes; | |
334 bytes_needed -= tmp_bytes; | |
335 } else { | |
336 return bytes - bytes_needed; | |
337 } | |
338 } | |
339 | |
340 // Finally take from the already committed region in the other space. | |
341 tmp_bytes = bytes_needed; | |
342 if (tmp_bytes > 0) { | |
343 // Reduce both committed and reserved in the other space. | |
344 other_space->set_committed(other_space->committed_low_addr(), | |
345 other_space->committed_high_addr() - tmp_bytes); | |
346 other_space->set_reserved(other_space->reserved_low_addr(), | |
347 other_space->reserved_high_addr() - tmp_bytes, | |
348 other_space->special()); | |
349 | |
350 // Grow both reserved and committed in this space. | |
351 _reserved_low_addr -= tmp_bytes; | |
352 _committed_low_addr -= tmp_bytes; | |
353 } | |
354 | |
355 return bytes; | |
356 } | |
357 | |
358 void | |
359 PSVirtualSpaceHighToLow::print_space_boundaries_on(outputStream* st) const { | |
360 st->print_cr(" (" PTR_FORMAT ", " PTR_FORMAT ", " PTR_FORMAT "]", | |
361 high_boundary(), low(), low_boundary()); | |
362 } |