# HG changeset patch # User dcubed # Date 1325895509 28800 # Node ID 2b3acb34791f3262cedfeead89947cbd296cb216 # Parent 2ee4167627a35fc7e61da90a4713d5fab3511a5f# Parent 66259eca2bf7259c7248cb0febff3500cdb2b04c Merge diff -r 2ee4167627a3 -r 2b3acb34791f src/cpu/x86/vm/vm_version_x86.cpp --- a/src/cpu/x86/vm/vm_version_x86.cpp Thu Jan 05 21:02:05 2012 -0800 +++ b/src/cpu/x86/vm/vm_version_x86.cpp Fri Jan 06 16:18:29 2012 -0800 @@ -50,7 +50,7 @@ VM_Version::CpuidInfo VM_Version::_cpuid_info = { 0, }; static BufferBlob* stub_blob; -static const int stub_size = 400; +static const int stub_size = 500; extern "C" { typedef void (*getPsrInfo_stub_t)(void*); @@ -73,7 +73,7 @@ const uint32_t CPU_FAMILY_486 = (4 << CPU_FAMILY_SHIFT); Label detect_486, cpu486, detect_586, std_cpuid1, std_cpuid4; - Label ext_cpuid1, ext_cpuid5, done; + Label ext_cpuid1, ext_cpuid5, ext_cpuid7, done; StubCodeMark mark(this, "VM_Version", "getPsrInfo_stub"); # define __ _masm-> @@ -235,8 +235,10 @@ __ jcc(Assembler::belowEqual, done); __ cmpl(rax, 0x80000004); // Is cpuid(0x80000005) supported? __ jccb(Assembler::belowEqual, ext_cpuid1); + __ cmpl(rax, 0x80000006); // Is cpuid(0x80000007) supported? + __ jccb(Assembler::belowEqual, ext_cpuid5); __ cmpl(rax, 0x80000007); // Is cpuid(0x80000008) supported? - __ jccb(Assembler::belowEqual, ext_cpuid5); + __ jccb(Assembler::belowEqual, ext_cpuid7); // // Extended cpuid(0x80000008) // @@ -249,6 +251,18 @@ __ movl(Address(rsi,12), rdx); // + // Extended cpuid(0x80000007) + // + __ bind(ext_cpuid7); + __ movl(rax, 0x80000007); + __ cpuid(); + __ lea(rsi, Address(rbp, in_bytes(VM_Version::ext_cpuid7_offset()))); + __ movl(Address(rsi, 0), rax); + __ movl(Address(rsi, 4), rbx); + __ movl(Address(rsi, 8), rcx); + __ movl(Address(rsi,12), rdx); + + // // Extended cpuid(0x80000005) // __ bind(ext_cpuid5); @@ -365,7 +379,7 @@ } char buf[256]; - jio_snprintf(buf, sizeof(buf), "(%u cores per cpu, %u threads per core) family %d model %d stepping %d%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", + jio_snprintf(buf, sizeof(buf), "(%u cores per cpu, %u threads per core) family %d model %d stepping %d%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", cores_per_cpu(), threads_per_core(), cpu_family(), _model, _stepping, (supports_cmov() ? ", cmov" : ""), @@ -383,7 +397,10 @@ (supports_3dnow_prefetch() ? ", 3dnowpref" : ""), (supports_lzcnt() ? ", lzcnt": ""), (supports_sse4a() ? ", sse4a": ""), - (supports_ht() ? ", ht": "")); + (supports_ht() ? ", ht": ""), + (supports_tsc() ? ", tsc": ""), + (supports_tscinv_bit() ? ", tscinvbit": ""), + (supports_tscinv() ? ", tscinv": "")); _features_str = strdup(buf); // UseSSE is set to the smaller of what hardware supports and what diff -r 2ee4167627a3 -r 2b3acb34791f src/cpu/x86/vm/vm_version_x86.hpp --- a/src/cpu/x86/vm/vm_version_x86.hpp Thu Jan 05 21:02:05 2012 -0800 +++ b/src/cpu/x86/vm/vm_version_x86.hpp Fri Jan 06 16:18:29 2012 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2011, 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 @@ -176,32 +176,54 @@ } bits; }; + union ExtCpuid7Edx { + uint32_t value; + struct { + uint32_t : 8, + tsc_invariance : 1, + : 23; + } bits; + }; + protected: - static int _cpu; - static int _model; - static int _stepping; - static int _cpuFeatures; // features returned by the "cpuid" instruction - // 0 if this instruction is not available - static const char* _features_str; + static int _cpu; + static int _model; + static int _stepping; + static int _cpuFeatures; // features returned by the "cpuid" instruction + // 0 if this instruction is not available + static const char* _features_str; - enum { - CPU_CX8 = (1 << 0), // next bits are from cpuid 1 (EDX) - CPU_CMOV = (1 << 1), - CPU_FXSR = (1 << 2), - CPU_HT = (1 << 3), - CPU_MMX = (1 << 4), - CPU_3DNOW_PREFETCH = (1 << 5), // Processor supports 3dnow prefetch and prefetchw instructions - // may not necessarily support other 3dnow instructions - CPU_SSE = (1 << 6), - CPU_SSE2 = (1 << 7), - CPU_SSE3 = (1 << 8), // SSE3 comes from cpuid 1 (ECX) - CPU_SSSE3 = (1 << 9), - CPU_SSE4A = (1 << 10), - CPU_SSE4_1 = (1 << 11), - CPU_SSE4_2 = (1 << 12), - CPU_POPCNT = (1 << 13), - CPU_LZCNT = (1 << 14) - } cpuFeatureFlags; + enum { + CPU_CX8 = (1 << 0), // next bits are from cpuid 1 (EDX) + CPU_CMOV = (1 << 1), + CPU_FXSR = (1 << 2), + CPU_HT = (1 << 3), + CPU_MMX = (1 << 4), + CPU_3DNOW_PREFETCH = (1 << 5), // Processor supports 3dnow prefetch and prefetchw instructions + // may not necessarily support other 3dnow instructions + CPU_SSE = (1 << 6), + CPU_SSE2 = (1 << 7), + CPU_SSE3 = (1 << 8), // SSE3 comes from cpuid 1 (ECX) + CPU_SSSE3 = (1 << 9), + CPU_SSE4A = (1 << 10), + CPU_SSE4_1 = (1 << 11), + CPU_SSE4_2 = (1 << 12), + CPU_POPCNT = (1 << 13), + CPU_LZCNT = (1 << 14), + CPU_TSC = (1 << 15), + CPU_TSCINV = (1 << 16) + } cpuFeatureFlags; + + enum { + // AMD + CPU_FAMILY_AMD_11H = 17, + // Intel + CPU_FAMILY_INTEL_CORE = 6, + CPU_MODEL_NEHALEM_EP = 26, + CPU_MODEL_WESTMERE_EP = 44, +// CPU_MODEL_IVYBRIDGE_EP = ??, TODO - get real value + CPU_MODEL_SANDYBRIDGE_EP = 45 + } cpuExtendedFamily; // cpuid information block. All info derived from executing cpuid with // various function numbers is stored here. Intel and AMD info is @@ -270,6 +292,12 @@ ExtCpuid5Ex ext_cpuid5_ecx; // L1 data cache info (AMD) ExtCpuid5Ex ext_cpuid5_edx; // L1 instruction cache info (AMD) + // cpuid function 0x80000007 + uint32_t ext_cpuid7_eax; // reserved + uint32_t ext_cpuid7_ebx; // reserved + uint32_t ext_cpuid7_ecx; // reserved + ExtCpuid7Edx ext_cpuid7_edx; // tscinv + // cpuid function 0x80000008 uint32_t ext_cpuid8_eax; // unused currently uint32_t ext_cpuid8_ebx; // reserved @@ -286,19 +314,23 @@ result += _cpuid_info.std_cpuid1_eax.bits.ext_family; return result; } + static uint32_t extended_cpu_model() { uint32_t result = _cpuid_info.std_cpuid1_eax.bits.model; result |= _cpuid_info.std_cpuid1_eax.bits.ext_model << 4; return result; } + static uint32_t cpu_stepping() { uint32_t result = _cpuid_info.std_cpuid1_eax.bits.stepping; return result; } + static uint logical_processor_count() { uint result = threads_per_core(); return result; } + static uint32_t feature_flags() { uint32_t result = 0; if (_cpuid_info.std_cpuid1_edx.bits.cmpxchg8 != 0) @@ -328,6 +360,10 @@ result |= CPU_SSE4_2; if (_cpuid_info.std_cpuid1_ecx.bits.popcnt != 0) result |= CPU_POPCNT; + if (_cpuid_info.std_cpuid1_edx.bits.tsc != 0) + result |= CPU_TSC; + if (_cpuid_info.ext_cpuid7_edx.bits.tsc_invariance != 0) + result |= CPU_TSCINV; // AMD features. if (is_amd()) { @@ -352,6 +388,7 @@ static ByteSize dcp_cpuid4_offset() { return byte_offset_of(CpuidInfo, dcp_cpuid4_eax); } static ByteSize ext_cpuid1_offset() { return byte_offset_of(CpuidInfo, ext_cpuid1_eax); } static ByteSize ext_cpuid5_offset() { return byte_offset_of(CpuidInfo, ext_cpuid5_eax); } + static ByteSize ext_cpuid7_offset() { return byte_offset_of(CpuidInfo, ext_cpuid7_eax); } static ByteSize ext_cpuid8_offset() { return byte_offset_of(CpuidInfo, ext_cpuid8_eax); } static ByteSize tpl_cpuidB0_offset() { return byte_offset_of(CpuidInfo, tpl_cpuidB0_eax); } static ByteSize tpl_cpuidB1_offset() { return byte_offset_of(CpuidInfo, tpl_cpuidB1_eax); } @@ -382,7 +419,6 @@ // static int cpu_family() { return _cpu;} static bool is_P6() { return cpu_family() >= 6; } - static bool is_amd() { assert_is_initialized(); return _cpuid_info.std_vendor_name_0 == 0x68747541; } // 'htuA' static bool is_intel() { assert_is_initialized(); return _cpuid_info.std_vendor_name_0 == 0x756e6547; } // 'uneG' @@ -447,14 +483,49 @@ static bool supports_sse4_1() { return (_cpuFeatures & CPU_SSE4_1) != 0; } static bool supports_sse4_2() { return (_cpuFeatures & CPU_SSE4_2) != 0; } static bool supports_popcnt() { return (_cpuFeatures & CPU_POPCNT) != 0; } - // + static bool supports_tsc() { return (_cpuFeatures & CPU_TSC) != 0; } + + // Intel features + static bool is_intel_family_core() { return is_intel() && + extended_cpu_family() == CPU_FAMILY_INTEL_CORE; } + + static bool is_intel_tsc_synched_at_init() { + if (is_intel_family_core()) { + uint32_t ext_model = extended_cpu_model(); + if (ext_model == CPU_MODEL_NEHALEM_EP || + ext_model == CPU_MODEL_WESTMERE_EP || +// TODO ext_model == CPU_MODEL_IVYBRIDGE_EP || + ext_model == CPU_MODEL_SANDYBRIDGE_EP) { + // 2-socket invtsc support. EX versions with 4 sockets are not + // guaranteed to synchronize tscs at initialization via a double + // handshake. The tscs can be explicitly set in software. Code + // that uses tsc values must be prepared for them to arbitrarily + // jump backward or forward. + return true; + } + } + return false; + } + // AMD features - // static bool supports_3dnow_prefetch() { return (_cpuFeatures & CPU_3DNOW_PREFETCH) != 0; } static bool supports_mmx_ext() { return is_amd() && _cpuid_info.ext_cpuid1_edx.bits.mmx_amd != 0; } static bool supports_lzcnt() { return (_cpuFeatures & CPU_LZCNT) != 0; } static bool supports_sse4a() { return (_cpuFeatures & CPU_SSE4A) != 0; } + static bool is_amd_Barcelona() { return is_amd() && + extended_cpu_family() == CPU_FAMILY_AMD_11H; } + + // Intel and AMD newer cores support fast timestamps well + static bool supports_tscinv_bit() { + return (_cpuFeatures & CPU_TSCINV) != 0; + } + static bool supports_tscinv() { + return supports_tscinv_bit() && + ( (is_amd() && !is_amd_Barcelona()) || + is_intel_tsc_synched_at_init() ); + } + // Intel Core and newer cpus have fast IDIV instruction (excluding Atom). static bool has_fast_idiv() { return is_intel() && cpu_family() == 6 && supports_sse3() && _model != 0x1C; } diff -r 2ee4167627a3 -r 2b3acb34791f src/os/posix/vm/os_posix.cpp --- a/src/os/posix/vm/os_posix.cpp Thu Jan 05 21:02:05 2012 -0800 +++ b/src/os/posix/vm/os_posix.cpp Fri Jan 06 16:18:29 2012 -0800 @@ -59,6 +59,10 @@ VMError::report_coredump_status(buffer, success); } +int os::get_last_error() { + return errno; +} + bool os::is_debugger_attached() { // not implemented return false; diff -r 2ee4167627a3 -r 2b3acb34791f src/os/windows/vm/os_windows.cpp --- a/src/os/windows/vm/os_windows.cpp Thu Jan 05 21:02:05 2012 -0800 +++ b/src/os/windows/vm/os_windows.cpp Fri Jan 06 16:18:29 2012 -0800 @@ -132,7 +132,6 @@ // save DLL module handle, used by GetModuleFileName HINSTANCE vm_lib_handle; -static int getLastErrorString(char *buf, size_t len); BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved) { switch (reason) { @@ -1452,7 +1451,7 @@ return result; } - long errcode = GetLastError(); + DWORD errcode = GetLastError(); if (errcode == ERROR_MOD_NOT_FOUND) { strncpy(ebuf, "Can't find dependent libraries", ebuflen-1); ebuf[ebuflen-1]='\0'; @@ -1463,11 +1462,11 @@ // If we can read dll-info and find that dll was built // for an architecture other than Hotspot is running in // - then print to buffer "DLL was built for a different architecture" - // else call getLastErrorString to obtain system error message + // else call os::lasterror to obtain system error message // Read system error message into ebuf // It may or may not be overwritten below (in the for loop and just above) - getLastErrorString(ebuf, (size_t) ebuflen); + lasterror(ebuf, (size_t) ebuflen); ebuf[ebuflen-1]='\0'; int file_descriptor=::open(name, O_RDONLY | O_BINARY, 0); if (file_descriptor<0) @@ -1500,7 +1499,7 @@ ::close(file_descriptor); if (failed_to_get_lib_arch) { - // file i/o error - report getLastErrorString(...) msg + // file i/o error - report os::lasterror(...) msg return NULL; } @@ -1543,7 +1542,7 @@ "Didn't find runing architecture code in arch_array"); // If the architure is right - // but some other error took place - report getLastErrorString(...) msg + // but some other error took place - report os::lasterror(...) msg if (lib_arch == running_arch) { return NULL; @@ -1775,12 +1774,12 @@ // This method is a copy of JDK's sysGetLastErrorString // from src/windows/hpi/src/system_md.c -size_t os::lasterror(char *buf, size_t len) { - long errval; +size_t os::lasterror(char* buf, size_t len) { + DWORD errval; if ((errval = GetLastError()) != 0) { - /* DOS error */ - int n = (int)FormatMessage( + // DOS error + size_t n = (size_t)FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, NULL, errval, @@ -1789,7 +1788,7 @@ (DWORD)len, NULL); if (n > 3) { - /* Drop final '.', CR, LF */ + // Drop final '.', CR, LF if (buf[n - 1] == '\n') n--; if (buf[n - 1] == '\r') n--; if (buf[n - 1] == '.') n--; @@ -1799,17 +1798,25 @@ } if (errno != 0) { - /* C runtime error that has no corresponding DOS error code */ - const char *s = strerror(errno); + // C runtime error that has no corresponding DOS error code + const char* s = strerror(errno); size_t n = strlen(s); if (n >= len) n = len - 1; strncpy(buf, s, n); buf[n] = '\0'; return n; } + return 0; } +int os::get_last_error() { + DWORD error = GetLastError(); + if (error == 0) + error = errno; + return (int)error; +} + // sun.misc.Signal // NOTE that this is a workaround for an apparent kernel bug where if // a signal handler for SIGBREAK is installed then that signal handler @@ -4746,7 +4753,7 @@ fatal("corrupted C heap"); } } - int err = GetLastError(); + DWORD err = GetLastError(); if (err != ERROR_NO_MORE_ITEMS && err != ERROR_CALL_NOT_IMPLEMENTED) { fatal(err_msg("heap walk aborted with error %d", err)); } @@ -4778,45 +4785,6 @@ return EXCEPTION_CONTINUE_SEARCH; } -static int getLastErrorString(char *buf, size_t len) -{ - long errval; - - if ((errval = GetLastError()) != 0) - { - /* DOS error */ - size_t n = (size_t)FormatMessage( - FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - errval, - 0, - buf, - (DWORD)len, - NULL); - if (n > 3) { - /* Drop final '.', CR, LF */ - if (buf[n - 1] == '\n') n--; - if (buf[n - 1] == '\r') n--; - if (buf[n - 1] == '.') n--; - buf[n] = '\0'; - } - return (int)n; - } - - if (errno != 0) - { - /* C runtime error that has no corresponding DOS error code */ - const char *s = strerror(errno); - size_t n = strlen(s); - if (n >= len) n = len - 1; - strncpy(buf, s, n); - buf[n] = '\0'; - return (int)n; - } - return 0; -} - - // We don't build a headless jre for Windows bool os::is_headless_jre() { return false; } diff -r 2ee4167627a3 -r 2b3acb34791f src/os_cpu/bsd_x86/vm/os_bsd_x86.hpp --- a/src/os_cpu/bsd_x86/vm/os_bsd_x86.hpp Thu Jan 05 21:02:05 2012 -0800 +++ b/src/os_cpu/bsd_x86/vm/os_bsd_x86.hpp Fri Jan 06 16:18:29 2012 -0800 @@ -28,6 +28,8 @@ static void setup_fpu(); static bool supports_sse(); + static jlong rdtsc(); + static bool is_allocatable(size_t bytes); // Used to register dynamic code cache area with the OS diff -r 2ee4167627a3 -r 2b3acb34791f src/os_cpu/bsd_x86/vm/os_bsd_x86.inline.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/os_cpu/bsd_x86/vm/os_bsd_x86.inline.hpp Fri Jan 06 16:18:29 2012 -0800 @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2011, 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. + * + */ + +#ifndef OS_CPU_BSD_X86_VM_OS_BSD_X86_INLINE_HPP +#define OS_CPU_BSD_X86_VM_OS_BSD_X86_INLINE_HPP + +#include "runtime/os.hpp" + +// See http://www.technovelty.org/code/c/reading-rdtsc.htl for details +inline jlong os::rdtsc() { +#ifndef AMD64 + // 64 bit result in edx:eax + uint64_t res; + __asm__ __volatile__ ("rdtsc" : "=A" (res)); + return (jlong)res; +#else + uint64_t res; + uint32_t ts1, ts2; + __asm__ __volatile__ ("rdtsc" : "=a" (ts1), "=d" (ts2)); + res = ((uint64_t)ts1 | (uint64_t)ts2 << 32); + return (jlong)res; +#endif // AMD64 +} + +#endif // OS_CPU_BSD_X86_VM_OS_BSD_X86_INLINE_HPP diff -r 2ee4167627a3 -r 2b3acb34791f src/os_cpu/linux_x86/vm/os_linux_x86.hpp --- a/src/os_cpu/linux_x86/vm/os_linux_x86.hpp Thu Jan 05 21:02:05 2012 -0800 +++ b/src/os_cpu/linux_x86/vm/os_linux_x86.hpp Fri Jan 06 16:18:29 2012 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2011, 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 @@ -28,6 +28,8 @@ static void setup_fpu(); static bool supports_sse(); + static jlong rdtsc(); + static bool is_allocatable(size_t bytes); // Used to register dynamic code cache area with the OS diff -r 2ee4167627a3 -r 2b3acb34791f src/os_cpu/linux_x86/vm/os_linux_x86.inline.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/os_cpu/linux_x86/vm/os_linux_x86.inline.hpp Fri Jan 06 16:18:29 2012 -0800 @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2011, 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. + * + */ + +#ifndef OS_CPU_LINUX_X86_VM_OS_LINUX_X86_INLINE_HPP +#define OS_CPU_LINUX_X86_VM_OS_LINUX_X86_INLINE_HPP + +#include "runtime/os.hpp" + +// See http://www.technovelty.org/code/c/reading-rdtsc.htl for details +inline jlong os::rdtsc() { +#ifndef AMD64 + // 64 bit result in edx:eax + uint64_t res; + __asm__ __volatile__ ("rdtsc" : "=A" (res)); + return (jlong)res; +#else + uint64_t res; + uint32_t ts1, ts2; + __asm__ __volatile__ ("rdtsc" : "=a" (ts1), "=d" (ts2)); + res = ((uint64_t)ts1 | (uint64_t)ts2 << 32); + return (jlong)res; +#endif // AMD64 +} + +#endif // OS_CPU_LINUX_X86_VM_OS_LINUX_X86_INLINE_HPP diff -r 2ee4167627a3 -r 2b3acb34791f src/os_cpu/solaris_x86/vm/os_solaris_x86.hpp --- a/src/os_cpu/solaris_x86/vm/os_solaris_x86.hpp Thu Jan 05 21:02:05 2012 -0800 +++ b/src/os_cpu/solaris_x86/vm/os_solaris_x86.hpp Fri Jan 06 16:18:29 2012 -0800 @@ -46,6 +46,8 @@ static bool supports_sse(); + static jlong rdtsc(); + static bool is_allocatable(size_t bytes); // Used to register dynamic code cache area with the OS diff -r 2ee4167627a3 -r 2b3acb34791f src/os_cpu/solaris_x86/vm/os_solaris_x86.inline.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/os_cpu/solaris_x86/vm/os_solaris_x86.inline.hpp Fri Jan 06 16:18:29 2012 -0800 @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2011, 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. + * + */ + +#ifndef OS_CPU_SOLARIS_X86_VM_OS_SOLARIS_X86_INLINE_HPP +#define OS_CPU_SOLARIS_X86_VM_OS_SOLARIS_X86_INLINE_HPP + +#include "runtime/os.hpp" + +inline jlong os::rdtsc() { return _raw_rdtsc(); } + +#endif // OS_CPU_SOLARIS_X86_VM_OS_SOLARIS_X86_INLINE_HPP diff -r 2ee4167627a3 -r 2b3acb34791f src/os_cpu/solaris_x86/vm/solaris_x86_32.il --- a/src/os_cpu/solaris_x86/vm/solaris_x86_32.il Thu Jan 05 21:02:05 2012 -0800 +++ b/src/os_cpu/solaris_x86/vm/solaris_x86_32.il Fri Jan 06 16:18:29 2012 -0800 @@ -43,6 +43,11 @@ movl %ebp, %eax .end + // Support for os::rdtsc() + .inline _raw_rdtsc,0 + rdtsc + .end + // Support for jint Atomic::add(jint inc, volatile jint* dest) // An additional bool (os::is_MP()) is passed as the last argument. .inline _Atomic_add,3 @@ -113,7 +118,6 @@ fistpll (%eax) .end - // Support for OrderAccess::acquire() .inline _OrderAccess_acquire,0 movl 0(%esp), %eax diff -r 2ee4167627a3 -r 2b3acb34791f src/os_cpu/solaris_x86/vm/solaris_x86_64.il --- a/src/os_cpu/solaris_x86/vm/solaris_x86_64.il Thu Jan 05 21:02:05 2012 -0800 +++ b/src/os_cpu/solaris_x86/vm/solaris_x86_64.il Fri Jan 06 16:18:29 2012 -0800 @@ -30,12 +30,19 @@ movq %fs:0, %rax .end - // Get the frame pointer from current frame. + // Get current fp .inline _get_current_fp,0 .volatile movq %rbp, %rax .end + // Support for os::rdtsc() + .inline _raw_rdtsc,0 + rdtsc + salq $32, %rdx + orq %rdx, %rax + .end + // Support for jint Atomic::add(jint add_value, volatile jint* dest) .inline _Atomic_add,2 movl %edi, %eax // save add_value for return diff -r 2ee4167627a3 -r 2b3acb34791f src/os_cpu/windows_x86/vm/os_windows_x86.hpp --- a/src/os_cpu/windows_x86/vm/os_windows_x86.hpp Thu Jan 05 21:02:05 2012 -0800 +++ b/src/os_cpu/windows_x86/vm/os_windows_x86.hpp Fri Jan 06 16:18:29 2012 -0800 @@ -58,6 +58,8 @@ static void setup_fpu(); static bool supports_sse() { return true; } + static jlong rdtsc(); + static bool register_code_area(char *low, char *high); #endif // OS_CPU_WINDOWS_X86_VM_OS_WINDOWS_X86_HPP diff -r 2ee4167627a3 -r 2b3acb34791f src/os_cpu/windows_x86/vm/os_windows_x86.inline.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/os_cpu/windows_x86/vm/os_windows_x86.inline.hpp Fri Jan 06 16:18:29 2012 -0800 @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2011, 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. + * + */ + +#ifndef OS_CPU_WINDOWS_X86_VM_OS_WINDOWS_X86_INLINE_HPP +#define OS_CPU_WINDOWS_X86_VM_OS_WINDOWS_X86_INLINE_HPP + +#include "runtime/os.hpp" + +inline jlong os::rdtsc() { + // 32 bit: 64 bit result in edx:eax + // 64 bit: 64 bit value in rax + uint64_t res; + res = (uint64_t)__rdtsc(); + return (jlong)res; +} + +#endif // OS_CPU_WINDOWS_X86_VM_OS_WINDOWS_X86_INLINE_HPP diff -r 2ee4167627a3 -r 2b3acb34791f src/share/vm/classfile/classFileParser.cpp --- a/src/share/vm/classfile/classFileParser.cpp Thu Jan 05 21:02:05 2012 -0800 +++ b/src/share/vm/classfile/classFileParser.cpp Fri Jan 06 16:18:29 2012 -0800 @@ -2666,18 +2666,23 @@ _max_bootstrap_specifier_index = -1; if (JvmtiExport::should_post_class_file_load_hook()) { - // Get the cached class file bytes (if any) from the - // class that is being redefined. - JvmtiThreadState *state = JvmtiThreadState::state_for(jt); - KlassHandle *h_class_being_redefined = - state->get_class_being_redefined(); - if (h_class_being_redefined != NULL) { - instanceKlassHandle ikh_class_being_redefined = - instanceKlassHandle(THREAD, (*h_class_being_redefined)()); - cached_class_file_bytes = - ikh_class_being_redefined->get_cached_class_file_bytes(); - cached_class_file_length = - ikh_class_being_redefined->get_cached_class_file_len(); + // Get the cached class file bytes (if any) from the class that + // is being redefined or retransformed. We use jvmti_thread_state() + // instead of JvmtiThreadState::state_for(jt) so we don't allocate + // a JvmtiThreadState any earlier than necessary. This will help + // avoid the bug described by 7126851. + JvmtiThreadState *state = jt->jvmti_thread_state(); + if (state != NULL) { + KlassHandle *h_class_being_redefined = + state->get_class_being_redefined(); + if (h_class_being_redefined != NULL) { + instanceKlassHandle ikh_class_being_redefined = + instanceKlassHandle(THREAD, (*h_class_being_redefined)()); + cached_class_file_bytes = + ikh_class_being_redefined->get_cached_class_file_bytes(); + cached_class_file_length = + ikh_class_being_redefined->get_cached_class_file_len(); + } } unsigned char* ptr = cfs->buffer(); diff -r 2ee4167627a3 -r 2b3acb34791f src/share/vm/runtime/init.cpp --- a/src/share/vm/runtime/init.cpp Thu Jan 05 21:02:05 2012 -0800 +++ b/src/share/vm/runtime/init.cpp Fri Jan 06 16:18:29 2012 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2011, 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 @@ -47,15 +47,16 @@ void classLoader_init(); void codeCache_init(); void VM_Version_init(); +void os_init_globals(); // depends on VM_Version_init, before universe_init void stubRoutines_init1(); -jint universe_init(); // dependent on codeCache_init and stubRoutines_init -void interpreter_init(); // before any methods loaded -void invocationCounter_init(); // before any methods loaded +jint universe_init(); // depends on codeCache_init and stubRoutines_init +void interpreter_init(); // before any methods loaded +void invocationCounter_init(); // before any methods loaded void marksweep_init(); void accessFlags_init(); void templateTable_init(); void InterfaceSupport_init(); -void universe2_init(); // dependent on codeCache_init and stubRoutines_init +void universe2_init(); // dependent on codeCache_init and stubRoutines_init, loads primordial classes void referenceProcessor_init(); void jni_handles_init(); void vmStructs_init(); @@ -94,8 +95,10 @@ classLoader_init(); codeCache_init(); VM_Version_init(); + os_init_globals(); stubRoutines_init1(); - jint status = universe_init(); // dependent on codeCache_init and stubRoutines_init + jint status = universe_init(); // dependent on codeCache_init and + // stubRoutines_init1 if (status != JNI_OK) return status; @@ -106,7 +109,7 @@ templateTable_init(); InterfaceSupport_init(); SharedRuntime::generate_stubs(); - universe2_init(); // dependent on codeCache_init and stubRoutines_init + universe2_init(); // dependent on codeCache_init and stubRoutines_init1 referenceProcessor_init(); jni_handles_init(); #ifndef VM_STRUCTS_KERNEL @@ -122,7 +125,7 @@ if (!universe_post_init()) { return JNI_ERR; } - javaClasses_init(); // must happen after vtable initialization + javaClasses_init(); // must happen after vtable initialization stubRoutines_init2(); // note: StubRoutines need 2-phase init // Although we'd like to, we can't easily do a heap verify diff -r 2ee4167627a3 -r 2b3acb34791f src/share/vm/runtime/os.cpp --- a/src/share/vm/runtime/os.cpp Thu Jan 05 21:02:05 2012 -0800 +++ b/src/share/vm/runtime/os.cpp Fri Jan 06 16:18:29 2012 -0800 @@ -82,6 +82,12 @@ julong os::free_bytes = 0; // # of bytes freed #endif +void os_init_globals() { + // Called from init_globals(). + // See Threads::create_vm() in thread.cpp, and init.cpp. + os::init_globals(); +} + // Fill in buffer with current local time as an ISO-8601 string. // E.g., yyyy-mm-ddThh:mm:ss-zzzz. // Returns buffer, or NULL if it failed. diff -r 2ee4167627a3 -r 2b3acb34791f src/share/vm/runtime/os.hpp --- a/src/share/vm/runtime/os.hpp Thu Jan 05 21:02:05 2012 -0800 +++ b/src/share/vm/runtime/os.hpp Fri Jan 06 16:18:29 2012 -0800 @@ -99,9 +99,11 @@ } public: - static void init(void); // Called before command line parsing static jint init_2(void); // Called after command line parsing + static void init_globals(void) { // Called from init_globals() in init.cpp + init_globals_ext(); + } static void init_3(void); // Called at the end of vm init // File names are case-insensitive on windows only @@ -500,6 +502,7 @@ static void print_location(outputStream* st, intptr_t x, bool verbose = false); static size_t lasterror(char *buf, size_t len); + static int get_last_error(); // Determines whether the calling process is being debugged by a user-mode debugger. static bool is_debugger_attached(); @@ -671,6 +674,11 @@ // rest of line is skipped. Returns number of bytes read or -1 on EOF static int get_line_chars(int fd, char *buf, const size_t bsize); + // Extensions +#include "runtime/os_ext.hpp" + + public: + // Platform dependent stuff #ifdef TARGET_OS_FAMILY_linux # include "os_linux.hpp" @@ -715,6 +723,7 @@ # include "os_bsd_zero.hpp" #endif + public: // debugging support (mostly used by debug.cpp but also fatal error handler) static bool find(address pc, outputStream* st = tty); // OS specific function to make sense out of an address diff -r 2ee4167627a3 -r 2b3acb34791f src/share/vm/runtime/os_ext.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/vm/runtime/os_ext.hpp Fri Jan 06 16:18:29 2012 -0800 @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2011 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. + * + */ + +#ifndef SHARE_VM_RUNTIME_OS_EXT_HPP +#define SHARE_VM_RUNTIME_OS_EXT_HPP + + public: + static void init_globals_ext() {} // Run from init_globals(). + // See os.hpp/cpp and init.cpp. + + private: + +#endif // SHARE_VM_RUNTIME_OS_EXT_HPP diff -r 2ee4167627a3 -r 2b3acb34791f src/share/vm/services/management.hpp --- a/src/share/vm/services/management.hpp Thu Jan 05 21:02:05 2012 -0800 +++ b/src/share/vm/services/management.hpp Fri Jan 06 16:18:29 2012 -0800 @@ -76,6 +76,9 @@ _stamp.update(); } + static jlong begin_vm_creation_time() { + return _begin_vm_creation_time->get_value(); + } static jlong vm_init_done_time() { return _vm_init_done_time->get_value(); } diff -r 2ee4167627a3 -r 2b3acb34791f src/share/vm/services/threadService.cpp --- a/src/share/vm/services/threadService.cpp Thu Jan 05 21:02:05 2012 -0800 +++ b/src/share/vm/services/threadService.cpp Fri Jan 06 16:18:29 2012 -0800 @@ -377,7 +377,7 @@ } } - + delete cycle; return deadlocks; }