duke@435: /* trims@1907: * Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved. duke@435: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. duke@435: * duke@435: * This code is free software; you can redistribute it and/or modify it duke@435: * under the terms of the GNU General Public License version 2 only, as duke@435: * published by the Free Software Foundation. duke@435: * duke@435: * This code is distributed in the hope that it will be useful, but WITHOUT duke@435: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or duke@435: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License duke@435: * version 2 for more details (a copy is included in the LICENSE file that duke@435: * accompanied this code). duke@435: * duke@435: * You should have received a copy of the GNU General Public License version duke@435: * 2 along with this work; if not, write to the Free Software Foundation, duke@435: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. duke@435: * trims@1907: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA trims@1907: * or visit www.oracle.com if you need additional information or have any trims@1907: * questions. duke@435: * duke@435: */ duke@435: duke@435: #include "incls/_precompiled.incl" never@739: #include "incls/_assembler_windows_x86.cpp.incl" duke@435: duke@435: duke@435: void MacroAssembler::int3() { duke@435: emit_byte(0xCC); duke@435: } duke@435: never@739: #ifndef _LP64 duke@435: // The current scheme to accelerate access to the thread duke@435: // pointer is to store the current thread in the os_exception_wrapper duke@435: // and reference the current thread from stubs and compiled code duke@435: // via the FS register. FS[0] contains a pointer to the structured duke@435: // exception block which is actually a stack address. The first time duke@435: // we call the os exception wrapper, we calculate and store the duke@435: // offset from this exception block and use that offset here. duke@435: // duke@435: // The last mechanism we used was problematic in that the duke@435: // the offset we had hard coded in the VM kept changing as Microsoft duke@435: // evolved the OS. duke@435: // duke@435: // Warning: This mechanism assumes that we only attempt to get the duke@435: // thread when we are nested below a call wrapper. duke@435: // duke@435: // movl reg, fs:[0] Get exeception pointer duke@435: // movl reg, [reg + thread_ptr_offset] Load thread duke@435: // duke@435: void MacroAssembler::get_thread(Register thread) { duke@435: // can't use ExternalAddress because it can't take NULL duke@435: AddressLiteral null(0, relocInfo::none); duke@435: duke@435: prefix(FS_segment); duke@435: movptr(thread, null); duke@435: assert(ThreadLocalStorage::get_thread_ptr_offset() != 0, duke@435: "Thread Pointer Offset has not been initialized"); duke@435: movl(thread, Address(thread, ThreadLocalStorage::get_thread_ptr_offset())); duke@435: } never@739: #else never@739: // call (Thread*)TlsGetValue(thread_index()); never@739: void MacroAssembler::get_thread(Register thread) { never@739: if (thread != rax) { never@739: push(rax); never@739: } never@739: push(rdi); never@739: push(rsi); never@739: push(rdx); never@739: push(rcx); never@739: push(r8); never@739: push(r9); never@739: push(r10); never@739: // XXX never@739: mov(r10, rsp); never@739: andq(rsp, -16); never@739: push(r10); never@739: push(r11); never@739: never@739: movl(c_rarg0, ThreadLocalStorage::thread_index()); never@739: call(RuntimeAddress((address)TlsGetValue)); never@739: never@739: pop(r11); never@739: pop(rsp); never@739: pop(r10); never@739: pop(r9); never@739: pop(r8); never@739: pop(rcx); never@739: pop(rdx); never@739: pop(rsi); never@739: pop(rdi); never@739: if (thread != rax) { never@739: mov(thread, rax); never@739: pop(rax); never@739: } never@739: } never@739: #endif