[JAEGER] Bug 588267 - Re-land Win64 port. r=dvander

This commit is contained in:
Makoto Kato 2010-08-23 15:43:43 +09:00
parent 23154dc5b9
commit 2086652819
14 changed files with 240 additions and 33 deletions

View File

@ -320,7 +320,7 @@ CPPSRCS += MethodJIT.cpp \
ifeq (86, $(findstring 86,$(TARGET_CPU)))
ifeq (x86_64, $(TARGET_CPU))
ifeq ($(OS_ARCH),WINNT)
ifdef _MSC_VER
ASFILES += TrampolineMasmX64.asm
endif
ifdef SOLARIS_SUNPRO_CXX

View File

@ -1115,12 +1115,21 @@ private:
int flags_edx = 0;
int flags_ecx = 0;
#if WTF_COMPILER_MSVC
#if WTF_CPU_X86_64
extern void __cpuid(int a[4], int b);
int cpuinfo[4];
__cpuid(cpuinfo, 1);
flags_ecx = cpuinfo[2];
flags_edx = cpuinfo[3];
#else
_asm {
mov eax, 1 // cpuid function 1 gives us the standard feature set
cpuid;
mov flags_ecx, ecx;
mov flags_edx, edx;
}
#endif
#elif WTF_COMPILER_GCC
asm (
"movl $0x1, %%eax;"

View File

@ -849,7 +849,9 @@ public:
#if WTF_CPU_X86_64
void xorq_rr(RegisterID src, RegisterID dst)
{
FIXME_INSN_PRINTING;
js::JaegerSpew(js::JSpew_Insns,
IPFX "xorq %s, %s\n", MAYBE_PAD,
nameIReg(4,src), nameIReg(4, dst));
m_formatter.oneByteOp64(OP_XOR_EvGv, src, dst);
}

View File

@ -2058,6 +2058,9 @@ ia64*-hpux*)
HOST_CC='$(CC)'
HOST_CXX='$(CXX)'
HOST_LD='$(LD)'
if test "$AS_BIN"; then
AS="$(basename "$AS_BIN")"
fi
AR='lib -NOLOGO -OUT:"$@"'
AR_FLAGS=
RANLIB='echo not_ranlib'
@ -2067,6 +2070,7 @@ ia64*-hpux*)
UNZIP=unzip
DOXYGEN=:
GARBAGE='$(OBJDIR)/vc20.pdb $(OBJDIR)/vc40.pdb'
ASM_SUFFIX=asm
OBJ_SUFFIX=obj
LIB_SUFFIX=lib
DLL_PREFIX=

View File

@ -235,7 +235,7 @@ namespace mjit {
{
void (* forceReturn)();
JSC::ExecutablePool *forceReturnPool;
#if defined(JS_NO_FASTCALL) && defined(JS_CPU_X86)
#if (defined(JS_NO_FASTCALL) && defined(JS_CPU_X86)) || defined(_WIN64)
void (* forceReturnFast)();
JSC::ExecutablePool *forceReturnFastPool;
#endif

View File

@ -102,7 +102,7 @@ JS_END_EXTERN_C
static JS_ALWAYS_INLINE int
NativeCompareAndSwap(volatile jsword *w, jsword ov, jsword nv)
{
return _InterlockedCompareExchange64(w, nv, ov) == ov;
return _InterlockedCompareExchange64((long long *volatile)w, nv, ov) == ov;
}
#elif defined(XP_MACOSX) || defined(DARWIN)

View File

@ -111,7 +111,7 @@ class BaseAssembler : public JSC::MacroAssembler
Vector<CallPatch, 64, SystemAllocPolicy> callPatches;
public:
#if defined(JS_NO_FASTCALL) && defined(JS_CPU_X86)
#if (defined(JS_NO_FASTCALL) && defined(JS_CPU_X86)) || defined(_WIN64)
// If there is no fast call, we need to add esp by 8 after the call.
// This callLabel is to record the Label exactly after the call.
Label callLabel;
@ -267,12 +267,19 @@ static const JSC::MacroAssembler::RegisterID JSReturnReg_Data = JSC::ARMRegister
#if defined(JS_NO_FASTCALL) && defined(JS_CPU_X86)
push(Registers::ArgReg1);
push(Registers::ArgReg0);
#elif defined(_WIN64)
subPtr(JSC::MacroAssembler::Imm32(32),
JSC::MacroAssembler::stackPointerRegister);
#endif
Call cl = call(pfun);
#if defined(JS_NO_FASTCALL) && defined(JS_CPU_X86)
callLabel = label();
addPtr(JSC::MacroAssembler::Imm32(8),
JSC::MacroAssembler::stackPointerRegister);
#elif defined(_WIN64)
callLabel = label();
addPtr(JSC::MacroAssembler::Imm32(32),
JSC::MacroAssembler::stackPointerRegister);
#endif
return cl;
}
@ -293,18 +300,8 @@ static const JSC::MacroAssembler::RegisterID JSReturnReg_Data = JSC::ARMRegister
}
Call call(void *fun) {
#if defined(_MSC_VER) && defined(_M_X64)
subPtr(JSC::MacroAssembler::Imm32(32),
JSC::MacroAssembler::stackPointerRegister);
#endif
Call cl = JSC::MacroAssembler::call();
#if defined(_MSC_VER) && defined(_M_X64)
addPtr(JSC::MacroAssembler::Imm32(32),
JSC::MacroAssembler::stackPointerRegister);
#endif
callPatches.append(CallPatch(differenceBetween(startLabel, cl), fun));
return cl;
}

View File

@ -494,6 +494,13 @@ mjit::Compiler::generateMethod()
masm.callLabel = masm.label();
masm.addPtr(Imm32(8), Registers::StackPointer);
}
#elif defined(_WIN64)
// In case of Win64 ABI, stub caller make 32-bytes spcae on stack
else {
masm.subPtr(Imm32(32), Registers::StackPointer);
masm.callLabel = masm.label();
masm.addPtr(Imm32(32), Registers::StackPointer);
}
#endif
ADD_CALLSITE(false);
@ -1826,7 +1833,7 @@ mjit::Compiler::inlineCallHelper(uint32 argc, bool callingNew)
/* Fast-path: return address contains scripted call. */
masm.call(Registers::ReturnReg);
#if defined(JS_NO_FASTCALL) && defined(JS_CPU_X86)
#if (defined(JS_NO_FASTCALL) && defined(JS_CPU_X86)) || defined(_WIN64)
masm.callLabel = masm.label();
#endif
ADD_CALLSITE(false);
@ -1870,11 +1877,12 @@ mjit::Compiler::addCallSite(uint32 id, bool stub)
{
InternalCallSite site;
site.stub = stub;
#if defined(JS_NO_FASTCALL) && defined(JS_CPU_X86)
#if (defined(JS_NO_FASTCALL) && defined(JS_CPU_X86)) || defined(_WIN64)
site.location = stub ? stubcc.masm.callLabel : masm.callLabel;
#else
site.location = stub ? stubcc.masm.label() : masm.label();
#endif
site.pc = PC;
site.id = id;
callSites.append(site);

View File

@ -675,8 +675,11 @@ extern "C" {
* If these assertions break, update the constants below.
* *** DANGER ***
*/
JS_STATIC_ASSERT(offsetof(VMFrame, savedRBX) == 0x48);
JS_STATIC_ASSERT(offsetof(VMFrame, fp) == 0x30);
JS_STATIC_ASSERT(offsetof(VMFrame, savedRBX) == 0x58);
JS_STATIC_ASSERT(offsetof(VMFrame, fp) == 0x38);
JS_STATIC_ASSERT(offsetof(JSStackFrame, ncode) == 0x60);
JS_STATIC_ASSERT(JSVAL_TAG_MASK == 0xFFFF800000000000LL);
JS_STATIC_ASSERT(JSVAL_PAYLOAD_MASK == 0x00007FFFFFFFFFFFLL);
// Windows x64 uses assembler version since compiler doesn't support
// inline assembler

View File

@ -91,7 +91,7 @@ struct VMFrame
# endif
#elif defined(JS_CPU_X64)
void *savedRBX;
# ifdef _MSC_VER
# ifdef _WIN64
void *savedRSI;
void *savedRDI;
# endif
@ -102,7 +102,7 @@ struct VMFrame
void *savedRBP;
void *savedRIP;
# ifdef _MSC_VER
# ifdef _WIN64
inline void** returnAddressLocation() {
return reinterpret_cast<void**>(this) - 5;
}

View File

@ -1364,12 +1364,12 @@ stubs::Debugger(VMFrame &f, jsbytecode *pc)
case JSTRAP_RETURN:
f.cx->throwing = JS_FALSE;
f.cx->fp->setReturnValue(rval);
*f.returnAddressLocation() = JS_FUNC_TO_DATA_PTR(void *,
JS_METHODJIT_DATA(f.cx).trampolines.forceReturn);
#if defined(JS_NO_FASTCALL) && defined(JS_CPU_X86)
#if (defined(JS_NO_FASTCALL) && defined(JS_CPU_X86)) || defined(_WIN64)
*f.returnAddressLocation() = JS_FUNC_TO_DATA_PTR(void *,
JS_METHODJIT_DATA(f.cx).trampolines.forceReturnFast);
#else
*f.returnAddressLocation() = JS_FUNC_TO_DATA_PTR(void *,
JS_METHODJIT_DATA(f.cx).trampolines.forceReturn);
#endif
break;
@ -1404,12 +1404,12 @@ stubs::Trap(VMFrame &f, jsbytecode *pc)
case JSTRAP_RETURN:
f.cx->throwing = JS_FALSE;
f.cx->fp->setReturnValue(rval);
*f.returnAddressLocation() = JS_FUNC_TO_DATA_PTR(void *,
JS_METHODJIT_DATA(f.cx).trampolines.forceReturn);
#if defined(JS_NO_FASTCALL) && defined(JS_CPU_X86)
#if (defined(JS_NO_FASTCALL) && defined(JS_CPU_X86)) || defined(_WIN64)
*f.returnAddressLocation() = JS_FUNC_TO_DATA_PTR(void *,
JS_METHODJIT_DATA(f.cx).trampolines.forceReturnFast);
#else
*f.returnAddressLocation() = JS_FUNC_TO_DATA_PTR(void *,
JS_METHODJIT_DATA(f.cx).trampolines.forceReturn);
#endif
break;

View File

@ -62,7 +62,7 @@ TrampolineCompiler::compile()
#endif
COMPILE(trampolines->forceReturn, trampolines->forceReturnPool, generateForceReturn);
#if defined(JS_NO_FASTCALL) && defined(JS_CPU_X86)
#if (defined(JS_NO_FASTCALL) && defined(JS_CPU_X86)) || defined(_WIN64)
COMPILE(trampolines->forceReturnFast, trampolines->forceReturnFastPool, generateForceReturnFast);
#endif
@ -73,7 +73,7 @@ void
TrampolineCompiler::release(Trampolines *tramps)
{
RELEASE(tramps->forceReturn, tramps->forceReturnPool);
#if defined(JS_NO_FASTCALL) && defined(JS_CPU_X86)
#if (defined(JS_NO_FASTCALL) && defined(JS_CPU_X86)) || defined(_WIN64)
RELEASE(tramps->forceReturnFast, tramps->forceReturnFastPool);
#endif
}
@ -151,13 +151,17 @@ TrampolineCompiler::generateForceReturn(Assembler &masm)
return true;
}
#if defined(JS_NO_FASTCALL) && defined(JS_CPU_X86)
#if (defined(JS_NO_FASTCALL) && defined(JS_CPU_X86)) || defined(_WIN64)
bool
TrampolineCompiler::generateForceReturnFast(Assembler &masm)
{
#ifdef _WIN64
masm.addPtr(Imm32(32), Registers::StackPointer);
#else
// In case of no fast call, when we change the return address,
// we need to make sure add esp by 8.
masm.addPtr(Imm32(8), Registers::StackPointer);
#endif
return generateForceReturn(masm);
}
#endif

View File

@ -71,7 +71,7 @@ private:
/* Generators for trampolines. */
static bool generateForceReturn(Assembler &masm);
#if defined(JS_NO_FASTCALL) && defined(JS_CPU_X86)
#if (defined(JS_NO_FASTCALL) && defined(JS_CPU_X86)) || defined(_WIN64)
static bool generateForceReturnFast(Assembler &masm);
#endif

View File

@ -0,0 +1,180 @@
; -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
; ***** BEGIN LICENSE BLOCK *****
; Version: MPL 1.1/GPL 2.0/LGPL 2.1
;
; The contents of this file are subject to the Mozilla Public License Version
; 1.1 (the "License"); you may not use this file except in compliance with
; the License. You may obtain a copy of the License at
; http://www.mozilla.org/MPL/
;
; Software distributed under the License is distributed on an "AS IS" basis,
; WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
; for the specific language governing rights and limitations under the
; License.
;
; The Original Code is mozilla.org code.
;
; The Initial Developer of the Original Code is Mozilla Japan.
; Portions created by the Initial Developer are Copyright (C) 2010
; the Initial Developer. All Rights Reserved.
;
; Contributor(s):
; Makoto Kato <m_kato@ga2.so-net.ne.jp>
;
; Alternatively, the contents of this file may be used under the terms of
; either the GNU General Public License Version 2 or later (the "GPL"), or
; the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
; in which case the provisions of the GPL or the LGPL are applicable instead
; of those above. If you wish to allow use of your version of this file only
; under the terms of either the GPL or the LGPL, and not to allow others to
; use your version of this file under the terms of the MPL, indicate your
; decision by deleting the provisions above and replace them with the notice
; and other provisions required by the GPL or the LGPL. If you do not delete
; the provisions above, a recipient may use your version of this file under
; the terms of any one of the MPL, the GPL or the LGPL.
;
; ***** END LICENSE BLOCK *****
extern js_InternalThrow:PROC
extern SetVMFrameRegs:PROC
extern UnsetVMFrameRegs:PROC
extern PushActiveVMFrame:PROC
extern PopActiveVMFrame:PROC
.CODE
; JSBool JaegerTrampoline(JSContext *cx, JSStackFrame *fp, void *code,
; Value *stackLimit, void *safePoint);
JaegerTrampoline PROC FRAME
push rbp
.PUSHREG rbp
mov rbp, rsp
.SETFRAME rbp, 0
push r12
.PUSHREG r12
push r13
.PUSHREG r13
push r14
.PUSHREG r14
push r15
.PUSHREG r15
push rdi
.PUSHREG rdi
push rsi
.PUSHREG rsi
push rbx
.PUSHREG rbx
.ENDPROLOG
; Load mask registers
mov r13, 0ffff800000000000h
mov r14, 7fffffffffffh
; Build the JIT frame.
; rcx = cx
; rdx = fp
; r9 = inlineCallCount
; fp must go into rbx
push rdx ; entryFp
push r9 ; inlineCallCount
push rcx ; cx
push rdx ; fp
mov rbx, rdx
; Space for the rest of the VMFrame.
sub rsp, 28h
; This is actually part of VMFrame, but we need to save 5th param for
; SafePointTrampoline
mov r10, [rbp+8*5+8]
push r10
; Set cx->regs and set the active frame. Save r8 and align frame in one
push r8
mov rcx, rsp
sub rsp, 20h
call SetVMFrameRegs
lea rcx, [rsp+20h]
call PushActiveVMFrame
add rsp, 20h
; Jump into the JIT code.
call qword ptr [rsp]
sub rsp, 20h
lea rcx, [rsp+20h]
call PopActiveVMFrame
lea rcx, [rsp+20h]
call UnsetVMFrameRegs
add rsp, 58h+20h
pop rbx
pop rsi
pop rdi
pop r15
pop r14
pop r13
pop r12
pop rbp
mov rax, 1
ret
JaegerTrampoline ENDP
; void JaegerThrowpoline()
JaegerThrowpoline PROC FRAME
.ENDPROLOG
; For Windows x64 stub calls, we pad the stack by 32 before
; calling, so we must account for that here. See doStubCall.
lea rcx, [rsp+20h]
call js_InternalThrow
test rax, rax
je throwpoline_exit
add rsp, 20h
jmp rax
throwpoline_exit:
lea rcx, [rsp+20h]
call PopActiveVMFrame
add rsp, 58h+20h
pop rbx
pop rsi
pop rdi
pop r15
pop r14
pop r13
pop r12
pop rbp
xor rax, rax
ret
JaegerThrowpoline ENDP
; void SafePointTrampoline();
SafePointTrampoline PROC FRAME
.ENDPROLOG
pop rax
mov qword ptr [rbx+60h], rax
jmp qword ptr [rsp+8]
SafePointTrampoline ENDP
; void InjectJaegerReturn();
InjectJaegerReturn PROC FRAME
.ENDPROLOG
mov rcx, qword ptr [rbx+40h] ; load value into typeReg
mov rax, qword ptr [rbx+60h] ; fp->ncode
; Reimplementation of PunboxAssembler::loadValueAsComponents()
mov rdx, r14
and rdx, rcx
xor rcx, rdx
; For Windows x64 stub calls, we pad the stack by 32 before
; calling, so we must account for that here. See doStubCall.
mov rbx, qword ptr [rsp+38h+20h] ; f.fp
add rsp, 20h
jmp rax ; return
InjectJaegerReturn ENDP
END