aboutsummaryrefslogtreecommitdiff
path: root/src/os_cpu/windows_x86
diff options
context:
space:
mode:
authorduke <none@none>2007-12-01 00:00:00 +0000
committerduke <none@none>2007-12-01 00:00:00 +0000
commitfa88c88cef63eb7f9083dccb60548d78635a44b1 (patch)
tree8376f6e5c41e70162b5867d9e1fea3f17f540473 /src/os_cpu/windows_x86
downloadjdk8u_hotspot-fa88c88cef63eb7f9083dccb60548d78635a44b1.tar.gz
Initial load
Diffstat (limited to 'src/os_cpu/windows_x86')
-rw-r--r--src/os_cpu/windows_x86/vm/assembler_windows_x86_32.cpp64
-rw-r--r--src/os_cpu/windows_x86/vm/assembler_windows_x86_64.cpp71
-rw-r--r--src/os_cpu/windows_x86/vm/atomic_windows_x86.inline.hpp251
-rw-r--r--src/os_cpu/windows_x86/vm/bytes_windows_x86.inline.hpp82
-rw-r--r--src/os_cpu/windows_x86/vm/copy_windows_x86.inline.hpp166
-rw-r--r--src/os_cpu/windows_x86/vm/globals_windows_x86.hpp49
-rw-r--r--src/os_cpu/windows_x86/vm/orderAccess_windows_x86.inline.hpp210
-rw-r--r--src/os_cpu/windows_x86/vm/os_windows_x86.cpp478
-rw-r--r--src/os_cpu/windows_x86/vm/os_windows_x86.hpp63
-rw-r--r--src/os_cpu/windows_x86/vm/prefetch_windows_x86.inline.hpp26
-rw-r--r--src/os_cpu/windows_x86/vm/threadLS_windows_x86.cpp48
-rw-r--r--src/os_cpu/windows_x86/vm/threadLS_windows_x86.hpp44
-rw-r--r--src/os_cpu/windows_x86/vm/thread_windows_x86.cpp86
-rw-r--r--src/os_cpu/windows_x86/vm/thread_windows_x86.hpp62
-rw-r--r--src/os_cpu/windows_x86/vm/unwind_windows_x86.hpp78
-rw-r--r--src/os_cpu/windows_x86/vm/vmStructs_windows_x86.hpp54
-rw-r--r--src/os_cpu/windows_x86/vm/vm_version_windows_x86.cpp26
-rw-r--r--src/os_cpu/windows_x86/vm/windows_x86_32.ad158
-rw-r--r--src/os_cpu/windows_x86/vm/windows_x86_64.ad159
19 files changed, 2175 insertions, 0 deletions
diff --git a/src/os_cpu/windows_x86/vm/assembler_windows_x86_32.cpp b/src/os_cpu/windows_x86/vm/assembler_windows_x86_32.cpp
new file mode 100644
index 000000000..dd90d704f
--- /dev/null
+++ b/src/os_cpu/windows_x86/vm/assembler_windows_x86_32.cpp
@@ -0,0 +1,64 @@
+/*
+ * Copyright 1999-2003 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_assembler_windows_x86_32.cpp.incl"
+
+
+void MacroAssembler::int3() {
+ emit_byte(0xCC);
+}
+
+// The current scheme to accelerate access to the thread
+// pointer is to store the current thread in the os_exception_wrapper
+// and reference the current thread from stubs and compiled code
+// via the FS register. FS[0] contains a pointer to the structured
+// exception block which is actually a stack address. The first time
+// we call the os exception wrapper, we calculate and store the
+// offset from this exception block and use that offset here.
+//
+// The last mechanism we used was problematic in that the
+// the offset we had hard coded in the VM kept changing as Microsoft
+// evolved the OS.
+//
+// Warning: This mechanism assumes that we only attempt to get the
+// thread when we are nested below a call wrapper.
+//
+// movl reg, fs:[0] Get exeception pointer
+// movl reg, [reg + thread_ptr_offset] Load thread
+//
+void MacroAssembler::get_thread(Register thread) {
+ // can't use ExternalAddress because it can't take NULL
+ AddressLiteral null(0, relocInfo::none);
+
+ prefix(FS_segment);
+ movptr(thread, null);
+ assert(ThreadLocalStorage::get_thread_ptr_offset() != 0,
+ "Thread Pointer Offset has not been initialized");
+ movl(thread, Address(thread, ThreadLocalStorage::get_thread_ptr_offset()));
+}
+
+bool MacroAssembler::needs_explicit_null_check(int offset) {
+ return offset < 0 || (int)os::vm_page_size() <= offset;
+}
diff --git a/src/os_cpu/windows_x86/vm/assembler_windows_x86_64.cpp b/src/os_cpu/windows_x86/vm/assembler_windows_x86_64.cpp
new file mode 100644
index 000000000..c0211d0af
--- /dev/null
+++ b/src/os_cpu/windows_x86/vm/assembler_windows_x86_64.cpp
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2003-2005 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_assembler_windows_x86_64.cpp.incl"
+
+
+void MacroAssembler::int3() {
+ emit_byte(0xCC);
+}
+
+// call (Thread*)TlsGetValue(thread_index());
+void MacroAssembler::get_thread(Register thread) {
+ if (thread != rax) {
+ pushq(rax);
+ }
+ pushq(rdi);
+ pushq(rsi);
+ pushq(rdx);
+ pushq(rcx);
+ pushq(r8);
+ pushq(r9);
+ pushq(r10);
+ // XXX
+ movq(r10, rsp);
+ andq(rsp, -16);
+ pushq(r10);
+ pushq(r11);
+
+ movl(c_rarg0, ThreadLocalStorage::thread_index());
+ call(RuntimeAddress((address)TlsGetValue));
+
+ popq(r11);
+ popq(rsp);
+ popq(r10);
+ popq(r9);
+ popq(r8);
+ popq(rcx);
+ popq(rdx);
+ popq(rsi);
+ popq(rdi);
+ if (thread != rax) {
+ movq(thread, rax);
+ popq(rax);
+ }
+}
+
+bool MacroAssembler::needs_explicit_null_check(int offset) {
+ return offset < 0 || (int)os::vm_page_size() <= offset;
+}
diff --git a/src/os_cpu/windows_x86/vm/atomic_windows_x86.inline.hpp b/src/os_cpu/windows_x86/vm/atomic_windows_x86.inline.hpp
new file mode 100644
index 000000000..cb85f306b
--- /dev/null
+++ b/src/os_cpu/windows_x86/vm/atomic_windows_x86.inline.hpp
@@ -0,0 +1,251 @@
+/*
+ * Copyright 1999-2005 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+// The following alternative implementations are needed because
+// Windows 95 doesn't support (some of) the corresponding Windows NT
+// calls. Furthermore, these versions allow inlining in the caller.
+// (More precisely: The documentation for InterlockedExchange says
+// it is supported for Windows 95. However, when single-stepping
+// through the assembly code we cannot step into the routine and
+// when looking at the routine address we see only garbage code.
+// Better safe then sorry!). Was bug 7/31/98 (gri).
+//
+// Performance note: On uniprocessors, the 'lock' prefixes are not
+// necessary (and expensive). We should generate separate cases if
+// this becomes a performance problem.
+
+#pragma warning(disable: 4035) // Disables warnings reporting missing return statement
+
+inline void Atomic::store (jbyte store_value, jbyte* dest) { *dest = store_value; }
+inline void Atomic::store (jshort store_value, jshort* dest) { *dest = store_value; }
+inline void Atomic::store (jint store_value, jint* dest) { *dest = store_value; }
+
+inline void Atomic::store_ptr(intptr_t store_value, intptr_t* dest) { *dest = store_value; }
+inline void Atomic::store_ptr(void* store_value, void* dest) { *(void**)dest = store_value; }
+
+inline void Atomic::store (jbyte store_value, volatile jbyte* dest) { *dest = store_value; }
+inline void Atomic::store (jshort store_value, volatile jshort* dest) { *dest = store_value; }
+inline void Atomic::store (jint store_value, volatile jint* dest) { *dest = store_value; }
+
+
+inline void Atomic::store_ptr(intptr_t store_value, volatile intptr_t* dest) { *dest = store_value; }
+inline void Atomic::store_ptr(void* store_value, volatile void* dest) { *(void* volatile *)dest = store_value; }
+
+// Adding a lock prefix to an instruction on MP machine
+// VC++ doesn't like the lock prefix to be on a single line
+// so we can't insert a label after the lock prefix.
+// By emitting a lock prefix, we can define a label after it.
+#define LOCK_IF_MP(mp) __asm cmp mp, 0 \
+ __asm je L0 \
+ __asm _emit 0xF0 \
+ __asm L0:
+
+#ifdef AMD64
+inline void Atomic::store (jlong store_value, jlong* dest) { *dest = store_value; }
+inline void Atomic::store (jlong store_value, volatile jlong* dest) { *dest = store_value; }
+
+inline jint Atomic::add (jint add_value, volatile jint* dest) {
+ return (jint)(*os::atomic_add_func)(add_value, dest);
+}
+
+inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) {
+ return (intptr_t)(*os::atomic_add_ptr_func)(add_value, dest);
+}
+
+inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) {
+ return (void*)(*os::atomic_add_ptr_func)(add_value, (volatile intptr_t*)dest);
+}
+
+inline void Atomic::inc (volatile jint* dest) {
+ (void)add (1, dest);
+}
+
+inline void Atomic::inc_ptr(volatile intptr_t* dest) {
+ (void)add_ptr(1, dest);
+}
+
+inline void Atomic::inc_ptr(volatile void* dest) {
+ (void)add_ptr(1, dest);
+}
+
+inline void Atomic::dec (volatile jint* dest) {
+ (void)add (-1, dest);
+}
+
+inline void Atomic::dec_ptr(volatile intptr_t* dest) {
+ (void)add_ptr(-1, dest);
+}
+
+inline void Atomic::dec_ptr(volatile void* dest) {
+ (void)add_ptr(-1, dest);
+}
+
+inline jint Atomic::xchg (jint exchange_value, volatile jint* dest) {
+ return (jint)(*os::atomic_xchg_func)(exchange_value, dest);
+}
+
+inline intptr_t Atomic::xchg_ptr(intptr_t exchange_value, volatile intptr_t* dest) {
+ return (intptr_t)(os::atomic_xchg_ptr_func)(exchange_value, dest);
+}
+
+inline void* Atomic::xchg_ptr(void* exchange_value, volatile void* dest) {
+ return (void *)(os::atomic_xchg_ptr_func)((intptr_t)exchange_value, (volatile intptr_t*)dest);
+}
+
+inline jint Atomic::cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value) {
+ return (*os::atomic_cmpxchg_func)(exchange_value, dest, compare_value);
+}
+
+inline jlong Atomic::cmpxchg (jlong exchange_value, volatile jlong* dest, jlong compare_value) {
+ return (*os::atomic_cmpxchg_long_func)(exchange_value, dest, compare_value);
+}
+
+inline intptr_t Atomic::cmpxchg_ptr(intptr_t exchange_value, volatile intptr_t* dest, intptr_t compare_value) {
+ return (intptr_t)cmpxchg((jlong)exchange_value, (volatile jlong*)dest, (jlong)compare_value);
+}
+
+inline void* Atomic::cmpxchg_ptr(void* exchange_value, volatile void* dest, void* compare_value) {
+ return (void*)cmpxchg((jlong)exchange_value, (volatile jlong*)dest, (jlong)compare_value);
+}
+
+#else // !AMD64
+
+//inline void Atomic::store (jlong store_value, jlong* dest) { *dest = store_value; }
+//inline void Atomic::store (jlong store_value, volatile jlong* dest) { *dest = store_value; }
+inline jint Atomic::add (jint add_value, volatile jint* dest) {
+ int mp = os::is_MP();
+ __asm {
+ mov edx, dest;
+ mov eax, add_value;
+ mov ecx, eax;
+ LOCK_IF_MP(mp)
+ xadd dword ptr [edx], eax;
+ add eax, ecx;
+ }
+}
+
+inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) {
+ return (intptr_t)add((jint)add_value, (volatile jint*)dest);
+}
+
+inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) {
+ return (void*)add((jint)add_value, (volatile jint*)dest);
+}
+
+inline void Atomic::inc (volatile jint* dest) {
+ // alternative for InterlockedIncrement
+ int mp = os::is_MP();
+ __asm {
+ mov edx, dest;
+ LOCK_IF_MP(mp)
+ add dword ptr [edx], 1;
+ }
+}
+
+inline void Atomic::inc_ptr(volatile intptr_t* dest) {
+ inc((volatile jint*)dest);
+}
+
+inline void Atomic::inc_ptr(volatile void* dest) {
+ inc((volatile jint*)dest);
+}
+
+inline void Atomic::dec (volatile jint* dest) {
+ // alternative for InterlockedDecrement
+ int mp = os::is_MP();
+ __asm {
+ mov edx, dest;
+ LOCK_IF_MP(mp)
+ sub dword ptr [edx], 1;
+ }
+}
+
+inline void Atomic::dec_ptr(volatile intptr_t* dest) {
+ dec((volatile jint*)dest);
+}
+
+inline void Atomic::dec_ptr(volatile void* dest) {
+ dec((volatile jint*)dest);
+}
+
+inline jint Atomic::xchg (jint exchange_value, volatile jint* dest) {
+ // alternative for InterlockedExchange
+ __asm {
+ mov eax, exchange_value;
+ mov ecx, dest;
+ xchg eax, dword ptr [ecx];
+ }
+}
+
+inline intptr_t Atomic::xchg_ptr(intptr_t exchange_value, volatile intptr_t* dest) {
+ return (intptr_t)xchg((jint)exchange_value, (volatile jint*)dest);
+}
+
+inline void* Atomic::xchg_ptr(void* exchange_value, volatile void* dest) {
+ return (void*)xchg((jint)exchange_value, (volatile jint*)dest);
+}
+
+inline jint Atomic::cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value) {
+ // alternative for InterlockedCompareExchange
+ int mp = os::is_MP();
+ __asm {
+ mov edx, dest
+ mov ecx, exchange_value
+ mov eax, compare_value
+ LOCK_IF_MP(mp)
+ cmpxchg dword ptr [edx], ecx
+ }
+}
+
+inline jlong Atomic::cmpxchg (jlong exchange_value, volatile jlong* dest, jlong compare_value) {
+ int mp = os::is_MP();
+ jint ex_lo = (jint)exchange_value;
+ jint ex_hi = *( ((jint*)&exchange_value) + 1 );
+ jint cmp_lo = (jint)compare_value;
+ jint cmp_hi = *( ((jint*)&compare_value) + 1 );
+ __asm {
+ push ebx
+ push edi
+ mov eax, cmp_lo
+ mov edx, cmp_hi
+ mov edi, dest
+ mov ebx, ex_lo
+ mov ecx, ex_hi
+ LOCK_IF_MP(mp)
+ cmpxchg8b qword ptr [edi]
+ pop edi
+ pop ebx
+ }
+}
+
+inline intptr_t Atomic::cmpxchg_ptr(intptr_t exchange_value, volatile intptr_t* dest, intptr_t compare_value) {
+ return (intptr_t)cmpxchg((jint)exchange_value, (volatile jint*)dest, (jint)compare_value);
+}
+
+inline void* Atomic::cmpxchg_ptr(void* exchange_value, volatile void* dest, void* compare_value) {
+ return (void*)cmpxchg((jint)exchange_value, (volatile jint*)dest, (jint)compare_value);
+}
+#endif // AMD64
+
+#pragma warning(default: 4035) // Enables warnings reporting missing return statement
diff --git a/src/os_cpu/windows_x86/vm/bytes_windows_x86.inline.hpp b/src/os_cpu/windows_x86/vm/bytes_windows_x86.inline.hpp
new file mode 100644
index 000000000..345bfbd38
--- /dev/null
+++ b/src/os_cpu/windows_x86/vm/bytes_windows_x86.inline.hpp
@@ -0,0 +1,82 @@
+/*
+ * Copyright 1998 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+#pragma warning(disable: 4035) // Disable warning 4035: no return value
+
+// Efficient swapping of data bytes from Java byte
+// ordering to native byte ordering and vice versa.
+inline u2 Bytes::swap_u2(u2 x) {
+#ifdef AMD64
+ address p = (address) &x;
+ return ( (u2(p[0]) << 8 ) | ( u2(p[1])) );
+#else
+ __asm {
+ mov ax, x
+ xchg al, ah
+ }
+ // no return statement needed, result is already in ax
+ // compiler warning C4035 disabled via warning pragma
+#endif // AMD64
+}
+
+inline u4 Bytes::swap_u4(u4 x) {
+#ifdef AMD64
+ address p = (address) &x;
+ return ( (u4(p[0]) << 24) | (u4(p[1]) << 16) | (u4(p[2]) << 8) | u4(p[3])) ;
+#else
+ __asm {
+ mov eax, x
+ bswap eax
+ }
+ // no return statement needed, result is already in eax
+ // compiler warning C4035 disabled via warning pragma
+#endif // AMD64
+}
+
+#ifdef AMD64
+inline u8 Bytes::swap_u8(u8 x) {
+ address p = (address) &x;
+ return ( (u8(p[0]) << 56) | (u8(p[1]) << 48) | (u8(p[2]) << 40) | (u8(p[3]) << 32) |
+ (u8(p[4]) << 24) | (u8(p[5]) << 16) | (u8(p[6]) << 8) | u8(p[7])) ;
+}
+
+#else
+// Helper function for swap_u8
+inline u8 Bytes::swap_u8_base(u4 x, u4 y) {
+ __asm {
+ mov eax, y
+ mov edx, x
+ bswap eax
+ bswap edx
+ }
+ // no return statement needed, result is already in edx:eax
+ // compiler warning C4035 disabled via warning pragma
+}
+
+inline u8 Bytes::swap_u8(u8 x) {
+ return swap_u8_base(*(u4*)&x, *(((u4*)&x)+1));
+}
+#endif // AMD64
+
+#pragma warning(default: 4035) // Enable warning 4035: no return value
diff --git a/src/os_cpu/windows_x86/vm/copy_windows_x86.inline.hpp b/src/os_cpu/windows_x86/vm/copy_windows_x86.inline.hpp
new file mode 100644
index 000000000..2d6c05195
--- /dev/null
+++ b/src/os_cpu/windows_x86/vm/copy_windows_x86.inline.hpp
@@ -0,0 +1,166 @@
+/*
+ * Copyright 2003-2004 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+static void pd_conjoint_words(HeapWord* from, HeapWord* to, size_t count) {
+ (void)memmove(to, from, count * HeapWordSize);
+}
+
+static void pd_disjoint_words(HeapWord* from, HeapWord* to, size_t count) {
+#ifdef AMD64
+ switch (count) {
+ case 8: to[7] = from[7];
+ case 7: to[6] = from[6];
+ case 6: to[5] = from[5];
+ case 5: to[4] = from[4];
+ case 4: to[3] = from[3];
+ case 3: to[2] = from[2];
+ case 2: to[1] = from[1];
+ case 1: to[0] = from[0];
+ case 0: break;
+ default:
+ (void)memcpy(to, from, count * HeapWordSize);
+ break;
+ }
+#else
+ (void)memcpy(to, from, count * HeapWordSize);
+#endif // AMD64
+}
+
+static void pd_disjoint_words_atomic(HeapWord* from, HeapWord* to, size_t count) {
+ switch (count) {
+ case 8: to[7] = from[7];
+ case 7: to[6] = from[6];
+ case 6: to[5] = from[5];
+ case 5: to[4] = from[4];
+ case 4: to[3] = from[3];
+ case 3: to[2] = from[2];
+ case 2: to[1] = from[1];
+ case 1: to[0] = from[0];
+ case 0: break;
+ default: while (count-- > 0) {
+ *to++ = *from++;
+ }
+ break;
+ }
+}
+
+static void pd_aligned_conjoint_words(HeapWord* from, HeapWord* to, size_t count) {
+ (void)memmove(to, from, count * HeapWordSize);
+}
+
+static void pd_aligned_disjoint_words(HeapWord* from, HeapWord* to, size_t count) {
+ pd_disjoint_words(from, to, count);
+}
+
+static void pd_conjoint_bytes(void* from, void* to, size_t count) {
+ (void)memmove(to, from, count);
+}
+
+static void pd_conjoint_bytes_atomic(void* from, void* to, size_t count) {
+ pd_conjoint_bytes(from, to, count);
+}
+
+static void pd_conjoint_jshorts_atomic(jshort* from, jshort* to, size_t count) {
+ // FIXME
+ (void)memmove(to, from, count << LogBytesPerShort);
+}
+
+static void pd_conjoint_jints_atomic(jint* from, jint* to, size_t count) {
+ // FIXME
+ (void)memmove(to, from, count << LogBytesPerInt);
+}
+
+static void pd_conjoint_jlongs_atomic(jlong* from, jlong* to, size_t count) {
+#ifdef AMD64
+ assert(BytesPerLong == BytesPerOop, "jlongs and oops must be the same size");
+ pd_conjoint_oops_atomic((oop*)from, (oop*)to, count);
+#else
+ // Guarantee use of fild/fistp or xmm regs via some asm code, because compilers won't.
+ __asm {
+ mov eax, from;
+ mov edx, to;
+ mov ecx, count;
+ cmp eax, edx;
+ jbe downtest;
+ jmp uptest;
+ up:
+ fild qword ptr [eax];
+ fistp qword ptr [edx];
+ add eax, 8;
+ add edx, 8;
+ uptest:
+ sub ecx, 1;
+ jge up;
+ jmp done;
+ down:
+ fild qword ptr [eax][ecx*8];
+ fistp qword ptr [edx][ecx*8];
+ downtest:
+ sub ecx, 1;
+ jge down;
+ done:;
+ }
+#endif // AMD64
+}
+
+static void pd_conjoint_oops_atomic(oop* from, oop* to, size_t count) {
+ // Do better than this: inline memmove body NEEDS CLEANUP
+ if (from > to) {
+ while (count-- > 0) {
+ // Copy forwards
+ *to++ = *from++;
+ }
+ } else {
+ from += count - 1;
+ to += count - 1;
+ while (count-- > 0) {
+ // Copy backwards
+ *to-- = *from--;
+ }
+ }
+}
+
+static void pd_arrayof_conjoint_bytes(HeapWord* from, HeapWord* to, size_t count) {
+#ifdef AMD64
+ pd_conjoint_bytes_atomic(from, to, count);
+#else
+ pd_conjoint_bytes(from, to, count);
+#endif // AMD64
+}
+
+static void pd_arrayof_conjoint_jshorts(HeapWord* from, HeapWord* to, size_t count) {
+ pd_conjoint_jshorts_atomic((jshort*)from, (jshort*)to, count);
+}
+
+static void pd_arrayof_conjoint_jints(HeapWord* from, HeapWord* to, size_t count) {
+ pd_conjoint_jints_atomic((jint*)from, (jint*)to, count);
+}
+
+static void pd_arrayof_conjoint_jlongs(HeapWord* from, HeapWord* to, size_t count) {
+ pd_conjoint_jlongs_atomic((jlong*)from, (jlong*)to, count);
+}
+
+static void pd_arrayof_conjoint_oops(HeapWord* from, HeapWord* to, size_t count) {
+ pd_conjoint_oops_atomic((oop*)from, (oop*)to, count);
+}
diff --git a/src/os_cpu/windows_x86/vm/globals_windows_x86.hpp b/src/os_cpu/windows_x86/vm/globals_windows_x86.hpp
new file mode 100644
index 000000000..7c578df70
--- /dev/null
+++ b/src/os_cpu/windows_x86/vm/globals_windows_x86.hpp
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2000-2005 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+//
+// Sets the default values for platform dependent flags used by the runtime system.
+// (see globals.hpp)
+//
+define_pd_global(bool, DontYieldALot, false);
+
+// Default stack size on Windows is determined by the executable (java.exe
+// has a default value of 320K/1MB [32bit/64bit]). Depending on Windows version, changing
+// ThreadStackSize to non-zero may have significant impact on memory usage.
+// See comments in os_windows.cpp.
+define_pd_global(intx, ThreadStackSize, 0); // 0 => use system default
+define_pd_global(intx, VMThreadStackSize, 0); // 0 => use system default
+
+define_pd_global(intx, SurvivorRatio, 8);
+
+#ifdef ASSERT
+define_pd_global(intx, CompilerThreadStackSize, 1024);
+#else
+define_pd_global(intx, CompilerThreadStackSize, 0);
+#endif
+
+define_pd_global(uintx, JVMInvokeMethodSlack, 8192);
+
+// Only used on 64 bit Windows platforms
+define_pd_global(bool, UseVectoredExceptions, false);
diff --git a/src/os_cpu/windows_x86/vm/orderAccess_windows_x86.inline.hpp b/src/os_cpu/windows_x86/vm/orderAccess_windows_x86.inline.hpp
new file mode 100644
index 000000000..b0a98bb0b
--- /dev/null
+++ b/src/os_cpu/windows_x86/vm/orderAccess_windows_x86.inline.hpp
@@ -0,0 +1,210 @@
+/*
+ * Copyright 2003 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+#pragma warning(disable: 4035) // Disables warnings reporting missing return statement
+
+// Implementation of class OrderAccess.
+
+inline void OrderAccess::loadload() { acquire(); }
+inline void OrderAccess::storestore() { release(); }
+inline void OrderAccess::loadstore() { acquire(); }
+inline void OrderAccess::storeload() { fence(); }
+
+inline void OrderAccess::acquire() {
+#ifndef AMD64
+ __asm {
+ mov eax, dword ptr [esp];
+ }
+#endif // !AMD64
+}
+
+inline void OrderAccess::release() {
+ // A volatile store has release semantics.
+ dummy = 0;
+}
+
+inline void OrderAccess::fence() {
+#ifdef AMD64
+ (*os::fence_func)();
+#else
+ if (os::is_MP()) {
+ __asm {
+ lock add dword ptr [esp], 0;
+ }
+ }
+#endif // AMD64
+}
+
+inline jbyte OrderAccess::load_acquire(volatile jbyte* p) { return *p; }
+inline jshort OrderAccess::load_acquire(volatile jshort* p) { return *p; }
+inline jint OrderAccess::load_acquire(volatile jint* p) { return *p; }
+inline jlong OrderAccess::load_acquire(volatile jlong* p) { return *p; }
+inline jubyte OrderAccess::load_acquire(volatile jubyte* p) { return *p; }
+inline jushort OrderAccess::load_acquire(volatile jushort* p) { return *p; }
+inline juint OrderAccess::load_acquire(volatile juint* p) { return *p; }
+inline julong OrderAccess::load_acquire(volatile julong* p) { return *p; }
+inline jfloat OrderAccess::load_acquire(volatile jfloat* p) { return *p; }
+inline jdouble OrderAccess::load_acquire(volatile jdouble* p) { return *p; }
+
+inline intptr_t OrderAccess::load_ptr_acquire(volatile intptr_t* p) { return *p; }
+inline void* OrderAccess::load_ptr_acquire(volatile void* p) { return *(void* volatile *)p; }
+inline void* OrderAccess::load_ptr_acquire(const volatile void* p) { return *(void* const volatile *)p; }
+
+inline void OrderAccess::release_store(volatile jbyte* p, jbyte v) { *p = v; }
+inline void OrderAccess::release_store(volatile jshort* p, jshort v) { *p = v; }
+inline void OrderAccess::release_store(volatile jint* p, jint v) { *p = v; }
+inline void OrderAccess::release_store(volatile jlong* p, jlong v) { *p = v; }
+inline void OrderAccess::release_store(volatile jubyte* p, jubyte v) { *p = v; }
+inline void OrderAccess::release_store(volatile jushort* p, jushort v) { *p = v; }
+inline void OrderAccess::release_store(volatile juint* p, juint v) { *p = v; }
+inline void OrderAccess::release_store(volatile julong* p, julong v) { *p = v; }
+inline void OrderAccess::release_store(volatile jfloat* p, jfloat v) { *p = v; }
+inline void OrderAccess::release_store(volatile jdouble* p, jdouble v) { *p = v; }
+
+inline void OrderAccess::release_store_ptr(volatile intptr_t* p, intptr_t v) { *p = v; }
+inline void OrderAccess::release_store_ptr(volatile void* p, void* v) { *(void* volatile *)p = v; }
+
+inline void OrderAccess::store_fence(jbyte* p, jbyte v) {
+#ifdef AMD64
+ *p = v; fence();
+#else
+ __asm {
+ mov edx, p;
+ mov al, v;
+ xchg al, byte ptr [edx];
+ }
+#endif // AMD64
+}
+
+inline void OrderAccess::store_fence(jshort* p, jshort v) {
+#ifdef AMD64
+ *p = v; fence();
+#else
+ __asm {
+ mov edx, p;
+ mov ax, v;
+ xchg ax, word ptr [edx];
+ }
+#endif // AMD64
+}
+
+inline void OrderAccess::store_fence(jint* p, jint v) {
+#ifdef AMD64
+ *p = v; fence();
+#else
+ __asm {
+ mov edx, p;
+ mov eax, v;
+ xchg eax, dword ptr [edx];
+ }
+#endif // AMD64
+}
+
+inline void OrderAccess::store_fence(jlong* p, jlong v) { *p = v; fence(); }
+inline void OrderAccess::store_fence(jubyte* p, jubyte v) { store_fence((jbyte*)p, (jbyte)v); }
+inline void OrderAccess::store_fence(jushort* p, jushort v) { store_fence((jshort*)p, (jshort)v); }
+inline void OrderAccess::store_fence(juint* p, juint v) { store_fence((jint*)p, (jint)v); }
+inline void OrderAccess::store_fence(julong* p, julong v) { store_fence((jlong*)p, (jlong)v); }
+inline void OrderAccess::store_fence(jfloat* p, jfloat v) { *p = v; fence(); }
+inline void OrderAccess::store_fence(jdouble* p, jdouble v) { *p = v; fence(); }
+
+inline void OrderAccess::store_ptr_fence(intptr_t* p, intptr_t v) {
+#ifdef AMD64
+ *p = v; fence();
+#else
+ store_fence((jint*)p, (jint)v);
+#endif // AMD64
+}
+
+inline void OrderAccess::store_ptr_fence(void** p, void* v) {
+#ifdef AMD64
+ *p = v; fence();
+#else
+ store_fence((jint*)p, (jint)v);
+#endif // AMD64
+}
+
+// Must duplicate definitions instead of calling store_fence because we don't want to cast away volatile.
+inline void OrderAccess::release_store_fence(volatile jbyte* p, jbyte v) {
+#ifdef AMD64
+ *p = v; fence();
+#else
+ __asm {
+ mov edx, p;
+ mov al, v;
+ xchg al, byte ptr [edx];
+ }
+#endif // AMD64
+}
+
+inline void OrderAccess::release_store_fence(volatile jshort* p, jshort v) {
+#ifdef AMD64
+ *p = v; fence();
+#else
+ __asm {
+ mov edx, p;
+ mov ax, v;
+ xchg ax, word ptr [edx];
+ }
+#endif // AMD64
+}
+
+inline void OrderAccess::release_store_fence(volatile jint* p, jint v) {
+#ifdef AMD64
+ *p = v; fence();
+#else
+ __asm {
+ mov edx, p;
+ mov eax, v;
+ xchg eax, dword ptr [edx];
+ }
+#endif // AMD64
+}
+
+inline void OrderAccess::release_store_fence(volatile jlong* p, jlong v) { *p = v; fence(); }
+
+inline void OrderAccess::release_store_fence(volatile jubyte* p, jubyte v) { release_store_fence((volatile jbyte*)p, (jbyte)v); }
+inline void OrderAccess::release_store_fence(volatile jushort* p, jushort v) { release_store_fence((volatile jshort*)p, (jshort)v); }
+inline void OrderAccess::release_store_fence(volatile juint* p, juint v) { release_store_fence((volatile jint*)p, (jint)v); }
+inline void OrderAccess::release_store_fence(volatile julong* p, julong v) { release_store_fence((volatile jlong*)p, (jlong)v); }
+inline void OrderAccess::release_store_fence(volatile jfloat* p, jfloat v) { *p = v; fence(); }
+inline void OrderAccess::release_store_fence(volatile jdouble* p, jdouble v) { *p = v; fence(); }
+
+inline void OrderAccess::release_store_ptr_fence(volatile intptr_t* p, intptr_t v) {
+#ifdef AMD64
+ *p = v; fence();
+#else
+ release_store_fence((volatile jint*)p, (jint)v);
+#endif // AMD64
+}
+
+inline void OrderAccess::release_store_ptr_fence(volatile void* p, void* v) {
+#ifdef AMD64
+ *(void* volatile *)p = v; fence();
+#else
+ release_store_fence((volatile jint*)p, (jint)v);
+#endif // AMD64
+}
+
+#pragma warning(default: 4035) // Enables warnings reporting missing return statement
diff --git a/src/os_cpu/windows_x86/vm/os_windows_x86.cpp b/src/os_cpu/windows_x86/vm/os_windows_x86.cpp
new file mode 100644
index 000000000..a25040459
--- /dev/null
+++ b/src/os_cpu/windows_x86/vm/os_windows_x86.cpp
@@ -0,0 +1,478 @@
+/*
+ * Copyright 1999-2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+// do not include precompiled header file
+# include "incls/_os_windows_x86.cpp.incl"
+# include "unwind_windows_x86.hpp"
+#undef REG_SP
+#undef REG_FP
+#undef REG_PC
+#ifdef AMD64
+#define REG_SP Rsp
+#define REG_FP Rbp
+#define REG_PC Rip
+#else
+#define REG_SP Esp
+#define REG_FP Ebp
+#define REG_PC Eip
+#endif // AMD64
+
+extern LONG WINAPI topLevelExceptionFilter(_EXCEPTION_POINTERS* );
+
+// Install a win32 structured exception handler around thread.
+void os::os_exception_wrapper(java_call_t f, JavaValue* value, methodHandle* method, JavaCallArguments* args, Thread* thread) {
+ __try {
+
+#ifndef AMD64
+ // We store the current thread in this wrapperthread location
+ // and determine how far away this address is from the structured
+ // execption pointer that FS:[0] points to. This get_thread
+ // code can then get the thread pointer via FS.
+ //
+ // Warning: This routine must NEVER be inlined since we'd end up with
+ // multiple offsets.
+ //
+ volatile Thread* wrapperthread = thread;
+
+ if ( ThreadLocalStorage::get_thread_ptr_offset() == 0 ) {
+ int thread_ptr_offset;
+ __asm {
+ lea eax, dword ptr wrapperthread;
+ sub eax, dword ptr FS:[0H];
+ mov thread_ptr_offset, eax
+ };
+ ThreadLocalStorage::set_thread_ptr_offset(thread_ptr_offset);
+ }
+#ifdef ASSERT
+ // Verify that the offset hasn't changed since we initally captured
+ // it. This might happen if we accidentally ended up with an
+ // inlined version of this routine.
+ else {
+ int test_thread_ptr_offset;
+ __asm {
+ lea eax, dword ptr wrapperthread;
+ sub eax, dword ptr FS:[0H];
+ mov test_thread_ptr_offset, eax
+ };
+ assert(test_thread_ptr_offset == ThreadLocalStorage::get_thread_ptr_offset(),
+ "thread pointer offset from SEH changed");
+ }
+#endif // ASSERT
+#endif // !AMD64
+
+ f(value, method, args, thread);
+ } __except(topLevelExceptionFilter((_EXCEPTION_POINTERS*)_exception_info())) {
+ // Nothing to do.
+ }
+}
+
+#ifdef AMD64
+
+// This is the language specific handler for exceptions
+// originating from dynamically generated code.
+// We call the standard structured exception handler
+// We only expect Continued Execution since we cannot unwind
+// from generated code.
+LONG HandleExceptionFromCodeCache(
+ IN PEXCEPTION_RECORD ExceptionRecord,
+ IN ULONG64 EstablisherFrame,
+ IN OUT PCONTEXT ContextRecord,
+ IN OUT PDISPATCHER_CONTEXT DispatcherContext) {
+ EXCEPTION_POINTERS ep;
+ LONG result;
+
+ ep.ExceptionRecord = ExceptionRecord;
+ ep.ContextRecord = ContextRecord;
+
+ result = topLevelExceptionFilter(&ep);
+
+ // We better only get a CONTINUE_EXECUTION from our handler
+ // since we don't have unwind information registered.
+
+ guarantee( result == EXCEPTION_CONTINUE_EXECUTION,
+ "Unexpected result from topLevelExceptionFilter");
+
+ return(ExceptionContinueExecution);
+}
+
+
+// Structure containing the Windows Data Structures required
+// to register our Code Cache exception handler.
+// We put these in the CodeCache since the API requires
+// all addresses in these structures are relative to the Code
+// area registered with RtlAddFunctionTable.
+typedef struct {
+ char ExceptionHandlerInstr[16]; // jmp HandleExceptionFromCodeCache
+ RUNTIME_FUNCTION rt;
+ UNWIND_INFO_EH_ONLY unw;
+} DynamicCodeData, *pDynamicCodeData;
+
+#endif // AMD64
+//
+// Register our CodeCache area with the OS so it will dispatch exceptions
+// to our topLevelExceptionFilter when we take an exception in our
+// dynamically generated code.
+//
+// Arguments: low and high are the address of the full reserved
+// codeCache area
+//
+bool os::register_code_area(char *low, char *high) {
+#ifdef AMD64
+
+ ResourceMark rm;
+
+ pDynamicCodeData pDCD;
+ PRUNTIME_FUNCTION prt;
+ PUNWIND_INFO_EH_ONLY punwind;
+
+ // If we are using Vectored Exceptions we don't need this registration
+ if (UseVectoredExceptions) return true;
+
+ BufferBlob* b = BufferBlob::create("CodeCache Exception Handler", sizeof (DynamicCodeData));
+ CodeBuffer cb(b->instructions_begin(), b->instructions_size());
+ MacroAssembler* masm = new MacroAssembler(&cb);
+ pDCD = (pDynamicCodeData) masm->pc();
+
+ masm->jump(ExternalAddress((address)&HandleExceptionFromCodeCache));
+ masm->flush();
+
+ // Create an Unwind Structure specifying no unwind info
+ // other than an Exception Handler
+ punwind = &pDCD->unw;
+ punwind->Version = 1;
+ punwind->Flags = UNW_FLAG_EHANDLER;
+ punwind->SizeOfProlog = 0;
+ punwind->CountOfCodes = 0;
+ punwind->FrameRegister = 0;
+ punwind->FrameOffset = 0;
+ punwind->ExceptionHandler = (char *)(&(pDCD->ExceptionHandlerInstr[0])) -
+ (char*)low;
+ punwind->ExceptionData[0] = 0;
+
+ // This structure describes the covered dynamic code area.
+ // Addresses are relative to the beginning on the code cache area
+ prt = &pDCD->rt;
+ prt->BeginAddress = 0;
+ prt->EndAddress = (ULONG)(high - low);
+ prt->UnwindData = ((char *)punwind - low);
+
+ guarantee(RtlAddFunctionTable(prt, 1, (ULONGLONG)low),
+ "Failed to register Dynamic Code Exception Handler with RtlAddFunctionTable");
+
+#endif // AMD64
+ return true;
+}
+
+void os::initialize_thread() {
+// Nothing to do.
+}
+
+// Atomics and Stub Functions
+
+typedef jint xchg_func_t (jint, volatile jint*);
+typedef intptr_t xchg_ptr_func_t (intptr_t, volatile intptr_t*);
+typedef jint cmpxchg_func_t (jint, volatile jint*, jint);
+typedef jlong cmpxchg_long_func_t (jlong, volatile jlong*, jlong);
+typedef jint add_func_t (jint, volatile jint*);
+typedef intptr_t add_ptr_func_t (intptr_t, volatile intptr_t*);
+typedef void fence_func_t ();
+
+#ifdef AMD64
+
+jint os::atomic_xchg_bootstrap(jint exchange_value, volatile jint* dest) {
+ // try to use the stub:
+ xchg_func_t* func = CAST_TO_FN_PTR(xchg_func_t*, StubRoutines::atomic_xchg_entry());
+
+ if (func != NULL) {
+ os::atomic_xchg_func = func;
+ return (*func)(exchange_value, dest);
+ }
+ assert(Threads::number_of_threads() == 0, "for bootstrap only");
+
+ jint old_value = *dest;
+ *dest = exchange_value;
+ return old_value;
+}
+
+intptr_t os::atomic_xchg_ptr_bootstrap(intptr_t exchange_value, volatile intptr_t* dest) {
+ // try to use the stub:
+ xchg_ptr_func_t* func = CAST_TO_FN_PTR(xchg_ptr_func_t*, StubRoutines::atomic_xchg_ptr_entry());
+
+ if (func != NULL) {
+ os::atomic_xchg_ptr_func = func;
+ return (*func)(exchange_value, dest);
+ }
+ assert(Threads::number_of_threads() == 0, "for bootstrap only");
+
+ intptr_t old_value = *dest;
+ *dest = exchange_value;
+ return old_value;
+}
+
+
+jint os::atomic_cmpxchg_bootstrap(jint exchange_value, volatile jint* dest, jint compare_value) {
+ // try to use the stub:
+ cmpxchg_func_t* func = CAST_TO_FN_PTR(cmpxchg_func_t*, StubRoutines::atomic_cmpxchg_entry());
+
+ if (func != NULL) {
+ os::atomic_cmpxchg_func = func;
+ return (*func)(exchange_value, dest, compare_value);
+ }
+ assert(Threads::number_of_threads() == 0, "for bootstrap only");
+
+ jint old_value = *dest;
+ if (old_value == compare_value)
+ *dest = exchange_value;
+ return old_value;
+}
+#endif // AMD64
+
+jlong os::atomic_cmpxchg_long_bootstrap(jlong exchange_value, volatile jlong* dest, jlong compare_value) {
+ // try to use the stub:
+ cmpxchg_long_func_t* func = CAST_TO_FN_PTR(cmpxchg_long_func_t*, StubRoutines::atomic_cmpxchg_long_entry());
+
+ if (func != NULL) {
+ os::atomic_cmpxchg_long_func = func;
+ return (*func)(exchange_value, dest, compare_value);
+ }
+ assert(Threads::number_of_threads() == 0, "for bootstrap only");
+
+ jlong old_value = *dest;
+ if (old_value == compare_value)
+ *dest = exchange_value;
+ return old_value;
+}
+
+#ifdef AMD64
+
+jint os::atomic_add_bootstrap(jint add_value, volatile jint* dest) {
+ // try to use the stub:
+ add_func_t* func = CAST_TO_FN_PTR(add_func_t*, StubRoutines::atomic_add_entry());
+
+ if (func != NULL) {
+ os::atomic_add_func = func;
+ return (*func)(add_value, dest);
+ }
+ assert(Threads::number_of_threads() == 0, "for bootstrap only");
+
+ return (*dest) += add_value;
+}
+
+intptr_t os::atomic_add_ptr_bootstrap(intptr_t add_value, volatile intptr_t* dest) {
+ // try to use the stub:
+ add_ptr_func_t* func = CAST_TO_FN_PTR(add_ptr_func_t*, StubRoutines::atomic_add_ptr_entry());
+
+ if (func != NULL) {
+ os::atomic_add_ptr_func = func;
+ return (*func)(add_value, dest);
+ }
+ assert(Threads::number_of_threads() == 0, "for bootstrap only");
+
+ return (*dest) += add_value;
+}
+
+void os::fence_bootstrap() {
+ // try to use the stub:
+ fence_func_t* func = CAST_TO_FN_PTR(fence_func_t*, StubRoutines::fence_entry());
+
+ if (func != NULL) {
+ os::fence_func = func;
+ (*func)();
+ return;
+ }
+ assert(Threads::number_of_threads() == 0, "for bootstrap only");
+
+ // don't have to do anything for a single thread
+}
+
+
+xchg_func_t* os::atomic_xchg_func = os::atomic_xchg_bootstrap;
+xchg_ptr_func_t* os::atomic_xchg_ptr_func = os::atomic_xchg_ptr_bootstrap;
+cmpxchg_func_t* os::atomic_cmpxchg_func = os::atomic_cmpxchg_bootstrap;
+add_func_t* os::atomic_add_func = os::atomic_add_bootstrap;
+add_ptr_func_t* os::atomic_add_ptr_func = os::atomic_add_ptr_bootstrap;
+fence_func_t* os::fence_func = os::fence_bootstrap;
+
+#endif // AMD64
+
+cmpxchg_long_func_t* os::atomic_cmpxchg_long_func = os::atomic_cmpxchg_long_bootstrap;
+
+ExtendedPC os::fetch_frame_from_context(void* ucVoid,
+ intptr_t** ret_sp, intptr_t** ret_fp) {
+
+ ExtendedPC epc;
+ CONTEXT* uc = (CONTEXT*)ucVoid;
+
+ if (uc != NULL) {
+ epc = ExtendedPC((address)uc->REG_PC);
+ if (ret_sp) *ret_sp = (intptr_t*)uc->REG_SP;
+ if (ret_fp) *ret_fp = (intptr_t*)uc->REG_FP;
+ } else {
+ // construct empty ExtendedPC for return value checking
+ epc = ExtendedPC(NULL);
+ if (ret_sp) *ret_sp = (intptr_t *)NULL;
+ if (ret_fp) *ret_fp = (intptr_t *)NULL;
+ }
+
+ return epc;
+}
+
+frame os::fetch_frame_from_context(void* ucVoid) {
+ intptr_t* sp;
+ intptr_t* fp;
+ ExtendedPC epc = fetch_frame_from_context(ucVoid, &sp, &fp);
+ return frame(sp, fp, epc.pc());
+}
+
+// VC++ does not save frame pointer on stack in optimized build. It
+// can be turned off by /Oy-. If we really want to walk C frames,
+// we can use the StackWalk() API.
+frame os::get_sender_for_C_frame(frame* fr) {
+ return frame(fr->sender_sp(), fr->link(), fr->sender_pc());
+}
+
+
+#ifndef AMD64
+intptr_t* _get_previous_fp() {
+ intptr_t **frameptr;
+ __asm {
+ mov frameptr, ebp
+ };
+ return *frameptr;
+}
+#endif // !AMD64
+
+frame os::current_frame() {
+
+#ifdef AMD64
+ // apparently _asm not supported on windows amd64
+ typedef intptr_t* get_fp_func ();
+ get_fp_func* func = CAST_TO_FN_PTR(get_fp_func*,
+ StubRoutines::amd64::get_previous_fp_entry());
+ if (func == NULL) return frame(NULL, NULL, NULL);
+ intptr_t* fp = (*func)();
+#else
+ intptr_t* fp = _get_previous_fp();
+#endif // AMD64
+
+ frame myframe((intptr_t*)os::current_stack_pointer(),
+ (intptr_t*)fp,
+ CAST_FROM_FN_PTR(address, os::current_frame));
+ if (os::is_first_C_frame(&myframe)) {
+ // stack is not walkable
+ return frame(NULL, NULL, NULL);
+ } else {
+ return os::get_sender_for_C_frame(&myframe);
+ }
+}
+
+void os::print_context(outputStream *st, void *context) {
+ if (context == NULL) return;
+
+ CONTEXT* uc = (CONTEXT*)context;
+
+ st->print_cr("Registers:");
+#ifdef AMD64
+ st->print( "EAX=" INTPTR_FORMAT, uc->Rax);
+ st->print(", EBX=" INTPTR_FORMAT, uc->Rbx);
+ st->print(", ECX=" INTPTR_FORMAT, uc->Rcx);
+ st->print(", EDX=" INTPTR_FORMAT, uc->Rdx);
+ st->cr();
+ st->print( "ESP=" INTPTR_FORMAT, uc->Rsp);
+ st->print(", EBP=" INTPTR_FORMAT, uc->Rbp);
+ st->print(", ESI=" INTPTR_FORMAT, uc->Rsi);
+ st->print(", EDI=" INTPTR_FORMAT, uc->Rdi);
+ st->cr();
+ st->print( "EIP=" INTPTR_FORMAT, uc->Rip);
+ st->print(", EFLAGS=" INTPTR_FORMAT, uc->EFlags);
+#else
+ st->print( "EAX=" INTPTR_FORMAT, uc->Eax);
+ st->print(", EBX=" INTPTR_FORMAT, uc->Ebx);
+ st->print(", ECX=" INTPTR_FORMAT, uc->Ecx);
+ st->print(", EDX=" INTPTR_FORMAT, uc->Edx);
+ st->cr();
+ st->print( "ESP=" INTPTR_FORMAT, uc->Esp);
+ st->print(", EBP=" INTPTR_FORMAT, uc->Ebp);
+ st->print(", ESI=" INTPTR_FORMAT, uc->Esi);
+ st->print(", EDI=" INTPTR_FORMAT, uc->Edi);
+ st->cr();
+ st->print( "EIP=" INTPTR_FORMAT, uc->Eip);
+ st->print(", EFLAGS=" INTPTR_FORMAT, uc->EFlags);
+#endif // AMD64
+ st->cr();
+ st->cr();
+
+ intptr_t *sp = (intptr_t *)uc->REG_SP;
+ st->print_cr("Top of Stack: (sp=" PTR_FORMAT ")", sp);
+ print_hex_dump(st, (address)sp, (address)(sp + 32), sizeof(intptr_t));
+ st->cr();
+
+ // Note: it may be unsafe to inspect memory near pc. For example, pc may
+ // point to garbage if entry point in an nmethod is corrupted. Leave
+ // this at the end, and hope for the best.
+ address pc = (address)uc->REG_PC;
+ st->print_cr("Instructions: (pc=" PTR_FORMAT ")", pc);
+ print_hex_dump(st, pc - 16, pc + 16, sizeof(char));
+ st->cr();
+}
+
+extern "C" int SafeFetch32 (int * adr, int Err) {
+ int rv = Err ;
+ _try {
+ rv = *((volatile int *) adr) ;
+ } __except(EXCEPTION_EXECUTE_HANDLER) {
+ }
+ return rv ;
+}
+
+extern "C" intptr_t SafeFetchN (intptr_t * adr, intptr_t Err) {
+ intptr_t rv = Err ;
+ _try {
+ rv = *((volatile intptr_t *) adr) ;
+ } __except(EXCEPTION_EXECUTE_HANDLER) {
+ }
+ return rv ;
+}
+
+extern "C" int SpinPause () {
+#ifdef AMD64
+ return 0 ;
+#else
+ // pause == rep:nop
+ // On systems that don't support pause a rep:nop
+ // is executed as a nop. The rep: prefix is ignored.
+ _asm {
+ pause ;
+ };
+ return 1 ;
+#endif // AMD64
+}
+
+
+void os::setup_fpu() {
+#ifndef AMD64
+ int fpu_cntrl_word = StubRoutines::fpu_cntrl_wrd_std();
+ __asm fldcw fpu_cntrl_word;
+#endif // !AMD64
+}
diff --git a/src/os_cpu/windows_x86/vm/os_windows_x86.hpp b/src/os_cpu/windows_x86/vm/os_windows_x86.hpp
new file mode 100644
index 000000000..d75781016
--- /dev/null
+++ b/src/os_cpu/windows_x86/vm/os_windows_x86.hpp
@@ -0,0 +1,63 @@
+/*
+ * Copyright 1999-2004 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+ //
+ // NOTE: we are back in class os here, not win32
+ //
+#ifdef AMD64
+ static jint (*atomic_xchg_func) (jint, volatile jint*);
+ static intptr_t (*atomic_xchg_ptr_func) (intptr_t, volatile intptr_t*);
+
+ static jint (*atomic_cmpxchg_func) (jint, volatile jint*, jint);
+ static jlong (*atomic_cmpxchg_long_func) (jlong, volatile jlong*, jlong);
+
+ static jint (*atomic_add_func) (jint, volatile jint*);
+ static intptr_t (*atomic_add_ptr_func) (intptr_t, volatile intptr_t*);
+
+ static void (*fence_func) ();
+
+
+ static jint atomic_xchg_bootstrap (jint, volatile jint*);
+ static intptr_t atomic_xchg_ptr_bootstrap (intptr_t, volatile intptr_t*);
+
+ static jint atomic_cmpxchg_bootstrap (jint, volatile jint*, jint);
+#else
+
+ static jlong (*atomic_cmpxchg_long_func) (jlong, volatile jlong*, jlong);
+
+#endif // AMD64
+
+ static jlong atomic_cmpxchg_long_bootstrap(jlong, volatile jlong*, jlong);
+
+#ifdef AMD64
+ static jint atomic_add_bootstrap (jint, volatile jint*);
+ static intptr_t atomic_add_ptr_bootstrap (intptr_t, volatile intptr_t*);
+
+ static void fence_bootstrap ();
+#endif // AMD64
+
+ static void setup_fpu();
+ static bool supports_sse() { return true; }
+
+ static bool register_code_area(char *low, char *high);
diff --git a/src/os_cpu/windows_x86/vm/prefetch_windows_x86.inline.hpp b/src/os_cpu/windows_x86/vm/prefetch_windows_x86.inline.hpp
new file mode 100644
index 000000000..d40d3418a
--- /dev/null
+++ b/src/os_cpu/windows_x86/vm/prefetch_windows_x86.inline.hpp
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2003 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+inline void Prefetch::read (void *loc, intx interval) {}
+inline void Prefetch::write(void *loc, intx interval) {}
diff --git a/src/os_cpu/windows_x86/vm/threadLS_windows_x86.cpp b/src/os_cpu/windows_x86/vm/threadLS_windows_x86.cpp
new file mode 100644
index 000000000..c46f115d3
--- /dev/null
+++ b/src/os_cpu/windows_x86/vm/threadLS_windows_x86.cpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright 1998-2003 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+// Provides an entry point we can link against and
+// a buffer we can emit code into. The buffer is
+// filled by ThreadLocalStorage::generate_code_for_get_thread
+// and called from ThreadLocalStorage::thread()
+
+#include "incls/_precompiled.incl"
+#include "incls/_threadLS_windows_x86.cpp.incl"
+
+int ThreadLocalStorage::_thread_ptr_offset = 0;
+
+static void call_wrapper_dummy() {}
+
+// We need to call the os_exception_wrapper once so that it sets
+// up the offset from FS of the thread pointer.
+void ThreadLocalStorage::generate_code_for_get_thread() {
+ os::os_exception_wrapper( (java_call_t)call_wrapper_dummy,
+ NULL, NULL, NULL, NULL);
+}
+
+void ThreadLocalStorage::pd_init() { }
+
+void ThreadLocalStorage::pd_set_thread(Thread* thread) {
+ os::thread_local_storage_at_put(ThreadLocalStorage::thread_index(), thread);
+}
diff --git a/src/os_cpu/windows_x86/vm/threadLS_windows_x86.hpp b/src/os_cpu/windows_x86/vm/threadLS_windows_x86.hpp
new file mode 100644
index 000000000..e295abe22
--- /dev/null
+++ b/src/os_cpu/windows_x86/vm/threadLS_windows_x86.hpp
@@ -0,0 +1,44 @@
+/*
+ * Copyright 1998-2003 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+// Processor dependent parts of ThreadLocalStorage
+
+protected:
+
+ static int _thread_ptr_offset;
+
+public:
+
+ // Java Thread
+ static inline Thread* thread() {
+ return (Thread*)TlsGetValue(thread_index());
+ }
+
+ static inline Thread* get_thread() {
+ return (Thread*)TlsGetValue(thread_index());
+ }
+
+ static inline void set_thread_ptr_offset( int offset ) { _thread_ptr_offset = offset; }
+
+ static inline int get_thread_ptr_offset() { return _thread_ptr_offset; }
diff --git a/src/os_cpu/windows_x86/vm/thread_windows_x86.cpp b/src/os_cpu/windows_x86/vm/thread_windows_x86.cpp
new file mode 100644
index 000000000..a11a746af
--- /dev/null
+++ b/src/os_cpu/windows_x86/vm/thread_windows_x86.cpp
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2003-2005 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_thread_windows_x86.cpp.incl"
+
+// For Forte Analyzer AsyncGetCallTrace profiling support - thread is
+// currently interrupted by SIGPROF
+bool JavaThread::pd_get_top_frame_for_signal_handler(frame* fr_addr,
+ void* ucontext, bool isInJava) {
+
+ assert(Thread::current() == this, "caller must be current thread");
+ assert(this->is_Java_thread(), "must be JavaThread");
+
+ JavaThread* jt = (JavaThread *)this;
+
+ // If we have a last_Java_frame, then we should use it even if
+ // isInJava == true. It should be more reliable than CONTEXT info.
+ if (jt->has_last_Java_frame()) {
+ *fr_addr = jt->pd_last_frame();
+ return true;
+ }
+
+ // At this point, we don't have a last_Java_frame, so
+ // we try to glean some information out of the CONTEXT
+ // if we were running Java code when SIGPROF came in.
+ if (isInJava) {
+ CONTEXT* uc = (CONTEXT*)ucontext;
+
+#ifdef AMD64
+ intptr_t* ret_fp = (intptr_t*) uc->Rbp;
+ intptr_t* ret_sp = (intptr_t*) uc->Rsp;
+ ExtendedPC addr = ExtendedPC((address)uc->Rip);
+#else
+ intptr_t* ret_fp = (intptr_t*) uc->Ebp;
+ intptr_t* ret_sp = (intptr_t*) uc->Esp;
+ ExtendedPC addr = ExtendedPC((address)uc->Eip);
+#endif // AMD64
+ if (addr.pc() == NULL || ret_sp == NULL ) {
+ // CONTEXT wasn't useful
+ return false;
+ }
+
+ frame ret_frame(ret_sp, ret_fp, addr.pc());
+ if (!ret_frame.safe_for_sender(jt)) {
+#ifdef COMPILER2
+ // C2 uses ebp as a general register see if NULL fp helps
+ frame ret_frame2(ret_sp, NULL, addr.pc());
+ if (!ret_frame2.safe_for_sender(jt)) {
+ // nothing else to try if the frame isn't good
+ return false;
+ }
+ ret_frame = ret_frame2;
+#else
+ // nothing else to try if the frame isn't good
+ return false;
+#endif /* COMPILER2 */
+ }
+ *fr_addr = ret_frame;
+ return true;
+ }
+
+ // nothing else to try
+ return false;
+}
diff --git a/src/os_cpu/windows_x86/vm/thread_windows_x86.hpp b/src/os_cpu/windows_x86/vm/thread_windows_x86.hpp
new file mode 100644
index 000000000..8e61fdd92
--- /dev/null
+++ b/src/os_cpu/windows_x86/vm/thread_windows_x86.hpp
@@ -0,0 +1,62 @@
+/*
+ * Copyright 1999-2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+ private:
+ void pd_initialize() {
+ _anchor.clear();
+ }
+
+ frame pd_last_frame() {
+ assert(has_last_Java_frame(), "must have last_Java_sp() when suspended");
+ if (_anchor.last_Java_pc() != NULL) {
+ return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp(), _anchor.last_Java_pc());
+ } else {
+ // This will pick up pc from sp
+ return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp());
+ }
+ }
+
+ public:
+ // Mutators are highly dangerous....
+ intptr_t* last_Java_fp() { return _anchor.last_Java_fp(); }
+ void set_last_Java_fp(intptr_t* fp) { _anchor.set_last_Java_fp(fp); }
+
+ void set_base_of_stack_pointer(intptr_t* base_sp) {}
+
+
+ static ByteSize last_Java_fp_offset() {
+ return byte_offset_of(JavaThread, _anchor) + JavaFrameAnchor::last_Java_fp_offset();
+ }
+
+ intptr_t* base_of_stack_pointer() { return NULL; }
+ void record_base_of_stack_pointer() {}
+
+ bool pd_get_top_frame_for_signal_handler(frame* fr_addr, void* ucontext,
+ bool isInJava);
+
+ // These routines are only used on cpu architectures that
+ // have separate register stacks (Itanium).
+ static bool register_stack_overflow() { return false; }
+ static void enable_register_stack_guard() {}
+ static void disable_register_stack_guard() {}
diff --git a/src/os_cpu/windows_x86/vm/unwind_windows_x86.hpp b/src/os_cpu/windows_x86/vm/unwind_windows_x86.hpp
new file mode 100644
index 000000000..1e8ed078d
--- /dev/null
+++ b/src/os_cpu/windows_x86/vm/unwind_windows_x86.hpp
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2004 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+
+#ifdef AMD64
+typedef unsigned char UBYTE;
+
+#define UNW_FLAG_EHANDLER 0x01
+#define UNW_FLAG_UHANDLER 0x02
+#define UNW_FLAG_CHAININFO 0x04
+
+// This structure is used to define an UNWIND_INFO that
+// only has an ExceptionHandler. There are no UnwindCodes
+// declared.
+typedef struct _UNWIND_INFO_EH_ONLY {
+ UBYTE Version : 3;
+ UBYTE Flags : 5;
+ UBYTE SizeOfProlog;
+ UBYTE CountOfCodes;
+ UBYTE FrameRegister : 4;
+ UBYTE FrameOffset : 4;
+ union {
+ OPTIONAL ULONG ExceptionHandler;
+ OPTIONAL ULONG FunctionEntry;
+ };
+ OPTIONAL ULONG ExceptionData[1];
+} UNWIND_INFO_EH_ONLY, *PUNWIND_INFO_EH_ONLY;
+
+
+/*
+typedef struct _RUNTIME_FUNCTION {
+ ULONG BeginAddress;
+ ULONG EndAddress;
+ ULONG UnwindData;
+} RUNTIME_FUNCTION, *PRUNTIME_FUNCTION;
+*/
+
+typedef struct _DISPATCHER_CONTEXT {
+ ULONG64 ControlPc;
+ ULONG64 ImageBase;
+ PRUNTIME_FUNCTION FunctionEntry;
+ ULONG64 EstablisherFrame;
+ ULONG64 TargetIp;
+ PCONTEXT ContextRecord;
+// PEXCEPTION_ROUTINE LanguageHandler;
+ char * LanguageHandler; // double dependency problem
+ PVOID HandlerData;
+} DISPATCHER_CONTEXT, *PDISPATCHER_CONTEXT;
+
+typedef EXCEPTION_DISPOSITION (*PEXCEPTION_ROUTINE) (
+ IN PEXCEPTION_RECORD ExceptionRecord,
+ IN ULONG64 EstablisherFrame,
+ IN OUT PCONTEXT ContextRecord,
+ IN OUT PDISPATCHER_CONTEXT DispatcherContext
+);
+
+#endif // AMD64
diff --git a/src/os_cpu/windows_x86/vm/vmStructs_windows_x86.hpp b/src/os_cpu/windows_x86/vm/vmStructs_windows_x86.hpp
new file mode 100644
index 000000000..bf2c029b4
--- /dev/null
+++ b/src/os_cpu/windows_x86/vm/vmStructs_windows_x86.hpp
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2000-2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+// These are the OS and CPU-specific fields, types and integer
+// constants required by the Serviceability Agent. This file is
+// referenced by vmStructs.cpp.
+
+#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field, last_entry) \
+ \
+ /******************************/ \
+ /* Threads (NOTE: incomplete) */ \
+ /******************************/ \
+ \
+ nonstatic_field(OSThread, _thread_id, unsigned long) \
+ unchecked_nonstatic_field(OSThread, _thread_handle, sizeof(HANDLE)) /* NOTE: no type */ \
+ \
+ /* This must be the last entry, and must be present */ \
+ last_entry()
+
+#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type, last_entry) \
+ \
+ /* This must be the last entry, and must be present */ \
+ last_entry()
+
+#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
+ \
+ /* This must be the last entry, and must be present */ \
+ last_entry()
+
+#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
+ \
+ /* This must be the last entry, and must be present */ \
+ last_entry()
diff --git a/src/os_cpu/windows_x86/vm/vm_version_windows_x86.cpp b/src/os_cpu/windows_x86/vm/vm_version_windows_x86.cpp
new file mode 100644
index 000000000..c3abce485
--- /dev/null
+++ b/src/os_cpu/windows_x86/vm/vm_version_windows_x86.cpp
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2006 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+# include "incls/_precompiled.incl"
+# include "incls/_vm_version_windows_x86.cpp.incl"
diff --git a/src/os_cpu/windows_x86/vm/windows_x86_32.ad b/src/os_cpu/windows_x86/vm/windows_x86_32.ad
new file mode 100644
index 000000000..83a5421c1
--- /dev/null
+++ b/src/os_cpu/windows_x86/vm/windows_x86_32.ad
@@ -0,0 +1,158 @@
+//
+// Copyright 1999-2006 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+// CA 95054 USA or visit www.sun.com if you need additional information or
+// have any questions.
+//
+//
+
+// X86 Win32 Architecture Description File
+
+//----------OS-DEPENDENT ENCODING BLOCK-----------------------------------------------------
+// This block specifies the encoding classes used by the compiler to output
+// byte streams. Encoding classes generate functions which are called by
+// Machine Instruction Nodes in order to generate the bit encoding of the
+// instruction. Operands specify their base encoding interface with the
+// interface keyword. There are currently supported four interfaces,
+// REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER. REG_INTER causes an
+// operand to generate a function which returns its register number when
+// queried. CONST_INTER causes an operand to generate a function which
+// returns the value of the constant when queried. MEMORY_INTER causes an
+// operand to generate four functions which return the Base Register, the
+// Index Register, the Scale Value, and the Offset Value of the operand when
+// queried. COND_INTER causes an operand to generate six functions which
+// return the encoding code (ie - encoding bits for the instruction)
+// associated with each basic boolean condition for a conditional instruction.
+// Instructions specify two basic values for encoding. They use the
+// ins_encode keyword to specify their encoding class (which must be one of
+// the class names specified in the encoding block), and they use the
+// opcode keyword to specify, in order, their primary, secondary, and
+// tertiary opcode. Only the opcode sections which a particular instruction
+// needs for encoding need to be specified.
+encode %{
+ // Build emit functions for each basic byte or larger field in the intel
+ // encoding scheme (opcode, rm, sib, immediate), and call them from C++
+ // code in the enc_class source block. Emit functions will live in the
+ // main source block for now. In future, we can generalize this by
+ // adding a syntax that specifies the sizes of fields in an order,
+ // so that the adlc can build the emit functions automagically
+
+ enc_class tlsencode (eRegP dst, eRegP src) %{
+ emit_rm(cbuf, 0x2, $dst$$reg, $src$$reg);
+ emit_d32(cbuf, ThreadLocalStorage::get_thread_ptr_offset() );
+ %}
+
+ enc_class call_epilog %{
+ if( VerifyStackAtCalls ) {
+ // Check that stack depth is unchanged: find majik cookie on stack
+ int framesize = ra_->reg2offset_unchecked(OptoReg::add(ra_->_matcher._old_SP,-3*VMRegImpl::slots_per_word));
+ if(framesize >= 128) {
+ emit_opcode(cbuf, 0x81); // cmp [esp+0],0xbadb1ood
+ emit_d8(cbuf,0xBC);
+ emit_d8(cbuf,0x24);
+ emit_d32(cbuf,framesize); // Find majik cookie from ESP
+ emit_d32(cbuf, 0xbadb100d);
+ }
+ else {
+ emit_opcode(cbuf, 0x81); // cmp [esp+0],0xbadb1ood
+ emit_d8(cbuf,0x7C);
+ emit_d8(cbuf,0x24);
+ emit_d8(cbuf,framesize); // Find majik cookie from ESP
+ emit_d32(cbuf, 0xbadb100d);
+ }
+ // jmp EQ around INT3
+ emit_opcode(cbuf,0x74);
+ emit_d8(cbuf,1);
+ // Die if stack mismatch
+ emit_opcode(cbuf,0xCC);
+ }
+ %}
+
+%}
+
+// INSTRUCTIONS -- Platform dependent
+
+
+//----------OS and Locking Instructions----------------------------------------
+
+// The prefix of this name is KNOWN by the ADLC and cannot be changed.
+instruct tlsLoadP_prefixLoadP(eRegP t1) %{
+ effect(DEF t1);
+
+ format %{ "MOV $t1,FS:[0x00] "%}
+ opcode(0x8B, 0x64);
+ ins_encode(OpcS, OpcP, conmemref(t1));
+ ins_pipe( ialu_reg_fat );
+%}
+
+// This name is KNOWN by the ADLC and cannot be changed.
+// The ADLC forces a 'TypeRawPtr::BOTTOM' output type
+// for this guy.
+// %%% Should do this with a clause like: bottom_type(TypeRawPtr::BOTTOM);
+instruct tlsLoadP(eRegP dst, eRegP t1) %{
+ effect(DEF dst, USE t1);
+
+ format %{ "MOV $dst,[$t1 + TLS::thread_ptr_offset()]" %}
+ opcode(0x8B);
+ ins_encode(OpcP, tlsencode(dst, t1));
+ ins_pipe( ialu_reg_reg_fat );
+%}
+
+instruct TLS(eRegP dst) %{
+ match(Set dst (ThreadLocal));
+ expand %{
+ eRegP t1;
+ tlsLoadP_prefixLoadP(t1);
+ tlsLoadP(dst, t1);
+ %}
+%}
+
+// Die now
+instruct ShouldNotReachHere( )
+%{
+ match(Halt);
+ // Use the following format syntax
+ format %{ "INT3 ; ShouldNotReachHere" %}
+ opcode(0xCC);
+ ins_encode(OpcP);
+ ins_pipe( pipe_slow );
+%}
+
+//
+// Platform dependent source
+//
+source %{
+
+// emit an interrupt that is caught by the debugger
+void emit_break(CodeBuffer &cbuf) {
+ *(cbuf.code_end()) = (unsigned char)(0xcc);
+ cbuf.set_code_end(cbuf.code_end() + 1);
+}
+
+void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
+ emit_break(cbuf);
+}
+
+
+uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const {
+ return 1;
+}
+
+
+%}
diff --git a/src/os_cpu/windows_x86/vm/windows_x86_64.ad b/src/os_cpu/windows_x86/vm/windows_x86_64.ad
new file mode 100644
index 000000000..0ef5a15bf
--- /dev/null
+++ b/src/os_cpu/windows_x86/vm/windows_x86_64.ad
@@ -0,0 +1,159 @@
+//
+// Copyright 2003-2006 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+// CA 95054 USA or visit www.sun.com if you need additional information or
+// have any questions.
+//
+//
+
+// AMD64 Win32 Architecture Description File
+
+//----------OS-DEPENDENT ENCODING BLOCK-----------------------------------------------------
+// This block specifies the encoding classes used by the compiler to output
+// byte streams. Encoding classes generate functions which are called by
+// Machine Instruction Nodes in order to generate the bit encoding of the
+// instruction. Operands specify their base encoding interface with the
+// interface keyword. There are currently supported four interfaces,
+// REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER. REG_INTER causes an
+// operand to generate a function which returns its register number when
+// queried. CONST_INTER causes an operand to generate a function which
+// returns the value of the constant when queried. MEMORY_INTER causes an
+// operand to generate four functions which return the Base Register, the
+// Index Register, the Scale Value, and the Offset Value of the operand when
+// queried. COND_INTER causes an operand to generate six functions which
+// return the encoding code (ie - encoding bits for the instruction)
+// associated with each basic boolean condition for a conditional instruction.
+// Instructions specify two basic values for encoding. They use the
+// ins_encode keyword to specify their encoding class (which must be one of
+// the class names specified in the encoding block), and they use the
+// opcode keyword to specify, in order, their primary, secondary, and
+// tertiary opcode. Only the opcode sections which a particular instruction
+// needs for encoding need to be specified.
+encode %{
+ // Build emit functions for each basic byte or larger field in the intel
+ // encoding scheme (opcode, rm, sib, immediate), and call them from C++
+ // code in the enc_class source block. Emit functions will live in the
+ // main source block for now. In future, we can generalize this by
+ // adding a syntax that specifies the sizes of fields in an order,
+ // so that the adlc can build the emit functions automagically
+
+ enc_class Java_To_Runtime (method meth) %{ // CALL Java_To_Runtime
+ // No relocation needed
+
+ // movq r10, <meth>
+ emit_opcode(cbuf, Assembler::REX_WB);
+ emit_opcode(cbuf, 0xB8 | (R10_enc - 8));
+ emit_d64(cbuf, (int64_t) $meth$$method);
+
+ // call (r10)
+ emit_opcode(cbuf, Assembler::REX_B);
+ emit_opcode(cbuf, 0xFF);
+ emit_opcode(cbuf, 0xD0 | (R10_enc - 8));
+ %}
+
+ enc_class call_epilog %{
+ if (VerifyStackAtCalls) {
+ // Check that stack depth is unchanged: find majik cookie on stack
+ int framesize =
+ ra_->reg2offset_unchecked(OptoReg::add(ra_->_matcher._old_SP, -3*VMRegImpl::slots_per_word));
+ if (framesize) {
+ if (framesize < 0x80) {
+ emit_opcode(cbuf, Assembler::REX_W);
+ emit_opcode(cbuf, 0x81); // cmpq [rsp+0],0xbadb1ood
+ emit_d8(cbuf, 0x7C);
+ emit_d8(cbuf, 0x24);
+ emit_d8(cbuf, framesize); // Find majik cookie from ESP
+ emit_d32(cbuf, 0xbadb100d);
+ } else {
+ emit_opcode(cbuf, Assembler::REX_W);
+ emit_opcode(cbuf, 0x81); // cmpq [rsp+0],0xbadb1ood
+ emit_d8(cbuf, 0xBC);
+ emit_d8(cbuf, 0x24);
+ emit_d32(cbuf, framesize); // Find majik cookie from ESP
+ emit_d32(cbuf, 0xbadb100d);
+ }
+ }
+ // jmp EQ around INT3
+ // QQQ TODO
+ const int jump_around = 5; // size of call to breakpoint, 1 for CC
+ emit_opcode(cbuf, 0x74);
+ emit_d8(cbuf, jump_around);
+ // QQQ temporary
+ emit_break(cbuf);
+ // Die if stack mismatch
+ // emit_opcode(cbuf,0xCC);
+ }
+ %}
+%}
+
+// INSTRUCTIONS -- Platform dependent
+
+
+//----------OS and Locking Instructions----------------------------------------
+
+// This name is KNOWN by the ADLC and cannot be changed.
+// The ADLC forces a 'TypeRawPtr::BOTTOM' output type
+// for this guy.
+instruct tlsLoadP(r15_RegP dst)
+%{
+ match(Set dst (ThreadLocal));
+ effect(DEF dst);
+
+ size(0);
+ format %{ "# TLS is in R15" %}
+ ins_encode( /*empty encoding*/ );
+ ins_pipe(ialu_reg_reg);
+%}
+
+// Die now
+instruct ShouldNotReachHere( )
+%{
+ match(Halt);
+ // Use the following format syntax
+ format %{ "INT3 ; ShouldNotReachHere" %}
+ opcode(0xCC);
+ ins_encode(OpcP);
+ ins_pipe( pipe_slow );
+%}
+
+//
+// Platform dependent source
+//
+source %{
+
+int MachCallRuntimeNode::ret_addr_offset()
+{
+ return 13; // movq r10,#addr; callq (r10)
+}
+
+// emit an interrupt that is caught by the debugger
+void emit_break(CodeBuffer &cbuf) {
+ *(cbuf.code_end()) = (unsigned char)(0xcc);
+ cbuf.set_code_end(cbuf.code_end() + 1);
+}
+
+void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
+ emit_break(cbuf);
+}
+
+uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const {
+ return 1;
+}
+
+%}