Mercurial > hg > release > icedtea7-forest-2.4 > hotspot
changeset 4805:4cc0a758a4dc
Merge
author | jprovino |
---|---|
date | Wed, 17 Jul 2013 11:16:35 -0400 |
parents | f9b44439e294 (current diff) 370cbb35dbca (diff) |
children | a9e7513d1e09 |
files | src/share/vm/services/memTracker.cpp |
diffstat | 36 files changed, 1092 insertions(+), 336 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgtags Wed Jul 17 11:12:43 2013 -0400 +++ b/.hgtags Wed Jul 17 11:16:35 2013 -0400 @@ -513,3 +513,5 @@ 2417fa1acf2ba8521f480f2baef9af279ec2bf15 hs24-b51 9658c969b7cf0de256691a80f44dcfe73d72a02f jdk7u40-b32 15706a73a506943059a6bbf59e2ec8866a026114 hs24-b52 +0b9149d22ee08fe13b4f198ff258a1348e27b8b2 jdk7u40-b33 +1118c5d38ac0693d98f913485ceb3c57366cfbab hs24-b53
--- a/make/hotspot_version Wed Jul 17 11:12:43 2013 -0400 +++ b/make/hotspot_version Wed Jul 17 11:16:35 2013 -0400 @@ -35,7 +35,7 @@ HS_MAJOR_VER=24 HS_MINOR_VER=0 -HS_BUILD_NUMBER=53 +HS_BUILD_NUMBER=54 JDK_MAJOR_VER=1 JDK_MINOR_VER=7
--- a/src/cpu/x86/vm/stubGenerator_x86_64.cpp Wed Jul 17 11:12:43 2013 -0400 +++ b/src/cpu/x86/vm/stubGenerator_x86_64.cpp Wed Jul 17 11:16:35 2013 -0400 @@ -290,7 +290,7 @@ __ stmxcsr(mxcsr_save); __ movl(rax, mxcsr_save); __ andl(rax, MXCSR_MASK); // Only check control and mask bits - ExternalAddress mxcsr_std(StubRoutines::x86::mxcsr_std()); + ExternalAddress mxcsr_std(StubRoutines::addr_mxcsr_std()); __ cmp32(rax, mxcsr_std); __ jcc(Assembler::equal, skip_ldmx); __ ldmxcsr(mxcsr_std); @@ -740,17 +740,18 @@ if (CheckJNICalls) { Label ok_ret; + ExternalAddress mxcsr_std(StubRoutines::addr_mxcsr_std()); __ push(rax); __ subptr(rsp, wordSize); // allocate a temp location __ stmxcsr(mxcsr_save); __ movl(rax, mxcsr_save); __ andl(rax, MXCSR_MASK); // Only check control and mask bits - __ cmpl(rax, *(int *)(StubRoutines::x86::mxcsr_std())); + __ cmp32(rax, mxcsr_std); __ jcc(Assembler::equal, ok_ret); __ warn("MXCSR changed by native JNI code, use -XX:+RestoreMXCSROnJNICall"); - __ ldmxcsr(ExternalAddress(StubRoutines::x86::mxcsr_std())); + __ ldmxcsr(mxcsr_std); __ bind(ok_ret); __ addptr(rsp, wordSize); @@ -3719,12 +3720,35 @@ return stub->entry_point(); } + void create_control_words() { + // Round to nearest, 53-bit mode, exceptions masked + StubRoutines::_fpu_cntrl_wrd_std = 0x027F; + // Round to zero, 53-bit mode, exception mased + StubRoutines::_fpu_cntrl_wrd_trunc = 0x0D7F; + // Round to nearest, 24-bit mode, exceptions masked + StubRoutines::_fpu_cntrl_wrd_24 = 0x007F; + // Round to nearest, 64-bit mode, exceptions masked + StubRoutines::_fpu_cntrl_wrd_64 = 0x037F; + // Round to nearest, 64-bit mode, exceptions masked + StubRoutines::_mxcsr_std = 0x1F80; + // Note: the following two constants are 80-bit values + // layout is critical for correct loading by FPU. + // Bias for strict fp multiply/divide + StubRoutines::_fpu_subnormal_bias1[0]= 0x00000000; // 2^(-15360) == 0x03ff 8000 0000 0000 0000 + StubRoutines::_fpu_subnormal_bias1[1]= 0x80000000; + StubRoutines::_fpu_subnormal_bias1[2]= 0x03ff; + // Un-Bias for strict fp multiply/divide + StubRoutines::_fpu_subnormal_bias2[0]= 0x00000000; // 2^(+15360) == 0x7bff 8000 0000 0000 0000 + StubRoutines::_fpu_subnormal_bias2[1]= 0x80000000; + StubRoutines::_fpu_subnormal_bias2[2]= 0x7bff; + } + // Initialization void generate_initial() { // Generates all stubs and initializes the entry points - // This platform-specific stub is needed by generate_call_stub() - StubRoutines::x86::_mxcsr_std = generate_fp_mask("mxcsr_std", 0x0000000000001F80); + // This platform-specific settings are needed by generate_call_stub() + create_control_words(); // entry points that exist in all platforms Note: This is code // that could be shared among different platforms - however the
--- a/src/cpu/x86/vm/stubRoutines_x86_64.cpp Wed Jul 17 11:12:43 2013 -0400 +++ b/src/cpu/x86/vm/stubRoutines_x86_64.cpp Wed Jul 17 11:16:35 2013 -0400 @@ -55,5 +55,4 @@ address StubRoutines::x86::_float_sign_flip = NULL; address StubRoutines::x86::_double_sign_mask = NULL; address StubRoutines::x86::_double_sign_flip = NULL; -address StubRoutines::x86::_mxcsr_std = NULL; address StubRoutines::x86::_key_shuffle_mask_addr = NULL;
--- a/src/cpu/x86/vm/stubRoutines_x86_64.hpp Wed Jul 17 11:12:43 2013 -0400 +++ b/src/cpu/x86/vm/stubRoutines_x86_64.hpp Wed Jul 17 11:16:35 2013 -0400 @@ -53,7 +53,6 @@ static address _float_sign_flip; static address _double_sign_mask; static address _double_sign_flip; - static address _mxcsr_std; // shuffle mask for fixing up 128-bit words consisting of big-endian 32-bit integers static address _key_shuffle_mask_addr; @@ -114,11 +113,6 @@ return _double_sign_flip; } - static address mxcsr_std() - { - return _mxcsr_std; - } - static address key_shuffle_mask_addr() { return _key_shuffle_mask_addr; } };
--- a/src/os/bsd/vm/attachListener_bsd.cpp Wed Jul 17 11:12:43 2013 -0400 +++ b/src/os/bsd/vm/attachListener_bsd.cpp Wed Jul 17 11:16:35 2013 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -452,6 +452,30 @@ return op; } + +// Performs initialization at vm startup +// For BSD we remove any stale .java_pid file which could cause +// an attaching process to think we are ready to receive on the +// domain socket before we are properly initialized + +void AttachListener::vm_start() { + char fn[UNIX_PATH_MAX]; + struct stat64 st; + int ret; + + int n = snprintf(fn, UNIX_PATH_MAX, "%s/.java_pid%d", + os::get_temp_directory(), os::current_process_id()); + assert(n < (int)UNIX_PATH_MAX, "java_pid file name buffer overflow"); + + RESTARTABLE(::stat64(fn, &st), ret); + if (ret == 0) { + ret = ::unlink(fn); + if (ret == -1) { + debug_only(warning("failed to remove stale attach pid file at %s", fn)); + } + } +} + int AttachListener::pd_init() { JavaThread* thread = JavaThread::current(); ThreadBlockInVM tbivm(thread);
--- a/src/os/bsd/vm/os_bsd.cpp Wed Jul 17 11:12:43 2013 -0400 +++ b/src/os/bsd/vm/os_bsd.cpp Wed Jul 17 11:16:35 2013 -0400 @@ -1946,12 +1946,13 @@ Dl_info dlinfo; if (libjvm_base_addr == NULL) { - dladdr(CAST_FROM_FN_PTR(void *, os::address_is_in_vm), &dlinfo); - libjvm_base_addr = (address)dlinfo.dli_fbase; + if (dladdr(CAST_FROM_FN_PTR(void *, os::address_is_in_vm), &dlinfo) != 0) { + libjvm_base_addr = (address)dlinfo.dli_fbase; + } assert(libjvm_base_addr !=NULL, "Cannot obtain base address for libjvm"); } - if (dladdr((void *)addr, &dlinfo)) { + if (dladdr((void *)addr, &dlinfo) != 0) { if (libjvm_base_addr == (address)dlinfo.dli_fbase) return true; } @@ -1963,35 +1964,40 @@ bool os::dll_address_to_function_name(address addr, char *buf, int buflen, int *offset) { + // buf is not optional, but offset is optional + assert(buf != NULL, "sanity check"); + Dl_info dlinfo; char localbuf[MACH_MAXSYMLEN]; - // dladdr will find names of dynamic functions only, but does - // it set dli_fbase with mach_header address when it "fails" ? - if (dladdr((void*)addr, &dlinfo) && dlinfo.dli_sname != NULL) { - if (buf != NULL) { - if(!Decoder::demangle(dlinfo.dli_sname, buf, buflen)) { + if (dladdr((void*)addr, &dlinfo) != 0) { + // see if we have a matching symbol + if (dlinfo.dli_saddr != NULL && dlinfo.dli_sname != NULL) { + if (!Decoder::demangle(dlinfo.dli_sname, buf, buflen)) { jio_snprintf(buf, buflen, "%s", dlinfo.dli_sname); } + if (offset != NULL) *offset = addr - (address)dlinfo.dli_saddr; + return true; + } + // no matching symbol so try for just file info + if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != NULL) { + if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase), + buf, buflen, offset, dlinfo.dli_fname)) { + return true; + } } - if (offset != NULL) *offset = addr - (address)dlinfo.dli_saddr; - return true; - } else if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != 0) { - if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase), - buf, buflen, offset, dlinfo.dli_fname)) { - return true; + + // Handle non-dynamic manually: + if (dlinfo.dli_fbase != NULL && + Decoder::decode(addr, localbuf, MACH_MAXSYMLEN, offset, + dlinfo.dli_fbase)) { + if (!Decoder::demangle(localbuf, buf, buflen)) { + jio_snprintf(buf, buflen, "%s", localbuf); + } + return true; } } - - // Handle non-dymanic manually: - if (dlinfo.dli_fbase != NULL && - Decoder::decode(addr, localbuf, MACH_MAXSYMLEN, offset, dlinfo.dli_fbase)) { - if(!Decoder::demangle(localbuf, buf, buflen)) { - jio_snprintf(buf, buflen, "%s", localbuf); - } - return true; - } - if (buf != NULL) buf[0] = '\0'; + buf[0] = '\0'; if (offset != NULL) *offset = -1; return false; } @@ -2000,17 +2006,24 @@ // ported from solaris version bool os::dll_address_to_library_name(address addr, char* buf, int buflen, int* offset) { + // buf is not optional, but offset is optional + assert(buf != NULL, "sanity check"); + Dl_info dlinfo; - if (dladdr((void*)addr, &dlinfo)){ - if (buf) jio_snprintf(buf, buflen, "%s", dlinfo.dli_fname); - if (offset) *offset = addr - (address)dlinfo.dli_fbase; - return true; - } else { - if (buf) buf[0] = '\0'; - if (offset) *offset = -1; - return false; - } + if (dladdr((void*)addr, &dlinfo) != 0) { + if (dlinfo.dli_fname != NULL) { + jio_snprintf(buf, buflen, "%s", dlinfo.dli_fname); + } + if (dlinfo.dli_fbase != NULL && offset != NULL) { + *offset = addr - (address)dlinfo.dli_fbase; + } + return true; + } + + buf[0] = '\0'; + if (offset) *offset = -1; + return false; } #else struct _address_to_library_name { @@ -2309,60 +2322,61 @@ } void os::print_dll_info(outputStream *st) { - st->print_cr("Dynamic libraries:"); + st->print_cr("Dynamic libraries:"); #ifdef _ALLBSD_SOURCE #ifdef RTLD_DI_LINKMAP - Dl_info dli; - void *handle; - Link_map *map; - Link_map *p; - - if (!dladdr(CAST_FROM_FN_PTR(void *, os::print_dll_info), &dli)) { - st->print_cr("Error: Cannot print dynamic libraries."); - return; - } - handle = dlopen(dli.dli_fname, RTLD_LAZY); - if (handle == NULL) { - st->print_cr("Error: Cannot print dynamic libraries."); - return; - } - dlinfo(handle, RTLD_DI_LINKMAP, &map); - if (map == NULL) { - st->print_cr("Error: Cannot print dynamic libraries."); - return; - } - - while (map->l_prev != NULL) - map = map->l_prev; - - while (map != NULL) { - st->print_cr(PTR_FORMAT " \t%s", map->l_addr, map->l_name); - map = map->l_next; - } - - dlclose(handle); + Dl_info dli; + void *handle; + Link_map *map; + Link_map *p; + + if (dladdr(CAST_FROM_FN_PTR(void *, os::print_dll_info), &dli) == 0 || + dli.dli_fname == NULL) { + st->print_cr("Error: Cannot print dynamic libraries."); + return; + } + handle = dlopen(dli.dli_fname, RTLD_LAZY); + if (handle == NULL) { + st->print_cr("Error: Cannot print dynamic libraries."); + return; + } + dlinfo(handle, RTLD_DI_LINKMAP, &map); + if (map == NULL) { + st->print_cr("Error: Cannot print dynamic libraries."); + return; + } + + while (map->l_prev != NULL) + map = map->l_prev; + + while (map != NULL) { + st->print_cr(PTR_FORMAT " \t%s", map->l_addr, map->l_name); + map = map->l_next; + } + + dlclose(handle); #elif defined(__APPLE__) - uint32_t count; - uint32_t i; - - count = _dyld_image_count(); - for (i = 1; i < count; i++) { - const char *name = _dyld_get_image_name(i); - intptr_t slide = _dyld_get_image_vmaddr_slide(i); - st->print_cr(PTR_FORMAT " \t%s", slide, name); - } + uint32_t count; + uint32_t i; + + count = _dyld_image_count(); + for (i = 1; i < count; i++) { + const char *name = _dyld_get_image_name(i); + intptr_t slide = _dyld_get_image_vmaddr_slide(i); + st->print_cr(PTR_FORMAT " \t%s", slide, name); + } #else - st->print_cr("Error: Cannot print dynamic libraries."); + st->print_cr("Error: Cannot print dynamic libraries."); #endif #else - char fname[32]; - pid_t pid = os::Bsd::gettid(); - - jio_snprintf(fname, sizeof(fname), "/proc/%d/maps", pid); - - if (!_print_ascii_file(fname, st)) { - st->print("Can not get library information for pid = %d\n", pid); - } + char fname[32]; + pid_t pid = os::Bsd::gettid(); + + jio_snprintf(fname, sizeof(fname), "/proc/%d/maps", pid); + + if (!_print_ascii_file(fname, st)) { + st->print("Can not get library information for pid = %d\n", pid); + } #endif } @@ -2519,8 +2533,11 @@ bool ret = dll_address_to_library_name( CAST_FROM_FN_PTR(address, os::jvm_path), dli_fname, sizeof(dli_fname), NULL); - assert(ret != 0, "cannot locate libjvm"); - char *rp = realpath(dli_fname, buf); + assert(ret, "cannot locate libjvm"); + char *rp = NULL; + if (ret && dli_fname[0] != '\0') { + rp = realpath(dli_fname, buf); + } if (rp == NULL) return; @@ -4985,20 +5002,20 @@ bool os::find(address addr, outputStream* st) { Dl_info dlinfo; memset(&dlinfo, 0, sizeof(dlinfo)); - if (dladdr(addr, &dlinfo)) { + if (dladdr(addr, &dlinfo) != 0) { st->print(PTR_FORMAT ": ", addr); - if (dlinfo.dli_sname != NULL) { + if (dlinfo.dli_sname != NULL && dlinfo.dli_saddr != NULL) { st->print("%s+%#x", dlinfo.dli_sname, addr - (intptr_t)dlinfo.dli_saddr); - } else if (dlinfo.dli_fname) { + } else if (dlinfo.dli_fbase != NULL) { st->print("<offset %#x>", addr - (intptr_t)dlinfo.dli_fbase); } else { st->print("<absolute address>"); } - if (dlinfo.dli_fname) { + if (dlinfo.dli_fname != NULL) { st->print(" in %s", dlinfo.dli_fname); } - if (dlinfo.dli_fbase) { + if (dlinfo.dli_fbase != NULL) { st->print(" at " PTR_FORMAT, dlinfo.dli_fbase); } st->cr(); @@ -5011,7 +5028,7 @@ if (!lowest) lowest = (address) dlinfo.dli_fbase; if (begin < lowest) begin = lowest; Dl_info dlinfo2; - if (dladdr(end, &dlinfo2) && dlinfo2.dli_saddr != dlinfo.dli_saddr + if (dladdr(end, &dlinfo2) != 0 && dlinfo2.dli_saddr != dlinfo.dli_saddr && end > dlinfo2.dli_saddr && dlinfo2.dli_saddr > begin) end = (address) dlinfo2.dli_saddr; Disassembler::decode(begin, end, st);
--- a/src/os/linux/vm/attachListener_linux.cpp Wed Jul 17 11:12:43 2013 -0400 +++ b/src/os/linux/vm/attachListener_linux.cpp Wed Jul 17 11:16:35 2013 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -435,6 +435,30 @@ return op; } + +// Performs initialization at vm startup +// For Linux we remove any stale .java_pid file which could cause +// an attaching process to think we are ready to receive on the +// domain socket before we are properly initialized + +void AttachListener::vm_start() { + char fn[UNIX_PATH_MAX]; + struct stat64 st; + int ret; + + int n = snprintf(fn, UNIX_PATH_MAX, "%s/.java_pid%d", + os::get_temp_directory(), os::current_process_id()); + assert(n < (int)UNIX_PATH_MAX, "java_pid file name buffer overflow"); + + RESTARTABLE(::stat64(fn, &st), ret); + if (ret == 0) { + ret = ::unlink(fn); + if (ret == -1) { + debug_only(warning("failed to remove stale attach pid file at %s", fn)); + } + } +} + int AttachListener::pd_init() { JavaThread* thread = JavaThread::current(); ThreadBlockInVM tbivm(thread);
--- a/src/os/linux/vm/os_linux.cpp Wed Jul 17 11:12:43 2013 -0400 +++ b/src/os/linux/vm/os_linux.cpp Wed Jul 17 11:16:35 2013 -0400 @@ -1707,12 +1707,13 @@ Dl_info dlinfo; if (libjvm_base_addr == NULL) { - dladdr(CAST_FROM_FN_PTR(void *, os::address_is_in_vm), &dlinfo); - libjvm_base_addr = (address)dlinfo.dli_fbase; + if (dladdr(CAST_FROM_FN_PTR(void *, os::address_is_in_vm), &dlinfo) != 0) { + libjvm_base_addr = (address)dlinfo.dli_fbase; + } assert(libjvm_base_addr !=NULL, "Cannot obtain base address for libjvm"); } - if (dladdr((void *)addr, &dlinfo)) { + if (dladdr((void *)addr, &dlinfo) != 0) { if (libjvm_base_addr == (address)dlinfo.dli_fbase) return true; } @@ -1721,24 +1722,30 @@ bool os::dll_address_to_function_name(address addr, char *buf, int buflen, int *offset) { + // buf is not optional, but offset is optional + assert(buf != NULL, "sanity check"); + Dl_info dlinfo; - if (dladdr((void*)addr, &dlinfo) && dlinfo.dli_sname != NULL) { - if (buf != NULL) { - if(!Decoder::demangle(dlinfo.dli_sname, buf, buflen)) { + if (dladdr((void*)addr, &dlinfo) != 0) { + // see if we have a matching symbol + if (dlinfo.dli_saddr != NULL && dlinfo.dli_sname != NULL) { + if (!Decoder::demangle(dlinfo.dli_sname, buf, buflen)) { jio_snprintf(buf, buflen, "%s", dlinfo.dli_sname); } + if (offset != NULL) *offset = addr - (address)dlinfo.dli_saddr; + return true; + } + // no matching symbol so try for just file info + if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != NULL) { + if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase), + buf, buflen, offset, dlinfo.dli_fname)) { + return true; + } } - if (offset != NULL) *offset = addr - (address)dlinfo.dli_saddr; - return true; - } else if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != 0) { - if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase), - buf, buflen, offset, dlinfo.dli_fname)) { - return true; - } - } - - if (buf != NULL) buf[0] = '\0'; + } + + buf[0] = '\0'; if (offset != NULL) *offset = -1; return false; } @@ -1789,6 +1796,9 @@ bool os::dll_address_to_library_name(address addr, char* buf, int buflen, int* offset) { + // buf is not optional, but offset is optional + assert(buf != NULL, "sanity check"); + Dl_info dlinfo; struct _address_to_library_name data; @@ -1807,15 +1817,20 @@ // buf already contains library name if (offset) *offset = addr - data.base; return true; - } else if (dladdr((void*)addr, &dlinfo)){ - if (buf) jio_snprintf(buf, buflen, "%s", dlinfo.dli_fname); - if (offset) *offset = addr - (address)dlinfo.dli_fbase; - return true; - } else { - if (buf) buf[0] = '\0'; - if (offset) *offset = -1; - return false; - } + } + if (dladdr((void*)addr, &dlinfo) != 0) { + if (dlinfo.dli_fname != NULL) { + jio_snprintf(buf, buflen, "%s", dlinfo.dli_fname); + } + if (dlinfo.dli_fbase != NULL && offset != NULL) { + *offset = addr - (address)dlinfo.dli_fbase; + } + return true; + } + + buf[0] = '\0'; + if (offset) *offset = -1; + return false; } // Loads .dll/.so and @@ -2342,8 +2357,11 @@ bool ret = dll_address_to_library_name( CAST_FROM_FN_PTR(address, os::jvm_path), dli_fname, sizeof(dli_fname), NULL); - assert(ret != 0, "cannot locate libjvm"); - char *rp = realpath(dli_fname, buf); + assert(ret, "cannot locate libjvm"); + char *rp = NULL; + if (ret && dli_fname[0] != '\0') { + rp = realpath(dli_fname, buf); + } if (rp == NULL) return; @@ -4772,20 +4790,20 @@ bool os::find(address addr, outputStream* st) { Dl_info dlinfo; memset(&dlinfo, 0, sizeof(dlinfo)); - if (dladdr(addr, &dlinfo)) { + if (dladdr(addr, &dlinfo) != 0) { st->print(PTR_FORMAT ": ", addr); - if (dlinfo.dli_sname != NULL) { + if (dlinfo.dli_sname != NULL && dlinfo.dli_saddr != NULL) { st->print("%s+%#x", dlinfo.dli_sname, addr - (intptr_t)dlinfo.dli_saddr); - } else if (dlinfo.dli_fname) { + } else if (dlinfo.dli_fbase != NULL) { st->print("<offset %#x>", addr - (intptr_t)dlinfo.dli_fbase); } else { st->print("<absolute address>"); } - if (dlinfo.dli_fname) { + if (dlinfo.dli_fname != NULL) { st->print(" in %s", dlinfo.dli_fname); } - if (dlinfo.dli_fbase) { + if (dlinfo.dli_fbase != NULL) { st->print(" at " PTR_FORMAT, dlinfo.dli_fbase); } st->cr(); @@ -4798,7 +4816,7 @@ if (!lowest) lowest = (address) dlinfo.dli_fbase; if (begin < lowest) begin = lowest; Dl_info dlinfo2; - if (dladdr(end, &dlinfo2) && dlinfo2.dli_saddr != dlinfo.dli_saddr + if (dladdr(end, &dlinfo2) != 0 && dlinfo2.dli_saddr != dlinfo.dli_saddr && end > dlinfo2.dli_saddr && dlinfo2.dli_saddr > begin) end = (address) dlinfo2.dli_saddr; Disassembler::decode(begin, end, st);
--- a/src/os/solaris/vm/attachListener_solaris.cpp Wed Jul 17 11:12:43 2013 -0400 +++ b/src/os/solaris/vm/attachListener_solaris.cpp Wed Jul 17 11:16:35 2013 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -576,6 +576,30 @@ return op; } + +// Performs initialization at vm startup +// For Solaris we remove any stale .java_pid file which could cause +// an attaching process to think we are ready to receive a door_call +// before we are properly initialized + +void AttachListener::vm_start() { + char fn[PATH_MAX+1]; + struct stat64 st; + int ret; + + int n = snprintf(fn, sizeof(fn), "%s/.java_pid%d", + os::get_temp_directory(), os::current_process_id()); + assert(n < sizeof(fn), "java_pid file name buffer overflow"); + + RESTARTABLE(::stat64(fn, &st), ret); + if (ret == 0) { + ret = ::unlink(fn); + if (ret == -1) { + debug_only(warning("failed to remove stale attach pid file at %s", fn)); + } + } +} + int AttachListener::pd_init() { JavaThread* thread = JavaThread::current(); ThreadBlockInVM tbivm(thread);
--- a/src/os/solaris/vm/os_solaris.cpp Wed Jul 17 11:12:43 2013 -0400 +++ b/src/os/solaris/vm/os_solaris.cpp Wed Jul 17 11:16:35 2013 -0400 @@ -1945,12 +1945,13 @@ Dl_info dlinfo; if (libjvm_base_addr == NULL) { - dladdr(CAST_FROM_FN_PTR(void *, os::address_is_in_vm), &dlinfo); - libjvm_base_addr = (address)dlinfo.dli_fbase; + if (dladdr(CAST_FROM_FN_PTR(void *, os::address_is_in_vm), &dlinfo) != 0) { + libjvm_base_addr = (address)dlinfo.dli_fbase; + } assert(libjvm_base_addr !=NULL, "Cannot obtain base address for libjvm"); } - if (dladdr((void *)addr, &dlinfo)) { + if (dladdr((void *)addr, &dlinfo) != 0) { if (libjvm_base_addr == (address)dlinfo.dli_fbase) return true; } @@ -1962,114 +1963,133 @@ bool os::dll_address_to_function_name(address addr, char *buf, int buflen, int * offset) { + // buf is not optional, but offset is optional + assert(buf != NULL, "sanity check"); + Dl_info dlinfo; // dladdr1_func was initialized in os::init() - if (dladdr1_func){ - // yes, we have dladdr1 - - // Support for dladdr1 is checked at runtime; it may be - // available even if the vm is built on a machine that does - // not have dladdr1 support. Make sure there is a value for - // RTLD_DL_SYMENT. - #ifndef RTLD_DL_SYMENT - #define RTLD_DL_SYMENT 1 - #endif + if (dladdr1_func != NULL) { + // yes, we have dladdr1 + + // Support for dladdr1 is checked at runtime; it may be + // available even if the vm is built on a machine that does + // not have dladdr1 support. Make sure there is a value for + // RTLD_DL_SYMENT. + #ifndef RTLD_DL_SYMENT + #define RTLD_DL_SYMENT 1 + #endif #ifdef _LP64 - Elf64_Sym * info; + Elf64_Sym * info; #else - Elf32_Sym * info; + Elf32_Sym * info; #endif - if (dladdr1_func((void *)addr, &dlinfo, (void **)&info, - RTLD_DL_SYMENT)) { - if ((char *)dlinfo.dli_saddr + info->st_size > (char *)addr) { - if (buf != NULL) { - if (!Decoder::demangle(dlinfo.dli_sname, buf, buflen)) - jio_snprintf(buf, buflen, "%s", dlinfo.dli_sname); - } - if (offset != NULL) *offset = addr - (address)dlinfo.dli_saddr; - return true; - } - } - if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != 0) { - if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase), - buf, buflen, offset, dlinfo.dli_fname)) { + if (dladdr1_func((void *)addr, &dlinfo, (void **)&info, + RTLD_DL_SYMENT) != 0) { + // see if we have a matching symbol that covers our address + if (dlinfo.dli_saddr != NULL && + (char *)dlinfo.dli_saddr + info->st_size > (char *)addr) { + if (dlinfo.dli_sname != NULL) { + if (!Decoder::demangle(dlinfo.dli_sname, buf, buflen)) { + jio_snprintf(buf, buflen, "%s", dlinfo.dli_sname); + } + if (offset != NULL) *offset = addr - (address)dlinfo.dli_saddr; return true; } } - if (buf != NULL) buf[0] = '\0'; - if (offset != NULL) *offset = -1; - return false; - } else { - // no, only dladdr is available - if (dladdr((void *)addr, &dlinfo)) { - if (buf != NULL) { - if (!Decoder::demangle(dlinfo.dli_sname, buf, buflen)) - jio_snprintf(buf, buflen, dlinfo.dli_sname); - } - if (offset != NULL) *offset = addr - (address)dlinfo.dli_saddr; - return true; - } else if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != 0) { + // no matching symbol so try for just file info + if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != NULL) { if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase), - buf, buflen, offset, dlinfo.dli_fname)) { + buf, buflen, offset, dlinfo.dli_fname)) { return true; } } - if (buf != NULL) buf[0] = '\0'; - if (offset != NULL) *offset = -1; - return false; - } + } + buf[0] = '\0'; + if (offset != NULL) *offset = -1; + return false; + } + + // no, only dladdr is available + if (dladdr((void *)addr, &dlinfo) != 0) { + // see if we have a matching symbol + if (dlinfo.dli_saddr != NULL && dlinfo.dli_sname != NULL) { + if (!Decoder::demangle(dlinfo.dli_sname, buf, buflen)) { + jio_snprintf(buf, buflen, dlinfo.dli_sname); + } + if (offset != NULL) *offset = addr - (address)dlinfo.dli_saddr; + return true; + } + // no matching symbol so try for just file info + if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != NULL) { + if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase), + buf, buflen, offset, dlinfo.dli_fname)) { + return true; + } + } + } + buf[0] = '\0'; + if (offset != NULL) *offset = -1; + return false; } bool os::dll_address_to_library_name(address addr, char* buf, int buflen, int* offset) { + // buf is not optional, but offset is optional + assert(buf != NULL, "sanity check"); + Dl_info dlinfo; - if (dladdr((void*)addr, &dlinfo)){ - if (buf) jio_snprintf(buf, buflen, "%s", dlinfo.dli_fname); - if (offset) *offset = addr - (address)dlinfo.dli_fbase; - return true; - } else { - if (buf) buf[0] = '\0'; - if (offset) *offset = -1; - return false; - } + if (dladdr((void*)addr, &dlinfo) != 0) { + if (dlinfo.dli_fname != NULL) { + jio_snprintf(buf, buflen, "%s", dlinfo.dli_fname); + } + if (dlinfo.dli_fbase != NULL && offset != NULL) { + *offset = addr - (address)dlinfo.dli_fbase; + } + return true; + } + + buf[0] = '\0'; + if (offset) *offset = -1; + return false; } // Prints the names and full paths of all opened dynamic libraries // for current process void os::print_dll_info(outputStream * st) { - Dl_info dli; - void *handle; - Link_map *map; - Link_map *p; - - st->print_cr("Dynamic libraries:"); st->flush(); - - if (!dladdr(CAST_FROM_FN_PTR(void *, os::print_dll_info), &dli)) { - st->print_cr("Error: Cannot print dynamic libraries."); - return; - } - handle = dlopen(dli.dli_fname, RTLD_LAZY); - if (handle == NULL) { - st->print_cr("Error: Cannot print dynamic libraries."); - return; - } - dlinfo(handle, RTLD_DI_LINKMAP, &map); - if (map == NULL) { - st->print_cr("Error: Cannot print dynamic libraries."); - return; - } - - while (map->l_prev != NULL) - map = map->l_prev; - - while (map != NULL) { - st->print_cr(PTR_FORMAT " \t%s", map->l_addr, map->l_name); - map = map->l_next; - } - - dlclose(handle); + Dl_info dli; + void *handle; + Link_map *map; + Link_map *p; + + st->print_cr("Dynamic libraries:"); st->flush(); + + if (dladdr(CAST_FROM_FN_PTR(void *, os::print_dll_info), &dli) == 0 || + dli.dli_fname == NULL) { + st->print_cr("Error: Cannot print dynamic libraries."); + return; + } + handle = dlopen(dli.dli_fname, RTLD_LAZY); + if (handle == NULL) { + st->print_cr("Error: Cannot print dynamic libraries."); + return; + } + dlinfo(handle, RTLD_DI_LINKMAP, &map); + if (map == NULL) { + st->print_cr("Error: Cannot print dynamic libraries."); + return; + } + + while (map->l_prev != NULL) + map = map->l_prev; + + while (map != NULL) { + st->print_cr(PTR_FORMAT " \t%s", map->l_addr, map->l_name); + map = map->l_next; + } + + dlclose(handle); } // Loads .dll/.so and @@ -2496,7 +2516,12 @@ Dl_info dlinfo; int ret = dladdr(CAST_FROM_FN_PTR(void *, os::jvm_path), &dlinfo); assert(ret != 0, "cannot locate libjvm"); - realpath((char *)dlinfo.dli_fname, buf); + if (ret != 0 && dlinfo.dli_fname != NULL) { + realpath((char *)dlinfo.dli_fname, buf); + } else { + buf[0] = '\0'; + return; + } if (Arguments::created_by_gamma_launcher()) { // Support for the gamma launcher. Typical value for buf is @@ -6109,24 +6134,20 @@ bool os::find(address addr, outputStream* st) { Dl_info dlinfo; memset(&dlinfo, 0, sizeof(dlinfo)); - if (dladdr(addr, &dlinfo)) { -#ifdef _LP64 - st->print("0x%016lx: ", addr); -#else - st->print("0x%08x: ", addr); -#endif - if (dlinfo.dli_sname != NULL) + if (dladdr(addr, &dlinfo) != 0) { + st->print(PTR_FORMAT ": ", addr); + if (dlinfo.dli_sname != NULL && dlinfo.dli_saddr != NULL) { st->print("%s+%#lx", dlinfo.dli_sname, addr-(intptr_t)dlinfo.dli_saddr); - else if (dlinfo.dli_fname) + } else if (dlinfo.dli_fbase != NULL) st->print("<offset %#lx>", addr-(intptr_t)dlinfo.dli_fbase); else st->print("<absolute address>"); - if (dlinfo.dli_fname) st->print(" in %s", dlinfo.dli_fname); -#ifdef _LP64 - if (dlinfo.dli_fbase) st->print(" at 0x%016lx", dlinfo.dli_fbase); -#else - if (dlinfo.dli_fbase) st->print(" at 0x%08x", dlinfo.dli_fbase); -#endif + if (dlinfo.dli_fname != NULL) { + st->print(" in %s", dlinfo.dli_fname); + } + if (dlinfo.dli_fbase != NULL) { + st->print(" at " PTR_FORMAT, dlinfo.dli_fbase); + } st->cr(); if (Verbose) { @@ -6137,7 +6158,7 @@ if (!lowest) lowest = (address) dlinfo.dli_fbase; if (begin < lowest) begin = lowest; Dl_info dlinfo2; - if (dladdr(end, &dlinfo2) && dlinfo2.dli_saddr != dlinfo.dli_saddr + if (dladdr(end, &dlinfo2) != 0 && dlinfo2.dli_saddr != dlinfo.dli_saddr && end > dlinfo2.dli_saddr && dlinfo2.dli_saddr > begin) end = (address) dlinfo2.dli_saddr; Disassembler::decode(begin, end, st);
--- a/src/os/windows/vm/attachListener_windows.cpp Wed Jul 17 11:12:43 2013 -0400 +++ b/src/os/windows/vm/attachListener_windows.cpp Wed Jul 17 11:16:35 2013 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -358,6 +358,10 @@ return op; } +void AttachListener::vm_start() { + // nothing to do +} + int AttachListener::pd_init() { return Win32AttachListener::init(); }
--- a/src/os/windows/vm/os_windows.cpp Wed Jul 17 11:12:43 2013 -0400 +++ b/src/os/windows/vm/os_windows.cpp Wed Jul 17 11:16:35 2013 -0400 @@ -1369,34 +1369,40 @@ bool os::dll_address_to_library_name(address addr, char* buf, int buflen, int* offset) { + // buf is not optional, but offset is optional + assert(buf != NULL, "sanity check"); + // NOTE: the reason we don't use SymGetModuleInfo() is it doesn't always // return the full path to the DLL file, sometimes it returns path // to the corresponding PDB file (debug info); sometimes it only // returns partial path, which makes life painful. - struct _modinfo mi; - mi.addr = addr; - mi.full_path = buf; - mi.buflen = buflen; - int pid = os::current_process_id(); - if (enumerate_modules(pid, _locate_module_by_addr, (void *)&mi)) { - // buf already contains path name - if (offset) *offset = addr - mi.base_addr; - return true; - } else { - if (buf) buf[0] = '\0'; - if (offset) *offset = -1; - return false; - } + struct _modinfo mi; + mi.addr = addr; + mi.full_path = buf; + mi.buflen = buflen; + int pid = os::current_process_id(); + if (enumerate_modules(pid, _locate_module_by_addr, (void *)&mi)) { + // buf already contains path name + if (offset) *offset = addr - mi.base_addr; + return true; + } + + buf[0] = '\0'; + if (offset) *offset = -1; + return false; } bool os::dll_address_to_function_name(address addr, char *buf, int buflen, int *offset) { + // buf is not optional, but offset is optional + assert(buf != NULL, "sanity check"); + if (Decoder::decode(addr, buf, buflen, offset)) { return true; } if (offset != NULL) *offset = -1; - if (buf != NULL) buf[0] = '\0'; + buf[0] = '\0'; return false; } @@ -2623,6 +2629,19 @@ } #endif +#ifndef PRODUCT +void os::win32::call_test_func_with_wrapper(void (*funcPtr)(void)) { + // Install a win32 structured exception handler around the test + // function call so the VM can generate an error dump if needed. + __try { + (*funcPtr)(); + } __except(topLevelExceptionFilter( + (_EXCEPTION_POINTERS*)_exception_info())) { + // Nothing to do. + } +} +#endif + // Virtual Memory int os::vm_page_size() { return os::win32::vm_page_size(); }
--- a/src/os/windows/vm/os_windows.hpp Wed Jul 17 11:12:43 2013 -0400 +++ b/src/os/windows/vm/os_windows.hpp Wed Jul 17 11:16:35 2013 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -94,6 +94,10 @@ static address fast_jni_accessor_wrapper(BasicType); #endif +#ifndef PRODUCT + static void call_test_func_with_wrapper(void (*funcPtr)(void)); +#endif + // filter function to ignore faults on serializations page static LONG WINAPI serialize_fault_filter(struct _EXCEPTION_POINTERS* e); };
--- a/src/os/windows/vm/os_windows.inline.hpp Wed Jul 17 11:12:43 2013 -0400 +++ b/src/os/windows/vm/os_windows.inline.hpp Wed Jul 17 11:16:35 2013 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -109,4 +109,10 @@ inline int os::close(int fd) { return ::close(fd); } + +#ifndef PRODUCT + #define CALL_TEST_FUNC_WITH_WRAPPER_IF_NEEDED(f) \ + os::win32::call_test_func_with_wrapper(f) +#endif + #endif // OS_WINDOWS_VM_OS_WINDOWS_INLINE_HPP
--- a/src/share/vm/ci/bcEscapeAnalyzer.cpp Wed Jul 17 11:12:43 2013 -0400 +++ b/src/share/vm/ci/bcEscapeAnalyzer.cpp Wed Jul 17 11:16:35 2013 -0400 @@ -138,6 +138,16 @@ return false; } +// return true if all argument elements of vars are returned +bool BCEscapeAnalyzer::returns_all(ArgumentMap vars) { + for (int i = 0; i < _arg_size; i++) { + if (vars.contains(i) && !_arg_returned.test(i)) { + return false; + } + } + return true; +} + void BCEscapeAnalyzer::clear_bits(ArgumentMap vars, VectorSet &bm) { for (int i = 0; i < _arg_size; i++) { if (vars.contains(i)) { @@ -166,6 +176,11 @@ if (vars.contains_unknown() || vars.contains_vars()) { _return_allocated = false; } + if (_return_local && vars.contains_vars() && !returns_all(vars)) { + // Return result should be invalidated if args in new + // state are not recorded in return state. + _return_local = false; + } } }
--- a/src/share/vm/ci/bcEscapeAnalyzer.hpp Wed Jul 17 11:12:43 2013 -0400 +++ b/src/share/vm/ci/bcEscapeAnalyzer.hpp Wed Jul 17 11:16:35 2013 -0400 @@ -79,6 +79,7 @@ void set_returned(ArgumentMap vars); bool is_argument(ArgumentMap vars); bool is_arg_stack(ArgumentMap vars); + bool returns_all(ArgumentMap vars); void clear_bits(ArgumentMap vars, VectorSet &bs); void set_method_escape(ArgumentMap vars); void set_global_escape(ArgumentMap vars, bool merge = false);
--- a/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Wed Jul 17 11:12:43 2013 -0400 +++ b/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Wed Jul 17 11:16:35 2013 -0400 @@ -870,7 +870,7 @@ size_t alloc_byte_size = alloc_word_size * HeapWordSize; if ((cur_used_bytes + alloc_byte_size) > marking_initiating_used_threshold) { - if (gcs_are_young()) { + if (gcs_are_young() && !_last_young_gc) { ergo_verbose5(ErgoConcCycles, "request concurrent cycle initiation", ergo_format_reason("occupancy higher than threshold") @@ -928,7 +928,7 @@ last_pause_included_initial_mark = during_initial_mark_pause(); if (last_pause_included_initial_mark) { record_concurrent_mark_init_end(0.0); - } else if (!_last_young_gc && need_to_start_conc_mark("end of GC")) { + } else if (need_to_start_conc_mark("end of GC")) { // Note: this might have already been set, if during the last // pause we decided to start a cycle but at the beginning of // this pause we decided to postpone it. That's OK.
--- a/src/share/vm/opto/matcher.cpp Wed Jul 17 11:12:43 2013 -0400 +++ b/src/share/vm/opto/matcher.cpp Wed Jul 17 11:16:35 2013 -0400 @@ -2303,26 +2303,26 @@ // atomic instruction acting as a store_load barrier without any // intervening volatile load, and thus we don't need a barrier here. // We retain the Node to act as a compiler ordering barrier. -bool Matcher::post_store_load_barrier(const Node *vmb) { - Compile *C = Compile::current(); - assert( vmb->is_MemBar(), "" ); - assert( vmb->Opcode() != Op_MemBarAcquire, "" ); - const MemBarNode *mem = (const MemBarNode*)vmb; +bool Matcher::post_store_load_barrier(const Node* vmb) { + Compile* C = Compile::current(); + assert(vmb->is_MemBar(), ""); + assert(vmb->Opcode() != Op_MemBarAcquire, ""); + const MemBarNode* membar = vmb->as_MemBar(); - // Get the Proj node, ctrl, that can be used to iterate forward - Node *ctrl = NULL; - DUIterator_Fast imax, i = mem->fast_outs(imax); - while( true ) { - ctrl = mem->fast_out(i); // Throw out-of-bounds if proj not found - assert( ctrl->is_Proj(), "only projections here" ); - ProjNode *proj = (ProjNode*)ctrl; - if( proj->_con == TypeFunc::Control && - !C->node_arena()->contains(ctrl) ) // Unmatched old-space only + // Get the Ideal Proj node, ctrl, that can be used to iterate forward + Node* ctrl = NULL; + for (DUIterator_Fast imax, i = membar->fast_outs(imax); i < imax; i++) { + Node* p = membar->fast_out(i); + assert(p->is_Proj(), "only projections here"); + if ((p->as_Proj()->_con == TypeFunc::Control) && + !C->node_arena()->contains(p)) { // Unmatched old-space only + ctrl = p; break; - i++; + } } + assert((ctrl != NULL), "missing control projection"); - for( DUIterator_Fast jmax, j = ctrl->fast_outs(jmax); j < jmax; j++ ) { + for (DUIterator_Fast jmax, j = ctrl->fast_outs(jmax); j < jmax; j++) { Node *x = ctrl->fast_out(j); int xop = x->Opcode(); @@ -2334,37 +2334,36 @@ // that a monitor exit operation contains a serializing instruction. if (xop == Op_MemBarVolatile || - xop == Op_FastLock || xop == Op_CompareAndSwapL || xop == Op_CompareAndSwapP || xop == Op_CompareAndSwapN || - xop == Op_CompareAndSwapI) + xop == Op_CompareAndSwapI) { return true; + } + + // Op_FastLock previously appeared in the Op_* list above. + // With biased locking we're no longer guaranteed that a monitor + // enter operation contains a serializing instruction. + if ((xop == Op_FastLock) && !UseBiasedLocking) { + return true; + } if (x->is_MemBar()) { // We must retain this membar if there is an upcoming volatile - // load, which will be preceded by acquire membar. - if (xop == Op_MemBarAcquire) + // load, which will be followed by acquire membar. + if (xop == Op_MemBarAcquire) { return false; - // For other kinds of barriers, check by pretending we - // are them, and seeing if we can be removed. - else - return post_store_load_barrier((const MemBarNode*)x); + } else { + // For other kinds of barriers, check by pretending we + // are them, and seeing if we can be removed. + return post_store_load_barrier(x->as_MemBar()); + } } - // Delicate code to detect case of an upcoming fastlock block - if( x->is_If() && x->req() > 1 && - !C->node_arena()->contains(x) ) { // Unmatched old-space only - Node *iff = x; - Node *bol = iff->in(1); - // The iff might be some random subclass of If or bol might be Con-Top - if (!bol->is_Bool()) return false; - assert( bol->req() > 1, "" ); - return (bol->in(1)->Opcode() == Op_FastUnlock); + // probably not necessary to check for these + if (x->is_Call() || x->is_SafePoint() || x->is_block_proj()) { + return false; } - // probably not necessary to check for these - if (x->is_Call() || x->is_SafePoint() || x->is_block_proj()) - return false; } return false; }
--- a/src/share/vm/opto/parse3.cpp Wed Jul 17 11:12:43 2013 -0400 +++ b/src/share/vm/opto/parse3.cpp Wed Jul 17 11:16:35 2013 -0400 @@ -277,25 +277,7 @@ // If reference is volatile, prevent following volatiles ops from // floating up before the volatile write. if (is_vol) { - // First place the specific membar for THIS volatile index. This first - // membar is dependent on the store, keeping any other membars generated - // below from floating up past the store. - int adr_idx = C->get_alias_index(adr_type); - insert_mem_bar_volatile(Op_MemBarVolatile, adr_idx, store); - - // Now place a membar for AliasIdxBot for the unknown yet-to-be-parsed - // volatile alias indices. Skip this if the membar is redundant. - if (adr_idx != Compile::AliasIdxBot) { - insert_mem_bar_volatile(Op_MemBarVolatile, Compile::AliasIdxBot, store); - } - - // Finally, place alias-index-specific membars for each volatile index - // that isn't the adr_idx membar. Typically there's only 1 or 2. - for( int i = Compile::AliasIdxRaw; i < C->num_alias_types(); i++ ) { - if (i != adr_idx && C->alias_type(i)->is_volatile()) { - insert_mem_bar_volatile(Op_MemBarVolatile, i, store); - } - } + insert_mem_bar(Op_MemBarVolatile); // Use fat membar } // If the field is final, the rules of Java say we are in <init> or <clinit>.
--- a/src/share/vm/prims/jni.cpp Wed Jul 17 11:12:43 2013 -0400 +++ b/src/share/vm/prims/jni.cpp Wed Jul 17 11:16:35 2013 -0400 @@ -5146,8 +5146,20 @@ event.commit(); } +#ifndef PRODUCT + #ifndef TARGET_OS_FAMILY_windows + #define CALL_TEST_FUNC_WITH_WRAPPER_IF_NEEDED(f) f() + #endif + // Check if we should compile all classes on bootclasspath - NOT_PRODUCT(if (CompileTheWorld) ClassLoader::compile_the_world();) + if (CompileTheWorld) ClassLoader::compile_the_world(); + + // Some platforms (like Win*) need a wrapper around these test + // functions in order to properly handle error conditions. + CALL_TEST_FUNC_WITH_WRAPPER_IF_NEEDED(test_error_handler); + CALL_TEST_FUNC_WITH_WRAPPER_IF_NEEDED(execute_internal_vm_tests); +#endif + // Since this is not a JVM_ENTRY we have to set the thread state manually before leaving. ThreadStateTransition::transition_and_fence(thread, _thread_in_vm, _thread_in_native); } else { @@ -5164,8 +5176,6 @@ OrderAccess::release_store(&vm_created, 0); } - NOT_PRODUCT(test_error_handler(ErrorHandlerTest)); - NOT_PRODUCT(execute_internal_vm_tests()); return result; }
--- a/src/share/vm/runtime/arguments.cpp Wed Jul 17 11:12:43 2013 -0400 +++ b/src/share/vm/runtime/arguments.cpp Wed Jul 17 11:16:35 2013 -0400 @@ -245,6 +245,27 @@ JDK_Version::jdk_update(6,27), JDK_Version::jdk(8) }, { "AllowTransitionalJSR292", JDK_Version::jdk(7), JDK_Version::jdk(8) }, { "UseCompressedStrings", JDK_Version::jdk(7), JDK_Version::jdk(8) }, + { "AlwaysInflate", JDK_Version::jdk_update(7,40), JDK_Version::jdk(8) }, + { "AnonymousClasses", JDK_Version::jdk_update(7,40), JDK_Version::jdk(8) }, + { "CMSOldPLABReactivityCeiling", + JDK_Version::jdk_update(7,40), JDK_Version::jdk(8) }, + { "EventLogLength", JDK_Version::jdk_update(7,40), JDK_Version::jdk(8) }, + { "GCOverheadReporting", JDK_Version::jdk_update(7,40), JDK_Version::jdk(8) }, + { "GCOverheadReportingPeriodMS", + JDK_Version::jdk_update(7,40), JDK_Version::jdk(8) }, + { "HPILibPath", JDK_Version::jdk_update(7,40), JDK_Version::jdk(8) }, + { "PreSpinYield", JDK_Version::jdk_update(7,40), JDK_Version::jdk(8) }, + { "PreBlockSpin", JDK_Version::jdk_update(7,40), JDK_Version::jdk(8) }, + { "PostSpinYield", JDK_Version::jdk_update(7,40), JDK_Version::jdk(8) }, + { "PreserveMarkStackSize", + JDK_Version::jdk_update(7,40), JDK_Version::jdk(8) }, + { "ReadSpinIterations", JDK_Version::jdk_update(7,40), JDK_Version::jdk(8) }, + { "StressTieredRuntime", JDK_Version::jdk_update(7,40), JDK_Version::jdk(8) }, + { "Tier1Inline", JDK_Version::jdk_update(7,40), JDK_Version::jdk(8) }, + { "Tier1FreqInlineSize", JDK_Version::jdk_update(7,40), JDK_Version::jdk(8) }, + { "Tier1MaxInlineSize", JDK_Version::jdk_update(7,40), JDK_Version::jdk(8) }, + { "Tier1LoopOptsCount", JDK_Version::jdk_update(7,40), JDK_Version::jdk(8) }, + { "UseSpinning", JDK_Version::jdk_update(7,40), JDK_Version::jdk(8) }, #ifdef PRODUCT { "DesiredMethodLimit", JDK_Version::jdk_update(7, 2), JDK_Version::jdk(8) },
--- a/src/share/vm/runtime/os.hpp Wed Jul 17 11:12:43 2013 -0400 +++ b/src/share/vm/runtime/os.hpp Wed Jul 17 11:16:35 2013 -0400 @@ -507,16 +507,16 @@ // Symbol lookup, find nearest function name; basically it implements // dladdr() for all platforms. Name of the nearest function is copied - // to buf. Distance from its base address is returned as offset. + // to buf. Distance from its base address is optionally returned as offset. // If function name is not found, buf[0] is set to '\0' and offset is - // set to -1. + // set to -1 (if offset is non-NULL). static bool dll_address_to_function_name(address addr, char* buf, int buflen, int* offset); // Locate DLL/DSO. On success, full path of the library is copied to - // buf, and offset is set to be the distance between addr and the - // library's base address. On failure, buf[0] is set to '\0' and - // offset is set to -1. + // buf, and offset is optionally set to be the distance between addr + // and the library's base address. On failure, buf[0] is set to '\0' + // and offset is set to -1 (if offset is non-NULL). static bool dll_address_to_library_name(address addr, char* buf, int buflen, int* offset);
--- a/src/share/vm/runtime/thread.cpp Wed Jul 17 11:12:43 2013 -0400 +++ b/src/share/vm/runtime/thread.cpp Wed Jul 17 11:16:35 2013 -0400 @@ -3608,6 +3608,7 @@ // Start Attach Listener if +StartAttachListener or it can't be started lazily if (!DisableAttachMechanism) { + AttachListener::vm_start(); if (StartAttachListener || AttachListener::init_at_startup()) { AttachListener::init(); }
--- a/src/share/vm/services/attachListener.hpp Wed Jul 17 11:12:43 2013 -0400 +++ b/src/share/vm/services/attachListener.hpp Wed Jul 17 11:16:35 2013 -0400 @@ -49,6 +49,7 @@ class AttachListener: AllStatic { public: + static void vm_start(); static void init(); static void abort();
--- a/src/share/vm/services/memBaseline.cpp Wed Jul 17 11:12:43 2013 -0400 +++ b/src/share/vm/services/memBaseline.cpp Wed Jul 17 11:16:35 2013 -0400 @@ -486,7 +486,7 @@ const MemPointerRecord* mp1 = (const MemPointerRecord*)p1; const MemPointerRecord* mp2 = (const MemPointerRecord*)p2; int delta = UNSIGNED_COMPARE(mp1->addr(), mp2->addr()); - assert(delta != 0, "dup pointer"); + assert(p1 == p2 || delta != 0, "dup pointer"); return delta; }
--- a/src/share/vm/services/memTracker.cpp Wed Jul 17 11:12:43 2013 -0400 +++ b/src/share/vm/services/memTracker.cpp Wed Jul 17 11:16:35 2013 -0400 @@ -387,6 +387,7 @@ #define SAFE_SEQUENCE_THRESHOLD 30 #define HIGH_GENERATION_THRESHOLD 60 #define MAX_RECORDER_THREAD_RATIO 30 +#define MAX_RECORDER_PER_THREAD 100 void MemTracker::sync() { assert(_tracking_level > NMT_off, "NMT is not enabled"); @@ -439,8 +440,14 @@ // means that worker thread is lagging behind in processing them. if (!AutoShutdownNMT) { _slowdown_calling_thread = (MemRecorder::_instance_count > MAX_RECORDER_THREAD_RATIO * _thread_count); + } else { + // If auto shutdown is on, enforce MAX_RECORDER_PER_THREAD threshold to prevent OOM + if (MemRecorder::_instance_count >= _thread_count * MAX_RECORDER_PER_THREAD) { + shutdown(NMT_out_of_memory); + } } + // check _worker_thread with lock to avoid racing condition if (_worker_thread != NULL) { _worker_thread->at_sync_point(pending_recorders, instanceKlass::number_of_instance_classes());
--- a/src/share/vm/utilities/debug.cpp Wed Jul 17 11:12:43 2013 -0400 +++ b/src/share/vm/utilities/debug.cpp Wed Jul 17 11:16:35 2013 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -330,8 +330,8 @@ #ifndef PRODUCT #include <signal.h> -void test_error_handler(size_t test_num) -{ +void test_error_handler() { + uintx test_num = ErrorHandlerTest; if (test_num == 0) return; // If asserts are disabled, use the corresponding guarantee instead. @@ -343,6 +343,8 @@ const char* const eol = os::line_separator(); const char* const msg = "this message should be truncated during formatting"; + char * const dataPtr = NULL; // bad data pointer + const void (*funcPtr)(void) = (const void(*)()) 0xF; // bad function pointer // Keep this in sync with test/runtime/6888954/vmerrors.sh. switch (n) { @@ -364,11 +366,16 @@ case 9: ShouldNotCallThis(); case 10: ShouldNotReachHere(); case 11: Unimplemented(); - // This is last because it does not generate an hs_err* file on Windows. - case 12: os::signal_raise(SIGSEGV); + // There's no guarantee the bad data pointer will crash us + // so "break" out to the ShouldNotReachHere(). + case 12: *dataPtr = '\0'; break; + // There's no guarantee the bad function pointer will crash us + // so "break" out to the ShouldNotReachHere(). + case 13: (*funcPtr)(); break; - default: ShouldNotReachHere(); + default: tty->print_cr("ERROR: %d: unexpected test_num value.", n); } + ShouldNotReachHere(); } #endif // !PRODUCT
--- a/src/share/vm/utilities/debug.hpp Wed Jul 17 11:12:43 2013 -0400 +++ b/src/share/vm/utilities/debug.hpp Wed Jul 17 11:16:35 2013 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -235,7 +235,7 @@ void set_error_reported(); /* Test assert(), fatal(), guarantee(), etc. */ -NOT_PRODUCT(void test_error_handler(size_t test_num);) +NOT_PRODUCT(void test_error_handler();) void pd_ps(frame f); void pd_obfuscate_location(char *buf, size_t buflen);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/EscapeAnalysis/Test8020215.java Wed Jul 17 11:16:35 2013 -0400 @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8020215 + * @summary Different execution plan when using JIT vs interpreter + * @run main Test8020215 + */ + +import java.util.ArrayList; +import java.util.List; + +public class Test8020215 { + public static class NamedObject { + public int id; + public String name; + public NamedObject(int id, String name) { + this.id = id; + this.name = name; + } + } + + public static class NamedObjectList { + public List<NamedObject> namedObjectList = new ArrayList<NamedObject>(); + + public NamedObject getBest(int id) { + NamedObject bestObject = null; + for (NamedObject o : namedObjectList) { + bestObject = id==o.id ? getBetter(bestObject, o) : bestObject; + } + return (bestObject != null) ? bestObject : null; + } + + private static NamedObject getBetter(NamedObject p1, NamedObject p2) { + return (p1 == null) ? p2 : (p2 == null) ? p1 : (p2.name.compareTo(p1.name) >= 0) ? p2 : p1; + } + } + + static void test(NamedObjectList b, int i) { + NamedObject x = b.getBest(2); + // test + if (x == null) { + throw new RuntimeException("x should never be null here! (i=" + i + ")"); + } + } + + public static void main(String[] args) { + // setup + NamedObjectList b = new NamedObjectList(); + for (int i = 0; i < 10000; i++) { + b.namedObjectList.add(new NamedObject(1, "2012-12-31")); + } + b.namedObjectList.add(new NamedObject(2, "2013-12-31")); + + // execution + for (int i = 0; i < 12000; i++) { + test(b, i); + } + System.out.println("PASSED"); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/cpuflags/RestoreMXCSR.java Wed Jul 17 11:16:35 2013 -0400 @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8020433 + * @summary Crash when using -XX:+RestoreMXCSROnJNICalls + * @library /testlibrary + * + */ +import com.oracle.java.testlibrary.*; + +public class RestoreMXCSR { + public static void main(String[] args) throws Exception { + ProcessBuilder pb; + OutputAnalyzer out; + + pb = ProcessTools.createJavaProcessBuilder("-XX:+RestoreMXCSROnJNICalls", "-version"); + out = new OutputAnalyzer(pb.start()); + out.shouldHaveExitValue(0); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/membars/DekkerTest.java Wed Jul 17 11:16:35 2013 -0400 @@ -0,0 +1,163 @@ +/* + * Copyright 2013 SAP AG. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8007898 + * @summary Incorrect optimization of Memory Barriers in Matcher::post_store_load_barrier(). + * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:CICompilerCount=1 -XX:+StressGCM -XX:+StressLCM DekkerTest + * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:CICompilerCount=1 -XX:+StressGCM -XX:+StressLCM DekkerTest + * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:CICompilerCount=1 -XX:+StressGCM -XX:+StressLCM DekkerTest + * @author Martin Doerr martin DOT doerr AT sap DOT com + * + * Run 3 times since the failure is intermittent. + */ + +public class DekkerTest { + + /* + Read After Write Test (basically a simple Dekker test with volatile variables) + Derived from the original jcstress test, available at: + http://hg.openjdk.java.net/code-tools/jcstress/file/6c339a5aa00d/ + tests-custom/src/main/java/org/openjdk/jcstress/tests/volatiles/DekkerTest.java + */ + + static final int ITERATIONS = 1000000; + + static class TestData { + public volatile int a; + public volatile int b; + } + + static class ResultData { + public int a; + public int b; + } + + TestData[] testDataArray; + ResultData[] results; + + volatile boolean start; + + public DekkerTest() { + testDataArray = new TestData[ITERATIONS]; + results = new ResultData[ITERATIONS]; + for (int i = 0; i < ITERATIONS; ++i) { + testDataArray[i] = new TestData(); + results[i] = new ResultData(); + } + start = false; + } + + public void reset() { + for (int i = 0; i < ITERATIONS; ++i) { + testDataArray[i].a = 0; + testDataArray[i].b = 0; + results[i].a = 0; + results[i].b = 0; + } + start = false; + } + + int actor1(TestData t) { + t.a = 1; + return t.b; + } + + int actor2(TestData t) { + t.b = 1; + return t.a; + } + + class Runner1 extends Thread { + public void run() { + do {} while (!start); + for (int i = 0; i < ITERATIONS; ++i) { + results[i].a = actor1(testDataArray[i]); + } + } + } + + class Runner2 extends Thread { + public void run() { + do {} while (!start); + for (int i = 0; i < ITERATIONS; ++i) { + results[i].b = actor2(testDataArray[i]); + } + } + } + + void testRunner() { + Thread thread1 = new Runner1(); + Thread thread2 = new Runner2(); + thread1.start(); + thread2.start(); + do {} while (!thread1.isAlive()); + do {} while (!thread2.isAlive()); + start = true; + Thread.yield(); + try { + thread1.join(); + thread2.join(); + } catch (InterruptedException e) { + System.out.println("interrupted!"); + System.exit(1); + } + } + + boolean printResult() { + int[] count = new int[4]; + for (int i = 0; i < ITERATIONS; ++i) { + int event_kind = (results[i].a << 1) + results[i].b; + ++count[event_kind]; + } + if (count[0] == 0 && count[3] == 0) { + System.out.println("[not interesting]"); + return false; // not interesting + } + String error = (count[0] == 0) ? " ok" : " disallowed!"; + System.out.println("[0,0] " + count[0] + error); + System.out.println("[0,1] " + count[1]); + System.out.println("[1,0] " + count[2]); + System.out.println("[1,1] " + count[3]); + return (count[0] != 0); + } + + public static void main(String args[]) { + DekkerTest test = new DekkerTest(); + final int runs = 30; + int failed = 0; + for (int c = 0; c < runs; ++c) { + test.testRunner(); + if (test.printResult()) { + failed++; + } + test.reset(); + } + if (failed > 0) { + throw new InternalError("FAILED. Got " + failed + " failed ITERATIONS"); + } + System.out.println("PASSED."); + } + +}
--- a/test/runtime/6888954/vmerrors.sh Wed Jul 17 11:12:43 2013 -0400 +++ b/test/runtime/6888954/vmerrors.sh Wed Jul 17 11:16:35 2013 -0400 @@ -1,5 +1,6 @@ # @test # @bug 6888954 +# @bug 8015884 # @summary exercise HotSpot error handling code # @author John Coomes # @run shell vmerrors.sh @@ -27,9 +28,24 @@ rc=0 assert_re='(assert|guarantee)[(](str|num).*failed: *' +# for bad_data_ptr_re: +# EXCEPTION_ACCESS_VIOLATION - Win-* +# SIGILL - MacOS X +# SIGSEGV - Linux-*, Solaris SPARC-*, Solaris X86-* +# +bad_data_ptr_re='(SIGILL|SIGSEGV|EXCEPTION_ACCESS_VIOLATION).* at pc=' +# +# for bad_func_ptr_re: +# EXCEPTION_ACCESS_VIOLATION - Win-* +# SIGBUS - Solaris SPARC-64 +# SIGSEGV - Linux-*, Solaris SPARC-32, Solaris X86-* +# +# Note: would like to use "pc=0x00*0f," in the pattern, but Solaris SPARC-* +# gets its signal at a PC in test_error_handler(). +# +bad_func_ptr_re='(SIGBUS|SIGSEGV|EXCEPTION_ACCESS_VIOLATION).* at pc=' guarantee_re='guarantee[(](str|num).*failed: *' fatal_re='fatal error: *' -signal_re='(SIGSEGV|EXCEPTION_ACCESS_VIOLATION).* at pc=' tail_1='.*expected null' tail_2='.*num=' @@ -39,8 +55,9 @@ "${fatal_re}${tail_1}" "${fatal_re}${tail_2}" \ "${fatal_re}.*truncated" "ChunkPool::allocate" \ "ShouldNotCall" "ShouldNotReachHere" \ - "Unimplemented" "$signal_re" - + "Unimplemented" "$bad_data_ptr_re" \ + "$bad_func_ptr_re" + do i2=$i [ $i -lt 10 ] && i2=0$i
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/serviceability/attach/AttachWithStalePidFile.java Wed Jul 17 11:16:35 2013 -0400 @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 7162400 + * @key regression + * @summary Regression test for attach issue where stale pid files in /tmp lead to connection issues + * @library /testlibrary + * @compile AttachWithStalePidFileTarget.java + * @run main AttachWithStalePidFile + */ + +import com.oracle.java.testlibrary.*; +import com.sun.tools.attach.VirtualMachine; +import sun.tools.attach.HotSpotVirtualMachine; +import java.lang.reflect.Field; +import java.nio.file.*; +import java.nio.file.attribute.*; +import java.io.*; + +public class AttachWithStalePidFile { + public static void main(String... args) throws Exception { + + // this test is only valid on non-Windows platforms + if(Platform.isWindows()) { + System.out.println("This test is only valid on non-Windows platforms."); + return; + } + + // Since there might be stale pid-files owned by different + // users on the system we may need to retry the test in case we + // are unable to remove the existing file. + int retries = 5; + while(!runTest() && --retries > 0); + + if(retries == 0) { + throw new RuntimeException("Test failed after 5 retries. " + + "Remove any /tmp/.java_pid* files and retry."); + } + } + + public static boolean runTest() throws Exception { + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( + "-XX:+UnlockDiagnosticVMOptions", "-XX:+PauseAtStartup", "AttachWithStalePidFileTarget"); + Process target = pb.start(); + Path pidFile = null; + + try { + int pid = getUnixProcessId(target); + + // create the stale .java_pid file. use hard-coded /tmp path as in th VM + pidFile = createJavaPidFile(pid); + if(pidFile == null) { + return false; + } + + // wait for vm.paused file to be created and delete it once we find it. + waitForAndResumeVM(pid); + + // unfortunately there's no reliable way to know the VM is ready to receive the + // attach request so we have to do an arbitrary sleep. + Thread.sleep(5000); + + HotSpotVirtualMachine vm = (HotSpotVirtualMachine)VirtualMachine.attach(((Integer)pid).toString()); + BufferedReader remoteDataReader = new BufferedReader(new InputStreamReader(vm.remoteDataDump())); + String line = null; + while((line = remoteDataReader.readLine()) != null); + + vm.detach(); + return true; + } + finally { + target.destroy(); + target.waitFor(); + + if(pidFile != null && Files.exists(pidFile)) { + Files.delete(pidFile); + } + } + } + + private static Path createJavaPidFile(int pid) throws Exception { + Path pidFile = Paths.get("/tmp/.java_pid" + pid); + if(Files.exists(pidFile)) { + try { + Files.delete(pidFile); + } + catch(FileSystemException e) { + if(e.getReason().equals("Operation not permitted")) { + System.out.println("Unable to remove exisiting stale PID file" + pidFile); + return null; + } + throw e; + } + } + return Files.createFile(pidFile, + PosixFilePermissions.asFileAttribute(PosixFilePermissions.fromString("rw-------"))); + } + + private static void waitForAndResumeVM(int pid) throws Exception { + Path pauseFile = Paths.get("vm.paused." + pid); + int retries = 60; + while(!Files.exists(pauseFile) && --retries > 0) { + Thread.sleep(1000); + } + if(retries == 0) { + throw new RuntimeException("Timeout waiting for VM to start. " + + "vm.paused file not created within 60 seconds."); + } + Files.delete(pauseFile); + } + + private static int getUnixProcessId(Process unixProcess) throws Exception { + Field pidField = unixProcess.getClass().getDeclaredField("pid"); + pidField.setAccessible(true); + return (Integer)pidField.get(unixProcess); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/serviceability/attach/AttachWithStalePidFileTarget.java Wed Jul 17 11:16:35 2013 -0400 @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +public class AttachWithStalePidFileTarget { + public static void main(String... args) throws Exception { + Thread.sleep(2*60*1000); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/testlibrary/com/oracle/java/testlibrary/Platform.java Wed Jul 17 11:16:35 2013 -0400 @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.oracle.java.testlibrary; + +public class Platform { + private static final String osName = System.getProperty("os.name"); + private static final String dataModel = System.getProperty("sun.arch.data.model"); + private static final String vmVersion = System.getProperty("java.vm.version"); + + public static boolean is64bit() { + return dataModel.equals("64"); + } + + public static boolean isSolaris() { + return osName.toLowerCase().startsWith("sunos"); + } + + public static boolean isWindows() { + return osName.toLowerCase().startsWith("win"); + } + + public static boolean isOSX() { + return osName.toLowerCase().startsWith("mac"); + } + + public static boolean isLinux() { + return osName.toLowerCase().startsWith("linux"); + } + + public static String getOsName() { + return osName; + } + + public static boolean isDebugBuild() { + return vmVersion.toLowerCase().contains("debug"); + } + + public static String getVMVersion() { + return vmVersion; + } +}