comparison src/os/linux/vm/os_linux.cpp @ 1681:126ea7725993

6953477: Increase portability and flexibility of building Hotspot Summary: A collection of portability improvements including shared code support for PPC, ARM platforms, software floating point, cross compilation support and improvements in error crash detail. Reviewed-by: phh, never, coleenp, dholmes
author bobv
date Tue, 03 Aug 2010 08:13:38 -0400
parents 0e7d2a08b605
children c7004d700b49
comparison
equal deleted inserted replaced
1680:a64438a2b7e8 1681:126ea7725993
28 # include "incls/_os_linux.cpp.incl" 28 # include "incls/_os_linux.cpp.incl"
29 29
30 // put OS-includes here 30 // put OS-includes here
31 # include <sys/types.h> 31 # include <sys/types.h>
32 # include <sys/mman.h> 32 # include <sys/mman.h>
33 # include <sys/stat.h>
34 # include <sys/select.h>
33 # include <pthread.h> 35 # include <pthread.h>
34 # include <signal.h> 36 # include <signal.h>
35 # include <errno.h> 37 # include <errno.h>
36 # include <dlfcn.h> 38 # include <dlfcn.h>
37 # include <stdio.h> 39 # include <stdio.h>
186 static char cpu_arch[] = "ia64"; 188 static char cpu_arch[] = "ia64";
187 #elif defined(IA32) 189 #elif defined(IA32)
188 static char cpu_arch[] = "i386"; 190 static char cpu_arch[] = "i386";
189 #elif defined(AMD64) 191 #elif defined(AMD64)
190 static char cpu_arch[] = "amd64"; 192 static char cpu_arch[] = "amd64";
193 #elif defined(ARM)
194 static char cpu_arch[] = "arm";
195 #elif defined(PPC)
196 static char cpu_arch[] = "ppc";
191 #elif defined(SPARC) 197 #elif defined(SPARC)
192 # ifdef _LP64 198 # ifdef _LP64
193 static char cpu_arch[] = "sparcv9"; 199 static char cpu_arch[] = "sparcv9";
194 # else 200 # else
195 static char cpu_arch[] = "sparc"; 201 static char cpu_arch[] = "sparc";
1135 long nice; 1141 long nice;
1136 long junk; 1142 long junk;
1137 long it_real; 1143 long it_real;
1138 uintptr_t start; 1144 uintptr_t start;
1139 uintptr_t vsize; 1145 uintptr_t vsize;
1140 uintptr_t rss; 1146 intptr_t rss;
1141 unsigned long rsslim; 1147 uintptr_t rsslim;
1142 uintptr_t scodes; 1148 uintptr_t scodes;
1143 uintptr_t ecode; 1149 uintptr_t ecode;
1144 int i; 1150 int i;
1145 1151
1146 // Figure what the primordial thread stack base is. Code is inspired 1152 // Figure what the primordial thread stack base is. Code is inspired
1166 i = 0; 1172 i = 0;
1167 if (s) { 1173 if (s) {
1168 // Skip blank chars 1174 // Skip blank chars
1169 do s++; while (isspace(*s)); 1175 do s++; while (isspace(*s));
1170 1176
1171 /* 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 */ 1177 #define _UFM UINTX_FORMAT
1172 /* 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 */ 1178 #define _DFM INTX_FORMAT
1173 i = sscanf(s, "%c %d %d %d %d %d %lu %lu %lu %lu %lu %lu %lu %ld %ld %ld %ld %ld %ld " 1179
1174 UINTX_FORMAT UINTX_FORMAT UINTX_FORMAT 1180 /* 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 */
1175 " %lu " 1181 /* 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 */
1176 UINTX_FORMAT UINTX_FORMAT UINTX_FORMAT, 1182 i = sscanf(s, "%c %d %d %d %d %d %lu %lu %lu %lu %lu %lu %lu %ld %ld %ld %ld %ld %ld " _UFM _UFM _DFM _UFM _UFM _UFM _UFM,
1177 &state, /* 3 %c */ 1183 &state, /* 3 %c */
1178 &ppid, /* 4 %d */ 1184 &ppid, /* 4 %d */
1179 &pgrp, /* 5 %d */ 1185 &pgrp, /* 5 %d */
1180 &session, /* 6 %d */ 1186 &session, /* 6 %d */
1181 &nr, /* 7 %d */ 1187 &nr, /* 7 %d */
1191 &cstime, /* 17 %ld */ 1197 &cstime, /* 17 %ld */
1192 &prio, /* 18 %ld */ 1198 &prio, /* 18 %ld */
1193 &nice, /* 19 %ld */ 1199 &nice, /* 19 %ld */
1194 &junk, /* 20 %ld */ 1200 &junk, /* 20 %ld */
1195 &it_real, /* 21 %ld */ 1201 &it_real, /* 21 %ld */
1196 &start, /* 22 UINTX_FORMAT */ 1202 &start, /* 22 UINTX_FORMAT */
1197 &vsize, /* 23 UINTX_FORMAT */ 1203 &vsize, /* 23 UINTX_FORMAT */
1198 &rss, /* 24 UINTX_FORMAT */ 1204 &rss, /* 24 INTX_FORMAT */
1199 &rsslim, /* 25 %lu */ 1205 &rsslim, /* 25 UINTX_FORMAT */
1200 &scodes, /* 26 UINTX_FORMAT */ 1206 &scodes, /* 26 UINTX_FORMAT */
1201 &ecode, /* 27 UINTX_FORMAT */ 1207 &ecode, /* 27 UINTX_FORMAT */
1202 &stack_start); /* 28 UINTX_FORMAT */ 1208 &stack_start); /* 28 UINTX_FORMAT */
1203 } 1209 }
1210
1211 #undef _UFM
1212 #undef _DFM
1204 1213
1205 if (i != 28 - 2) { 1214 if (i != 28 - 2) {
1206 assert(false, "Bad conversion from /proc/self/stat"); 1215 assert(false, "Bad conversion from /proc/self/stat");
1207 // product mode - assume we are the initial thread, good luck in the 1216 // product mode - assume we are the initial thread, good luck in the
1208 // embedded case. 1217 // embedded case.
1334 1343
1335 #ifndef SYS_clock_getres 1344 #ifndef SYS_clock_getres
1336 1345
1337 #if defined(IA32) || defined(AMD64) 1346 #if defined(IA32) || defined(AMD64)
1338 #define SYS_clock_getres IA32_ONLY(266) AMD64_ONLY(229) 1347 #define SYS_clock_getres IA32_ONLY(266) AMD64_ONLY(229)
1348 #define sys_clock_getres(x,y) ::syscall(SYS_clock_getres, x, y)
1339 #else 1349 #else
1340 #error Value of SYS_clock_getres not known on this platform 1350 #warning "SYS_clock_getres not defined for this platform, disabling fast_thread_cpu_time"
1351 #define sys_clock_getres(x,y) -1
1341 #endif 1352 #endif
1342 1353
1354 #else
1355 #define sys_clock_getres(x,y) ::syscall(SYS_clock_getres, x, y)
1343 #endif 1356 #endif
1344
1345 #define sys_clock_getres(x,y) ::syscall(SYS_clock_getres, x, y)
1346 1357
1347 void os::Linux::fast_thread_clock_init() { 1358 void os::Linux::fast_thread_clock_init() {
1348 if (!UseLinuxPosixThreadCPUClocks) { 1359 if (!UseLinuxPosixThreadCPUClocks) {
1349 return; 1360 return;
1350 } 1361 }
1903 !_print_ascii_file("/etc/sun-release", st) && 1914 !_print_ascii_file("/etc/sun-release", st) &&
1904 !_print_ascii_file("/etc/redhat-release", st) && 1915 !_print_ascii_file("/etc/redhat-release", st) &&
1905 !_print_ascii_file("/etc/SuSE-release", st) && 1916 !_print_ascii_file("/etc/SuSE-release", st) &&
1906 !_print_ascii_file("/etc/turbolinux-release", st) && 1917 !_print_ascii_file("/etc/turbolinux-release", st) &&
1907 !_print_ascii_file("/etc/gentoo-release", st) && 1918 !_print_ascii_file("/etc/gentoo-release", st) &&
1908 !_print_ascii_file("/etc/debian_version", st)) { 1919 !_print_ascii_file("/etc/debian_version", st) &&
1920 !_print_ascii_file("/etc/ltib-release", st) &&
1921 !_print_ascii_file("/etc/angstrom-version", st)) {
1909 st->print("Linux"); 1922 st->print("Linux");
1910 } 1923 }
1911 st->cr(); 1924 st->cr();
1912 1925
1913 // kernel 1926 // kernel
1968 // load average 1981 // load average
1969 st->print("load average:"); 1982 st->print("load average:");
1970 double loadavg[3]; 1983 double loadavg[3];
1971 os::loadavg(loadavg, 3); 1984 os::loadavg(loadavg, 3);
1972 st->print("%0.02f %0.02f %0.02f", loadavg[0], loadavg[1], loadavg[2]); 1985 st->print("%0.02f %0.02f %0.02f", loadavg[0], loadavg[1], loadavg[2]);
1986 st->cr();
1987
1988 // meminfo
1989 st->print("\n/proc/meminfo:\n");
1990 _print_ascii_file("/proc/meminfo", st);
1973 st->cr(); 1991 st->cr();
1974 } 1992 }
1975 1993
1976 void os::print_memory_info(outputStream* st) { 1994 void os::print_memory_info(outputStream* st) {
1977 1995
2095 char dli_fname[MAXPATHLEN]; 2113 char dli_fname[MAXPATHLEN];
2096 bool ret = dll_address_to_library_name( 2114 bool ret = dll_address_to_library_name(
2097 CAST_FROM_FN_PTR(address, os::jvm_path), 2115 CAST_FROM_FN_PTR(address, os::jvm_path),
2098 dli_fname, sizeof(dli_fname), NULL); 2116 dli_fname, sizeof(dli_fname), NULL);
2099 assert(ret != 0, "cannot locate libjvm"); 2117 assert(ret != 0, "cannot locate libjvm");
2100 if (realpath(dli_fname, buf) == NULL) 2118 char *rp = realpath(dli_fname, buf);
2119 if (rp == NULL)
2101 return; 2120 return;
2102 2121
2103 if (strcmp(Arguments::sun_java_launcher(), "gamma") == 0) { 2122 if (strcmp(Arguments::sun_java_launcher(), "gamma") == 0) {
2104 // Support for the gamma launcher. Typical value for buf is 2123 // Support for the gamma launcher. Typical value for buf is
2105 // "<JAVA_HOME>/jre/lib/<arch>/<vmtype>/libjvm.so". If "/jre/lib/" appears at 2124 // "<JAVA_HOME>/jre/lib/<arch>/<vmtype>/libjvm.so". If "/jre/lib/" appears at
2123 // Check the current module name "libjvm.so" or "libjvm_g.so". 2142 // Check the current module name "libjvm.so" or "libjvm_g.so".
2124 p = strrchr(buf, '/'); 2143 p = strrchr(buf, '/');
2125 assert(strstr(p, "/libjvm") == p, "invalid library name"); 2144 assert(strstr(p, "/libjvm") == p, "invalid library name");
2126 p = strstr(p, "_g") ? "_g" : ""; 2145 p = strstr(p, "_g") ? "_g" : "";
2127 2146
2128 if (realpath(java_home_var, buf) == NULL) 2147 rp = realpath(java_home_var, buf);
2148 if (rp == NULL)
2129 return; 2149 return;
2130 2150
2131 // determine if this is a legacy image or modules image 2151 // determine if this is a legacy image or modules image
2132 // modules image doesn't have "jre" subdirectory 2152 // modules image doesn't have "jre" subdirectory
2133 len = strlen(buf); 2153 len = strlen(buf);
2145 // "libhpi[_g].so" in hpi::initialize_get_interface(). 2165 // "libhpi[_g].so" in hpi::initialize_get_interface().
2146 len = strlen(buf); 2166 len = strlen(buf);
2147 snprintf(buf + len, buflen-len, "/hotspot/libjvm%s.so", p); 2167 snprintf(buf + len, buflen-len, "/hotspot/libjvm%s.so", p);
2148 } else { 2168 } else {
2149 // Go back to path of .so 2169 // Go back to path of .so
2150 if (realpath(dli_fname, buf) == NULL) 2170 rp = realpath(dli_fname, buf);
2171 if (rp == NULL)
2151 return; 2172 return;
2152 } 2173 }
2153 } 2174 }
2154 } 2175 }
2155 } 2176 }
2506 os::Linux::numa_tonode_memory_func_t os::Linux::_numa_tonode_memory; 2527 os::Linux::numa_tonode_memory_func_t os::Linux::_numa_tonode_memory;
2507 os::Linux::numa_interleave_memory_func_t os::Linux::_numa_interleave_memory; 2528 os::Linux::numa_interleave_memory_func_t os::Linux::_numa_interleave_memory;
2508 unsigned long* os::Linux::_numa_all_nodes; 2529 unsigned long* os::Linux::_numa_all_nodes;
2509 2530
2510 bool os::uncommit_memory(char* addr, size_t size) { 2531 bool os::uncommit_memory(char* addr, size_t size) {
2511 return ::mmap(addr, size, PROT_NONE, 2532 uintptr_t res = (uintptr_t) ::mmap(addr, size, PROT_NONE,
2512 MAP_PRIVATE|MAP_FIXED|MAP_NORESERVE|MAP_ANONYMOUS, -1, 0) 2533 MAP_PRIVATE|MAP_FIXED|MAP_NORESERVE|MAP_ANONYMOUS, -1, 0);
2513 != MAP_FAILED; 2534 return res != (uintptr_t) MAP_FAILED;
2514 } 2535 }
2515 2536
2516 // Linux uses a growable mapping for the stack, and if the mapping for 2537 // Linux uses a growable mapping for the stack, and if the mapping for
2517 // the stack guard pages is not removed when we detach a thread the 2538 // the stack guard pages is not removed when we detach a thread the
2518 // stack cannot grow beyond the pages where the stack guard was 2539 // stack cannot grow beyond the pages where the stack guard was
2716 // If we can't determine the value (e.g. /proc is not mounted, or the text 2737 // If we can't determine the value (e.g. /proc is not mounted, or the text
2717 // format has been changed), we'll use the largest page size supported by 2738 // format has been changed), we'll use the largest page size supported by
2718 // the processor. 2739 // the processor.
2719 2740
2720 #ifndef ZERO 2741 #ifndef ZERO
2721 _large_page_size = IA32_ONLY(4 * M) AMD64_ONLY(2 * M) IA64_ONLY(256 * M) SPARC_ONLY(4 * M); 2742 _large_page_size = IA32_ONLY(4 * M) AMD64_ONLY(2 * M) IA64_ONLY(256 * M) SPARC_ONLY(4 * M)
2743 ARM_ONLY(2 * M) PPC_ONLY(4 * M);
2722 #endif // ZERO 2744 #endif // ZERO
2723 2745
2724 FILE *fp = fopen("/proc/meminfo", "r"); 2746 FILE *fp = fopen("/proc/meminfo", "r");
2725 if (fp) { 2747 if (fp) {
2726 while (!feof(fp)) { 2748 while (!feof(fp)) {
3979 prio_init(); 4001 prio_init();
3980 4002
3981 return JNI_OK; 4003 return JNI_OK;
3982 } 4004 }
3983 4005
4006 // this is called at the end of vm_initialization
4007 void os::init_3(void) { }
4008
3984 // Mark the polling page as unreadable 4009 // Mark the polling page as unreadable
3985 void os::make_polling_page_unreadable(void) { 4010 void os::make_polling_page_unreadable(void) {
3986 if( !guard_memory((char*)_polling_page, Linux::page_size()) ) 4011 if( !guard_memory((char*)_polling_page, Linux::page_size()) )
3987 fatal("Could not disable polling page"); 4012 fatal("Could not disable polling page");
3988 }; 4013 };
4059 } 4084 }
4060 4085
4061 //////////////////////////////////////////////////////////////////////////////// 4086 ////////////////////////////////////////////////////////////////////////////////
4062 // debug support 4087 // debug support
4063 4088
4064 #ifndef PRODUCT
4065 static address same_page(address x, address y) { 4089 static address same_page(address x, address y) {
4066 int page_bits = -os::vm_page_size(); 4090 int page_bits = -os::vm_page_size();
4067 if ((intptr_t(x) & page_bits) == (intptr_t(y) & page_bits)) 4091 if ((intptr_t(x) & page_bits) == (intptr_t(y) & page_bits))
4068 return x; 4092 return x;
4069 else if (x > y) 4093 else if (x > y)
4070 return (address)(intptr_t(y) | ~page_bits) + 1; 4094 return (address)(intptr_t(y) | ~page_bits) + 1;
4071 else 4095 else
4072 return (address)(intptr_t(y) & page_bits); 4096 return (address)(intptr_t(y) & page_bits);
4073 } 4097 }
4074 4098
4075 bool os::find(address addr) { 4099 bool os::find(address addr, outputStream* st) {
4076 Dl_info dlinfo; 4100 Dl_info dlinfo;
4077 memset(&dlinfo, 0, sizeof(dlinfo)); 4101 memset(&dlinfo, 0, sizeof(dlinfo));
4078 if (dladdr(addr, &dlinfo)) { 4102 if (dladdr(addr, &dlinfo)) {
4079 tty->print(PTR_FORMAT ": ", addr); 4103 st->print(PTR_FORMAT ": ", addr);
4080 if (dlinfo.dli_sname != NULL) { 4104 if (dlinfo.dli_sname != NULL) {
4081 tty->print("%s+%#x", dlinfo.dli_sname, 4105 st->print("%s+%#x", dlinfo.dli_sname,
4082 addr - (intptr_t)dlinfo.dli_saddr); 4106 addr - (intptr_t)dlinfo.dli_saddr);
4083 } else if (dlinfo.dli_fname) { 4107 } else if (dlinfo.dli_fname) {
4084 tty->print("<offset %#x>", addr - (intptr_t)dlinfo.dli_fbase); 4108 st->print("<offset %#x>", addr - (intptr_t)dlinfo.dli_fbase);
4085 } else { 4109 } else {
4086 tty->print("<absolute address>"); 4110 st->print("<absolute address>");
4087 } 4111 }
4088 if (dlinfo.dli_fname) { 4112 if (dlinfo.dli_fname) {
4089 tty->print(" in %s", dlinfo.dli_fname); 4113 st->print(" in %s", dlinfo.dli_fname);
4090 } 4114 }
4091 if (dlinfo.dli_fbase) { 4115 if (dlinfo.dli_fbase) {
4092 tty->print(" at " PTR_FORMAT, dlinfo.dli_fbase); 4116 st->print(" at " PTR_FORMAT, dlinfo.dli_fbase);
4093 } 4117 }
4094 tty->cr(); 4118 st->cr();
4095 4119
4096 if (Verbose) { 4120 if (Verbose) {
4097 // decode some bytes around the PC 4121 // decode some bytes around the PC
4098 address begin = same_page(addr-40, addr); 4122 address begin = same_page(addr-40, addr);
4099 address end = same_page(addr+40, addr); 4123 address end = same_page(addr+40, addr);
4102 if (begin < lowest) begin = lowest; 4126 if (begin < lowest) begin = lowest;
4103 Dl_info dlinfo2; 4127 Dl_info dlinfo2;
4104 if (dladdr(end, &dlinfo2) && dlinfo2.dli_saddr != dlinfo.dli_saddr 4128 if (dladdr(end, &dlinfo2) && dlinfo2.dli_saddr != dlinfo.dli_saddr
4105 && end > dlinfo2.dli_saddr && dlinfo2.dli_saddr > begin) 4129 && end > dlinfo2.dli_saddr && dlinfo2.dli_saddr > begin)
4106 end = (address) dlinfo2.dli_saddr; 4130 end = (address) dlinfo2.dli_saddr;
4107 Disassembler::decode(begin, end); 4131 Disassembler::decode(begin, end, st);
4108 } 4132 }
4109 return true; 4133 return true;
4110 } 4134 }
4111 return false; 4135 return false;
4112 } 4136 }
4113
4114 #endif
4115 4137
4116 //////////////////////////////////////////////////////////////////////////////// 4138 ////////////////////////////////////////////////////////////////////////////////
4117 // misc 4139 // misc
4118 4140
4119 // This does not do anything on Linux. This is basically a hook for being 4141 // This does not do anything on Linux. This is basically a hook for being
4319 int statlen; 4341 int statlen;
4320 char proc_name[64]; 4342 char proc_name[64];
4321 int count; 4343 int count;
4322 long sys_time, user_time; 4344 long sys_time, user_time;
4323 char string[64]; 4345 char string[64];
4346 char cdummy;
4324 int idummy; 4347 int idummy;
4325 long ldummy; 4348 long ldummy;
4326 FILE *fp; 4349 FILE *fp;
4327 4350
4328 // We first try accessing /proc/<pid>/cpu since this is faster to 4351 // We first try accessing /proc/<pid>/cpu since this is faster to
4379 if (s == NULL ) return -1; 4402 if (s == NULL ) return -1;
4380 4403
4381 // Skip blank chars 4404 // Skip blank chars
4382 do s++; while (isspace(*s)); 4405 do s++; while (isspace(*s));
4383 4406
4384 count = sscanf(s,"%*c %d %d %d %d %d %lu %lu %lu %lu %lu %lu %lu", 4407 count = sscanf(s,"%c %d %d %d %d %d %lu %lu %lu %lu %lu %lu %lu",
4385 &idummy, &idummy, &idummy, &idummy, &idummy, 4408 &cdummy, &idummy, &idummy, &idummy, &idummy, &idummy,
4386 &ldummy, &ldummy, &ldummy, &ldummy, &ldummy, 4409 &ldummy, &ldummy, &ldummy, &ldummy, &ldummy,
4387 &user_time, &sys_time); 4410 &user_time, &sys_time);
4388 if ( count != 12 ) return -1; 4411 if ( count != 13 ) return -1;
4389 if (user_sys_cpu_time) { 4412 if (user_sys_cpu_time) {
4390 return ((jlong)sys_time + (jlong)user_time) * (1000000000 / clock_tics_per_sec); 4413 return ((jlong)sys_time + (jlong)user_time) * (1000000000 / clock_tics_per_sec);
4391 } else { 4414 } else {
4392 return (jlong)user_time * (1000000000 / clock_tics_per_sec); 4415 return (jlong)user_time * (1000000000 / clock_tics_per_sec);
4393 } 4416 }
4978 // Unknown exit code; pass it through 5001 // Unknown exit code; pass it through
4979 return status; 5002 return status;
4980 } 5003 }
4981 } 5004 }
4982 } 5005 }
5006
5007 // is_headless_jre()
5008 //
5009 // Test for the existence of libmawt in motif21 or xawt directories
5010 // in order to report if we are running in a headless jre
5011 //
5012 bool os::is_headless_jre() {
5013 struct stat statbuf;
5014 char buf[MAXPATHLEN];
5015 char libmawtpath[MAXPATHLEN];
5016 const char *xawtstr = "/xawt/libmawt.so";
5017 const char *motifstr = "/motif21/libmawt.so";
5018 char *p;
5019
5020 // Get path to libjvm.so
5021 os::jvm_path(buf, sizeof(buf));
5022
5023 // Get rid of libjvm.so
5024 p = strrchr(buf, '/');
5025 if (p == NULL) return false;
5026 else *p = '\0';
5027
5028 // Get rid of client or server
5029 p = strrchr(buf, '/');
5030 if (p == NULL) return false;
5031 else *p = '\0';
5032
5033 // check xawt/libmawt.so
5034 strcpy(libmawtpath, buf);
5035 strcat(libmawtpath, xawtstr);
5036 if (::stat(libmawtpath, &statbuf) == 0) return false;
5037
5038 // check motif21/libmawt.so
5039 strcpy(libmawtpath, buf);
5040 strcat(libmawtpath, motifstr);
5041 if (::stat(libmawtpath, &statbuf) == 0) return false;
5042
5043 return true;
5044 }
5045