diff options
author | Frederik Gladhorn <frederik.gladhorn@digia.com> | 2013-04-03 14:57:41 +0200 |
---|---|---|
committer | Frederik Gladhorn <frederik.gladhorn@digia.com> | 2013-04-03 14:57:42 +0200 |
commit | 276fb8ee82394b8fe414196677ce6af4028c5652 (patch) | |
tree | 10fb46e05a825f367dce6204a90d93b83e7f8718 /Source/JavaScriptCore | |
parent | 3436b01e6296fa23d6b7a2fad875af6116a9650b (diff) | |
parent | fad1b063ed174a07392561c0323355115aa66992 (diff) | |
download | qtwebkit-276fb8ee82394b8fe414196677ce6af4028c5652.tar.gz |
Merge remote-tracking branch 'origin/stable' into dev
Change-Id: Ibb1f73326070b66000c54c3c722a45cb7b4791c1
Diffstat (limited to 'Source/JavaScriptCore')
-rw-r--r-- | Source/JavaScriptCore/Target.pri | 13 | ||||
-rw-r--r-- | Source/JavaScriptCore/dfg/DFGNodeFlags.h | 2 | ||||
-rw-r--r-- | Source/JavaScriptCore/dfg/DFGNodeType.h | 2 | ||||
-rw-r--r-- | Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp | 8 | ||||
-rw-r--r-- | Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp | 2 | ||||
-rw-r--r-- | Source/JavaScriptCore/jit/JITOpcodes.cpp | 16 | ||||
-rw-r--r-- | Source/JavaScriptCore/jit/JITStubs.cpp | 7 | ||||
-rw-r--r-- | Source/JavaScriptCore/jit/JITStubs.h | 30 | ||||
-rw-r--r-- | Source/JavaScriptCore/jit/JITStubsMSVC64.asm | 84 | ||||
-rw-r--r-- | Source/JavaScriptCore/jit/JSInterfaceJIT.h | 12 | ||||
-rw-r--r-- | Source/JavaScriptCore/yarr/YarrJIT.cpp | 20 |
11 files changed, 187 insertions, 9 deletions
diff --git a/Source/JavaScriptCore/Target.pri b/Source/JavaScriptCore/Target.pri index f609de10b..e1da901c1 100644 --- a/Source/JavaScriptCore/Target.pri +++ b/Source/JavaScriptCore/Target.pri @@ -297,6 +297,19 @@ linux-*:if(isEqual(QT_ARCH, "i386")|isEqual(QT_ARCH, "x86_64")) { disassembler/udis86/udis86_syn.c \ } +win32:!win32-g++*:isEqual(QT_ARCH, "x86_64"):{ + asm_compiler.commands = ml64 /c + asm_compiler.commands += /Fo ${QMAKE_FILE_OUT} ${QMAKE_FILE_IN} + asm_compiler.output = ${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_BASE}$${first(QMAKE_EXT_OBJ)} + asm_compiler.input = ASM_SOURCES + asm_compiler.variable_out = OBJECTS + asm_compiler.name = compiling[asm] ${QMAKE_FILE_IN} + silent:asm_compiler.commands = @echo compiling[asm] ${QMAKE_FILE_IN} && $$asm_compiler.commands + QMAKE_EXTRA_COMPILERS += asm_compiler + + ASM_SOURCES += jit/JITStubsMSVC64.asm +} + HEADERS += $$files(*.h, true) *sh4* { diff --git a/Source/JavaScriptCore/dfg/DFGNodeFlags.h b/Source/JavaScriptCore/dfg/DFGNodeFlags.h index 5e41bfc6b..463451c39 100644 --- a/Source/JavaScriptCore/dfg/DFGNodeFlags.h +++ b/Source/JavaScriptCore/dfg/DFGNodeFlags.h @@ -54,7 +54,7 @@ namespace JSC { namespace DFG { #define NodeBackPropMask 0x3C00 #define NodeUseBottom 0x000 -#define NodeUsedAsNumber 0x400 // The result of this computation may be used in a context that observes fractional results. +#define NodeUsedAsNumber 0x400 // The result of this computation may be used in a context that observes fractional, or bigger-than-int32, results. #define NodeNeedsNegZero 0x800 // The result of this computation may be used in a context that observes -0. #define NodeUsedAsOther 0x1000 // The result of this computation may be used in a context that distinguishes between NaN and other things (like undefined). #define NodeUsedAsValue (NodeUsedAsNumber | NodeNeedsNegZero | NodeUsedAsOther) diff --git a/Source/JavaScriptCore/dfg/DFGNodeType.h b/Source/JavaScriptCore/dfg/DFGNodeType.h index cbcdde660..b3fd78785 100644 --- a/Source/JavaScriptCore/dfg/DFGNodeType.h +++ b/Source/JavaScriptCore/dfg/DFGNodeType.h @@ -58,7 +58,7 @@ namespace JSC { namespace DFG { /* VariableAccessData, and thus will share predictions. */\ macro(GetLocal, NodeResultJS) \ macro(SetLocal, 0) \ - macro(Phantom, NodeMustGenerate | NodeDoesNotExit) \ + macro(Phantom, NodeMustGenerate) \ macro(Nop, 0 | NodeDoesNotExit) \ macro(Phi, 0 | NodeDoesNotExit) \ macro(Flush, NodeMustGenerate | NodeDoesNotExit) \ diff --git a/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp b/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp index 5b6c28ff7..4226fcc6a 100644 --- a/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp +++ b/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp @@ -211,7 +211,13 @@ private: case SetLocal: { VariableAccessData* variableAccessData = node.variableAccessData(); changed |= variableAccessData->predict(m_graph[node.child1()].prediction()); - changed |= m_graph[node.child1()].mergeFlags(variableAccessData->flags()); + + // Assume conservatively that a SetLocal implies that the value may flow through a loop, + // and so we would have overflow leading to the program "observing" numbers even if all + // users of the value are doing toInt32. It might be worthwhile to revisit this at some + // point and actually check if the data flow involves loops, but right now I don't think + // we have evidence that this would be beneficial for benchmarks. + changed |= m_graph[node.child1()].mergeFlags(variableAccessData->flags() | NodeUsedAsNumber); break; } diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp index f5b9ec9ce..fce151ef2 100644 --- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp +++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp @@ -3724,7 +3724,7 @@ void SpeculativeJIT::compile(Node& node) case NewArrayWithSize: { JSGlobalObject* globalObject = m_jit.graph().globalObjectFor(node.codeOrigin); - if (!globalObject->isHavingABadTime()) { + if (!globalObject->isHavingABadTime() && !hasArrayStorage(node.indexingType())) { globalObject->havingABadTimeWatchpoint()->add(speculationWatchpoint()); SpeculateStrictInt32Operand size(this, node.child1()); diff --git a/Source/JavaScriptCore/jit/JITOpcodes.cpp b/Source/JavaScriptCore/jit/JITOpcodes.cpp index 9f0ce3a77..36e7ece1b 100644 --- a/Source/JavaScriptCore/jit/JITOpcodes.cpp +++ b/Source/JavaScriptCore/jit/JITOpcodes.cpp @@ -244,6 +244,7 @@ JIT::Label JIT::privateCompileCTINativeCall(JSGlobalData* globalData, bool isCon peek(regT1); emitPutToCallFrameHeader(regT1, JSStack::ReturnPC); +#if !OS(WINDOWS) // Calling convention: f(edi, esi, edx, ecx, ...); // Host function signature: f(ExecState*); move(callFrameRegister, X86Registers::edi); @@ -256,6 +257,21 @@ JIT::Label JIT::privateCompileCTINativeCall(JSGlobalData* globalData, bool isCon call(Address(X86Registers::r9, executableOffsetToFunction)); addPtr(TrustedImm32(16 - sizeof(int64_t)), stackPointerRegister); +#else + // Calling convention: f(ecx, edx, r8, r9, ...); + // Host function signature: f(ExecState*); + move(callFrameRegister, X86Registers::ecx); + + // Leave space for the callee parameter home addresses and align the stack. + subPtr(TrustedImm32(4 * sizeof(int64_t) + 16 - sizeof(int64_t)), stackPointerRegister); + + emitGetFromCallFrameHeaderPtr(JSStack::Callee, X86Registers::edx); + loadPtr(Address(X86Registers::edx, OBJECT_OFFSETOF(JSFunction, m_executable)), X86Registers::r9); + move(regT0, callFrameRegister); // Eagerly restore caller frame register to avoid loading from stack. + call(Address(X86Registers::r9, executableOffsetToFunction)); + + addPtr(TrustedImm32(4 * sizeof(int64_t) + 16 - sizeof(int64_t)), stackPointerRegister); +#endif #elif CPU(ARM) // Load caller frame's scope chain into this callframe so that whatever we call can diff --git a/Source/JavaScriptCore/jit/JITStubs.cpp b/Source/JavaScriptCore/jit/JITStubs.cpp index fbef1fcb9..eca0fb079 100644 --- a/Source/JavaScriptCore/jit/JITStubs.cpp +++ b/Source/JavaScriptCore/jit/JITStubs.cpp @@ -433,6 +433,13 @@ SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n" "ret" "\n" ); +#elif COMPILER(MSVC) && CPU(X86_64) + +// These ASSERTs remind you that, if you change the layout of JITStackFrame, you +// need to change the assembly trampolines in JITStubsMSVC64.asm to match. +COMPILE_ASSERT(offsetof(struct JITStackFrame, code) % 16 == 0x0, JITStackFrame_maintains_16byte_stack_alignment); +COMPILE_ASSERT(offsetof(struct JITStackFrame, savedRBX) == 0x58, JITStackFrame_stub_argument_space_matches_ctiTrampoline); + #else #error "JIT not supported on this platform." #endif diff --git a/Source/JavaScriptCore/jit/JITStubs.h b/Source/JavaScriptCore/jit/JITStubs.h index 3bf13bbdf..fe64cd9bc 100644 --- a/Source/JavaScriptCore/jit/JITStubs.h +++ b/Source/JavaScriptCore/jit/JITStubs.h @@ -99,7 +99,7 @@ namespace JSC { MacroAssemblerCodePtr ctiNativeConstruct; }; -#if CPU(X86_64) +#if !OS(WINDOWS) && CPU(X86_64) struct JITStackFrame { void* reserved; // Unused JITStubArg args[6]; @@ -123,6 +123,34 @@ namespace JSC { // When JIT code makes a call, it pushes its return address just below the rest of the stack. ReturnAddressPtr* returnAddressSlot() { return reinterpret_cast<ReturnAddressPtr*>(this) - 1; } }; +#elif OS(WINDOWS) && CPU(X86_64) + struct JITStackFrame { + void* shadow[4]; // Shadow space reserved for a callee's parameters home addresses + void* reserved; // Unused, also maintains the 16-bytes stack alignment + JITStubArg args[6]; + + void* savedRBX; + void* savedR15; + void* savedR14; + void* savedR13; + void* savedR12; + void* savedRBP; + void* savedRIP; + + // Home addresses for our register passed parameters + // http://msdn.microsoft.com/en-us/library/ew5tede7.aspx + void* code; + JSStack* stack; + CallFrame* callFrame; + void* unused1; + + // Passed on the stack + void* unused2; + JSGlobalData* globalData; + + // When JIT code makes a call, it pushes its return address just below the rest of the stack. + ReturnAddressPtr* returnAddressSlot() { return reinterpret_cast<ReturnAddressPtr*>(this) - 1; } + }; #elif CPU(X86) #if COMPILER(MSVC) || (OS(WINDOWS) && COMPILER(GCC)) #pragma pack(push) diff --git a/Source/JavaScriptCore/jit/JITStubsMSVC64.asm b/Source/JavaScriptCore/jit/JITStubsMSVC64.asm new file mode 100644 index 000000000..4a00e0d14 --- /dev/null +++ b/Source/JavaScriptCore/jit/JITStubsMSVC64.asm @@ -0,0 +1,84 @@ +;/* +; Copyright (C) 2013 Digia Plc. and/or its subsidiary(-ies) +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; 1. Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; 2. Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; +; THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY +; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +; PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR +; CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +; EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +; PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +; OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;*/ + +EXTERN cti_vm_throw : near +PUBLIC ctiTrampoline +PUBLIC ctiVMThrowTrampoline +PUBLIC ctiOpThrowNotCaught + +_TEXT SEGMENT + +ctiTrampoline PROC + ; Dump register parameters to their home address + mov qword ptr[rsp+20h], r9 + mov qword ptr[rsp+18h], r8 + mov qword ptr[rsp+10h], rdx + mov qword ptr[rsp+8h], rcx + + push rbp + mov rbp, rsp + push r12 + push r13 + push r14 + push r15 + push rbx + + ; Decrease rsp to point to the start of our JITStackFrame + sub rsp, 58h + mov r12, 512 + mov r14, 0FFFF000000000000h + mov r15, 0FFFF000000000002h + mov r13, r8 + call rcx + add rsp, 58h + pop rbx + pop r15 + pop r14 + pop r13 + pop r12 + pop rbp + ret +ctiTrampoline ENDP + +ctiVMThrowTrampoline PROC + mov rcx, rsp + call cti_vm_throw + int 3 +ctiVMThrowTrampoline ENDP + +ctiOpThrowNotCaught PROC + add rsp, 58h + pop rbx + pop r15 + pop r14 + pop r13 + pop r12 + pop rbp + ret +ctiOpThrowNotCaught ENDP + +_TEXT ENDS + +END
\ No newline at end of file diff --git a/Source/JavaScriptCore/jit/JSInterfaceJIT.h b/Source/JavaScriptCore/jit/JSInterfaceJIT.h index d2a91ba0a..ad546d963 100644 --- a/Source/JavaScriptCore/jit/JSInterfaceJIT.h +++ b/Source/JavaScriptCore/jit/JSInterfaceJIT.h @@ -57,22 +57,26 @@ namespace JSC { #if CPU(X86_64) static const RegisterID returnValueRegister = X86Registers::eax; static const RegisterID cachedResultRegister = X86Registers::eax; +#if !OS(WINDOWS) static const RegisterID firstArgumentRegister = X86Registers::edi; - +#else + static const RegisterID firstArgumentRegister = X86Registers::ecx; +#endif + #if ENABLE(VALUE_PROFILER) static const RegisterID bucketCounterRegister = X86Registers::r10; #endif - + static const RegisterID timeoutCheckRegister = X86Registers::r12; static const RegisterID callFrameRegister = X86Registers::r13; static const RegisterID tagTypeNumberRegister = X86Registers::r14; static const RegisterID tagMaskRegister = X86Registers::r15; - + static const RegisterID regT0 = X86Registers::eax; static const RegisterID regT1 = X86Registers::edx; static const RegisterID regT2 = X86Registers::ecx; static const RegisterID regT3 = X86Registers::ebx; - + static const FPRegisterID fpRegT0 = X86Registers::xmm0; static const FPRegisterID fpRegT1 = X86Registers::xmm1; static const FPRegisterID fpRegT2 = X86Registers::xmm2; diff --git a/Source/JavaScriptCore/yarr/YarrJIT.cpp b/Source/JavaScriptCore/yarr/YarrJIT.cpp index ce84e2c74..d5b215413 100644 --- a/Source/JavaScriptCore/yarr/YarrJIT.cpp +++ b/Source/JavaScriptCore/yarr/YarrJIT.cpp @@ -87,10 +87,20 @@ class YarrGenerator : private MacroAssembler { static const RegisterID returnRegister = X86Registers::eax; static const RegisterID returnRegister2 = X86Registers::edx; #elif CPU(X86_64) +#if !OS(WINDOWS) static const RegisterID input = X86Registers::edi; static const RegisterID index = X86Registers::esi; static const RegisterID length = X86Registers::edx; static const RegisterID output = X86Registers::ecx; +#else + // If the return value doesn't fit in 64bits, its destination is pointed by rcx and the parameters are shifted. + // http://msdn.microsoft.com/en-us/library/7572ztz4.aspx + COMPILE_ASSERT(sizeof(MatchResult) > sizeof(void*), MatchResult_does_not_fit_in_64bits); + static const RegisterID input = X86Registers::edx; + static const RegisterID index = X86Registers::r8; + static const RegisterID length = X86Registers::r9; + static const RegisterID output = X86Registers::r10; +#endif static const RegisterID regT0 = X86Registers::eax; static const RegisterID regT1 = X86Registers::ebx; @@ -2502,6 +2512,10 @@ class YarrGenerator : private MacroAssembler { push(X86Registers::ebp); move(stackPointerRegister, X86Registers::ebp); push(X86Registers::ebx); +#if OS(WINDOWS) + if (compileMode == IncludeSubpatterns) + loadPtr(Address(X86Registers::ebp, 6 * sizeof(void*)), output); +#endif #elif CPU(X86) push(X86Registers::ebp); move(stackPointerRegister, X86Registers::ebp); @@ -2540,6 +2554,12 @@ class YarrGenerator : private MacroAssembler { void generateReturn() { #if CPU(X86_64) +#if OS(WINDOWS) + // Store the return value in the allocated space pointed by rcx. + store64(returnRegister, Address(X86Registers::ecx)); + store64(returnRegister2, Address(X86Registers::ecx, sizeof(void*))); + move(X86Registers::ecx, returnRegister); +#endif pop(X86Registers::ebx); pop(X86Registers::ebp); #elif CPU(X86) |