summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore
diff options
context:
space:
mode:
authorFrederik Gladhorn <frederik.gladhorn@digia.com>2013-04-03 14:57:41 +0200
committerFrederik Gladhorn <frederik.gladhorn@digia.com>2013-04-03 14:57:42 +0200
commit276fb8ee82394b8fe414196677ce6af4028c5652 (patch)
tree10fb46e05a825f367dce6204a90d93b83e7f8718 /Source/JavaScriptCore
parent3436b01e6296fa23d6b7a2fad875af6116a9650b (diff)
parentfad1b063ed174a07392561c0323355115aa66992 (diff)
downloadqtwebkit-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.pri13
-rw-r--r--Source/JavaScriptCore/dfg/DFGNodeFlags.h2
-rw-r--r--Source/JavaScriptCore/dfg/DFGNodeType.h2
-rw-r--r--Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp8
-rw-r--r--Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp2
-rw-r--r--Source/JavaScriptCore/jit/JITOpcodes.cpp16
-rw-r--r--Source/JavaScriptCore/jit/JITStubs.cpp7
-rw-r--r--Source/JavaScriptCore/jit/JITStubs.h30
-rw-r--r--Source/JavaScriptCore/jit/JITStubsMSVC64.asm84
-rw-r--r--Source/JavaScriptCore/jit/JSInterfaceJIT.h12
-rw-r--r--Source/JavaScriptCore/yarr/YarrJIT.cpp20
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)