Mercurial > hg > graal-jvmci-8
comparison src/os/linux/vm/os_linux.cpp @ 4137:04b9a2566eec
Merge with hsx23/hotspot.
author | Thomas Wuerthinger <thomas.wuerthinger@oracle.com> |
---|---|
date | Sat, 17 Dec 2011 21:40:27 +0100 |
parents | be4ca325525a 36b057451829 |
children | 33df1aeaebbf |
comparison
equal
deleted
inserted
replaced
3737:9dc19b7d89a3 | 4137:04b9a2566eec |
---|---|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
20 * or visit www.oracle.com if you need additional information or have any | 20 * or visit www.oracle.com if you need additional information or have any |
21 * questions. | 21 * questions. |
22 * | 22 * |
23 */ | 23 */ |
24 | |
25 # define __STDC_FORMAT_MACROS | |
26 | 24 |
27 // no precompiled headers | 25 // no precompiled headers |
28 #include "classfile/classLoader.hpp" | 26 #include "classfile/classLoader.hpp" |
29 #include "classfile/systemDictionary.hpp" | 27 #include "classfile/systemDictionary.hpp" |
30 #include "classfile/vmSymbols.hpp" | 28 #include "classfile/vmSymbols.hpp" |
167 sigset_t SR_sigset; | 165 sigset_t SR_sigset; |
168 | 166 |
169 /* Used to protect dlsym() calls */ | 167 /* Used to protect dlsym() calls */ |
170 static pthread_mutex_t dl_mutex; | 168 static pthread_mutex_t dl_mutex; |
171 | 169 |
172 //////////////////////////////////////////////////////////////////////////////// | 170 #ifdef JAVASE_EMBEDDED |
171 class MemNotifyThread: public Thread { | |
172 friend class VMStructs; | |
173 public: | |
174 virtual void run(); | |
175 | |
176 private: | |
177 static MemNotifyThread* _memnotify_thread; | |
178 int _fd; | |
179 | |
180 public: | |
181 | |
182 // Constructor | |
183 MemNotifyThread(int fd); | |
184 | |
185 // Tester | |
186 bool is_memnotify_thread() const { return true; } | |
187 | |
188 // Printing | |
189 char* name() const { return (char*)"Linux MemNotify Thread"; } | |
190 | |
191 // Returns the single instance of the MemNotifyThread | |
192 static MemNotifyThread* memnotify_thread() { return _memnotify_thread; } | |
193 | |
194 // Create and start the single instance of MemNotifyThread | |
195 static void start(); | |
196 }; | |
197 #endif // JAVASE_EMBEDDED | |
198 | |
173 // utility functions | 199 // utility functions |
174 | 200 |
175 static int SR_initialize(); | 201 static int SR_initialize(); |
176 static int SR_finalize(); | 202 static int SR_finalize(); |
177 | 203 |
2083 st->print("\n/proc/meminfo:\n"); | 2109 st->print("\n/proc/meminfo:\n"); |
2084 _print_ascii_file("/proc/meminfo", st); | 2110 _print_ascii_file("/proc/meminfo", st); |
2085 st->cr(); | 2111 st->cr(); |
2086 } | 2112 } |
2087 | 2113 |
2114 void os::pd_print_cpu_info(outputStream* st) { | |
2115 st->print("\n/proc/cpuinfo:\n"); | |
2116 if (!_print_ascii_file("/proc/cpuinfo", st)) { | |
2117 st->print(" <Not Available>"); | |
2118 } | |
2119 st->cr(); | |
2120 } | |
2121 | |
2088 void os::print_memory_info(outputStream* st) { | 2122 void os::print_memory_info(outputStream* st) { |
2089 | 2123 |
2090 st->print("Memory:"); | 2124 st->print("Memory:"); |
2091 st->print(" %dk page", os::vm_page_size()>>10); | 2125 st->print(" %dk page", os::vm_page_size()>>10); |
2092 | 2126 |
2460 // problem. | 2494 // problem. |
2461 bool os::commit_memory(char* addr, size_t size, bool exec) { | 2495 bool os::commit_memory(char* addr, size_t size, bool exec) { |
2462 int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE; | 2496 int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE; |
2463 uintptr_t res = (uintptr_t) ::mmap(addr, size, prot, | 2497 uintptr_t res = (uintptr_t) ::mmap(addr, size, prot, |
2464 MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0); | 2498 MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0); |
2465 return res != (uintptr_t) MAP_FAILED; | 2499 if (res != (uintptr_t) MAP_FAILED) { |
2500 if (UseNUMAInterleaving) { | |
2501 numa_make_global(addr, size); | |
2502 } | |
2503 return true; | |
2504 } | |
2505 return false; | |
2466 } | 2506 } |
2467 | 2507 |
2468 // Define MAP_HUGETLB here so we can build HotSpot on old systems. | 2508 // Define MAP_HUGETLB here so we can build HotSpot on old systems. |
2469 #ifndef MAP_HUGETLB | 2509 #ifndef MAP_HUGETLB |
2470 #define MAP_HUGETLB 0x40000 | 2510 #define MAP_HUGETLB 0x40000 |
2481 int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE; | 2521 int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE; |
2482 uintptr_t res = | 2522 uintptr_t res = |
2483 (uintptr_t) ::mmap(addr, size, prot, | 2523 (uintptr_t) ::mmap(addr, size, prot, |
2484 MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS|MAP_HUGETLB, | 2524 MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS|MAP_HUGETLB, |
2485 -1, 0); | 2525 -1, 0); |
2486 return res != (uintptr_t) MAP_FAILED; | 2526 if (res != (uintptr_t) MAP_FAILED) { |
2487 } | 2527 if (UseNUMAInterleaving) { |
2488 | 2528 numa_make_global(addr, size); |
2489 return commit_memory(addr, size, exec); | 2529 } |
2530 return true; | |
2531 } | |
2532 // Fall through and try to use small pages | |
2533 } | |
2534 | |
2535 if (commit_memory(addr, size, exec)) { | |
2536 realign_memory(addr, size, alignment_hint); | |
2537 return true; | |
2538 } | |
2539 return false; | |
2490 } | 2540 } |
2491 | 2541 |
2492 void os::realign_memory(char *addr, size_t bytes, size_t alignment_hint) { | 2542 void os::realign_memory(char *addr, size_t bytes, size_t alignment_hint) { |
2493 if (UseHugeTLBFS && alignment_hint > (size_t)vm_page_size()) { | 2543 if (UseHugeTLBFS && alignment_hint > (size_t)vm_page_size()) { |
2494 // We don't check the return value: madvise(MADV_HUGEPAGE) may not | 2544 // We don't check the return value: madvise(MADV_HUGEPAGE) may not |
2496 ::madvise(addr, bytes, MADV_HUGEPAGE); | 2546 ::madvise(addr, bytes, MADV_HUGEPAGE); |
2497 } | 2547 } |
2498 } | 2548 } |
2499 | 2549 |
2500 void os::free_memory(char *addr, size_t bytes) { | 2550 void os::free_memory(char *addr, size_t bytes) { |
2501 ::madvise(addr, bytes, MADV_DONTNEED); | 2551 commit_memory(addr, bytes, false); |
2502 } | 2552 } |
2503 | 2553 |
2504 void os::numa_make_global(char *addr, size_t bytes) { | 2554 void os::numa_make_global(char *addr, size_t bytes) { |
2505 Linux::numa_interleave_memory(addr, bytes); | 2555 Linux::numa_interleave_memory(addr, bytes); |
2506 } | 2556 } |
2538 return false; | 2588 return false; |
2539 } | 2589 } |
2540 | 2590 |
2541 char *os::scan_pages(char *start, char* end, page_info* page_expected, page_info* page_found) { | 2591 char *os::scan_pages(char *start, char* end, page_info* page_expected, page_info* page_found) { |
2542 return end; | 2592 return end; |
2593 } | |
2594 | |
2595 | |
2596 int os::Linux::sched_getcpu_syscall(void) { | |
2597 unsigned int cpu; | |
2598 int retval = -1; | |
2599 | |
2600 #if defined(IA32) | |
2601 # ifndef SYS_getcpu | |
2602 # define SYS_getcpu 318 | |
2603 # endif | |
2604 retval = syscall(SYS_getcpu, &cpu, NULL, NULL); | |
2605 #elif defined(AMD64) | |
2606 // Unfortunately we have to bring all these macros here from vsyscall.h | |
2607 // to be able to compile on old linuxes. | |
2608 # define __NR_vgetcpu 2 | |
2609 # define VSYSCALL_START (-10UL << 20) | |
2610 # define VSYSCALL_SIZE 1024 | |
2611 # define VSYSCALL_ADDR(vsyscall_nr) (VSYSCALL_START+VSYSCALL_SIZE*(vsyscall_nr)) | |
2612 typedef long (*vgetcpu_t)(unsigned int *cpu, unsigned int *node, unsigned long *tcache); | |
2613 vgetcpu_t vgetcpu = (vgetcpu_t)VSYSCALL_ADDR(__NR_vgetcpu); | |
2614 retval = vgetcpu(&cpu, NULL, NULL); | |
2615 #endif | |
2616 | |
2617 return (retval == -1) ? retval : cpu; | |
2543 } | 2618 } |
2544 | 2619 |
2545 // Something to do with the numa-aware allocator needs these symbols | 2620 // Something to do with the numa-aware allocator needs these symbols |
2546 extern "C" JNIEXPORT void numa_warn(int number, char *where, ...) { } | 2621 extern "C" JNIEXPORT void numa_warn(int number, char *where, ...) { } |
2547 extern "C" JNIEXPORT void numa_error(char *where) { } | 2622 extern "C" JNIEXPORT void numa_error(char *where) { } |
2562 | 2637 |
2563 bool os::Linux::libnuma_init() { | 2638 bool os::Linux::libnuma_init() { |
2564 // sched_getcpu() should be in libc. | 2639 // sched_getcpu() should be in libc. |
2565 set_sched_getcpu(CAST_TO_FN_PTR(sched_getcpu_func_t, | 2640 set_sched_getcpu(CAST_TO_FN_PTR(sched_getcpu_func_t, |
2566 dlsym(RTLD_DEFAULT, "sched_getcpu"))); | 2641 dlsym(RTLD_DEFAULT, "sched_getcpu"))); |
2642 | |
2643 // If it's not, try a direct syscall. | |
2644 if (sched_getcpu() == -1) | |
2645 set_sched_getcpu(CAST_TO_FN_PTR(sched_getcpu_func_t, (void*)&sched_getcpu_syscall)); | |
2567 | 2646 |
2568 if (sched_getcpu() != -1) { // Does it work? | 2647 if (sched_getcpu() != -1) { // Does it work? |
2569 void *handle = dlopen("libnuma.so.1", RTLD_LAZY); | 2648 void *handle = dlopen("libnuma.so.1", RTLD_LAZY); |
2570 if (handle != NULL) { | 2649 if (handle != NULL) { |
2571 set_numa_node_to_cpus(CAST_TO_FN_PTR(numa_node_to_cpus_func_t, | 2650 set_numa_node_to_cpus(CAST_TO_FN_PTR(numa_node_to_cpus_func_t, |
3051 if (warn_on_failure) { | 3130 if (warn_on_failure) { |
3052 jio_snprintf(msg, sizeof(msg), "Failed to attach shared memory (errno = %d).", err); | 3131 jio_snprintf(msg, sizeof(msg), "Failed to attach shared memory (errno = %d).", err); |
3053 warning(msg); | 3132 warning(msg); |
3054 } | 3133 } |
3055 return NULL; | 3134 return NULL; |
3135 } | |
3136 | |
3137 if ((addr != NULL) && UseNUMAInterleaving) { | |
3138 numa_make_global(addr, bytes); | |
3056 } | 3139 } |
3057 | 3140 |
3058 return addr; | 3141 return addr; |
3059 } | 3142 } |
3060 | 3143 |
3815 // Tell libjsig jvm finishes setting signal handlers | 3898 // Tell libjsig jvm finishes setting signal handlers |
3816 (*end_signal_setting)(); | 3899 (*end_signal_setting)(); |
3817 } | 3900 } |
3818 | 3901 |
3819 // We don't activate signal checker if libjsig is in place, we trust ourselves | 3902 // We don't activate signal checker if libjsig is in place, we trust ourselves |
3820 // and if UserSignalHandler is installed all bets are off | 3903 // and if UserSignalHandler is installed all bets are off. |
3904 // Log that signal checking is off only if -verbose:jni is specified. | |
3821 if (CheckJNICalls) { | 3905 if (CheckJNICalls) { |
3822 if (libjsig_is_loaded) { | 3906 if (libjsig_is_loaded) { |
3823 tty->print_cr("Info: libjsig is activated, all active signal checking is disabled"); | 3907 if (PrintJNIResolving) { |
3908 tty->print_cr("Info: libjsig is activated, all active signal checking is disabled"); | |
3909 } | |
3824 check_signals = false; | 3910 check_signals = false; |
3825 } | 3911 } |
3826 if (AllowUserSignalHandlers) { | 3912 if (AllowUserSignalHandlers) { |
3827 tty->print_cr("Info: AllowUserSignalHandlers is activated, all active signal checking is disabled"); | 3913 if (PrintJNIResolving) { |
3914 tty->print_cr("Info: AllowUserSignalHandlers is activated, all active signal checking is disabled"); | |
3915 } | |
3828 check_signals = false; | 3916 check_signals = false; |
3829 } | 3917 } |
3830 } | 3918 } |
3831 } | 3919 } |
3832 } | 3920 } |
4242 | 4330 |
4243 return JNI_OK; | 4331 return JNI_OK; |
4244 } | 4332 } |
4245 | 4333 |
4246 // this is called at the end of vm_initialization | 4334 // this is called at the end of vm_initialization |
4247 void os::init_3(void) { } | 4335 void os::init_3(void) |
4336 { | |
4337 #ifdef JAVASE_EMBEDDED | |
4338 // Start the MemNotifyThread | |
4339 if (LowMemoryProtection) { | |
4340 MemNotifyThread::start(); | |
4341 } | |
4342 return; | |
4343 #endif | |
4344 } | |
4248 | 4345 |
4249 // Mark the polling page as unreadable | 4346 // Mark the polling page as unreadable |
4250 void os::make_polling_page_unreadable(void) { | 4347 void os::make_polling_page_unreadable(void) { |
4251 if( !guard_memory((char*)_polling_page, Linux::page_size()) ) | 4348 if( !guard_memory((char*)_polling_page, Linux::page_size()) ) |
4252 fatal("Could not disable polling page"); | 4349 fatal("Could not disable polling page"); |
4263 // Linux doesn't yet have a (official) notion of processor sets, | 4360 // Linux doesn't yet have a (official) notion of processor sets, |
4264 // so just return the number of online processors. | 4361 // so just return the number of online processors. |
4265 int online_cpus = ::sysconf(_SC_NPROCESSORS_ONLN); | 4362 int online_cpus = ::sysconf(_SC_NPROCESSORS_ONLN); |
4266 assert(online_cpus > 0 && online_cpus <= processor_count(), "sanity check"); | 4363 assert(online_cpus > 0 && online_cpus <= processor_count(), "sanity check"); |
4267 return online_cpus; | 4364 return online_cpus; |
4365 } | |
4366 | |
4367 void os::set_native_thread_name(const char *name) { | |
4368 // Not yet implemented. | |
4369 return; | |
4268 } | 4370 } |
4269 | 4371 |
4270 bool os::distribute_processes(uint length, uint* distribution) { | 4372 bool os::distribute_processes(uint length, uint* distribution) { |
4271 // Not yet implemented. | 4373 // Not yet implemented. |
4272 return false; | 4374 return false; |
5328 } | 5430 } |
5329 } | 5431 } |
5330 | 5432 |
5331 // is_headless_jre() | 5433 // is_headless_jre() |
5332 // | 5434 // |
5333 // Test for the existence of libmawt in motif21 or xawt directories | 5435 // Test for the existence of xawt/libmawt.so or libawt_xawt.so |
5334 // in order to report if we are running in a headless jre | 5436 // in order to report if we are running in a headless jre |
5437 // | |
5438 // Since JDK8 xawt/libmawt.so was moved into the same directory | |
5439 // as libawt.so, and renamed libawt_xawt.so | |
5335 // | 5440 // |
5336 bool os::is_headless_jre() { | 5441 bool os::is_headless_jre() { |
5337 struct stat statbuf; | 5442 struct stat statbuf; |
5338 char buf[MAXPATHLEN]; | 5443 char buf[MAXPATHLEN]; |
5339 char libmawtpath[MAXPATHLEN]; | 5444 char libmawtpath[MAXPATHLEN]; |
5340 const char *xawtstr = "/xawt/libmawt.so"; | 5445 const char *xawtstr = "/xawt/libmawt.so"; |
5341 const char *motifstr = "/motif21/libmawt.so"; | 5446 const char *new_xawtstr = "/libawt_xawt.so"; |
5342 char *p; | 5447 char *p; |
5343 | 5448 |
5344 // Get path to libjvm.so | 5449 // Get path to libjvm.so |
5345 os::jvm_path(buf, sizeof(buf)); | 5450 os::jvm_path(buf, sizeof(buf)); |
5346 | 5451 |
5357 // check xawt/libmawt.so | 5462 // check xawt/libmawt.so |
5358 strcpy(libmawtpath, buf); | 5463 strcpy(libmawtpath, buf); |
5359 strcat(libmawtpath, xawtstr); | 5464 strcat(libmawtpath, xawtstr); |
5360 if (::stat(libmawtpath, &statbuf) == 0) return false; | 5465 if (::stat(libmawtpath, &statbuf) == 0) return false; |
5361 | 5466 |
5362 // check motif21/libmawt.so | 5467 // check libawt_xawt.so |
5363 strcpy(libmawtpath, buf); | 5468 strcpy(libmawtpath, buf); |
5364 strcat(libmawtpath, motifstr); | 5469 strcat(libmawtpath, new_xawtstr); |
5365 if (::stat(libmawtpath, &statbuf) == 0) return false; | 5470 if (::stat(libmawtpath, &statbuf) == 0) return false; |
5366 | 5471 |
5367 return true; | 5472 return true; |
5368 } | 5473 } |
5369 | 5474 |
5475 | |
5476 #ifdef JAVASE_EMBEDDED | |
5477 // | |
5478 // A thread to watch the '/dev/mem_notify' device, which will tell us when the OS is running low on memory. | |
5479 // | |
5480 MemNotifyThread* MemNotifyThread::_memnotify_thread = NULL; | |
5481 | |
5482 // ctor | |
5483 // | |
5484 MemNotifyThread::MemNotifyThread(int fd): Thread() { | |
5485 assert(memnotify_thread() == NULL, "we can only allocate one MemNotifyThread"); | |
5486 _fd = fd; | |
5487 | |
5488 if (os::create_thread(this, os::os_thread)) { | |
5489 _memnotify_thread = this; | |
5490 os::set_priority(this, NearMaxPriority); | |
5491 os::start_thread(this); | |
5492 } | |
5493 } | |
5494 | |
5495 // Where all the work gets done | |
5496 // | |
5497 void MemNotifyThread::run() { | |
5498 assert(this == memnotify_thread(), "expected the singleton MemNotifyThread"); | |
5499 | |
5500 // Set up the select arguments | |
5501 fd_set rfds; | |
5502 if (_fd != -1) { | |
5503 FD_ZERO(&rfds); | |
5504 FD_SET(_fd, &rfds); | |
5505 } | |
5506 | |
5507 // Now wait for the mem_notify device to wake up | |
5508 while (1) { | |
5509 // Wait for the mem_notify device to signal us.. | |
5510 int rc = select(_fd+1, _fd != -1 ? &rfds : NULL, NULL, NULL, NULL); | |
5511 if (rc == -1) { | |
5512 perror("select!\n"); | |
5513 break; | |
5514 } else if (rc) { | |
5515 //ssize_t free_before = os::available_memory(); | |
5516 //tty->print ("Notified: Free: %dK \n",os::available_memory()/1024); | |
5517 | |
5518 // The kernel is telling us there is not much memory left... | |
5519 // try to do something about that | |
5520 | |
5521 // If we are not already in a GC, try one. | |
5522 if (!Universe::heap()->is_gc_active()) { | |
5523 Universe::heap()->collect(GCCause::_allocation_failure); | |
5524 | |
5525 //ssize_t free_after = os::available_memory(); | |
5526 //tty->print ("Post-Notify: Free: %dK\n",free_after/1024); | |
5527 //tty->print ("GC freed: %dK\n", (free_after - free_before)/1024); | |
5528 } | |
5529 // We might want to do something like the following if we find the GC's are not helping... | |
5530 // Universe::heap()->size_policy()->set_gc_time_limit_exceeded(true); | |
5531 } | |
5532 } | |
5533 } | |
5534 | |
5535 // | |
5536 // See if the /dev/mem_notify device exists, and if so, start a thread to monitor it. | |
5537 // | |
5538 void MemNotifyThread::start() { | |
5539 int fd; | |
5540 fd = open ("/dev/mem_notify", O_RDONLY, 0); | |
5541 if (fd < 0) { | |
5542 return; | |
5543 } | |
5544 | |
5545 if (memnotify_thread() == NULL) { | |
5546 new MemNotifyThread(fd); | |
5547 } | |
5548 } | |
5549 #endif // JAVASE_EMBEDDED |