--- a/hotspot/src/cpu/x86/vm/vm_version_x86.cpp Thu Jan 05 21:02:05 2012 -0800
+++ b/hotspot/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
--- a/hotspot/src/cpu/x86/vm/vm_version_x86.hpp Thu Jan 05 21:02:05 2012 -0800
+++ b/hotspot/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; }
--- a/hotspot/src/os/posix/vm/os_posix.cpp Thu Jan 05 21:02:05 2012 -0800
+++ b/hotspot/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;
--- a/hotspot/src/os/windows/vm/os_windows.cpp Thu Jan 05 21:02:05 2012 -0800
+++ b/hotspot/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; }
--- a/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.hpp Thu Jan 05 21:02:05 2012 -0800
+++ b/hotspot/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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/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
--- a/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.hpp Thu Jan 05 21:02:05 2012 -0800
+++ b/hotspot/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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/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
--- a/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.hpp Thu Jan 05 21:02:05 2012 -0800
+++ b/hotspot/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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/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
--- a/hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_32.il Thu Jan 05 21:02:05 2012 -0800
+++ b/hotspot/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
--- a/hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_64.il Thu Jan 05 21:02:05 2012 -0800
+++ b/hotspot/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
--- a/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.hpp Thu Jan 05 21:02:05 2012 -0800
+++ b/hotspot/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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/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
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp Thu Jan 05 21:02:05 2012 -0800
+++ b/hotspot/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();
--- a/hotspot/src/share/vm/runtime/init.cpp Thu Jan 05 21:02:05 2012 -0800
+++ b/hotspot/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
--- a/hotspot/src/share/vm/runtime/os.cpp Thu Jan 05 21:02:05 2012 -0800
+++ b/hotspot/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.
--- a/hotspot/src/share/vm/runtime/os.hpp Thu Jan 05 21:02:05 2012 -0800
+++ b/hotspot/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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/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
--- a/hotspot/src/share/vm/services/management.hpp Thu Jan 05 21:02:05 2012 -0800
+++ b/hotspot/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();
}
--- a/hotspot/src/share/vm/services/threadService.cpp Thu Jan 05 21:02:05 2012 -0800
+++ b/hotspot/src/share/vm/services/threadService.cpp Fri Jan 06 16:18:29 2012 -0800
@@ -377,7 +377,7 @@
}
}
-
+ delete cycle;
return deadlocks;
}