<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[171005] trunk/Source</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/171005">171005</a></dd>
<dt>Author</dt> <dd>commit-queue@webkit.org</dd>
<dt>Date</dt> <dd>2014-07-11 11:53:19 -0700 (Fri, 11 Jul 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>[Win] Enable DFG JIT.
https://bugs.webkit.org/show_bug.cgi?id=123615

Patch by peavo@outlook.com &lt;peavo@outlook.com&gt; on 2014-07-11
Reviewed by Mark Lam.

Source/JavaScriptCore:
When the return type of a JIT generated function call is larger than 64-bit (e.g. SlowPathReturnType),
the normal call() implementation cannot be used on 64-bit Windows, because the 64-bit Windows ABI is different in this case.
Also, when generating calls with double arguments, we need to make sure the arguments are put in the correct registers,
since the register allocation differs on 64-bit Windows.

* assembler/MacroAssemblerX86_64.h:
(JSC::MacroAssemblerX86_64::callWithSlowPathReturnType): Added method to handle function calls where the return value type size is larger than 64-bit.
* jit/CCallHelpers.h:
(JSC::CCallHelpers::setupArgumentsWithExecState): Move arguments to correct registers when there are floating point arguments.
(JSC::CCallHelpers::setupArgumentsWithExecStateForCallWithSlowPathReturnType): Added method.
* jit/JIT.h:
(JSC::JIT::appendCallWithSlowPathReturnType): Added method.
* jit/JITInlines.h:
(JSC::JIT::appendCallWithExceptionCheckAndSlowPathReturnType): Added method.
(JSC::JIT::callOperation): Call new method.

Source/WTF:
* wtf/Platform.h:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreassemblerMacroAssemblerX86_64h">trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitCCallHelpersh">trunk/Source/JavaScriptCore/jit/CCallHelpers.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITh">trunk/Source/JavaScriptCore/jit/JIT.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITInlinesh">trunk/Source/JavaScriptCore/jit/JITInlines.h</a></li>
<li><a href="#trunkSourceWTFChangeLog">trunk/Source/WTF/ChangeLog</a></li>
<li><a href="#trunkSourceWTFwtfPlatformh">trunk/Source/WTF/wtf/Platform.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (171004 => 171005)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2014-07-11 17:32:17 UTC (rev 171004)
+++ trunk/Source/JavaScriptCore/ChangeLog        2014-07-11 18:53:19 UTC (rev 171005)
</span><span class="lines">@@ -1,3 +1,26 @@
</span><ins>+2014-07-11  peavo@outlook.com  &lt;peavo@outlook.com&gt;
+
+        [Win] Enable DFG JIT.
+        https://bugs.webkit.org/show_bug.cgi?id=123615
+
+        Reviewed by Mark Lam.
+
+        When the return type of a JIT generated function call is larger than 64-bit (e.g. SlowPathReturnType),
+        the normal call() implementation cannot be used on 64-bit Windows, because the 64-bit Windows ABI is different in this case.
+        Also, when generating calls with double arguments, we need to make sure the arguments are put in the correct registers,
+        since the register allocation differs on 64-bit Windows.
+
+        * assembler/MacroAssemblerX86_64.h:
+        (JSC::MacroAssemblerX86_64::callWithSlowPathReturnType): Added method to handle function calls where the return value type size is larger than 64-bit.
+        * jit/CCallHelpers.h:
+        (JSC::CCallHelpers::setupArgumentsWithExecState): Move arguments to correct registers when there are floating point arguments.
+        (JSC::CCallHelpers::setupArgumentsWithExecStateForCallWithSlowPathReturnType): Added method.
+        * jit/JIT.h:
+        (JSC::JIT::appendCallWithSlowPathReturnType): Added method.
+        * jit/JITInlines.h:
+        (JSC::JIT::appendCallWithExceptionCheckAndSlowPathReturnType): Added method.
+        (JSC::JIT::callOperation): Call new method.
+
</ins><span class="cx"> 2014-07-09  Benjamin Poulain  &lt;benjamin@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         Use 16bits instructions for push/pop on ARMv7 when possible
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreassemblerMacroAssemblerX86_64h"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h (171004 => 171005)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h        2014-07-11 17:32:17 UTC (rev 171004)
+++ trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h        2014-07-11 18:53:19 UTC (rev 171005)
</span><span class="lines">@@ -151,6 +151,45 @@
</span><span class="cx">         store8(reg, Address(scratchRegister));
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+#if OS(WINDOWS)
+    Call callWithSlowPathReturnType()
+    {
+        // On Win64, when the return type is larger than 8 bytes, we need to allocate space on the stack for the return value.
+        // On entry, rcx should contain a pointer to this stack space. The other parameters are shifted to the right,
+        // rdx should contain the first argument, r8 should contain the second argument, and r9 should contain the third argument.
+        // On return, rax contains a pointer to this stack value. See http://msdn.microsoft.com/en-us/library/7572ztz4.aspx.
+        // We then need to copy the 16 byte return value into rax and rdx, since JIT expects the return value to be split between the two.
+        // It is assumed that the parameters are already shifted to the right, when entering this method.
+        // Note: this implementation supports up to 3 parameters.
+
+        // JIT relies on the CallerFrame (frame pointer) being put on the stack,
+        // On Win64 we need to manually copy the frame pointer to the stack, since MSVC may not maintain a frame pointer on 64-bit.
+        // See http://msdn.microsoft.com/en-us/library/9z1stfyw.aspx where it's stated that rbp MAY be used as a frame pointer.
+        store64(X86Registers::ebp, Address(X86Registers::esp, -16));
+
+        // We also need to allocate the shadow space on the stack for the 4 parameter registers.
+        // In addition, we need to allocate 16 bytes for the return value.
+        // Also, we should allocate 16 bytes for the frame pointer, and return address (not populated).
+        sub64(TrustedImm32(8 * sizeof(int64_t)), X86Registers::esp);
+
+        // The first parameter register should contain a pointer to the stack allocated space for the return value.
+        move(X86Registers::esp, X86Registers::ecx);
+        add64(TrustedImm32(4 * sizeof(int64_t)), X86Registers::ecx);
+
+        DataLabelPtr label = moveWithPatch(TrustedImmPtr(0), scratchRegister);
+        Call result = Call(m_assembler.call(scratchRegister), Call::Linkable);
+
+        add64(TrustedImm32(8 * sizeof(int64_t)), X86Registers::esp);
+
+        // Copy the return value into rax and rdx.
+        load64(Address(X86Registers::eax, sizeof(int64_t)), X86Registers::edx);
+        load64(Address(X86Registers::eax), X86Registers::eax);
+
+        ASSERT_UNUSED(label, differenceBetween(label, result) == REPTACH_OFFSET_CALL_R11);
+        return result;
+    }
+#endif
+
</ins><span class="cx">     Call call()
</span><span class="cx">     {
</span><span class="cx"> #if OS(WINDOWS)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitCCallHelpersh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/CCallHelpers.h (171004 => 171005)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/CCallHelpers.h        2014-07-11 17:32:17 UTC (rev 171004)
+++ trunk/Source/JavaScriptCore/jit/CCallHelpers.h        2014-07-11 18:53:19 UTC (rev 171005)
</span><span class="lines">@@ -798,14 +798,27 @@
</span><span class="cx">     
</span><span class="cx">     ALWAYS_INLINE void setupArgumentsWithExecState(FPRReg arg1, GPRReg arg2)
</span><span class="cx">     {
</span><ins>+#if OS(WINDOWS) &amp;&amp; CPU(X86_64)
+        // On Windows, arguments map to designated registers based on the argument positions, even when there are interlaced scalar and floating point arguments.
+        // See http://msdn.microsoft.com/en-us/library/zthk2dkh.aspx
+        moveDouble(arg1, FPRInfo::argumentFPR1);
+        move(arg2, GPRInfo::argumentGPR2);
+#else
</ins><span class="cx">         moveDouble(arg1, FPRInfo::argumentFPR0);
</span><span class="cx">         move(arg2, GPRInfo::argumentGPR1);
</span><ins>+#endif
</ins><span class="cx">         move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, FPRReg arg3)
</span><span class="cx">     {
</span><ins>+#if OS(WINDOWS) &amp;&amp; CPU(X86_64)
+        // On Windows, arguments map to designated registers based on the argument positions, even when there are interlaced scalar and floating point arguments.
+        // See http://msdn.microsoft.com/en-us/library/zthk2dkh.aspx
+        moveDouble(arg3, FPRInfo::argumentFPR3);
+#else
</ins><span class="cx">         moveDouble(arg3, FPRInfo::argumentFPR0);
</span><ins>+#endif
</ins><span class="cx">         setupStubArguments(arg1, arg2);
</span><span class="cx">         move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
</span><span class="cx">     }
</span><span class="lines">@@ -1061,6 +1074,14 @@
</span><span class="cx">         move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+#if OS(WINDOWS) &amp;&amp; CPU(X86_64)
+    ALWAYS_INLINE void setupArgumentsWithExecStateForCallWithSlowPathReturnType(TrustedImm32 arg1)
+    {
+        move(arg1, GPRInfo::argumentGPR2);
+        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR1);
+    }
+#endif
+
</ins><span class="cx">     ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2)
</span><span class="cx">     {
</span><span class="cx">         setupStubArguments(arg1, arg2);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JIT.h (171004 => 171005)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JIT.h        2014-07-11 17:32:17 UTC (rev 171004)
+++ trunk/Source/JavaScriptCore/jit/JIT.h        2014-07-11 18:53:19 UTC (rev 171005)
</span><span class="lines">@@ -264,6 +264,15 @@
</span><span class="cx">             return functionCall;
</span><span class="cx">         }
</span><span class="cx"> 
</span><ins>+#if OS(WINDOWS) &amp;&amp; CPU(X86_64)
+        Call appendCallWithSlowPathReturnType(const FunctionPtr&amp; function)
+        {
+            Call functionCall = callWithSlowPathReturnType();
+            m_calls.append(CallRecord(functionCall, m_bytecodeOffset, function.value()));
+            return functionCall;
+        }
+#endif
+
</ins><span class="cx">         void exceptionCheck(Jump jumpToHandler)
</span><span class="cx">         {
</span><span class="cx">             m_exceptionChecks.append(jumpToHandler);
</span><span class="lines">@@ -648,6 +657,9 @@
</span><span class="cx">         void linkSlowCaseIfNotJSCell(Vector&lt;SlowCaseEntry&gt;::iterator&amp;, int virtualRegisterIndex);
</span><span class="cx"> 
</span><span class="cx">         MacroAssembler::Call appendCallWithExceptionCheck(const FunctionPtr&amp;);
</span><ins>+#if OS(WINDOWS) &amp;&amp; CPU(X86_64)
+        MacroAssembler::Call appendCallWithExceptionCheckAndSlowPathReturnType(const FunctionPtr&amp;);
+#endif
</ins><span class="cx">         MacroAssembler::Call appendCallWithCallFrameRollbackOnException(const FunctionPtr&amp;);
</span><span class="cx">         MacroAssembler::Call appendCallWithExceptionCheckSetJSValueResult(const FunctionPtr&amp;, int);
</span><span class="cx">         MacroAssembler::Call appendCallWithExceptionCheckSetJSValueResultWithProfile(const FunctionPtr&amp;, int);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITInlines.h (171004 => 171005)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITInlines.h        2014-07-11 17:32:17 UTC (rev 171004)
+++ trunk/Source/JavaScriptCore/jit/JITInlines.h        2014-07-11 18:53:19 UTC (rev 171005)
</span><span class="lines">@@ -118,6 +118,16 @@
</span><span class="cx">     return call;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+#if OS(WINDOWS) &amp;&amp; CPU(X86_64)
+ALWAYS_INLINE MacroAssembler::Call JIT::appendCallWithExceptionCheckAndSlowPathReturnType(const FunctionPtr&amp; function)
+{
+    updateTopCallFrame();
+    MacroAssembler::Call call = appendCallWithSlowPathReturnType(function);
+    exceptionCheck();
+    return call;
+}
+#endif
+
</ins><span class="cx"> ALWAYS_INLINE MacroAssembler::Call JIT::appendCallWithCallFrameRollbackOnException(const FunctionPtr&amp; function)
</span><span class="cx"> {
</span><span class="cx">     updateTopCallFrame(); // The callee is responsible for setting topCallFrame to their caller
</span><span class="lines">@@ -235,8 +245,13 @@
</span><span class="cx"> 
</span><span class="cx"> ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(Sprt_JITOperation_EZ operation, int32_t op)
</span><span class="cx"> {
</span><ins>+#if OS(WINDOWS) &amp;&amp; CPU(X86_64)
+    setupArgumentsWithExecStateForCallWithSlowPathReturnType(TrustedImm32(op));
+    return appendCallWithExceptionCheckAndSlowPathReturnType(operation);
+#else
</ins><span class="cx">     setupArgumentsWithExecState(TrustedImm32(op));
</span><span class="cx">     return appendCallWithExceptionCheck(operation);
</span><ins>+#endif
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(V_JITOperation_E operation)
</span></span></pre></div>
<a id="trunkSourceWTFChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/ChangeLog (171004 => 171005)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/ChangeLog        2014-07-11 17:32:17 UTC (rev 171004)
+++ trunk/Source/WTF/ChangeLog        2014-07-11 18:53:19 UTC (rev 171005)
</span><span class="lines">@@ -1,3 +1,12 @@
</span><ins>+2014-07-11  peavo@outlook.com  &lt;peavo@outlook.com&gt;
+
+        [Win] Enable DFG JIT.
+        https://bugs.webkit.org/show_bug.cgi?id=123615
+
+        Reviewed by Mark Lam.
+
+        * wtf/Platform.h:
+
</ins><span class="cx"> 2014-07-11  Commit Queue  &lt;commit-queue@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         Unreviewed, rolling out r170995.
</span></span></pre></div>
<a id="trunkSourceWTFwtfPlatformh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/Platform.h (171004 => 171005)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/Platform.h        2014-07-11 17:32:17 UTC (rev 171004)
+++ trunk/Source/WTF/wtf/Platform.h        2014-07-11 18:53:19 UTC (rev 171005)
</span><span class="lines">@@ -695,9 +695,9 @@
</span><span class="cx"> #define ENABLE_DISASSEMBLER 1
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-#if !defined(ENABLE_DFG_JIT) &amp;&amp; ENABLE(JIT) &amp;&amp; !COMPILER(MSVC)
-/* Enable the DFG JIT on X86 and X86_64.  Only tested on Mac, GNU/Linux and FreeBSD. */
-#if (CPU(X86) || CPU(X86_64)) &amp;&amp; (OS(DARWIN) || OS(LINUX) || OS(FREEBSD))
</del><ins>+#if !defined(ENABLE_DFG_JIT) &amp;&amp; ENABLE(JIT)
+/* Enable the DFG JIT on X86 and X86_64. */
+#if (CPU(X86) || CPU(X86_64)) &amp;&amp; (OS(DARWIN) || OS(LINUX) || OS(FREEBSD) || OS(WINDOWS))
</ins><span class="cx"> #define ENABLE_DFG_JIT 1
</span><span class="cx"> #endif
</span><span class="cx"> /* Enable the DFG JIT on ARMv7.  Only tested on iOS and Qt/GTK+ Linux. */
</span></span></pre>
</div>
</div>

</body>
</html>