<!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>[162242] branches/jsCStack/Source/JavaScriptCore</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/162242">162242</a></dd>
<dt>Author</dt> <dd>msaboff@apple.com</dd>
<dt>Date</dt> <dd>2014-01-17 21:10:15 -0800 (Fri, 17 Jan 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>CStack Branch: Fix Baseline JIT for X86-32
https://bugs.webkit.org/show_bug.cgi?id=127201

Reviewed by Geoffrey Garen.

Most of the changes are to follow calling convention (emiting function prologues and
epilogues) and making room on the stack for outgoing arguments.

* interpreter/Interpreter.cpp:
(JSC::Interpreter::unwind):
* jit/JIT.cpp:
(JSC::JIT::privateCompile): Eliminated stack alignment check before moving the stack
pointer down for locals since it will not be aligned at that time.  The move will align
the stack pointer.
(JSC::JIT::frameRegisterCountFor): Changed to allocate the outgoing register space
after rounding the number of local registers as the outgoing register count will
properly align the local registers.
* jit/JITCall32_64.cpp:
(JSC::JIT::emit_op_ret): Changed to emit epilogue.
(JSC::JIT::emit_op_ret_object_or_this): Changed to emit epilogue.
(JSC::JIT::compileLoadVarargs): Alignment changes matching what is in
JITCall.cpp::JIT::compileLoadVarargs.
(JSC::JIT::compileCallEvalSlowCase): Changed to use the stack pointer to fill-in the
new callee frame.
(JSC::JIT::compileOpCall): Changed to use the stack pointer to fill-in the
new callee frame.
(JSC::JIT::compileOpCallSlowCase): Code to restore the stack pointer after the call.
* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_ret_object_or_this): Remove dead code in 64 bit path found while 
working on this patch.
* jit/JITOpcodes32_64.cpp:
(JSC::JIT::privateCompileCTINativeCall): Changes to follow native calling convention,
allocate space and populate outgoing args and pass the caller to operationVMHandleException.
(JSC::JIT::emit_op_end): Emit the epilogue.
* jit/ThunkGenerators.cpp:
(JSC::slowPathFor): Allocate stack space for arguments.
(JSC::arityFixup): Changes to match 64 bit code.
* runtime/CommonSlowPaths.cpp:
(JSC::SLOW_PATH_DECL): Whitespace cleanup.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#branchesjsCStackSourceJavaScriptCoreChangeLog">branches/jsCStack/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoreinterpreterInterpretercpp">branches/jsCStack/Source/JavaScriptCore/interpreter/Interpreter.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCorejitJITcpp">branches/jsCStack/Source/JavaScriptCore/jit/JIT.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCorejitJITCall32_64cpp">branches/jsCStack/Source/JavaScriptCore/jit/JITCall32_64.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCorejitJITOpcodescpp">branches/jsCStack/Source/JavaScriptCore/jit/JITOpcodes.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCorejitJITOpcodes32_64cpp">branches/jsCStack/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCorejitThunkGeneratorscpp">branches/jsCStack/Source/JavaScriptCore/jit/ThunkGenerators.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoreruntimeCommonSlowPathscpp">branches/jsCStack/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="branchesjsCStackSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/ChangeLog (162241 => 162242)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/ChangeLog        2014-01-18 05:06:32 UTC (rev 162241)
+++ branches/jsCStack/Source/JavaScriptCore/ChangeLog        2014-01-18 05:10:15 UTC (rev 162242)
</span><span class="lines">@@ -1,5 +1,47 @@
</span><span class="cx"> 2014-01-17  Michael Saboff  &lt;msaboff@apple.com&gt;
</span><span class="cx"> 
</span><ins>+        CStack Branch: Fix Baseline JIT for X86-32
+        https://bugs.webkit.org/show_bug.cgi?id=127201
+
+        Reviewed by Geoffrey Garen.
+
+        Most of the changes are to follow calling convention (emiting function prologues and
+        epilogues) and making room on the stack for outgoing arguments.
+
+        * interpreter/Interpreter.cpp:
+        (JSC::Interpreter::unwind):
+        * jit/JIT.cpp:
+        (JSC::JIT::privateCompile): Eliminated stack alignment check before moving the stack
+        pointer down for locals since it will not be aligned at that time.  The move will align
+        the stack pointer.
+        (JSC::JIT::frameRegisterCountFor): Changed to allocate the outgoing register space
+        after rounding the number of local registers as the outgoing register count will
+        properly align the local registers.
+        * jit/JITCall32_64.cpp:
+        (JSC::JIT::emit_op_ret): Changed to emit epilogue.
+        (JSC::JIT::emit_op_ret_object_or_this): Changed to emit epilogue.
+        (JSC::JIT::compileLoadVarargs): Alignment changes matching what is in
+        JITCall.cpp::JIT::compileLoadVarargs.
+        (JSC::JIT::compileCallEvalSlowCase): Changed to use the stack pointer to fill-in the
+        new callee frame.
+        (JSC::JIT::compileOpCall): Changed to use the stack pointer to fill-in the
+        new callee frame.
+        (JSC::JIT::compileOpCallSlowCase): Code to restore the stack pointer after the call.
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_ret_object_or_this): Remove dead code in 64 bit path found while 
+        working on this patch.
+        * jit/JITOpcodes32_64.cpp:
+        (JSC::JIT::privateCompileCTINativeCall): Changes to follow native calling convention,
+        allocate space and populate outgoing args and pass the caller to operationVMHandleException.
+        (JSC::JIT::emit_op_end): Emit the epilogue.
+        * jit/ThunkGenerators.cpp:
+        (JSC::slowPathFor): Allocate stack space for arguments.
+        (JSC::arityFixup): Changes to match 64 bit code.
+        * runtime/CommonSlowPaths.cpp:
+        (JSC::SLOW_PATH_DECL): Whitespace cleanup.
+
+2014-01-17  Michael Saboff  &lt;msaboff@apple.com&gt;
+
</ins><span class="cx">         CStack Branch: X86-32 Fix LLInt
</span><span class="cx">         https://bugs.webkit.org/show_bug.cgi?id=127071
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoreinterpreterInterpretercpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/interpreter/Interpreter.cpp (162241 => 162242)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/interpreter/Interpreter.cpp        2014-01-18 05:06:32 UTC (rev 162241)
+++ branches/jsCStack/Source/JavaScriptCore/interpreter/Interpreter.cpp        2014-01-18 05:10:15 UTC (rev 162242)
</span><span class="lines">@@ -659,6 +659,7 @@
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     CodeBlock* codeBlock = callFrame-&gt;codeBlock();
</span><ins>+    ASSERT(codeBlock);
</ins><span class="cx">     bool isTermination = false;
</span><span class="cx"> 
</span><span class="cx">     ASSERT(!exceptionValue.isEmpty());
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCorejitJITcpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/jit/JIT.cpp (162241 => 162242)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/jit/JIT.cpp        2014-01-18 05:06:32 UTC (rev 162241)
+++ branches/jsCStack/Source/JavaScriptCore/jit/JIT.cpp        2014-01-18 05:10:15 UTC (rev 162242)
</span><span class="lines">@@ -537,7 +537,6 @@
</span><span class="cx">         stackOverflow = branchPtr(Above, AbsoluteAddress(m_vm-&gt;addressOfJSStackLimit()), regT1);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    checkStackPointerAlignment();
</del><span class="cx">     addPtr(TrustedImm32(stackPointerOffsetFor(m_codeBlock) * sizeof(Register)), callFrameRegister, stackPointerRegister);
</span><span class="cx">     checkStackPointerAlignment();
</span><span class="cx"> 
</span><span class="lines">@@ -552,6 +551,8 @@
</span><span class="cx">     if (m_codeBlock-&gt;codeType() == FunctionCode) {
</span><span class="cx">         stackOverflow.link(this);
</span><span class="cx">         m_bytecodeOffset = 0;
</span><ins>+        if (maxFrameExtentForSlowPathCall)
+            addPtr(TrustedImm32(-maxFrameExtentForSlowPathCall), stackPointerRegister);
</ins><span class="cx">         callOperationWithCallFrameRollbackOnException(operationThrowStackOverflowError, m_codeBlock);
</span><span class="cx"> 
</span><span class="cx">         arityCheck = label();
</span><span class="lines">@@ -728,9 +729,9 @@
</span><span class="cx"> 
</span><span class="cx"> unsigned JIT::frameRegisterCountFor(CodeBlock* codeBlock)
</span><span class="cx"> {
</span><del>-    size_t registerCount = codeBlock-&gt;m_numCalleeRegisters + maxFrameExtentForSlowPathCallInRegisters;
-    ASSERT(registerCount == WTF::roundUpToMultipleOf(stackAlignmentRegisters(), registerCount));
-    return registerCount;
</del><ins>+    ASSERT(static_cast&lt;unsigned&gt;(codeBlock-&gt;m_numCalleeRegisters) == WTF::roundUpToMultipleOf(stackAlignmentRegisters(), static_cast&lt;unsigned&gt;(codeBlock-&gt;m_numCalleeRegisters)));
+
+    return roundLocalRegisterCountForFramePointerOffset(codeBlock-&gt;m_numCalleeRegisters + maxFrameExtentForSlowPathCallInRegisters);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> int JIT::stackPointerOffsetFor(CodeBlock* codeBlock)
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCorejitJITCall32_64cpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/jit/JITCall32_64.cpp (162241 => 162242)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/jit/JITCall32_64.cpp        2014-01-18 05:06:32 UTC (rev 162241)
+++ branches/jsCStack/Source/JavaScriptCore/jit/JITCall32_64.cpp        2014-01-18 05:10:15 UTC (rev 162242)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2008, 2013 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2008, 2013, 2014 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -39,6 +39,7 @@
</span><span class="cx"> #include &quot;RepatchBuffer.h&quot;
</span><span class="cx"> #include &quot;ResultType.h&quot;
</span><span class="cx"> #include &quot;SamplingTool.h&quot;
</span><ins>+#include &quot;StackAlignment.h&quot;
</ins><span class="cx"> #include &lt;wtf/StringPrintStream.h&gt;
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -56,10 +57,9 @@
</span><span class="cx">     unsigned dst = currentInstruction[1].u.operand;
</span><span class="cx"> 
</span><span class="cx">     emitLoad(dst, regT1, regT0);
</span><del>-    emitGetReturnPCFromCallFrameHeaderPtr(regT2);
-    emitGetCallerFrameFromCallFrameHeaderPtr(callFrameRegister);
</del><span class="cx"> 
</span><del>-    restoreReturnAddressBeforeReturn(regT2);
</del><ins>+    checkStackPointerAlignment();
+    emitFunctionEpilogue();
</ins><span class="cx">     ret();
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -73,20 +73,16 @@
</span><span class="cx">     loadPtr(Address(regT0, JSCell::structureOffset()), regT2);
</span><span class="cx">     Jump notObject = emitJumpIfNotObject(regT2);
</span><span class="cx"> 
</span><del>-    emitGetReturnPCFromCallFrameHeaderPtr(regT2);
-    emitGetCallerFrameFromCallFrameHeaderPtr(callFrameRegister);
-
-    restoreReturnAddressBeforeReturn(regT2);
</del><ins>+    checkStackPointerAlignment();
+    emitFunctionEpilogue();
</ins><span class="cx">     ret();
</span><span class="cx"> 
</span><span class="cx">     notJSCell.link(this);
</span><span class="cx">     notObject.link(this);
</span><span class="cx">     emitLoad(thisReg, regT1, regT0);
</span><span class="cx"> 
</span><del>-    emitGetReturnPCFromCallFrameHeaderPtr(regT2);
-    emitGetCallerFrameFromCallFrameHeaderPtr(callFrameRegister);
-
-    restoreReturnAddressBeforeReturn(regT2);
</del><ins>+    checkStackPointerAlignment();
+    emitFunctionEpilogue();
</ins><span class="cx">     ret();
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -151,8 +147,12 @@
</span><span class="cx">         // regT2: argumentCountIncludingThis
</span><span class="cx"> 
</span><span class="cx">         move(regT2, regT3);
</span><ins>+        addPtr(TrustedImm32(-firstFreeRegister + JSStack::CallFrameHeaderSize), regT3);
+        // regT1 now has the required frame size in Register units
+        // Round regT1 to next multiple of stackAlignmentRegisters()
+        addPtr(TrustedImm32(stackAlignmentRegisters() - 1), regT3);
+        andPtr(TrustedImm32(~(stackAlignmentRegisters() - 1)), regT3);
</ins><span class="cx">         neg32(regT3);
</span><del>-        add32(TrustedImm32(firstFreeRegister - JSStack::CallFrameHeaderSize), regT3);
</del><span class="cx">         lshift32(TrustedImm32(3), regT3);
</span><span class="cx">         addPtr(callFrameRegister, regT3);
</span><span class="cx">         // regT3: newCallFrame
</span><span class="lines">@@ -186,14 +186,16 @@
</span><span class="cx"> 
</span><span class="cx">     emitLoad(arguments, regT1, regT0);
</span><span class="cx">     callOperation(operationSizeFrameForVarargs, regT1, regT0, firstFreeRegister);
</span><del>-    move(returnValueGPR, regT5);
-    emitLoad(thisValue, regT1, regT0);
</del><ins>+    move(returnValueGPR, stackPointerRegister);
+    emitLoad(thisValue, regT1, regT4);
</ins><span class="cx">     emitLoad(arguments, regT3, regT2);
</span><del>-    callOperation(operationLoadVarargs, regT5, regT1, regT0, regT3, regT2);
</del><ins>+    callOperation(operationLoadVarargs, returnValueGPR, regT1, regT4, regT3, regT2);
</ins><span class="cx">     move(returnValueGPR, regT3);
</span><span class="cx"> 
</span><span class="cx">     if (canOptimize)
</span><span class="cx">         end.link(this);
</span><ins>+
+    addPtr(TrustedImm32(sizeof(CallerFrameAndPC)), regT3, stackPointerRegister);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void JIT::compileCallEval(Instruction* instruction)
</span><span class="lines">@@ -221,8 +223,13 @@
</span><span class="cx"> {
</span><span class="cx">     linkSlowCase(iter);
</span><span class="cx"> 
</span><ins>+    loadPtr(Address(stackPointerRegister, sizeof(Register) * JSStack::Callee - sizeof(CallerFrameAndPC)), regT0);
+    loadPtr(Address(stackPointerRegister, sizeof(Register) * JSStack::Callee - sizeof(CallerFrameAndPC)), regT1);
+
</ins><span class="cx">     emitLoad(JSStack::Callee, regT1, regT0);
</span><span class="cx">     emitNakedCall(m_vm-&gt;getCTIStub(virtualCallThunkGenerator).code());
</span><ins>+    addPtr(TrustedImm32(stackPointerOffsetFor(m_codeBlock) * sizeof(Register)), callFrameRegister, stackPointerRegister);
+    checkStackPointerAlignment();
</ins><span class="cx"> 
</span><span class="cx">     sampleCodeBlock(m_codeBlock);
</span><span class="cx">     
</span><span class="lines">@@ -261,18 +268,17 @@
</span><span class="cx">             done.link(this);
</span><span class="cx">         }
</span><span class="cx">     
</span><del>-        addPtr(TrustedImm32(registerOffset * sizeof(Register)), callFrameRegister, regT3);
</del><ins>+        addPtr(TrustedImm32(registerOffset * sizeof(Register) + sizeof(CallerFrameAndPC)), callFrameRegister, stackPointerRegister);
</ins><span class="cx"> 
</span><del>-        store32(TrustedImm32(argCount), payloadFor(JSStack::ArgumentCount, regT3));
-    } // regT3 holds newCallFrame with ArgumentCount initialized.
</del><ins>+        store32(TrustedImm32(argCount), Address(stackPointerRegister, JSStack::ArgumentCount * static_cast&lt;int&gt;(sizeof(Register)) + PayloadOffset - sizeof(CallerFrameAndPC)));
+    } // SP holds newCallFrame + sizeof(CallerFrameAndPC), with ArgumentCount initialized.
</ins><span class="cx">     
</span><span class="cx">     uint32_t locationBits = CallFrame::Location::encodeAsBytecodeInstruction(instruction);
</span><span class="cx">     store32(TrustedImm32(locationBits), tagFor(JSStack::ArgumentCount, callFrameRegister));
</span><span class="cx">     emitLoad(callee, regT1, regT0); // regT1, regT0 holds callee.
</span><span class="cx"> 
</span><del>-    storePtr(callFrameRegister, Address(regT3, CallFrame::callerFrameOffset()));
-    emitStore(JSStack::Callee, regT1, regT0, regT3);
-    move(regT3, callFrameRegister);
</del><ins>+    store32(regT0, Address(stackPointerRegister, JSStack::Callee * static_cast&lt;int&gt;(sizeof(Register)) + PayloadOffset - sizeof(CallerFrameAndPC)));
+    store32(regT1, Address(stackPointerRegister, JSStack::Callee * static_cast&lt;int&gt;(sizeof(Register)) + TagOffset - sizeof(CallerFrameAndPC)));
</ins><span class="cx"> 
</span><span class="cx">     if (opcodeID == op_call_eval) {
</span><span class="cx">         compileCallEval(instruction);
</span><span class="lines">@@ -291,10 +297,15 @@
</span><span class="cx">     m_callStructureStubCompilationInfo[callLinkInfoIndex].callType = CallLinkInfo::callTypeFor(opcodeID);
</span><span class="cx">     m_callStructureStubCompilationInfo[callLinkInfoIndex].bytecodeIndex = m_bytecodeOffset;
</span><span class="cx"> 
</span><del>-    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_scope)), regT1);
-    emitPutCellToCallFrameHeader(regT1, JSStack::ScopeChain);
</del><ins>+    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_scope)), regT2);
+    store32(regT2, Address(MacroAssembler::stackPointerRegister, JSStack::ScopeChain * sizeof(Register) + PayloadOffset - sizeof(CallerFrameAndPC)));
+    store32(TrustedImm32(JSValue::CellTag), Address(stackPointerRegister, JSStack::ScopeChain * sizeof(Register) + TagOffset - sizeof(CallerFrameAndPC)));
+
</ins><span class="cx">     m_callStructureStubCompilationInfo[callLinkInfoIndex].hotPathOther = emitNakedCall();
</span><span class="cx"> 
</span><ins>+    addPtr(TrustedImm32(stackPointerOffsetFor(m_codeBlock) * sizeof(Register)), callFrameRegister, stackPointerRegister);
+    checkStackPointerAlignment();
+
</ins><span class="cx">     sampleCodeBlock(m_codeBlock);
</span><span class="cx">     emitPutCallResult(instruction);
</span><span class="cx"> }
</span><span class="lines">@@ -315,6 +326,9 @@
</span><span class="cx">     
</span><span class="cx">     m_callStructureStubCompilationInfo[callLinkInfoIndex].callReturnLocation = emitNakedCall(m_vm-&gt;getCTIStub(generator).code());
</span><span class="cx"> 
</span><ins>+    addPtr(TrustedImm32(stackPointerOffsetFor(m_codeBlock) * sizeof(Register)), callFrameRegister, stackPointerRegister);
+    checkStackPointerAlignment();
+
</ins><span class="cx">     sampleCodeBlock(m_codeBlock);
</span><span class="cx">     emitPutCallResult(instruction);
</span><span class="cx"> }
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCorejitJITOpcodescpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/jit/JITOpcodes.cpp (162241 => 162242)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/jit/JITOpcodes.cpp        2014-01-18 05:06:32 UTC (rev 162241)
+++ branches/jsCStack/Source/JavaScriptCore/jit/JITOpcodes.cpp        2014-01-18 05:10:15 UTC (rev 162242)
</span><span class="lines">@@ -280,9 +280,6 @@
</span><span class="cx">     loadPtr(Address(returnValueGPR, JSCell::structureOffset()), regT2);
</span><span class="cx">     Jump notObject = emitJumpIfNotObject(regT2);
</span><span class="cx"> 
</span><del>-    // Grab the return address.
-    emitGetReturnPCFromCallFrameHeaderPtr(regT1);
-
</del><span class="cx">     // Return.
</span><span class="cx">     emitFunctionEpilogue();
</span><span class="cx">     ret();
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCorejitJITOpcodes32_64cpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp (162241 => 162242)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp        2014-01-18 05:06:32 UTC (rev 162241)
+++ branches/jsCStack/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp        2014-01-18 05:10:15 UTC (rev 162242)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2009, 2012, 2013 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2009, 2012, 2013, 2014 Apple Inc. All rights reserved.
</ins><span class="cx">  * Copyright (C) 2010 Patrick Gansterer &lt;paroga@paroga.com&gt;
</span><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="lines">@@ -49,6 +49,7 @@
</span><span class="cx"> {
</span><span class="cx">     Call nativeCall;
</span><span class="cx"> 
</span><ins>+    emitFunctionPrologue();
</ins><span class="cx">     emitPutImmediateToCallFrameHeader(0, JSStack::CodeBlock);
</span><span class="cx">     storePtr(callFrameRegister, &amp;m_vm-&gt;topCallFrame);
</span><span class="cx"> 
</span><span class="lines">@@ -59,21 +60,17 @@
</span><span class="cx">     emitGetFromCallFrameHeaderPtr(JSStack::ScopeChain, regT1, regT0);
</span><span class="cx">     emitPutCellToCallFrameHeader(regT1, JSStack::ScopeChain);
</span><span class="cx"> 
</span><del>-    peek(regT1);
-    emitPutReturnPCToCallFrameHeader(regT1);
-
</del><span class="cx">     // Calling convention:      f(ecx, edx, ...);
</span><span class="cx">     // Host function signature: f(ExecState*);
</span><span class="cx">     move(callFrameRegister, X86Registers::ecx);
</span><span class="cx"> 
</span><del>-    subPtr(TrustedImm32(16 - sizeof(void*)), stackPointerRegister); // Align stack after call.
</del><ins>+    subPtr(TrustedImm32(8), stackPointerRegister); // Align stack for call.
+    storePtr(X86Registers::ecx, Address(stackPointerRegister));
</ins><span class="cx"> 
</span><del>-    move(regT0, callFrameRegister); // Eagerly restore caller frame register to avoid loading from stack.
-
</del><span class="cx">     // call the function
</span><span class="cx">     nativeCall = call();
</span><span class="cx"> 
</span><del>-    addPtr(TrustedImm32(16 - sizeof(void*)), stackPointerRegister);
</del><ins>+    addPtr(TrustedImm32(8), stackPointerRegister);
</ins><span class="cx"> 
</span><span class="cx"> #elif CPU(ARM) || CPU(SH4) || CPU(MIPS)
</span><span class="cx">     // Load caller frame's scope chain into this callframe so that whatever we call can get to its global data.
</span><span class="lines">@@ -81,9 +78,6 @@
</span><span class="cx">     emitGetFromCallFrameHeaderPtr(JSStack::ScopeChain, regT1, regT2);
</span><span class="cx">     emitPutCellToCallFrameHeader(regT1, JSStack::ScopeChain);
</span><span class="cx"> 
</span><del>-    preserveReturnAddressAfterCall(regT3); // Callee preserved
-    emitPutReturnPCToCallFrameHeader(regT3);
-
</del><span class="cx"> #if CPU(MIPS)
</span><span class="cx">     // Allocate stack space for (unused) 16 bytes (8-byte aligned) for 4 arguments.
</span><span class="cx">     subPtr(TrustedImm32(16), stackPointerRegister);
</span><span class="lines">@@ -94,7 +88,6 @@
</span><span class="cx">     move(callFrameRegister, argumentGPR0);
</span><span class="cx"> 
</span><span class="cx">     emitGetFromCallFrameHeaderPtr(JSStack::Callee, argumentGPR1);
</span><del>-    move(regT2, callFrameRegister); // Eagerly restore caller frame register to avoid loading from stack.
</del><span class="cx">     loadPtr(Address(argumentGPR1, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2);
</span><span class="cx"> 
</span><span class="cx">     // call the function
</span><span class="lines">@@ -114,6 +107,7 @@
</span><span class="cx">     // Check for an exception
</span><span class="cx">     Jump sawException = branch32(NotEqual, AbsoluteAddress(reinterpret_cast&lt;char*&gt;(vm-&gt;addressOfException()) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), TrustedImm32(JSValue::EmptyValueTag)); 
</span><span class="cx"> 
</span><ins>+    emitFunctionEpilogue();
</ins><span class="cx">     // Return.
</span><span class="cx">     ret();
</span><span class="cx"> 
</span><span class="lines">@@ -123,16 +117,17 @@
</span><span class="cx">     storePtr(callFrameRegister, &amp;m_vm-&gt;topCallFrame);
</span><span class="cx"> 
</span><span class="cx"> #if CPU(X86)
</span><del>-    addPtr(TrustedImm32(-12), stackPointerRegister);
-    push(callFrameRegister);
</del><ins>+    addPtr(TrustedImm32(-4), stackPointerRegister);
+    loadPtr(Address(callFrameRegister), X86Registers::ecx);
+    push(X86Registers::ecx);
</ins><span class="cx"> #else
</span><del>-    move(callFrameRegister, argumentGPR0);
</del><ins>+    loadPtr(Address(callFrameRegister), argumentGPR0);
</ins><span class="cx"> #endif
</span><span class="cx">     move(TrustedImmPtr(FunctionPtr(operationVMHandleException).value()), regT3);
</span><span class="cx">     call(regT3);
</span><span class="cx"> 
</span><span class="cx"> #if CPU(X86)
</span><del>-    addPtr(TrustedImm32(16), stackPointerRegister);
</del><ins>+    addPtr(TrustedImm32(8), stackPointerRegister);
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">     jumpToExceptionHandler();
</span><span class="lines">@@ -171,7 +166,7 @@
</span><span class="cx"> {
</span><span class="cx">     ASSERT(returnValueGPR != callFrameRegister);
</span><span class="cx">     emitLoad(currentInstruction[1].u.operand, regT1, regT0);
</span><del>-    restoreReturnAddressBeforeReturn(Address(callFrameRegister, CallFrame::returnPCOffset()));
</del><ins>+    emitFunctionEpilogue();
</ins><span class="cx">     ret();
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCorejitThunkGeneratorscpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/jit/ThunkGenerators.cpp (162241 => 162242)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/jit/ThunkGenerators.cpp        2014-01-18 05:06:32 UTC (rev 162241)
+++ branches/jsCStack/Source/JavaScriptCore/jit/ThunkGenerators.cpp        2014-01-18 05:10:15 UTC (rev 162242)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2010, 2012, 2013 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2010, 2012, 2013, 2014 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -31,6 +31,7 @@
</span><span class="cx"> #include &quot;JSArray.h&quot;
</span><span class="cx"> #include &quot;JSArrayIterator.h&quot;
</span><span class="cx"> #include &quot;JSStack.h&quot;
</span><ins>+#include &quot;MaxFrameExtentForSlowPathCall.h&quot;
</ins><span class="cx"> #include &quot;Operations.h&quot;
</span><span class="cx"> #include &quot;SpecializedThunkJIT.h&quot;
</span><span class="cx"> #include &lt;wtf/InlineASM.h&gt;
</span><span class="lines">@@ -81,10 +82,14 @@
</span><span class="cx"> {
</span><span class="cx">     jit.emitFunctionPrologue();
</span><span class="cx">     jit.storePtr(GPRInfo::callFrameRegister, &amp;vm-&gt;topCallFrame);
</span><ins>+    if (maxFrameExtentForSlowPathCall)
+        jit.addPtr(CCallHelpers::TrustedImm32(-maxFrameExtentForSlowPathCall), CCallHelpers::stackPointerRegister);
</ins><span class="cx">     jit.setupArgumentsExecState();
</span><span class="cx">     jit.move(CCallHelpers::TrustedImmPtr(bitwise_cast&lt;void*&gt;(slowPathFunction)), GPRInfo::nonArgGPR0);
</span><span class="cx">     emitPointerValidation(jit, GPRInfo::nonArgGPR0);
</span><span class="cx">     jit.call(GPRInfo::nonArgGPR0);
</span><ins>+    if (maxFrameExtentForSlowPathCall)
+        jit.addPtr(CCallHelpers::TrustedImm32(maxFrameExtentForSlowPathCall), CCallHelpers::stackPointerRegister);
</ins><span class="cx">     
</span><span class="cx">     // This slow call will return the address of one of the following:
</span><span class="cx">     // 1) Exception throwing thunk.
</span><span class="lines">@@ -471,9 +476,10 @@
</span><span class="cx"> #  if CPU(X86)
</span><span class="cx">     jit.pop(JSInterfaceJIT::regT4);
</span><span class="cx"> #  endif
</span><ins>+    jit.lshift32(JSInterfaceJIT::TrustedImm32(logStackAlignmentRegisters()), JSInterfaceJIT::regT0);
</ins><span class="cx">     jit.neg32(JSInterfaceJIT::regT0);
</span><span class="cx">     jit.move(JSInterfaceJIT::callFrameRegister, JSInterfaceJIT::regT3);
</span><del>-    jit.load32(JSInterfaceJIT::Address(JSInterfaceJIT::callFrameRegister, JSStack::ArgumentCount * 8), JSInterfaceJIT::regT2);
</del><ins>+    jit.load32(JSInterfaceJIT::Address(JSInterfaceJIT::callFrameRegister, JSStack::ArgumentCount * sizeof(Register)), JSInterfaceJIT::regT2);
</ins><span class="cx">     jit.add32(JSInterfaceJIT::TrustedImm32(JSStack::CallFrameHeaderSize), JSInterfaceJIT::regT2);
</span><span class="cx"> 
</span><span class="cx">     // Move current frame down regT0 number of slots
</span><span class="lines">@@ -485,8 +491,9 @@
</span><span class="cx">     jit.addPtr(JSInterfaceJIT::TrustedImm32(8), JSInterfaceJIT::regT3);
</span><span class="cx">     jit.branchSub32(MacroAssembler::NonZero, JSInterfaceJIT::TrustedImm32(1), JSInterfaceJIT::regT2).linkTo(copyLoop, &amp;jit);
</span><span class="cx"> 
</span><del>-    // Fill in regT0 missing arg slots with undefined
</del><ins>+    // Fill in regT0 - 1 missing arg slots with undefined
</ins><span class="cx">     jit.move(JSInterfaceJIT::regT0, JSInterfaceJIT::regT2);
</span><ins>+    jit.add32(JSInterfaceJIT::TrustedImm32(1), JSInterfaceJIT::regT2);
</ins><span class="cx">     JSInterfaceJIT::Label fillUndefinedLoop(jit.label());
</span><span class="cx">     jit.move(JSInterfaceJIT::TrustedImm32(0), JSInterfaceJIT::regT1);
</span><span class="cx">     jit.store32(JSInterfaceJIT::regT1, MacroAssembler::BaseIndex(JSInterfaceJIT::regT3, JSInterfaceJIT::regT0, JSInterfaceJIT::TimesEight));
</span><span class="lines">@@ -496,10 +503,25 @@
</span><span class="cx">     jit.addPtr(JSInterfaceJIT::TrustedImm32(8), JSInterfaceJIT::regT3);
</span><span class="cx">     jit.branchAdd32(MacroAssembler::NonZero, JSInterfaceJIT::TrustedImm32(1), JSInterfaceJIT::regT2).linkTo(fillUndefinedLoop, &amp;jit);
</span><span class="cx"> 
</span><del>-    // Adjust call frame register to account for missing args
-    jit.lshift32(JSInterfaceJIT::TrustedImm32(3), JSInterfaceJIT::regT0);
-    jit.addPtr(JSInterfaceJIT::regT0, JSInterfaceJIT::callFrameRegister);
</del><ins>+    // Adjust call frame register and stack pointer to account for missing args
+    jit.move(JSInterfaceJIT::regT0, JSInterfaceJIT::regT1);
+    jit.lshift32(JSInterfaceJIT::TrustedImm32(3), JSInterfaceJIT::regT1);
+    jit.addPtr(JSInterfaceJIT::regT1, JSInterfaceJIT::callFrameRegister);
+    jit.addPtr(JSInterfaceJIT::regT1, JSInterfaceJIT::stackPointerRegister);
</ins><span class="cx"> 
</span><ins>+    // Save the original return PC.
+    jit.loadPtr(JSInterfaceJIT::Address(JSInterfaceJIT::callFrameRegister, CallFrame::returnPCOffset()), GPRInfo::regT1);
+    jit.storePtr(GPRInfo::regT1, MacroAssembler::BaseIndex(JSInterfaceJIT::regT3, JSInterfaceJIT::regT0, JSInterfaceJIT::TimesEight));
+    
+    // Install the new return PC.
+    // FIXME: I don't think currentReturnThunkPC is used and should be deleted.
+#  if 0
+    jit.loadPtr(&amp;vm-&gt;currentReturnThunkPC, GPRInfo::regT2);
+    jit.storePtr(GPRInfo::regT2, JSInterfaceJIT::Address(JSInterfaceJIT::callFrameRegister, CallFrame::returnPCOffset()));
+#   else
+    jit.storePtr(GPRInfo::regT5, JSInterfaceJIT::Address(JSInterfaceJIT::callFrameRegister, CallFrame::returnPCOffset()));
+#   endif
+    
</ins><span class="cx"> #  if CPU(X86)
</span><span class="cx">     jit.push(JSInterfaceJIT::regT4);
</span><span class="cx"> #  endif
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoreruntimeCommonSlowPathscpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp (162241 => 162242)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp        2014-01-18 05:06:32 UTC (rev 162241)
+++ branches/jsCStack/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp        2014-01-18 05:10:15 UTC (rev 162242)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2011, 2012, 2013, 2014 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -361,7 +361,6 @@
</span><span class="cx"> SLOW_PATH_DECL(slow_path_add)
</span><span class="cx"> {
</span><span class="cx">     BEGIN();
</span><del>-    
</del><span class="cx">     JSValue v1 = OP_C(2).jsValue();
</span><span class="cx">     JSValue v2 = OP_C(3).jsValue();
</span><span class="cx">     
</span></span></pre>
</div>
</div>

</body>
</html>