Mercurial > hg > truffle
annotate src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp @ 20543:e7d0505c8a30
8059758: Footprint regressions with JDK-8038423
Summary: Changes in JDK-8038423 always initialize (zero out) virtual memory used for auxiliary data structures. This causes a footprint regression for G1 in startup benchmarks. This is because they do not touch that memory at all, so the operating system does not actually commit these pages. The fix is to, if the initialization value of the data structures matches the default value of just committed memory (=0), do not do anything.
Reviewed-by: jwilhelm, brutisso
author | tschatzl |
---|---|
date | Fri, 10 Oct 2014 15:51:58 +0200 |
parents | 55fb97c4c58d |
children | 4ca6dc0799b6 |
rev | line source |
---|---|
3960 | 1 /* |
17467
55fb97c4c58d
8029233: Update copyright year to match last edit in jdk8 hotspot repository for 2013
mikael
parents:
12077
diff
changeset
|
2 * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. |
3960 | 3 * Copyright 2007, 2008, 2009, 2010 Red Hat, Inc. |
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
5 * | |
6 * This code is free software; you can redistribute it and/or modify it | |
7 * under the terms of the GNU General Public License version 2 only, as | |
8 * published by the Free Software Foundation. | |
9 * | |
10 * This code is distributed in the hope that it will be useful, but WITHOUT | |
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
13 * version 2 for more details (a copy is included in the LICENSE file that | |
14 * accompanied this code). | |
15 * | |
16 * You should have received a copy of the GNU General Public License version | |
17 * 2 along with this work; if not, write to the Free Software Foundation, | |
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
19 * | |
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
21 * or visit www.oracle.com if you need additional information or have any | |
22 * questions. | |
23 * | |
24 */ | |
25 | |
6918 | 26 #if !defined(__APPLE__) && !defined(__NetBSD__) |
3960 | 27 #include <pthread.h> |
28 # include <pthread_np.h> /* For pthread_attr_get_np */ | |
29 #endif | |
30 | |
31 // no precompiled headers | |
32 #include "assembler_zero.inline.hpp" | |
33 #include "classfile/classLoader.hpp" | |
34 #include "classfile/systemDictionary.hpp" | |
35 #include "classfile/vmSymbols.hpp" | |
36 #include "code/icBuffer.hpp" | |
37 #include "code/vtableStubs.hpp" | |
38 #include "interpreter/interpreter.hpp" | |
39 #include "jvm_bsd.h" | |
40 #include "memory/allocation.inline.hpp" | |
41 #include "mutex_bsd.inline.hpp" | |
42 #include "nativeInst_zero.hpp" | |
43 #include "os_share_bsd.hpp" | |
44 #include "prims/jniFastGetField.hpp" | |
45 #include "prims/jvm.h" | |
46 #include "prims/jvm_misc.hpp" | |
47 #include "runtime/arguments.hpp" | |
48 #include "runtime/extendedPC.hpp" | |
49 #include "runtime/frame.inline.hpp" | |
50 #include "runtime/interfaceSupport.hpp" | |
51 #include "runtime/java.hpp" | |
52 #include "runtime/javaCalls.hpp" | |
53 #include "runtime/mutexLocker.hpp" | |
54 #include "runtime/osThread.hpp" | |
55 #include "runtime/sharedRuntime.hpp" | |
56 #include "runtime/stubRoutines.hpp" | |
7180
f34d701e952e
8003935: Simplify the needed includes for using Thread::current()
stefank
parents:
6918
diff
changeset
|
57 #include "runtime/thread.inline.hpp" |
3960 | 58 #include "runtime/timer.hpp" |
59 #include "utilities/events.hpp" | |
60 #include "utilities/vmError.hpp" | |
61 | |
62 address os::current_stack_pointer() { | |
63 address dummy = (address) &dummy; | |
64 return dummy; | |
65 } | |
66 | |
67 frame os::get_sender_for_C_frame(frame* fr) { | |
68 ShouldNotCallThis(); | |
12077 | 69 return frame(); |
3960 | 70 } |
71 | |
72 frame os::current_frame() { | |
73 // The only thing that calls this is the stack printing code in | |
74 // VMError::report: | |
75 // - Step 110 (printing stack bounds) uses the sp in the frame | |
76 // to determine the amount of free space on the stack. We | |
77 // set the sp to a close approximation of the real value in | |
78 // order to allow this step to complete. | |
79 // - Step 120 (printing native stack) tries to walk the stack. | |
80 // The frame we create has a NULL pc, which is ignored as an | |
81 // invalid frame. | |
82 frame dummy = frame(); | |
83 dummy.set_sp((intptr_t *) current_stack_pointer()); | |
84 return dummy; | |
85 } | |
86 | |
87 char* os::non_memory_address_word() { | |
88 // Must never look like an address returned by reserve_memory, | |
89 // even in its subfields (as defined by the CPU immediate fields, | |
90 // if the CPU splits constants across multiple instructions). | |
91 #ifdef SPARC | |
92 // On SPARC, 0 != %hi(any real address), because there is no | |
93 // allocation in the first 1Kb of the virtual address space. | |
94 return (char *) 0; | |
95 #else | |
96 // This is the value for x86; works pretty well for PPC too. | |
97 return (char *) -1; | |
98 #endif // SPARC | |
99 } | |
100 | |
6768
716e6ef4482a
7190089: NMT ON: NMT failed assertion on thread's stack base address
zgu
parents:
5903
diff
changeset
|
101 void os::initialize_thread(Thread* thr) { |
3960 | 102 // Nothing to do. |
103 } | |
104 | |
105 address os::Bsd::ucontext_get_pc(ucontext_t* uc) { | |
106 ShouldNotCallThis(); | |
12077 | 107 return NULL; |
3960 | 108 } |
109 | |
110 ExtendedPC os::fetch_frame_from_context(void* ucVoid, | |
111 intptr_t** ret_sp, | |
112 intptr_t** ret_fp) { | |
113 ShouldNotCallThis(); | |
12077 | 114 return ExtendedPC(); |
3960 | 115 } |
116 | |
117 frame os::fetch_frame_from_context(void* ucVoid) { | |
118 ShouldNotCallThis(); | |
12077 | 119 return frame(); |
3960 | 120 } |
121 | |
122 extern "C" JNIEXPORT int | |
123 JVM_handle_bsd_signal(int sig, | |
124 siginfo_t* info, | |
125 void* ucVoid, | |
126 int abort_if_unrecognized) { | |
127 ucontext_t* uc = (ucontext_t*) ucVoid; | |
128 | |
129 Thread* t = ThreadLocalStorage::get_thread_slow(); | |
130 | |
131 SignalHandlerMark shm(t); | |
132 | |
133 // Note: it's not uncommon that JNI code uses signal/sigset to | |
134 // install then restore certain signal handler (e.g. to temporarily | |
135 // block SIGPIPE, or have a SIGILL handler when detecting CPU | |
136 // type). When that happens, JVM_handle_bsd_signal() might be | |
137 // invoked with junk info/ucVoid. To avoid unnecessary crash when | |
138 // libjsig is not preloaded, try handle signals that do not require | |
139 // siginfo/ucontext first. | |
140 | |
141 if (sig == SIGPIPE || sig == SIGXFSZ) { | |
142 // allow chained handler to go first | |
143 if (os::Bsd::chained_handler(sig, info, ucVoid)) { | |
144 return true; | |
145 } else { | |
146 if (PrintMiscellaneous && (WizardMode || Verbose)) { | |
147 char buf[64]; | |
148 warning("Ignoring %s - see bugs 4229104 or 646499219", | |
149 os::exception_name(sig, buf, sizeof(buf))); | |
150 } | |
151 return true; | |
152 } | |
153 } | |
154 | |
155 JavaThread* thread = NULL; | |
156 VMThread* vmthread = NULL; | |
157 if (os::Bsd::signal_handlers_are_installed) { | |
158 if (t != NULL ){ | |
159 if(t->is_Java_thread()) { | |
160 thread = (JavaThread*)t; | |
161 } | |
162 else if(t->is_VM_thread()){ | |
163 vmthread = (VMThread *)t; | |
164 } | |
165 } | |
166 } | |
167 | |
168 if (info != NULL && thread != NULL) { | |
169 // Handle ALL stack overflow variations here | |
4006 | 170 if (sig == SIGSEGV || sig == SIGBUS) { |
3960 | 171 address addr = (address) info->si_addr; |
172 | |
173 // check if fault address is within thread stack | |
174 if (addr < thread->stack_base() && | |
175 addr >= thread->stack_base() - thread->stack_size()) { | |
176 // stack overflow | |
177 if (thread->in_stack_yellow_zone(addr)) { | |
178 thread->disable_stack_yellow_zone(); | |
179 ShouldNotCallThis(); | |
180 } | |
181 else if (thread->in_stack_red_zone(addr)) { | |
182 thread->disable_stack_red_zone(); | |
183 ShouldNotCallThis(); | |
184 } | |
185 } | |
186 } | |
187 | |
188 /*if (thread->thread_state() == _thread_in_Java) { | |
189 ShouldNotCallThis(); | |
190 } | |
191 else*/ if (thread->thread_state() == _thread_in_vm && | |
192 sig == SIGBUS && thread->doing_unsafe_access()) { | |
193 ShouldNotCallThis(); | |
194 } | |
195 | |
196 // jni_fast_Get<Primitive>Field can trap at certain pc's if a GC | |
197 // kicks in and the heap gets shrunk before the field access. | |
198 /*if (sig == SIGSEGV || sig == SIGBUS) { | |
199 address addr = JNI_FastGetField::find_slowcase_pc(pc); | |
200 if (addr != (address)-1) { | |
201 stub = addr; | |
202 } | |
203 }*/ | |
204 | |
205 // Check to see if we caught the safepoint code in the process | |
206 // of write protecting the memory serialization page. It write | |
207 // enables the page immediately after protecting it so we can | |
208 // just return to retry the write. | |
4006 | 209 if ((sig == SIGSEGV || sig == SIGBUS) && |
3960 | 210 os::is_memory_serialize_page(thread, (address) info->si_addr)) { |
211 // Block current thread until permission is restored. | |
212 os::block_on_serialize_page_trap(); | |
213 return true; | |
214 } | |
215 } | |
216 | |
217 // signal-chaining | |
218 if (os::Bsd::chained_handler(sig, info, ucVoid)) { | |
219 return true; | |
220 } | |
221 | |
222 if (!abort_if_unrecognized) { | |
223 // caller wants another chance, so give it to him | |
224 return false; | |
225 } | |
226 | |
227 #ifndef PRODUCT | |
228 if (sig == SIGSEGV) { | |
229 fatal("\n#" | |
230 "\n# /--------------------\\" | |
231 "\n# | segmentation fault |" | |
232 "\n# \\---\\ /--------------/" | |
233 "\n# /" | |
234 "\n# [-] |\\_/| " | |
235 "\n# (+)=C |o o|__ " | |
236 "\n# | | =-*-=__\\ " | |
237 "\n# OOO c_c_(___)"); | |
238 } | |
239 #endif // !PRODUCT | |
240 | |
4006 | 241 const char *fmt = |
242 "caught unhandled signal " INT32_FORMAT " at address " PTR_FORMAT; | |
243 char buf[128]; | |
3960 | 244 |
4006 | 245 sprintf(buf, fmt, sig, info->si_addr); |
3960 | 246 fatal(buf); |
12077 | 247 return false; |
3960 | 248 } |
249 | |
250 void os::Bsd::init_thread_fpu_state(void) { | |
251 // Nothing to do | |
252 } | |
253 | |
254 bool os::is_allocatable(size_t bytes) { | |
255 #ifdef _LP64 | |
256 return true; | |
257 #else | |
258 if (bytes < 2 * G) { | |
259 return true; | |
260 } | |
261 | |
262 char* addr = reserve_memory(bytes, NULL); | |
263 | |
264 if (addr != NULL) { | |
265 release_memory(addr, bytes); | |
266 } | |
267 | |
268 return addr != NULL; | |
269 #endif // _LP64 | |
270 } | |
271 | |
272 /////////////////////////////////////////////////////////////////////////////// | |
273 // thread stack | |
274 | |
275 size_t os::Bsd::min_stack_allowed = 64 * K; | |
276 | |
277 bool os::Bsd::supports_variable_stack_size() { | |
278 return true; | |
279 } | |
280 | |
281 size_t os::Bsd::default_stack_size(os::ThreadType thr_type) { | |
282 #ifdef _LP64 | |
283 size_t s = (thr_type == os::compiler_thread ? 4 * M : 1 * M); | |
284 #else | |
285 size_t s = (thr_type == os::compiler_thread ? 2 * M : 512 * K); | |
286 #endif // _LP64 | |
287 return s; | |
288 } | |
289 | |
290 size_t os::Bsd::default_guard_size(os::ThreadType thr_type) { | |
291 // Only enable glibc guard pages for non-Java threads | |
292 // (Java threads have HotSpot guard pages) | |
293 return (thr_type == java_thread ? 0 : page_size()); | |
294 } | |
295 | |
296 static void current_stack_region(address *bottom, size_t *size) { | |
297 address stack_bottom; | |
298 address stack_top; | |
299 size_t stack_bytes; | |
300 | |
301 #ifdef __APPLE__ | |
302 pthread_t self = pthread_self(); | |
303 stack_top = (address) pthread_get_stackaddr_np(self); | |
304 stack_bytes = pthread_get_stacksize_np(self); | |
305 stack_bottom = stack_top - stack_bytes; | |
306 #elif defined(__OpenBSD__) | |
307 stack_t ss; | |
308 int rslt = pthread_stackseg_np(pthread_self(), &ss); | |
309 | |
310 if (rslt != 0) | |
4006 | 311 fatal(err_msg("pthread_stackseg_np failed with err = " INT32_FORMAT, |
312 rslt)); | |
3960 | 313 |
314 stack_top = (address) ss.ss_sp; | |
315 stack_bytes = ss.ss_size; | |
316 stack_bottom = stack_top - stack_bytes; | |
6918 | 317 #else |
3960 | 318 pthread_attr_t attr; |
319 | |
320 int rslt = pthread_attr_init(&attr); | |
321 | |
322 // JVM needs to know exact stack location, abort if it fails | |
323 if (rslt != 0) | |
4006 | 324 fatal(err_msg("pthread_attr_init failed with err = " INT32_FORMAT, rslt)); |
3960 | 325 |
326 rslt = pthread_attr_get_np(pthread_self(), &attr); | |
327 | |
328 if (rslt != 0) | |
4006 | 329 fatal(err_msg("pthread_attr_get_np failed with err = " INT32_FORMAT, |
330 rslt)); | |
3960 | 331 |
332 if (pthread_attr_getstackaddr(&attr, (void **) &stack_bottom) != 0 || | |
333 pthread_attr_getstacksize(&attr, &stack_bytes) != 0) { | |
334 fatal("Can not locate current stack attributes!"); | |
335 } | |
336 | |
337 pthread_attr_destroy(&attr); | |
338 | |
339 stack_top = stack_bottom + stack_bytes; | |
340 #endif | |
341 | |
342 assert(os::current_stack_pointer() >= stack_bottom, "should do"); | |
343 assert(os::current_stack_pointer() < stack_top, "should do"); | |
344 | |
345 *bottom = stack_bottom; | |
346 *size = stack_top - stack_bottom; | |
347 } | |
348 | |
349 address os::current_stack_base() { | |
350 address bottom; | |
351 size_t size; | |
352 current_stack_region(&bottom, &size); | |
353 return bottom + size; | |
354 } | |
355 | |
356 size_t os::current_stack_size() { | |
357 // stack size includes normal stack and HotSpot guard pages | |
358 address bottom; | |
359 size_t size; | |
360 current_stack_region(&bottom, &size); | |
361 return size; | |
362 } | |
363 | |
364 ///////////////////////////////////////////////////////////////////////////// | |
365 // helper functions for fatal error handler | |
366 | |
367 void os::print_context(outputStream* st, void* context) { | |
368 ShouldNotCallThis(); | |
369 } | |
370 | |
371 void os::print_register_info(outputStream *st, void *context) { | |
372 ShouldNotCallThis(); | |
373 } | |
374 | |
375 ///////////////////////////////////////////////////////////////////////////// | |
376 // Stubs for things that would be in bsd_zero.s if it existed. | |
377 // You probably want to disassemble these monkeys to check they're ok. | |
378 | |
379 extern "C" { | |
380 int SpinPause() { | |
12077 | 381 return 1; |
3960 | 382 } |
383 | |
384 void _Copy_conjoint_jshorts_atomic(jshort* from, jshort* to, size_t count) { | |
385 if (from > to) { | |
386 jshort *end = from + count; | |
387 while (from < end) | |
388 *(to++) = *(from++); | |
389 } | |
390 else if (from < to) { | |
391 jshort *end = from; | |
392 from += count - 1; | |
393 to += count - 1; | |
394 while (from >= end) | |
395 *(to--) = *(from--); | |
396 } | |
397 } | |
398 void _Copy_conjoint_jints_atomic(jint* from, jint* to, size_t count) { | |
399 if (from > to) { | |
400 jint *end = from + count; | |
401 while (from < end) | |
402 *(to++) = *(from++); | |
403 } | |
404 else if (from < to) { | |
405 jint *end = from; | |
406 from += count - 1; | |
407 to += count - 1; | |
408 while (from >= end) | |
409 *(to--) = *(from--); | |
410 } | |
411 } | |
412 void _Copy_conjoint_jlongs_atomic(jlong* from, jlong* to, size_t count) { | |
413 if (from > to) { | |
414 jlong *end = from + count; | |
415 while (from < end) | |
416 os::atomic_copy64(from++, to++); | |
417 } | |
418 else if (from < to) { | |
419 jlong *end = from; | |
420 from += count - 1; | |
421 to += count - 1; | |
422 while (from >= end) | |
423 os::atomic_copy64(from--, to--); | |
424 } | |
425 } | |
426 | |
427 void _Copy_arrayof_conjoint_bytes(HeapWord* from, | |
428 HeapWord* to, | |
429 size_t count) { | |
430 memmove(to, from, count); | |
431 } | |
432 void _Copy_arrayof_conjoint_jshorts(HeapWord* from, | |
433 HeapWord* to, | |
434 size_t count) { | |
435 memmove(to, from, count * 2); | |
436 } | |
437 void _Copy_arrayof_conjoint_jints(HeapWord* from, | |
438 HeapWord* to, | |
439 size_t count) { | |
440 memmove(to, from, count * 4); | |
441 } | |
442 void _Copy_arrayof_conjoint_jlongs(HeapWord* from, | |
443 HeapWord* to, | |
444 size_t count) { | |
445 memmove(to, from, count * 8); | |
446 } | |
447 }; | |
448 | |
449 ///////////////////////////////////////////////////////////////////////////// | |
450 // Implementations of atomic operations not supported by processors. | |
451 // -- http://gcc.gnu.org/onlinedocs/gcc-4.2.1/gcc/Atomic-Builtins.html | |
452 | |
453 #ifndef _LP64 | |
454 extern "C" { | |
455 long long unsigned int __sync_val_compare_and_swap_8( | |
456 volatile void *ptr, | |
457 long long unsigned int oldval, | |
458 long long unsigned int newval) { | |
459 ShouldNotCallThis(); | |
460 } | |
461 }; | |
462 #endif // !_LP64 | |
5903
da4be62fb889
7147740: add assertions to check stack alignment on VM entry from generated code (x64)
roland
parents:
4006
diff
changeset
|
463 |
da4be62fb889
7147740: add assertions to check stack alignment on VM entry from generated code (x64)
roland
parents:
4006
diff
changeset
|
464 #ifndef PRODUCT |
da4be62fb889
7147740: add assertions to check stack alignment on VM entry from generated code (x64)
roland
parents:
4006
diff
changeset
|
465 void os::verify_stack_alignment() { |
da4be62fb889
7147740: add assertions to check stack alignment on VM entry from generated code (x64)
roland
parents:
4006
diff
changeset
|
466 } |
da4be62fb889
7147740: add assertions to check stack alignment on VM entry from generated code (x64)
roland
parents:
4006
diff
changeset
|
467 #endif |