<!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>[160094] trunk/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/160094">160094</a></dd>
<dt>Author</dt> <dd>msaboff@apple.com</dd>
<dt>Date</dt> <dd>2013-12-04 08:40:17 -0800 (Wed, 04 Dec 2013)</dd>
</dl>
<h3>Log Message</h3>
<pre>Move the setting up of callee's callFrame from pushFrame to callToJavaScript thunk
https://bugs.webkit.org/show_bug.cgi?id=123999
Reviewed by Filip Pizlo.
Changed LLInt and/or JIT enabled ports to allocate the stack frame in the
callToJavaScript stub. Added an additional stub, callToNativeFunction that
allocates a stack frame in a similar way for calling native entry points
that take a single ExecState* argument. These stubs are implemented
using common macros in LowLevelInterpreter{32_64,64}.asm. There are also
Windows X86 and X86-64 versions in the corresponding JitStubsXX.h.
The stubs allocate and create a sentinel frame, then create the callee's
frame, populating the header and arguments from the passed in ProtoCallFrame*.
It is assumed that the caller of either stub does a check for enough stack space
via JSStack::entryCheck().
For ports using the C-Loop interpreter, the prior method for allocating stack
frame and invoking functions is used, namely with JSStack::pushFrame() and
::popFrame().
Made spelling changes "sentinal" -> "sentinel".
* CMakeLists.txt:
* GNUmakefile.list.am:
* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
* JavaScriptCore.xcodeproj/project.pbxproj:
* interpreter/CachedCall.h:
(JSC::CachedCall::CachedCall):
(JSC::CachedCall::setThis):
(JSC::CachedCall::setArgument):
* interpreter/CallFrameClosure.h:
(JSC::CallFrameClosure::resetCallFrame):
* interpreter/Interpreter.cpp:
(JSC::Interpreter::execute):
(JSC::Interpreter::executeCall):
(JSC::Interpreter::executeConstruct):
(JSC::Interpreter::prepareForRepeatCall):
* interpreter/Interpreter.h:
* interpreter/JSStack.h:
* interpreter/JSStackInlines.h:
(JSC::JSStack::entryCheck):
(JSC::JSStack::pushFrame):
(JSC::JSStack::popFrame):
* interpreter/ProtoCallFrame.cpp: Added.
(JSC::ProtoCallFrame::init):
* interpreter/ProtoCallFrame.h: Added.
(JSC::ProtoCallFrame::codeBlock):
(JSC::ProtoCallFrame::setCodeBlock):
(JSC::ProtoCallFrame::setScope):
(JSC::ProtoCallFrame::setCallee):
(JSC::ProtoCallFrame::argumentCountIncludingThis):
(JSC::ProtoCallFrame::argumentCount):
(JSC::ProtoCallFrame::setArgumentCountIncludingThis):
(JSC::ProtoCallFrame::setPaddedArgsCount):
(JSC::ProtoCallFrame::clearCurrentVPC):
(JSC::ProtoCallFrame::setThisValue):
(JSC::ProtoCallFrame::setArgument):
* jit/JITCode.cpp:
(JSC::JITCode::execute):
* jit/JITCode.h:
* jit/JITOperations.cpp:
* jit/JITStubs.h:
* jit/JITStubsMSVC64.asm:
* jit/JITStubsX86.h:
* llint/LLIntOffsetsExtractor.cpp:
* llint/LLIntThunks.h:
* llint/LowLevelInterpreter.asm:
* llint/LowLevelInterpreter32_64.asm:
* llint/LowLevelInterpreter64.asm:
* runtime/ArgList.h:
(JSC::ArgList::data):
* runtime/JSArray.cpp:
(JSC::AVLTreeAbstractorForArrayCompare::compare_key_key):
* runtime/StringPrototype.cpp:
(JSC::replaceUsingRegExpSearch):</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreCMakeListstxt">trunk/Source/JavaScriptCore/CMakeLists.txt</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreGNUmakefilelistam">trunk/Source/JavaScriptCore/GNUmakefile.list.am</a></li>
<li><a href="#trunkSourceJavaScriptCoreJavaScriptCorevcxprojJavaScriptCorevcxproj">trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj</a></li>
<li><a href="#trunkSourceJavaScriptCoreJavaScriptCorevcxprojJavaScriptCorevcxprojfilters">trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters</a></li>
<li><a href="#trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj">trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceJavaScriptCoreinterpreterCachedCallh">trunk/Source/JavaScriptCore/interpreter/CachedCall.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreinterpreterCallFrameClosureh">trunk/Source/JavaScriptCore/interpreter/CallFrameClosure.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreinterpreterInterpretercpp">trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreinterpreterInterpreterh">trunk/Source/JavaScriptCore/interpreter/Interpreter.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreinterpreterJSStackh">trunk/Source/JavaScriptCore/interpreter/JSStack.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreinterpreterJSStackInlinesh">trunk/Source/JavaScriptCore/interpreter/JSStackInlines.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITCodecpp">trunk/Source/JavaScriptCore/jit/JITCode.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITCodeh">trunk/Source/JavaScriptCore/jit/JITCode.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITOperationscpp">trunk/Source/JavaScriptCore/jit/JITOperations.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITStubsh">trunk/Source/JavaScriptCore/jit/JITStubs.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITStubsMSVC64asm">trunk/Source/JavaScriptCore/jit/JITStubsMSVC64.asm</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITStubsX86h">trunk/Source/JavaScriptCore/jit/JITStubsX86.h</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLLIntOffsetsExtractorcpp">trunk/Source/JavaScriptCore/llint/LLIntOffsetsExtractor.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLLIntThunksh">trunk/Source/JavaScriptCore/llint/LLIntThunks.h</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLowLevelInterpreterasm">trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLowLevelInterpreter32_64asm">trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLowLevelInterpreter64asm">trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeArgListh">trunk/Source/JavaScriptCore/runtime/ArgList.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSArraycpp">trunk/Source/JavaScriptCore/runtime/JSArray.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeStringPrototypecpp">trunk/Source/JavaScriptCore/runtime/StringPrototype.cpp</a></li>
</ul>
<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreinterpreterProtoCallFramecpp">trunk/Source/JavaScriptCore/interpreter/ProtoCallFrame.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreinterpreterProtoCallFrameh">trunk/Source/JavaScriptCore/interpreter/ProtoCallFrame.h</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/CMakeLists.txt (160093 => 160094)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/CMakeLists.txt        2013-12-04 16:13:53 UTC (rev 160093)
+++ trunk/Source/JavaScriptCore/CMakeLists.txt        2013-12-04 16:40:17 UTC (rev 160094)
</span><span class="lines">@@ -217,6 +217,7 @@
</span><span class="cx"> interpreter/CallFrame.cpp
</span><span class="cx"> interpreter/Interpreter.cpp
</span><span class="cx"> interpreter/JSStack.cpp
</span><ins>+ interpreter/ProtoCallFrame.cpp
</ins><span class="cx"> interpreter/StackVisitor.cpp
</span><span class="cx"> interpreter/VMInspector.cpp
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (160093 => 160094)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2013-12-04 16:13:53 UTC (rev 160093)
+++ trunk/Source/JavaScriptCore/ChangeLog        2013-12-04 16:40:17 UTC (rev 160094)
</span><span class="lines">@@ -1,3 +1,82 @@
</span><ins>+2013-12-04 Michael Saboff <msaboff@apple.com>
+
+ Move the setting up of callee's callFrame from pushFrame to callToJavaScript thunk
+ https://bugs.webkit.org/show_bug.cgi?id=123999
+
+ Reviewed by Filip Pizlo.
+
+ Changed LLInt and/or JIT enabled ports to allocate the stack frame in the
+ callToJavaScript stub. Added an additional stub, callToNativeFunction that
+ allocates a stack frame in a similar way for calling native entry points
+ that take a single ExecState* argument. These stubs are implemented
+ using common macros in LowLevelInterpreter{32_64,64}.asm. There are also
+ Windows X86 and X86-64 versions in the corresponding JitStubsXX.h.
+ The stubs allocate and create a sentinel frame, then create the callee's
+ frame, populating the header and arguments from the passed in ProtoCallFrame*.
+ It is assumed that the caller of either stub does a check for enough stack space
+ via JSStack::entryCheck().
+
+ For ports using the C-Loop interpreter, the prior method for allocating stack
+ frame and invoking functions is used, namely with JSStack::pushFrame() and
+ ::popFrame().
+
+ Made spelling changes "sentinal" -> "sentinel".
+
+ * CMakeLists.txt:
+ * GNUmakefile.list.am:
+ * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+ * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * interpreter/CachedCall.h:
+ (JSC::CachedCall::CachedCall):
+ (JSC::CachedCall::setThis):
+ (JSC::CachedCall::setArgument):
+ * interpreter/CallFrameClosure.h:
+ (JSC::CallFrameClosure::resetCallFrame):
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::execute):
+ (JSC::Interpreter::executeCall):
+ (JSC::Interpreter::executeConstruct):
+ (JSC::Interpreter::prepareForRepeatCall):
+ * interpreter/Interpreter.h:
+ * interpreter/JSStack.h:
+ * interpreter/JSStackInlines.h:
+ (JSC::JSStack::entryCheck):
+ (JSC::JSStack::pushFrame):
+ (JSC::JSStack::popFrame):
+ * interpreter/ProtoCallFrame.cpp: Added.
+ (JSC::ProtoCallFrame::init):
+ * interpreter/ProtoCallFrame.h: Added.
+ (JSC::ProtoCallFrame::codeBlock):
+ (JSC::ProtoCallFrame::setCodeBlock):
+ (JSC::ProtoCallFrame::setScope):
+ (JSC::ProtoCallFrame::setCallee):
+ (JSC::ProtoCallFrame::argumentCountIncludingThis):
+ (JSC::ProtoCallFrame::argumentCount):
+ (JSC::ProtoCallFrame::setArgumentCountIncludingThis):
+ (JSC::ProtoCallFrame::setPaddedArgsCount):
+ (JSC::ProtoCallFrame::clearCurrentVPC):
+ (JSC::ProtoCallFrame::setThisValue):
+ (JSC::ProtoCallFrame::setArgument):
+ * jit/JITCode.cpp:
+ (JSC::JITCode::execute):
+ * jit/JITCode.h:
+ * jit/JITOperations.cpp:
+ * jit/JITStubs.h:
+ * jit/JITStubsMSVC64.asm:
+ * jit/JITStubsX86.h:
+ * llint/LLIntOffsetsExtractor.cpp:
+ * llint/LLIntThunks.h:
+ * llint/LowLevelInterpreter.asm:
+ * llint/LowLevelInterpreter32_64.asm:
+ * llint/LowLevelInterpreter64.asm:
+ * runtime/ArgList.h:
+ (JSC::ArgList::data):
+ * runtime/JSArray.cpp:
+ (JSC::AVLTreeAbstractorForArrayCompare::compare_key_key):
+ * runtime/StringPrototype.cpp:
+ (JSC::replaceUsingRegExpSearch):
+
</ins><span class="cx"> 2013-12-04 László Langó <lango@inf.u-szeged.hu>
</span><span class="cx">
</span><span class="cx"> Remove stdio.h from JSC files.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreGNUmakefilelistam"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/GNUmakefile.list.am (160093 => 160094)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/GNUmakefile.list.am        2013-12-04 16:13:53 UTC (rev 160093)
+++ trunk/Source/JavaScriptCore/GNUmakefile.list.am        2013-12-04 16:40:17 UTC (rev 160094)
</span><span class="lines">@@ -622,6 +622,8 @@
</span><span class="cx">         Source/JavaScriptCore/interpreter/JSStack.cpp \
</span><span class="cx">         Source/JavaScriptCore/interpreter/JSStack.h \
</span><span class="cx">         Source/JavaScriptCore/interpreter/JSStackInlines.h \
</span><ins>+        Source/JavaScriptCore/interpreter/ProtoCallFrame.cpp \
+        Source/JavaScriptCore/interpreter/ProtoCallFrame.h \
</ins><span class="cx">         Source/JavaScriptCore/interpreter/Register.h \
</span><span class="cx">         Source/JavaScriptCore/interpreter/StackVisitor.cpp \
</span><span class="cx">         Source/JavaScriptCore/interpreter/StackVisitor.h \
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorevcxprojJavaScriptCorevcxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj (160093 => 160094)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj        2013-12-04 16:13:53 UTC (rev 160093)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj        2013-12-04 16:40:17 UTC (rev 160094)
</span><span class="lines">@@ -459,6 +459,7 @@
</span><span class="cx"> <ClCompile Include="..\interpreter\CallFrame.cpp" />
</span><span class="cx"> <ClCompile Include="..\interpreter\Interpreter.cpp" />
</span><span class="cx"> <ClCompile Include="..\interpreter\JSStack.cpp" />
</span><ins>+ <ClCompile Include="..\interpreter\ProtoCallFrame.cpp" />
</ins><span class="cx"> <ClCompile Include="..\interpreter\StackVisitor.cpp" />
</span><span class="cx"> <ClCompile Include="..\interpreter\VMInspector.cpp" />
</span><span class="cx"> <ClCompile Include="..\jit\AssemblyHelpers.cpp" />
</span><span class="lines">@@ -1003,6 +1004,7 @@
</span><span class="cx"> <ClInclude Include="..\interpreter\Interpreter.h" />
</span><span class="cx"> <ClInclude Include="..\interpreter\JSStack.h" />
</span><span class="cx"> <ClInclude Include="..\interpreter\JSStackInlines.h" />
</span><ins>+ <ClInclude Include="..\interpreter\ProtoCallFrame.h" />
</ins><span class="cx"> <ClInclude Include="..\interpreter\Register.h" />
</span><span class="cx"> <ClInclude Include="..\interpreter\StackVisitor.h" />
</span><span class="cx"> <ClInclude Include="..\interpreter\VMInspector.h" />
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorevcxprojJavaScriptCorevcxprojfilters"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters (160093 => 160094)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters        2013-12-04 16:13:53 UTC (rev 160093)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters        2013-12-04 16:40:17 UTC (rev 160094)
</span><span class="lines">@@ -288,6 +288,9 @@
</span><span class="cx"> <ClCompile Include="..\interpreter\JSStack.cpp">
</span><span class="cx"> <Filter>interpreter</Filter>
</span><span class="cx"> </ClCompile>
</span><ins>+ <ClCompile Include="..\interpreter\ProtoCallFrame.cpp">
+ <Filter>interpreter</Filter>
+ </ClCompile>
</ins><span class="cx"> <ClCompile Include="..\interpreter\StackVisitor.cpp">
</span><span class="cx"> <Filter>interpreter</Filter>
</span><span class="cx"> </ClCompile>
</span><span class="lines">@@ -1727,6 +1730,9 @@
</span><span class="cx"> <ClInclude Include="..\interpreter\JSStackInlines.h">
</span><span class="cx"> <Filter>interpreter</Filter>
</span><span class="cx"> </ClInclude>
</span><ins>+ <ClInclude Include="..\interpreter\ProtoCallFrame.h">
+ <Filter>interpreter</Filter>
+ </ClInclude>
</ins><span class="cx"> <ClInclude Include="..\interpreter\Register.h">
</span><span class="cx"> <Filter>interpreter</Filter>
</span><span class="cx"> </ClInclude>
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (160093 => 160094)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2013-12-04 16:13:53 UTC (rev 160093)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2013-12-04 16:40:17 UTC (rev 160094)
</span><span class="lines">@@ -735,6 +735,7 @@
</span><span class="cx">                 65C02850171795E200351E35 /* ARMv7Disassembler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 65C0284F171795E200351E35 /* ARMv7Disassembler.cpp */; };
</span><span class="cx">                 65C0285C1717966800351E35 /* ARMv7DOpcode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 65C0285A1717966800351E35 /* ARMv7DOpcode.cpp */; };
</span><span class="cx">                 65C0285D1717966800351E35 /* ARMv7DOpcode.h in Headers */ = {isa = PBXBuildFile; fileRef = 65C0285B1717966800351E35 /* ARMv7DOpcode.h */; };
</span><ins>+                65FB5117184EEE7000C12B70 /* ProtoCallFrame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 65FB5116184EE9BC00C12B70 /* ProtoCallFrame.cpp */; };
</ins><span class="cx">                 7C15F65D17C199CE00794D40 /* JSPromiseCallback.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C15F65B17C199CE00794D40 /* JSPromiseCallback.cpp */; };
</span><span class="cx">                 7C15F65E17C199CE00794D40 /* JSPromiseCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C15F65C17C199CE00794D40 /* JSPromiseCallback.h */; };
</span><span class="cx">                 7C184E1A17BEDBD3007CB63A /* JSPromise.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C184E1817BEDBD3007CB63A /* JSPromise.cpp */; };
</span><span class="lines">@@ -2015,6 +2016,8 @@
</span><span class="cx">                 65EA4C9A092AF9E20093D800 /* JSLock.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = JSLock.h; sourceTree = "<group>"; tabWidth = 8; };
</span><span class="cx">                 65EA73620BAE35D1001BB560 /* CommonIdentifiers.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CommonIdentifiers.cpp; sourceTree = "<group>"; };
</span><span class="cx">                 65EA73630BAE35D1001BB560 /* CommonIdentifiers.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CommonIdentifiers.h; sourceTree = "<group>"; };
</span><ins>+                65FB5115184EE8F800C12B70 /* ProtoCallFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProtoCallFrame.h; sourceTree = "<group>"; };
+                65FB5116184EE9BC00C12B70 /* ProtoCallFrame.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ProtoCallFrame.cpp; sourceTree = "<group>"; };
</ins><span class="cx">                 704FD35305697E6D003DBED9 /* BooleanObject.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = BooleanObject.h; sourceTree = "<group>"; tabWidth = 8; };
</span><span class="cx">                 7C15F65B17C199CE00794D40 /* JSPromiseCallback.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSPromiseCallback.cpp; sourceTree = "<group>"; };
</span><span class="cx">                 7C15F65C17C199CE00794D40 /* JSPromiseCallback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSPromiseCallback.h; sourceTree = "<group>"; };
</span><span class="lines">@@ -2918,6 +2921,8 @@
</span><span class="cx">                 1429D77A0ED20D7300B89619 /* interpreter */ = {
</span><span class="cx">                         isa = PBXGroup;
</span><span class="cx">                         children = (
</span><ins>+                                65FB5116184EE9BC00C12B70 /* ProtoCallFrame.cpp */,
+                                65FB5115184EE8F800C12B70 /* ProtoCallFrame.h */,
</ins><span class="cx">                                 0F55F0F114D1063600AC7649 /* AbstractPC.cpp */,
</span><span class="cx">                                 0F55F0F214D1063600AC7649 /* AbstractPC.h */,
</span><span class="cx">                                 A7F8690E0F9584A100558697 /* CachedCall.h */,
</span><span class="lines">@@ -5277,6 +5282,7 @@
</span><span class="cx">                         isa = PBXSourcesBuildPhase;
</span><span class="cx">                         buildActionMask = 2147483647;
</span><span class="cx">                         files = (
</span><ins>+                                65FB5117184EEE7000C12B70 /* ProtoCallFrame.cpp in Sources */,
</ins><span class="cx">                                 0FFA549716B8835000B3A982 /* A64DOpcode.cpp in Sources */,
</span><span class="cx">                                 0F55F0F414D1063900AC7649 /* AbstractPC.cpp in Sources */,
</span><span class="cx">                                 147F39BD107EC37600427A48 /* ArgList.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinterpreterCachedCallh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/interpreter/CachedCall.h (160093 => 160094)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/interpreter/CachedCall.h        2013-12-04 16:13:53 UTC (rev 160093)
+++ trunk/Source/JavaScriptCore/interpreter/CachedCall.h        2013-12-04 16:40:17 UTC (rev 160094)
</span><span class="lines">@@ -31,6 +31,7 @@
</span><span class="cx"> #include "JSFunction.h"
</span><span class="cx"> #include "JSGlobalObject.h"
</span><span class="cx"> #include "Interpreter.h"
</span><ins>+#include "ProtoCallFrame.h"
</ins><span class="cx"> #include "VMEntryScope.h"
</span><span class="cx">
</span><span class="cx"> namespace JSC {
</span><span class="lines">@@ -43,9 +44,14 @@
</span><span class="cx"> , m_entryScope(callFrame->vm(), function->scope()->globalObject())
</span><span class="cx"> {
</span><span class="cx"> ASSERT(!function->isHostFunction());
</span><del>- if (callFrame->vm().isSafeToRecurse())
</del><ins>+ if (callFrame->vm().isSafeToRecurse()) {
+#if !ENABLE(LLINT_C_LOOP)
+ m_arguments.resize(argumentCount);
+ m_closure = m_interpreter->prepareForRepeatCall(function->jsExecutable(), callFrame, &m_protoCallFrame, function, argumentCount + 1, function->scope(), m_arguments.data());
+#else
</ins><span class="cx"> m_closure = m_interpreter->prepareForRepeatCall(function->jsExecutable(), callFrame, function, argumentCount + 1, function->scope());
</span><del>- else
</del><ins>+#endif
+ } else
</ins><span class="cx"> throwStackOverflowError(callFrame);
</span><span class="cx"> m_valid = !callFrame->hadException();
</span><span class="cx"> }
</span><span class="lines">@@ -55,6 +61,10 @@
</span><span class="cx"> ASSERT(m_valid);
</span><span class="cx"> return m_interpreter->execute(m_closure);
</span><span class="cx"> }
</span><ins>+#if !ENABLE(LLINT_C_LOOP)
+ void setThis(JSValue v) { m_protoCallFrame.setThisValue(v); }
+ void setArgument(int n, JSValue v) { m_protoCallFrame.setArgument(n, v); }
+#else
</ins><span class="cx"> void setThis(JSValue v) { m_closure.setThis(v); }
</span><span class="cx"> void setArgument(int n, JSValue v) { m_closure.setArgument(n, v); }
</span><span class="cx">
</span><span class="lines">@@ -70,11 +80,16 @@
</span><span class="cx"> if (m_valid)
</span><span class="cx"> m_interpreter->endRepeatCall(m_closure);
</span><span class="cx"> }
</span><del>-
</del><ins>+#endif
+
</ins><span class="cx"> private:
</span><span class="cx"> bool m_valid;
</span><span class="cx"> Interpreter* m_interpreter;
</span><span class="cx"> VMEntryScope m_entryScope;
</span><ins>+#if !ENABLE(LLINT_C_LOOP)
+ ProtoCallFrame m_protoCallFrame;
+ Vector<JSValue> m_arguments;
+#endif
</ins><span class="cx"> CallFrameClosure m_closure;
</span><span class="cx"> };
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinterpreterCallFrameClosureh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/interpreter/CallFrameClosure.h (160093 => 160094)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/interpreter/CallFrameClosure.h        2013-12-04 16:13:53 UTC (rev 160093)
+++ trunk/Source/JavaScriptCore/interpreter/CallFrameClosure.h        2013-12-04 16:40:17 UTC (rev 160094)
</span><span class="lines">@@ -26,11 +26,17 @@
</span><span class="cx"> #ifndef CallFrameClosure_h
</span><span class="cx"> #define CallFrameClosure_h
</span><span class="cx">
</span><ins>+#include "ProtoCallFrame.h"
+
</ins><span class="cx"> namespace JSC {
</span><span class="cx">
</span><span class="cx"> struct CallFrameClosure {
</span><span class="cx"> CallFrame* oldCallFrame;
</span><ins>+#if ENABLE(LLINT_C_LOOP)
</ins><span class="cx"> CallFrame* newCallFrame;
</span><ins>+#else
+ ProtoCallFrame* newCallFrame;
+#endif
</ins><span class="cx"> JSFunction* function;
</span><span class="cx"> FunctionExecutable* functionExecutable;
</span><span class="cx"> VM* vm;
</span><span class="lines">@@ -51,12 +57,14 @@
</span><span class="cx"> void resetCallFrame()
</span><span class="cx"> {
</span><span class="cx"> newCallFrame->setScope(scope);
</span><ins>+#if ENABLE(LLINT_C_LOOP)
</ins><span class="cx"> // setArgument() takes an arg index that starts from 0 for the first
</span><span class="cx"> // argument after the 'this' value. Since both argumentCountIncludingThis
</span><span class="cx"> // and parameterCountIncludingThis includes the 'this' value, we need to
</span><del>- // subtract 1 from them to make i a valid argument index for setArgument().
</del><ins>+ // subtract 1 from them to make it a valid argument index for setArgument().
</ins><span class="cx"> for (int i = argumentCountIncludingThis-1; i < parameterCountIncludingThis-1; ++i)
</span><span class="cx"> newCallFrame->setArgument(i, jsUndefined());
</span><ins>+#endif
</ins><span class="cx"> }
</span><span class="cx"> };
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinterpreterInterpretercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp (160093 => 160094)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp        2013-12-04 16:13:53 UTC (rev 160093)
+++ trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp        2013-12-04 16:40:17 UTC (rev 160094)
</span><span class="lines">@@ -53,12 +53,14 @@
</span><span class="cx"> #include "JSString.h"
</span><span class="cx"> #include "JSWithScope.h"
</span><span class="cx"> #include "LLIntCLoop.h"
</span><ins>+#include "LLIntThunks.h"
</ins><span class="cx"> #include "LegacyProfiler.h"
</span><span class="cx"> #include "LiteralParser.h"
</span><span class="cx"> #include "NameInstance.h"
</span><span class="cx"> #include "ObjectPrototype.h"
</span><span class="cx"> #include "Operations.h"
</span><span class="cx"> #include "Parser.h"
</span><ins>+#include "ProtoCallFrame.h"
</ins><span class="cx"> #include "RegExpObject.h"
</span><span class="cx"> #include "RegExpPrototype.h"
</span><span class="cx"> #include "Register.h"
</span><span class="lines">@@ -860,13 +862,21 @@
</span><span class="cx">
</span><span class="cx"> // Push the call frame for this invocation:
</span><span class="cx"> ASSERT(codeBlock->numParameters() == 1); // 1 parameter for 'this'.
</span><ins>+#if ENABLE(LLINT_C_LOOP)
</ins><span class="cx"> CallFrame* newCallFrame = m_stack.pushFrame(callFrame, codeBlock, scope, 1, 0);
</span><span class="cx"> if (UNLIKELY(!newCallFrame))
</span><span class="cx"> return checkedReturn(throwStackOverflowError(callFrame));
</span><span class="cx">
</span><span class="cx"> // Set the arguments for the callee:
</span><span class="cx"> newCallFrame->setThisValue(thisObj);
</span><ins>+#else
+ if (UNLIKELY(!m_stack.entryCheck(codeBlock, 1)))
+ return checkedReturn(throwStackOverflowError(callFrame));
</ins><span class="cx">
</span><ins>+ ProtoCallFrame protoCallFrame;
+ protoCallFrame.init(codeBlock, scope, 0, thisObj, 1);
+#endif
+
</ins><span class="cx"> if (LegacyProfiler* profiler = vm.enabledProfiler())
</span><span class="cx"> profiler->willExecute(callFrame, program->sourceURL(), program->lineNo());
</span><span class="cx">
</span><span class="lines">@@ -879,14 +889,16 @@
</span><span class="cx"> #if ENABLE(LLINT_C_LOOP)
</span><span class="cx"> result = LLInt::CLoop::execute(newCallFrame, llint_program_prologue);
</span><span class="cx"> #elif ENABLE(JIT)
</span><del>- result = program->generatedJITCode()->execute(&m_stack, newCallFrame, &vm);
</del><ins>+ result = program->generatedJITCode()->execute(&vm, &protoCallFrame, m_stack.getTopOfStack());
</ins><span class="cx"> #endif // ENABLE(JIT)
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> if (LegacyProfiler* profiler = vm.enabledProfiler())
</span><span class="cx"> profiler->didExecute(callFrame, program->sourceURL(), program->lineNo());
</span><span class="cx">
</span><ins>+#if ENABLE(LLINT_C_LOOP)
</ins><span class="cx"> m_stack.popFrame(newCallFrame);
</span><ins>+#endif
</ins><span class="cx">
</span><span class="cx"> return checkedReturn(result);
</span><span class="cx"> }
</span><span class="lines">@@ -930,6 +942,7 @@
</span><span class="cx"> if (UNLIKELY(vm.watchdog.didFire(callFrame)))
</span><span class="cx"> return throwTerminatedExecutionException(callFrame);
</span><span class="cx">
</span><ins>+#if ENABLE(LLINT_C_LOOP)
</ins><span class="cx"> CallFrame* newCallFrame = m_stack.pushFrame(callFrame, newCodeBlock, scope, argsCount, function);
</span><span class="cx"> if (UNLIKELY(!newCallFrame))
</span><span class="cx"> return checkedReturn(throwStackOverflowError(callFrame));
</span><span class="lines">@@ -938,7 +951,14 @@
</span><span class="cx"> newCallFrame->setThisValue(thisValue);
</span><span class="cx"> for (size_t i = 0; i < args.size(); ++i)
</span><span class="cx"> newCallFrame->setArgument(i, args.at(i));
</span><ins>+#else
+ if (UNLIKELY(!m_stack.entryCheck(newCodeBlock, argsCount)))
+ return checkedReturn(throwStackOverflowError(callFrame));
</ins><span class="cx">
</span><ins>+ ProtoCallFrame protoCallFrame;
+ protoCallFrame.init(newCodeBlock, scope, function, thisValue, argsCount, args.data());
+#endif
+
</ins><span class="cx"> if (LegacyProfiler* profiler = vm.enabledProfiler())
</span><span class="cx"> profiler->willExecute(callFrame, function);
</span><span class="cx">
</span><span class="lines">@@ -952,16 +972,23 @@
</span><span class="cx"> #if ENABLE(LLINT_C_LOOP)
</span><span class="cx"> result = LLInt::CLoop::execute(newCallFrame, llint_function_for_call_prologue);
</span><span class="cx"> #elif ENABLE(JIT)
</span><del>- result = callData.js.functionExecutable->generatedJITCodeForCall()->execute(&m_stack, newCallFrame, &vm);
</del><ins>+ result = callData.js.functionExecutable->generatedJITCodeForCall()->execute(&vm, &protoCallFrame, m_stack.getTopOfStack());
</ins><span class="cx"> #endif // ENABLE(JIT)
</span><del>- } else
</del><ins>+ } else {
+#if ENABLE(LLINT_C_LOOP)
</ins><span class="cx"> result = JSValue::decode(callData.native.function(newCallFrame));
</span><ins>+#else
+ result = JSValue::decode(callToNativeFunction(reinterpret_cast<void*>(callData.native.function), &vm.topCallFrame, &protoCallFrame, m_stack.getTopOfStack()));
+#endif
+ }
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> if (LegacyProfiler* profiler = vm.enabledProfiler())
</span><span class="cx"> profiler->didExecute(callFrame, function);
</span><span class="cx">
</span><ins>+#if ENABLE(LLINT_C_LOOP)
</ins><span class="cx"> m_stack.popFrame(newCallFrame);
</span><ins>+#endif
</ins><span class="cx"> return checkedReturn(result);
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -1005,7 +1032,7 @@
</span><span class="cx">
</span><span class="cx"> if (UNLIKELY(vm.watchdog.didFire(callFrame)))
</span><span class="cx"> return throwTerminatedExecutionException(callFrame);
</span><del>-
</del><ins>+#if ENABLE(LLINT_C_LOOP)
</ins><span class="cx"> CallFrame* newCallFrame = m_stack.pushFrame(callFrame, newCodeBlock, scope, argsCount, constructor);
</span><span class="cx"> if (UNLIKELY(!newCallFrame))
</span><span class="cx"> return checkedReturn(throwStackOverflowError(callFrame));
</span><span class="lines">@@ -1014,7 +1041,14 @@
</span><span class="cx"> newCallFrame->setThisValue(jsUndefined());
</span><span class="cx"> for (size_t i = 0; i < args.size(); ++i)
</span><span class="cx"> newCallFrame->setArgument(i, args.at(i));
</span><ins>+#else
+ if (UNLIKELY(!m_stack.entryCheck(newCodeBlock, argsCount)))
+ return checkedReturn(throwStackOverflowError(callFrame));
</ins><span class="cx">
</span><ins>+ ProtoCallFrame protoCallFrame;
+ protoCallFrame.init(newCodeBlock, scope, constructor, jsUndefined(), argsCount, args.data());
+#endif
+
</ins><span class="cx"> if (LegacyProfiler* profiler = vm.enabledProfiler())
</span><span class="cx"> profiler->willExecute(callFrame, constructor);
</span><span class="cx">
</span><span class="lines">@@ -1028,22 +1062,25 @@
</span><span class="cx"> #if ENABLE(LLINT_C_LOOP)
</span><span class="cx"> result = LLInt::CLoop::execute(newCallFrame, llint_function_for_construct_prologue);
</span><span class="cx"> #elif ENABLE(JIT)
</span><del>- result = constructData.js.functionExecutable->generatedJITCodeForConstruct()->execute(&m_stack, newCallFrame, &vm);
</del><ins>+ result = constructData.js.functionExecutable->generatedJITCodeForConstruct()->execute(&vm, &protoCallFrame, m_stack.getTopOfStack());
</ins><span class="cx"> #endif // ENABLE(JIT)
</span><span class="cx"> } else {
</span><ins>+#if ENABLE(LLINT_C_LOOP)
</ins><span class="cx"> result = JSValue::decode(constructData.native.function(newCallFrame));
</span><del>- if (!callFrame->hadException()) {
- ASSERT_WITH_MESSAGE(result.isObject(), "Host constructor returned non object.");
- if (!result.isObject())
- throwTypeError(newCallFrame);
- }
</del><ins>+#else
+ result = JSValue::decode(callToNativeFunction(reinterpret_cast<void*>(constructData.native.function), &vm.topCallFrame, &protoCallFrame, m_stack.getTopOfStack()));
+#endif
+ if (!callFrame->hadException())
+ RELEASE_ASSERT(result.isObject());
</ins><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> if (LegacyProfiler* profiler = vm.enabledProfiler())
</span><span class="cx"> profiler->didExecute(callFrame, constructor);
</span><span class="cx">
</span><ins>+#if ENABLE(LLINT_C_LOOP)
</ins><span class="cx"> m_stack.popFrame(newCallFrame);
</span><ins>+#endif
</ins><span class="cx">
</span><span class="cx"> if (callFrame->hadException())
</span><span class="cx"> return 0;
</span><span class="lines">@@ -1051,7 +1088,11 @@
</span><span class="cx"> return checkedReturn(asObject(result));
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+#if ENABLE(LLINT_C_LOOP)
</ins><span class="cx"> CallFrameClosure Interpreter::prepareForRepeatCall(FunctionExecutable* functionExecutable, CallFrame* callFrame, JSFunction* function, int argumentCountIncludingThis, JSScope* scope)
</span><ins>+#else
+CallFrameClosure Interpreter::prepareForRepeatCall(FunctionExecutable* functionExecutable, CallFrame* callFrame, ProtoCallFrame* protoCallFrame, JSFunction* function, int argumentCountIncludingThis, JSScope* scope, JSValue* args)
+#endif
</ins><span class="cx"> {
</span><span class="cx"> VM& vm = *scope->vm();
</span><span class="cx"> ASSERT(!vm.exception());
</span><span class="lines">@@ -1070,19 +1111,26 @@
</span><span class="cx">
</span><span class="cx"> size_t argsCount = argumentCountIncludingThis;
</span><span class="cx">
</span><del>- CallFrame* newCallFrame = m_stack.pushFrame(callFrame, newCodeBlock, scope, argsCount, function);
</del><ins>+#if ENABLE(LLINT_C_LOOP)
+ CallFrame* newCallFrame = m_stack.pushFrame(callFrame, newCodeBlock, scope, argsCount, function);
+
</ins><span class="cx"> if (UNLIKELY(!newCallFrame)) {
</span><span class="cx"> throwStackOverflowError(callFrame);
</span><span class="cx"> return CallFrameClosure();
</span><span class="cx"> }
</span><span class="cx">
</span><del>- if (UNLIKELY(!newCallFrame)) {
</del><ins>+ // Return the successful closure:
+ CallFrameClosure result = { callFrame, newCallFrame, function, functionExecutable, &vm, scope, newCodeBlock->numParameters(), argumentCountIncludingThis };
+#else
+ if (UNLIKELY(!m_stack.entryCheck(newCodeBlock, argsCount))) {
</ins><span class="cx"> throwStackOverflowError(callFrame);
</span><span class="cx"> return CallFrameClosure();
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+ protoCallFrame->init(newCodeBlock, scope, function, jsUndefined(), argsCount, args);
</ins><span class="cx"> // Return the successful closure:
</span><del>- CallFrameClosure result = { callFrame, newCallFrame, function, functionExecutable, &vm, scope, newCodeBlock->numParameters(), argumentCountIncludingThis };
</del><ins>+ CallFrameClosure result = { callFrame, protoCallFrame, function, functionExecutable, &vm, scope, newCodeBlock->numParameters(), argumentCountIncludingThis };
+#endif
</ins><span class="cx"> return result;
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -1096,9 +1144,13 @@
</span><span class="cx"> return jsNull();
</span><span class="cx">
</span><span class="cx"> StackStats::CheckPoint stackCheckPoint;
</span><ins>+#if ENABLE(LLINT_C_LOOP)
</ins><span class="cx"> m_stack.validateFence(closure.newCallFrame, "BEFORE");
</span><ins>+#endif
</ins><span class="cx"> closure.resetCallFrame();
</span><ins>+#if ENABLE(LLINT_C_LOOP)
</ins><span class="cx"> m_stack.validateFence(closure.newCallFrame, "STEP 1");
</span><ins>+#endif
</ins><span class="cx">
</span><span class="cx"> if (LegacyProfiler* profiler = vm.enabledProfiler())
</span><span class="cx"> profiler->willExecute(closure.oldCallFrame, closure.function);
</span><span class="lines">@@ -1114,7 +1166,9 @@
</span><span class="cx"> // Hence, we need to preserve the topCallFrame here ourselves before
</span><span class="cx"> // repeating this call on a second callback function.
</span><span class="cx">
</span><ins>+#if ENABLE(LLINT_C_LOOP)
</ins><span class="cx"> TopCallFrameSetter topCallFrame(vm, closure.newCallFrame);
</span><ins>+#endif
</ins><span class="cx">
</span><span class="cx"> // Execute the code:
</span><span class="cx"> JSValue result;
</span><span class="lines">@@ -1125,21 +1179,25 @@
</span><span class="cx"> #if ENABLE(LLINT_C_LOOP)
</span><span class="cx"> result = LLInt::CLoop::execute(closure.newCallFrame, llint_function_for_call_prologue);
</span><span class="cx"> #elif ENABLE(JIT)
</span><del>- result = closure.functionExecutable->generatedJITCodeForCall()->execute(&m_stack, closure.newCallFrame, &vm);
</del><ins>+ result = closure.functionExecutable->generatedJITCodeForCall()->execute(&vm, closure.newCallFrame, m_stack.getTopOfStack());
</ins><span class="cx"> #endif // ENABLE(JIT)
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> if (LegacyProfiler* profiler = vm.enabledProfiler())
</span><span class="cx"> profiler->didExecute(closure.oldCallFrame, closure.function);
</span><span class="cx">
</span><ins>+#if ENABLE(LLINT_C_LOOP)
</ins><span class="cx"> m_stack.validateFence(closure.newCallFrame, "AFTER");
</span><ins>+#endif
</ins><span class="cx"> return checkedReturn(result);
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+#if ENABLE(LLINT_C_LOOP)
</ins><span class="cx"> void Interpreter::endRepeatCall(CallFrameClosure& closure)
</span><span class="cx"> {
</span><span class="cx"> m_stack.popFrame(closure.newCallFrame);
</span><span class="cx"> }
</span><ins>+#endif
</ins><span class="cx">
</span><span class="cx"> JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSValue thisValue, JSScope* scope)
</span><span class="cx"> {
</span><span class="lines">@@ -1203,13 +1261,21 @@
</span><span class="cx">
</span><span class="cx"> // Push the frame:
</span><span class="cx"> ASSERT(codeBlock->numParameters() == 1); // 1 parameter for 'this'.
</span><ins>+#if ENABLE(LLINT_C_LOOP)
</ins><span class="cx"> CallFrame* newCallFrame = m_stack.pushFrame(callFrame, codeBlock, scope, 1, 0);
</span><span class="cx"> if (UNLIKELY(!newCallFrame))
</span><span class="cx"> return checkedReturn(throwStackOverflowError(callFrame));
</span><span class="cx">
</span><span class="cx"> // Set the arguments for the callee:
</span><span class="cx"> newCallFrame->setThisValue(thisValue);
</span><ins>+#else
+ if (UNLIKELY(!m_stack.entryCheck(codeBlock, 1)))
+ return checkedReturn(throwStackOverflowError(callFrame));
</ins><span class="cx">
</span><ins>+ ProtoCallFrame protoCallFrame;
+ protoCallFrame.init(codeBlock, scope, 0, thisValue, 1);
+#endif
+
</ins><span class="cx"> if (LegacyProfiler* profiler = vm.enabledProfiler())
</span><span class="cx"> profiler->willExecute(callFrame, eval->sourceURL(), eval->lineNo());
</span><span class="cx">
</span><span class="lines">@@ -1222,14 +1288,16 @@
</span><span class="cx"> #if ENABLE(LLINT_C_LOOP)
</span><span class="cx"> result = LLInt::CLoop::execute(newCallFrame, llint_eval_prologue);
</span><span class="cx"> #elif ENABLE(JIT)
</span><del>- result = eval->generatedJITCode()->execute(&m_stack, newCallFrame, &vm);
</del><ins>+ result = eval->generatedJITCode()->execute(&vm, &protoCallFrame, m_stack.getTopOfStack());
</ins><span class="cx"> #endif // ENABLE(JIT)
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> if (LegacyProfiler* profiler = vm.enabledProfiler())
</span><span class="cx"> profiler->didExecute(callFrame, eval->sourceURL(), eval->lineNo());
</span><span class="cx">
</span><ins>+#if ENABLE(LLINT_C_LOOP)
</ins><span class="cx"> m_stack.popFrame(newCallFrame);
</span><ins>+#endif
</ins><span class="cx"> return checkedReturn(result);
</span><span class="cx"> }
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinterpreterInterpreterh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/interpreter/Interpreter.h (160093 => 160094)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/interpreter/Interpreter.h        2013-12-04 16:13:53 UTC (rev 160093)
+++ trunk/Source/JavaScriptCore/interpreter/Interpreter.h        2013-12-04 16:40:17 UTC (rev 160094)
</span><span class="lines">@@ -59,7 +59,8 @@
</span><span class="cx"> struct CallFrameClosure;
</span><span class="cx"> struct HandlerInfo;
</span><span class="cx"> struct Instruction;
</span><del>-
</del><ins>+ struct ProtoCallFrame;
+
</ins><span class="cx"> enum DebugHookID {
</span><span class="cx"> WillExecuteProgram,
</span><span class="cx"> DidExecuteProgram,
</span><span class="lines">@@ -256,8 +257,12 @@
</span><span class="cx"> private:
</span><span class="cx"> enum ExecutionFlag { Normal, InitializeAndReturn };
</span><span class="cx">
</span><ins>+#if !ENABLE(LLINT_C_LOOP)
+ CallFrameClosure prepareForRepeatCall(FunctionExecutable*, CallFrame*, ProtoCallFrame*, JSFunction*, int argumentCountIncludingThis, JSScope*, JSValue*);
+#else
</ins><span class="cx"> CallFrameClosure prepareForRepeatCall(FunctionExecutable*, CallFrame*, JSFunction*, int argumentCountIncludingThis, JSScope*);
</span><span class="cx"> void endRepeatCall(CallFrameClosure&);
</span><ins>+#endif
</ins><span class="cx"> JSValue execute(CallFrameClosure&);
</span><span class="cx">
</span><span class="cx"> void getStackTrace(Vector<StackFrame>& results, size_t maxStackSize = std::numeric_limits<size_t>::max());
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinterpreterJSStackh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/interpreter/JSStack.h (160093 => 160094)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/interpreter/JSStack.h        2013-12-04 16:13:53 UTC (rev 160093)
+++ trunk/Source/JavaScriptCore/interpreter/JSStack.h        2013-12-04 16:40:17 UTC (rev 160094)
</span><span class="lines">@@ -35,6 +35,7 @@
</span><span class="cx"> #include <wtf/PageReservation.h>
</span><span class="cx"> #include <wtf/VMTags.h>
</span><span class="cx">
</span><ins>+#define ENABLE_DEBUG_JSSTACK 0
</ins><span class="cx"> #if !defined(NDEBUG) && !defined(ENABLE_DEBUG_JSSTACK)
</span><span class="cx"> #define ENABLE_DEBUG_JSSTACK 1
</span><span class="cx"> #endif
</span><span class="lines">@@ -99,6 +100,8 @@
</span><span class="cx"> Register* getStartOfFrame(CallFrame*);
</span><span class="cx"> Register* getTopOfStack();
</span><span class="cx">
</span><ins>+ bool entryCheck(class CodeBlock*, int);
+
</ins><span class="cx"> CallFrame* pushFrame(CallFrame* callerFrame, class CodeBlock*,
</span><span class="cx"> JSScope*, int argsCount, JSObject* callee);
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinterpreterJSStackInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/interpreter/JSStackInlines.h (160093 => 160094)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/interpreter/JSStackInlines.h        2013-12-04 16:13:53 UTC (rev 160093)
+++ trunk/Source/JavaScriptCore/interpreter/JSStackInlines.h        2013-12-04 16:40:17 UTC (rev 160094)
</span><span class="lines">@@ -51,6 +51,35 @@
</span><span class="cx"> return getTopOfFrame(callerFrame);
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+inline bool JSStack::entryCheck(class CodeBlock* codeBlock, int argsCount)
+{
+ Register* oldEnd = getTopOfStack();
+
+ // Ensure that we have enough space for the parameters:
+ size_t paddedArgsCount = argsCount;
+ if (codeBlock) {
+ size_t numParameters = codeBlock->numParameters();
+ if (paddedArgsCount < numParameters)
+ paddedArgsCount = numParameters;
+ }
+
+ Register* newCallFrameSlot = oldEnd - paddedArgsCount - (2 * JSStack::CallFrameHeaderSize) + 1;
+
+#if ENABLE(DEBUG_JSSTACK)
+ newCallFrameSlot -= JSStack::FenceSize;
+#endif
+
+ Register* newEnd = newCallFrameSlot;
+ if (!!codeBlock)
+ newEnd += virtualRegisterForLocal(codeBlock->frameRegisterCount()).offset();
+
+ // Ensure that we have the needed stack capacity to push the new frame:
+ if (!grow(newEnd))
+ return false;
+
+ return true;
+}
+
</ins><span class="cx"> inline CallFrame* JSStack::pushFrame(CallFrame* callerFrame,
</span><span class="cx"> class CodeBlock* codeBlock, JSScope* scope, int argsCount, JSObject* callee)
</span><span class="cx"> {
</span><span class="lines">@@ -79,9 +108,9 @@
</span><span class="cx"> if (!grow(newEnd))
</span><span class="cx"> return 0;
</span><span class="cx">
</span><del>- // Compute the address of the new VM sentinal frame for this invocation:
- CallFrame* newVMEntrySentinalFrame = CallFrame::create(newCallFrameSlot + paddedArgsCount + JSStack::CallFrameHeaderSize);
- ASSERT(!!newVMEntrySentinalFrame);
</del><ins>+ // Compute the address of the new VM sentinel frame for this invocation:
+ CallFrame* newVMEntrySentinelFrame = CallFrame::create(newCallFrameSlot + paddedArgsCount + JSStack::CallFrameHeaderSize);
+ ASSERT(!!newVMEntrySentinelFrame);
</ins><span class="cx">
</span><span class="cx"> // Compute the address of the new frame for this invocation:
</span><span class="cx"> CallFrame* newCallFrame = CallFrame::create(newCallFrameSlot);
</span><span class="lines">@@ -92,11 +121,11 @@
</span><span class="cx"> // the top frame on the stack.
</span><span class="cx"> callerFrame = m_topCallFrame;
</span><span class="cx">
</span><del>- // Initialize the VM sentinal frame header:
- newVMEntrySentinalFrame->initializeVMEntrySentinelFrame(callerFrame);
</del><ins>+ // Initialize the VM sentinel frame header:
+ newVMEntrySentinelFrame->initializeVMEntrySentinelFrame(callerFrame);
</ins><span class="cx">
</span><span class="cx"> // Initialize the callee frame header:
</span><del>- newCallFrame->init(codeBlock, 0, scope, newVMEntrySentinalFrame, argsCount, callee);
</del><ins>+ newCallFrame->init(codeBlock, 0, scope, newVMEntrySentinelFrame, argsCount, callee);
</ins><span class="cx">
</span><span class="cx"> ASSERT(!!newCallFrame->scope());
</span><span class="cx">
</span><span class="lines">@@ -120,7 +149,7 @@
</span><span class="cx"> {
</span><span class="cx"> validateFence(frame, __FUNCTION__, __LINE__);
</span><span class="cx">
</span><del>- // Pop off the callee frame and the sentinal frame.
</del><ins>+ // Pop off the callee frame and the sentinel frame.
</ins><span class="cx"> CallFrame* callerFrame = frame->callerFrame()->vmEntrySentinelCallerFrame();
</span><span class="cx">
</span><span class="cx"> // Pop to the caller:
</span><span class="lines">@@ -183,7 +212,7 @@
</span><span class="cx"> // |--------------------------------------|
</span><span class="cx"> // | *** the Fence *** |
</span><span class="cx"> // |--------------------------------------|
</span><del>-// | VM entry sentinal frame header |
</del><ins>+// | VM entry sentinel frame header |
</ins><span class="cx"> // |--------------------------------------|
</span><span class="cx"> // | Args of new frame |
</span><span class="cx"> // |--------------------------------------|
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinterpreterProtoCallFramecpp"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/interpreter/ProtoCallFrame.cpp (0 => 160094)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/interpreter/ProtoCallFrame.cpp         (rev 0)
+++ trunk/Source/JavaScriptCore/interpreter/ProtoCallFrame.cpp        2013-12-04 16:40:17 UTC (rev 160094)
</span><span class="lines">@@ -0,0 +1,51 @@
</span><ins>+/*
+ * Copyright (C) 2013 Apple Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "config.h"
+#include "ProtoCallFrame.h"
+
+#include "CodeBlock.h"
+
+namespace JSC {
+
+void ProtoCallFrame::init(CodeBlock* codeBlock, JSScope* scope, JSObject* callee, JSValue thisValue, int argCountIncludingThis, JSValue* otherArgs)
+{
+ this->args = otherArgs;
+ this->setCodeBlock(codeBlock);
+ this->setScope(scope);
+ this->setCallee(callee);
+ this->setArgumentCountIncludingThis(argCountIncludingThis);
+ size_t paddedArgsCount = argCountIncludingThis;
+ if (codeBlock) {
+ size_t numParameters = codeBlock->numParameters();
+ if (paddedArgsCount < numParameters)
+ paddedArgsCount = numParameters;
+ }
+ this->setPaddedArgsCount(paddedArgsCount);
+ this->clearCurrentVPC();
+ this->setThisValue(thisValue);
+}
+
+} // namespace JSC
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreinterpreterProtoCallFrameh"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/interpreter/ProtoCallFrame.h (0 => 160094)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/interpreter/ProtoCallFrame.h         (rev 0)
+++ trunk/Source/JavaScriptCore/interpreter/ProtoCallFrame.h        2013-12-04 16:40:17 UTC (rev 160094)
</span><span class="lines">@@ -0,0 +1,63 @@
</span><ins>+/*
+ * Copyright (C) 2013 Apple Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef ProtoCallFrame_h
+#define ProtoCallFrame_h
+
+#include "Register.h"
+
+namespace JSC {
+
+struct ProtoCallFrame {
+ Register codeBlockValue;
+ Register scopeChainValue;
+ Register calleeValue;
+ Register argCountAndCodeOriginValue;
+ Register thisArg;
+ size_t paddedArgCount;
+ JSValue *args;
+
+ void init(CodeBlock*, JSScope*, JSObject*, JSValue, int, JSValue* otherArgs = 0);
+ CodeBlock* codeBlock() const { return codeBlockValue.Register::codeBlock(); }
+ void setCodeBlock(CodeBlock* codeBlock) { codeBlockValue = codeBlock; }
+ void setScope(JSScope* scope) { scopeChainValue = scope; }
+ void setCallee(JSObject* callee) { calleeValue = Register::withCallee(callee); }
+ int argumentCountIncludingThis() const { return argCountAndCodeOriginValue.payload(); }
+ int argumentCount() const { return argumentCountIncludingThis() - 1; }
+ void setArgumentCountIncludingThis(int count) { argCountAndCodeOriginValue.payload() = count; }
+ void setPaddedArgsCount(size_t argCount) { paddedArgCount = argCount; }
+
+ void clearCurrentVPC() { argCountAndCodeOriginValue.tag() = 0; }
+ void setThisValue(JSValue value) { thisArg = value; }
+ void setArgument(size_t argument, JSValue value)
+ {
+ ASSERT(static_cast<int>(argument) < argumentCount());
+ args[argument] = value;
+ }
+};
+
+} // namespace JSC
+
+#endif // ProtoCallFrame_h
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITCodecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITCode.cpp (160093 => 160094)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITCode.cpp        2013-12-04 16:13:53 UTC (rev 160093)
+++ trunk/Source/JavaScriptCore/jit/JITCode.cpp        2013-12-04 16:40:17 UTC (rev 160094)
</span><span class="lines">@@ -42,11 +42,11 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> #if ENABLE(JIT)
</span><del>-JSValue JITCode::execute(JSStack* stack, CallFrame* callFrame, VM* vm)
</del><ins>+JSValue JITCode::execute(VM* vm, ProtoCallFrame* protoCallFrame, Register* topOfStack)
</ins><span class="cx"> {
</span><del>- UNUSED_PARAM(stack);
</del><ins>+ ASSERT(!vm->topCallFrame || ((Register*)(vm->topCallFrame) >= topOfStack));
</ins><span class="cx">
</span><del>- JSValue result = JSValue::decode(callToJavaScript(executableAddress(), callFrame));
</del><ins>+ JSValue result = JSValue::decode(callToJavaScript(executableAddress(), &vm->topCallFrame, protoCallFrame, topOfStack));
</ins><span class="cx"> return vm->exception() ? jsNull() : result;
</span><span class="cx"> }
</span><span class="cx"> #endif
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITCodeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITCode.h (160093 => 160094)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITCode.h        2013-12-04 16:13:53 UTC (rev 160093)
+++ trunk/Source/JavaScriptCore/jit/JITCode.h        2013-12-04 16:40:17 UTC (rev 160094)
</span><span class="lines">@@ -49,6 +49,7 @@
</span><span class="cx"> #if ENABLE(JIT)
</span><span class="cx"> class VM;
</span><span class="cx"> class JSStack;
</span><ins>+struct ProtoCallFrame;
</ins><span class="cx"> #endif
</span><span class="cx">
</span><span class="cx"> class JITCode : public ThreadSafeRefCounted<JITCode> {
</span><span class="lines">@@ -177,7 +178,7 @@
</span><span class="cx"> virtual FTL::JITCode* ftl();
</span><span class="cx"> virtual FTL::ForOSREntryJITCode* ftlForOSREntry();
</span><span class="cx">
</span><del>- JSValue execute(JSStack*, CallFrame*, VM*);
</del><ins>+ JSValue execute(VM*, ProtoCallFrame*, Register*);
</ins><span class="cx">
</span><span class="cx"> void* start() { return dataAddressAtOffset(0); }
</span><span class="cx"> virtual size_t size() = 0;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITOperationscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITOperations.cpp (160093 => 160094)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITOperations.cpp        2013-12-04 16:13:53 UTC (rev 160093)
+++ trunk/Source/JavaScriptCore/jit/JITOperations.cpp        2013-12-04 16:40:17 UTC (rev 160094)
</span><span class="lines">@@ -76,6 +76,9 @@
</span><span class="cx"> // We pass in our own code block, because the callframe hasn't been populated.
</span><span class="cx"> VM* vm = codeBlock->vm();
</span><span class="cx"> CallFrame* callerFrame = exec->callerFrameSkippingVMEntrySentinel();
</span><ins>+ if (!callerFrame)
+ callerFrame = exec;
+
</ins><span class="cx"> NativeCallFrameTracer tracer(vm, callerFrame);
</span><span class="cx">
</span><span class="cx"> JSStack& stack = vm->interpreter->stack();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITStubsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITStubs.h (160093 => 160094)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITStubs.h        2013-12-04 16:13:53 UTC (rev 160093)
+++ trunk/Source/JavaScriptCore/jit/JITStubs.h        2013-12-04 16:40:17 UTC (rev 160094)
</span><span class="lines">@@ -38,10 +38,13 @@
</span><span class="cx">
</span><span class="cx"> #if OS(WINDOWS)
</span><span class="cx"> class ExecState;
</span><ins>+class Register;
+struct ProtoCallFrame;
</ins><span class="cx">
</span><span class="cx"> extern "C" {
</span><del>- EncodedJSValue callToJavaScript(void*, ExecState*);
</del><ins>+ EncodedJSValue callToJavaScript(void*, ExecState**, ProtoCallFrame*, Register*);
</ins><span class="cx"> void returnFromJavaScript();
</span><ins>+ EncodedJSValue callToNativeFunction(void*, ExecState**, ProtoCallFrame*, Register*);
</ins><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITStubsMSVC64asm"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITStubsMSVC64.asm (160093 => 160094)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITStubsMSVC64.asm        2013-12-04 16:13:53 UTC (rev 160093)
+++ trunk/Source/JavaScriptCore/jit/JITStubsMSVC64.asm        2013-12-04 16:40:17 UTC (rev 160094)
</span><span class="lines">@@ -32,6 +32,10 @@
</span><span class="cx"> _TEXT SEGMENT
</span><span class="cx">
</span><span class="cx"> callToJavaScript PROC
</span><ins>+ ;; FIXME: This function has not been tested as the Win 64 port doesn't currently use the JIT.
+ ;; It is believed to be an accurate adaptation of the assembly created by the llint stub of the
+ ;; same name with changes for agrument register differences.
+ int 3
</ins><span class="cx"> mov r10, qword ptr[rsp]
</span><span class="cx"> push rbp
</span><span class="cx"> mov rax, rbp ; Save previous frame pointer
</span><span class="lines">@@ -49,13 +53,72 @@
</span><span class="cx"> ; requirement is 32 bytes. Based on these factors, we need to pad the stack
</span><span class="cx"> ; an additional 28h bytes.
</span><span class="cx"> sub rsp, 28h
</span><del>- mov rbp, rdx
- mov r11, qword ptr[rbp] ; Put the previous frame pointer in the sentinel call frame above us
- mov qword ptr[r11], rax
- mov qword ptr[r11 + 8], r10
</del><ins>+
+ mov rbp, r9
+ sub rbp, 40
+ mov qword ptr[rbp + 40], 0
+ mov qword ptr[rbp + 32], rdx
+
+ mov rax, qword ptr[rdx]
+ mov qword ptr[rbp + 24], rax
+ mov qword ptr[rbp + 16], 1
+ mov qword ptr[rbp + 8], r10
+ mov qword ptr[rbp], rax
+ mov rax, rbp
+
+ mov ebx, dword ptr[r8 + 40]
+ add rbx, 6
+ sal rbx, 3
+ sub rbp, rbx
+ mov qword ptr[rbp], rax
+
+ mov rax, 5
+
+copyHeaderLoop:
+ sub rax, 1
+ mov r10, qword ptr[r8 + rax * 8]
+ mov qword ptr[rbp + rax * 8 + 16], r10
+ test rax, rax
+ jnz copyHeaderLoop
+
+ mov ebx, dword ptr[r8 + 24]
+ sub rbx, 1
+ mov r10d, dword ptr[r8 + 40]
+ sub r10, 1
+ cmp rbx, r10
+ je copyArgs
+ mov rax, 0ah
+
+fillExtraArgsLoop:
+ sub r10, 1
+ mov qword ptr[rbp + r10 * 8 + 56], rax
+ cmp rbx, r10
+ jne fillExtraArgsLoop
+
+copyArgs:
+ mov rax, qword ptr[r8 + 48]
+
+copyArgsLoop:
+ test ebx, ebx
+ jz copyArgsDone
+ sub ebx, 1
+ mov r10, qword ptr[rax + rbx * 8]
+ mov qword ptr[rbp + rbx * 8 + 56], r10
+ jmp copyArgsLoop
+
+copyArgsDone:
+ mov qword ptr[rdx], rbp
</ins><span class="cx"> mov r14, 0FFFF000000000000h
</span><span class="cx"> mov r15, 0FFFF000000000002h
</span><span class="cx"> call rcx
</span><ins>+ cmp qword ptr[rbp + 16], 1
+ je calleeFramePopped
+ mov rbp, qword ptr[rbp]
+
+calleeFramePopped:
+ mov rbx, qword ptr[rbp + 32] ; VM.topCallFrame
+ mov r10, qword ptr[rbp + 24]
+ mov qword ptr[rbx], r10
</ins><span class="cx"> add rsp, 28h
</span><span class="cx"> pop rdi
</span><span class="cx"> pop rsi
</span><span class="lines">@@ -68,6 +131,110 @@
</span><span class="cx"> ret
</span><span class="cx"> callToJavaScript ENDP
</span><span class="cx">
</span><ins>+callToNativeFunction PROC
+ ;; FIXME: This function has not been tested as the Win 64 port doesn't currently use the JIT.
+ ;; It is believed to be an accurate adaptation of the assembly created by the llint stub of the
+ ;; same name with changes for agrument register differences.
+ int 3
+ mov r10, qword ptr[rsp]
+ push rbp
+ mov rax, rbp ; Save previous frame pointer
+ mov rbp, rsp
+ push r12
+ push r13
+ push r14
+ push r15
+ push rbx
+ push rsi
+ push rdi
+
+ ; JIT operations can use up to 6 args (4 in registers and 2 on the stack).
+ ; In addition, X86_64 ABI specifies that the worse case stack alignment
+ ; requirement is 32 bytes. Based on these factors, we need to pad the stack
+ ; an additional 28h bytes.
+ sub rsp, 28h
+
+ mov rbp, r9
+ sub rbp, 40
+ mov qword ptr[rbp + 40], 0
+ mov qword ptr[rbp + 32], rdx
+
+ mov rax, qword ptr[rdx]
+ mov qword ptr[rbp + 24], rax
+ mov qword ptr[rbp + 16], 1
+ mov qword ptr[rbp + 8], r10
+ mov qword ptr[rbp], rax
+ mov rax, rbp
+
+ mov ebx, dword ptr[r8 + 40]
+ add rbx, 6
+ sal rbx, 3
+ sub rbp, rbx
+ mov qword ptr[rbp], rax
+
+ mov rax, 5
+
+copyHeaderLoop:
+ sub rax, 1
+ mov r10, qword ptr[r8 + rax * 8]
+ mov qword ptr[rbp + rax * 8 + 16], r10
+ test rax, rax
+ jnz copyHeaderLoop
+
+ mov ebx, dword ptr[r8 + 24]
+ sub rbx, 1
+ mov r10d, dword ptr[r8 + 40]
+ sub r10, 1
+ cmp rbx, r10
+ je copyArgs
+ mov rax, 0ah
+
+fillExtraArgsLoop:
+ sub r10, 1
+ mov qword ptr[rbp + r10 * 8 + 56], rax
+ cmp rbx, r10
+ jne fillExtraArgsLoop
+
+copyArgs:
+ mov rax, qword ptr[r8 + 48]
+
+copyArgsLoop:
+ test rbx, rbx
+ jz copyArgsDone
+ sub rbx, 1
+ mov r10, qword ptr[rax + rbx * 8]
+ mov qword ptr[rbp + rbx * 8 + 56], r10
+ jmp copyArgsLoop
+
+copyArgsDone:
+ mov qword ptr[rdx], rbp
+ mov r14, 0FFFF000000000000h
+ mov r15, 0FFFF000000000002h
+
+ mov rax, rcx
+ mov rcx, rbp
+ call rax
+
+ cmp qword ptr[rbp + 16], 1
+ je calleeFramePopped
+ mov rbp, qword ptr[rbp]
+
+calleeFramePopped:
+ mov rbx, qword ptr[rbp + 32] ; VM.topCallFrame
+ mov r10, qword ptr[rbp + 24]
+ mov qword ptr[rbx], r10
+ add rsp, 28h
+ pop rdi
+ pop rsi
+ pop rbx
+ pop r15
+ pop r14
+ pop r13
+ pop r12
+ pop rbp
+ ret
+callToNativeFunction ENDP
+
</ins><span class="cx"> returnFromJavaScript PROC
</span><span class="cx"> add rsp, 28h
</span><span class="cx"> pop rdi
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITStubsX86h"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITStubsX86.h (160093 => 160094)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITStubsX86.h        2013-12-04 16:13:53 UTC (rev 160093)
+++ trunk/Source/JavaScriptCore/jit/JITStubsX86.h        2013-12-04 16:40:17 UTC (rev 160094)
</span><span class="lines">@@ -206,7 +206,7 @@
</span><span class="cx">
</span><span class="cx"> // FIXME: Since Windows doesn't use the LLInt, we have inline stubs here.
</span><span class="cx"> // Until the LLInt is changed to support Windows, these stub needs to be updated.
</span><del>- __declspec(naked) EncodedJSValue callToJavaScript(void* code, ExecState*)
</del><ins>+ __declspec(naked) EncodedJSValue callToJavaScript(void* code, ExecState**, ProtoCallFrame*, Register*)
</ins><span class="cx"> {
</span><span class="cx"> __asm {
</span><span class="cx"> mov edx, [esp]
</span><span class="lines">@@ -217,11 +217,86 @@
</span><span class="cx"> push edi;
</span><span class="cx"> push ebx;
</span><span class="cx"> sub esp, 0x1c;
</span><del>- mov ebp, [esp + 0x34];
- mov ebx, [ebp];
- mov [ebx], eax;
- mov 4[ebx], edx
- call [esp + 0x30];
</del><ins>+ mov ecx, dword ptr[esp + 0x34];
+ mov esi, dword ptr[esp + 0x38];
+ mov ebp, dword ptr[esp + 0x3c];
+ sub ebp, 0x20;
+ mov dword ptr[ebp + 0x24], 0;
+ mov dword ptr[ebp + 0x20], 0;
+ mov dword ptr[ebp + 0x1c], 0;
+ mov dword ptr[ebp + 0x18], ecx;
+ mov ebx, [ecx];
+ mov dword ptr[ebp + 0x14], 0;
+ mov dword ptr[ebp + 0x10], ebx;
+ mov dword ptr[ebp + 0xc], 0;
+ mov dword ptr[ebp + 0x8], 1;
+ mov dword ptr[ebp + 0x4], edx;
+ mov dword ptr[ebp], eax;
+ mov eax, ebp;
+
+ mov edx, dword ptr[esi + 0x28];
+ add edx, 5;
+ sal edx, 3;
+ sub ebp, edx;
+ mov dword ptr[ebp], eax;
+
+ mov eax, 5;
+
+ copyHeaderLoop:
+ sub eax, 1;
+ mov ecx, dword ptr[esi + eax * 8];
+ mov dword ptr 8[ebp + eax * 8], ecx;
+ mov ecx, dword ptr 4[esi + eax * 8];
+ mov dword ptr 12[ebp + eax * 8], ecx;
+ test eax, eax;
+ jnz copyHeaderLoop;
+
+ mov edx, dword ptr[esi + 0x18];
+ sub edx, 1;
+ mov ecx, dword ptr[esi + 0x28];
+ sub ecx, 1;
+
+ cmp edx, ecx;
+ je copyArgs;
+
+ xor eax, eax;
+ mov ebx, -4;
+
+ fillExtraArgsLoop:
+ sub ecx, 1;
+ mov dword ptr 0x30[ebp + ecx * 8], eax;
+ mov dword ptr 0x34[ebp + ecx * 8], ebx;
+ cmp edx, ecx;
+ jne fillExtraArgsLoop;
+
+ copyArgs:
+ mov eax, dword ptr[esi + 0x2c];
+
+ copyArgsLoop:
+ test edx, edx;
+ jz copyArgsDone;
+ sub edx, 1;
+ mov ecx, dword ptr 0[eax + edx * 8];
+ mov ebx, dword ptr 4[eax + edx * 8];
+ mov dword ptr 0x30[ebp + edx * 8], ecx;
+ mov dword ptr 0x34[ebp + edx * 8], ebx;
+ jmp copyArgsLoop;
+
+ copyArgsDone:
+ mov ecx, dword ptr[esp + 0x34];
+ mov dword ptr[ecx], ebp;
+
+ call dword ptr[esp + 0x30];
+
+ cmp dword ptr[ebp + 8], 1;
+ je calleeFramePopped;
+ mov ebp, dword ptr[ebp];
+
+ calleeFramePopped:
+ mov ecx, dword ptr[ebp + 0x18];
+ mov ebx, dword ptr[ebp + 0x10];
+ mov dword ptr[ecx], ebx;
+
</ins><span class="cx"> add esp, 0x1c;
</span><span class="cx"> pop ebx;
</span><span class="cx"> pop edi;
</span><span class="lines">@@ -242,6 +317,109 @@
</span><span class="cx"> ret;
</span><span class="cx"> }
</span><span class="cx"> }
</span><ins>+
+ __declspec(naked) EncodedJSValue callToNativeFunction(void* code, ExecState**, ProtoCallFrame*, Register*)
+ {
+ __asm {
+ mov edx, [esp]
+ push ebp;
+ mov eax, ebp;
+ mov ebp, esp;
+ push esi;
+ push edi;
+ push ebx;
+ sub esp, 0x1c;
+ mov ecx, [esp + 0x34];
+ mov esi, [esp + 0x38];
+ mov ebp, [esp + 0x3c];
+ sub ebp, 0x20;
+ mov dword ptr[ebp + 0x24], 0;
+ mov dword ptr[ebp + 0x20], 0;
+ mov dword ptr[ebp + 0x1c], 0;
+ mov dword ptr[ebp + 0x18], ecx;
+ mov ebx, [ecx];
+ mov dword ptr[ebp + 0x14], 0;
+ mov dword ptr[ebp + 0x10], ebx;
+ mov dword ptr[ebp + 0xc], 0;
+ mov dword ptr[ebp + 0x8], 1;
+ mov dword ptr[ebp + 0x4], edx;
+ mov dword ptr[ebp], eax;
+ mov eax, ebp;
+
+ mov edx, dword ptr[esi + 0x28];
+ add edx, 5;
+ sal edx, 3;
+ sub ebp, edx;
+ mov dword ptr[ebp], eax;
+
+ mov eax, 5;
+
+ copyHeaderLoop:
+ sub eax, 1;
+ mov ecx, dword ptr[esi + eax * 8];
+ mov dword ptr 8[ebp + eax * 8], ecx;
+ mov ecx, dword ptr 4[esi + eax * 8];
+ mov dword ptr 12[ebp + eax * 8], ecx;
+ test eax, eax;
+ jnz copyHeaderLoop;
+
+ mov edx, dword ptr[esi + 0x18];
+ sub edx, 1;
+ mov ecx, dword ptr[esi + 0x28];
+ sub ecx, 1;
+
+ cmp edx, ecx;
+ je copyArgs;
+
+ xor eax, eax;
+ mov ebx, -4;
+
+ fillExtraArgsLoop:
+ sub ecx, 1;
+ mov dword ptr 0x30[ebp + ecx * 8], eax;
+ mov dword ptr 0x34[ebp + ecx * 8], ebx;
+ cmp edx, ecx;
+ jne fillExtraArgsLoop;
+
+ copyArgs:
+ mov eax, dword ptr[esi + 0x2c];
+
+ copyArgsLoop:
+ test edx, edx;
+ jz copyArgsDone;
+ sub edx, 1;
+ mov ecx, dword ptr 0[eax + edx * 8];
+ mov ebx, dword ptr 4[eax + edx * 8];
+ mov dword ptr 0x30[ebp + edx * 8], ecx;
+ mov dword ptr 0x34[ebp + edx * 8], ebx;
+ jmp copyArgsLoop;
+
+ copyArgsDone:
+ mov ecx, dword ptr[esp + 0x34];
+ mov dword ptr[ecx], ebp;
+
+ mov edi, dword ptr[esp + 0x30];
+ mov dword ptr[esp + 0x30], ebp;
+ mov ecx, ebp;
+ call edi;
+
+ cmp dword ptr[ebp + 8], 1;
+ je calleeFramePopped;
+ mov ebp, dword ptr[ebp];
+
+ calleeFramePopped:
+ mov ecx, dword ptr[ebp + 0x18];
+ mov ebx, dword ptr[ebp + 0x10];
+ mov dword ptr[ecx], ebx;
+
+ add esp, 0x1c;
+ pop ebx;
+ pop edi;
+ pop esi;
+ pop ebp;
+ ret;
+ }
+ }
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> #endif // COMPILER(MSVC)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLLIntOffsetsExtractorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LLIntOffsetsExtractor.cpp (160093 => 160094)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LLIntOffsetsExtractor.cpp        2013-12-04 16:13:53 UTC (rev 160093)
+++ trunk/Source/JavaScriptCore/llint/LLIntOffsetsExtractor.cpp        2013-12-04 16:40:17 UTC (rev 160094)
</span><span class="lines">@@ -46,7 +46,7 @@
</span><span class="cx"> #include "JumpTable.h"
</span><span class="cx"> #include "LLIntOfflineAsmConfig.h"
</span><span class="cx"> #include "MarkedSpace.h"
</span><del>-
</del><ins>+#include "ProtoCallFrame.h"
</ins><span class="cx"> #include "Structure.h"
</span><span class="cx"> #include "StructureChain.h"
</span><span class="cx"> #include "ValueProfile.h"
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLLIntThunksh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LLIntThunks.h (160093 => 160094)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LLIntThunks.h        2013-12-04 16:13:53 UTC (rev 160093)
+++ trunk/Source/JavaScriptCore/llint/LLIntThunks.h        2013-12-04 16:40:17 UTC (rev 160094)
</span><span class="lines">@@ -35,11 +35,14 @@
</span><span class="cx"> namespace JSC {
</span><span class="cx">
</span><span class="cx"> class ExecState;
</span><ins>+class Register;
</ins><span class="cx"> class VM;
</span><ins>+struct ProtoCallFrame;
</ins><span class="cx">
</span><span class="cx"> extern "C" {
</span><del>- EncodedJSValue callToJavaScript(void*, ExecState*);
</del><ins>+ EncodedJSValue callToJavaScript(void*, ExecState**, ProtoCallFrame*, Register*);
</ins><span class="cx"> void returnFromJavaScript();
</span><ins>+ EncodedJSValue callToNativeFunction(void*, ExecState**, ProtoCallFrame*, Register*);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> namespace LLInt {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLowLevelInterpreterasm"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm (160093 => 160094)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm        2013-12-04 16:13:53 UTC (rev 160093)
+++ trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm        2013-12-04 16:40:17 UTC (rev 160094)
</span><span class="lines">@@ -423,12 +423,16 @@
</span><span class="cx">
</span><span class="cx"> if C_LOOP
</span><span class="cx"> else
</span><del>-# stub to call into JavaScript
-# EncodedJSValue callToJavaScript(void* code, Register* topOfStack)
-# Note, if this stub or one of it's related macros is changed, make the
</del><ins>+# stub to call into JavaScript or Native functions
+# EncodedJSValue callToJavaScript(void* code, ExecState** vm, ProtoCallFrame* protoFrame, Register* topOfStack)
+# EncodedJSValue callToNativeFunction(void* code, ExecState** vm, ProtoCallFrame* protoFrame, Register* topOfStack)
+# Note, if these stubs or one of their related macros are changed, make the
</ins><span class="cx"> # equivalent changes in jit/JITStubsX86.h and/or jit/JITStubsMSVC64.asm
</span><span class="cx"> _callToJavaScript:
</span><del>- doCallToJavaScript()
</del><ins>+ doCallToJavaScript(makeJavaScriptCall, doReturnFromJavaScript)
+
+_callToNativeFunction:
+ doCallToJavaScript(makeHostFunctionCall, doReturnFromHostFunction)
</ins><span class="cx"> end
</span><span class="cx">
</span><span class="cx"> # Indicate the beginning of LLInt.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLowLevelInterpreter32_64asm"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm (160093 => 160094)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm        2013-12-04 16:13:53 UTC (rev 160093)
+++ trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm        2013-12-04 16:40:17 UTC (rev 160094)
</span><span class="lines">@@ -170,37 +170,71 @@
</span><span class="cx"> end
</span><span class="cx"> end
</span><span class="cx">
</span><del>-macro doCallToJavaScript()
</del><ins>+macro doCallToJavaScript(makeCall, doReturn)
</ins><span class="cx"> if X86
</span><ins>+ const entry = t5
+ const vmTopCallFrame = t2
+ const protoCallFrame = t4
+
</ins><span class="cx"> const extraStackSpace = 28
</span><span class="cx"> const previousCFR = t0
</span><span class="cx"> const previousPC = t1
</span><del>- const entry = t5
- const newCallFrame = t4
</del><ins>+ const temp1 = t0 # Same as previousCFR
+ const temp2 = t1 # Same as previousPC
+ const temp3 = t2 # same as vmTopCallFrame
+ const temp4 = t3
</ins><span class="cx"> elsif ARM or ARMv7_TRADITIONAL
</span><ins>+ const entry = a0
+ const vmTopCallFrame = a1
+ const protoCallFrame = a2
+ const topOfStack = a3
+
</ins><span class="cx"> const extraStackSpace = 16
</span><del>- const previousCFR = t3
</del><ins>+ const previousCFR = t3
</ins><span class="cx"> const previousPC = lr
</span><ins>+ const temp1 = t3 # Same as previousCFR
+ const temp2 = a3 # Same as topOfStack
+ const temp3 = t4
+ const temp4 = t5
+ elsif ARMv7
</ins><span class="cx"> const entry = a0
</span><del>- const newCallFrame = a1
- elsif ARMv7
</del><ins>+ const vmTopCallFrame = a1
+ const protoCallFrame = a2
+ const topOfStack = a3
+
</ins><span class="cx"> const extraStackSpace = 28
</span><del>- const previousCFR = t3
</del><ins>+ const previousCFR = t3
</ins><span class="cx"> const previousPC = lr
</span><ins>+ const temp1 = t3 # Same as previousCFR
+ const temp2 = a3 # Same as topOfStack
+ const temp3 = t4
+ const temp4 = t5
+ elsif MIPS
</ins><span class="cx"> const entry = a0
</span><del>- const newCallFrame = a1
- elsif MIPS
</del><ins>+ const vmTopCallFrame = a1
+ const protoCallFrame = a2
+ const topOfStack = a3
+
</ins><span class="cx"> const extraStackSpace = 36
</span><span class="cx"> const previousCFR = t2
</span><span class="cx"> const previousPC = lr
</span><ins>+ const temp1 = t3
+ const temp2 = t4
+ const temp3 = t5
+ const temp4 = t6
+ elsif SH4
</ins><span class="cx"> const entry = a0
</span><del>- const newCallFrame = a1
- elsif SH4
</del><ins>+ const vmTopCallFrame = a1
+ const protoCallFrame = a2
+ const topOfStack = a3
+
</ins><span class="cx"> const extraStackSpace = 20
</span><del>- const previousCFR = t3
</del><ins>+ const previousCFR = t3
</ins><span class="cx"> const previousPC = lr
</span><del>- const entry = a0
- const newCallFrame = a1
</del><ins>+ const temp1 = t3 # Same as previousCFR
+ const temp2 = a3 # Same as topOfStack
+ const temp3 = t4
+ const temp4 = t5
</ins><span class="cx"> end
</span><span class="cx">
</span><span class="cx"> if X86
</span><span class="lines">@@ -210,22 +244,116 @@
</span><span class="cx"> functionPrologue(extraStackSpace)
</span><span class="cx"> if X86
</span><span class="cx"> loadp extraStackSpace+20[sp], entry
</span><del>- loadp extraStackSpace+24[sp], newCallFrame
</del><ins>+ loadp extraStackSpace+24[sp], vmTopCallFrame
+ loadp extraStackSpace+28[sp], protoCallFrame
+ loadp extraStackSpace+32[sp], cfr
</ins><span class="cx"> else
</span><span class="cx"> move cfr, previousCFR
</span><ins>+ move topOfStack, cfr
</ins><span class="cx"> end
</span><span class="cx">
</span><del>- move newCallFrame, cfr
- loadp [cfr], newCallFrame
- storep previousCFR, [newCallFrame]
- storep previousPC, 4[newCallFrame]
</del><ins>+ subp (CallFrameHeaderSlots-1)*8, cfr
+ storep 0, ArgumentCount+4[cfr]
+ storep 0, ArgumentCount[cfr]
+ storep 0, Callee+4[cfr]
+ storep vmTopCallFrame, Callee[cfr]
+ loadp [vmTopCallFrame], temp4
+ storep 0, ScopeChain+4[cfr]
+ storep temp4, ScopeChain[cfr]
+ storep 0, CodeBlock+4[cfr]
+ storep 1, CodeBlock[cfr]
+ storep previousPC, ReturnPC[cfr]
+ storep previousCFR, CallerFrame[cfr]
+ move cfr, temp1
+
+ loadi ProtoCallFrame::paddedArgCount[protoCallFrame], temp2
+ addp CallFrameHeaderSlots, temp2, temp2
+ lshiftp 3, temp2
+ subp temp2, cfr
+ storep temp1, CallerFrame[cfr]
+
+ move 5, temp1
+
+.copyHeaderLoop:
+ subi 1, temp1
+ loadp [protoCallFrame, temp1, 8], temp3
+ storep temp3, CodeBlock[cfr, temp1, 8]
+ loadp 4[protoCallFrame, temp1, 8], temp3
+ storep temp3, CodeBlock+4[cfr, temp1, 8]
+ btinz temp1, .copyHeaderLoop
+
+ loadi ProtoCallFrame::argCountAndCodeOriginValue[protoCallFrame], temp2
+ subi 1, temp2
+ loadi ProtoCallFrame::paddedArgCount[protoCallFrame], temp3
+ subi 1, temp3
+
+ bieq temp2, temp3, .copyArgs
+ move 0, temp1
+ move UndefinedTag, temp4
+.fillExtraArgsLoop:
+ subi 1, temp3
+ storep temp1, ThisArgumentOffset+8+PayloadOffset[cfr, temp3, 8]
+ storep temp4, ThisArgumentOffset+8+TagOffset[cfr, temp3, 8]
+ bineq temp2, temp3, .fillExtraArgsLoop
+
+.copyArgs:
+ loadp ProtoCallFrame::args[protoCallFrame], temp1
+
+.copyArgsLoop:
+ btiz temp2, .copyArgsDone
+ subi 1, temp2
+ loadp PayloadOffset[temp1, temp2, 8], temp3
+ loadp TagOffset[temp1, temp2, 8], temp4
+ storep temp3, ThisArgumentOffset+8+PayloadOffset[cfr, temp2, 8]
+ storep temp4, ThisArgumentOffset+8+TagOffset[cfr, temp2, 8]
+ jmp .copyArgsLoop
+
+.copyArgsDone:
+ if X86
+ loadp extraStackSpace+24[sp], vmTopCallFrame
+ end
+ storep cfr, [vmTopCallFrame]
+
+ makeCall(entry, temp1)
+
+ bpeq CodeBlock[cfr], 1, .calleeFramePopped
+ loadp CallerFrame[cfr], cfr
+
+.calleeFramePopped:
+ loadp Callee[cfr], temp3 # VM.topCallFrame
+ loadp ScopeChain[cfr], temp4
+ storep temp4, [temp3]
+
+ doReturn(extraStackSpace)
+end
+
+macro makeJavaScriptCall(entry, temp)
</ins><span class="cx"> call entry
</span><ins>+end
</ins><span class="cx">
</span><ins>+macro makeHostFunctionCall(entry, temp)
+ move entry, temp
+ if X86
+ # Put cfr on stack as arg0, also put it in ecx for "fastcall" targets
+ poke cfr, 0
+ move cfr, t2
+ else
+ move cfr, a0
+ end
+ call temp
+end
+
+macro doReturnFromJavaScript(extraStackSpace)
</ins><span class="cx"> _returnFromJavaScript:
</span><span class="cx"> functionEpilogue(extraStackSpace)
</span><span class="cx"> ret
</span><span class="cx"> end
</span><span class="cx">
</span><ins>+macro doReturnFromHostFunction(extraStackSpace)
+ functionEpilogue(extraStackSpace)
+ ret
+end
+
</ins><span class="cx"> # Debugging operation if you'd like to print an operand in the instruction stream. fromWhere
</span><span class="cx"> # should be an immediate integer - any integer you like; use it to identify the place you're
</span><span class="cx"> # debugging from. operand should likewise be an immediate, and should identify the operand
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLowLevelInterpreter64asm"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm (160093 => 160094)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm        2013-12-04 16:13:53 UTC (rev 160093)
+++ trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm        2013-12-04 16:40:17 UTC (rev 160094)
</span><span class="lines">@@ -113,25 +113,31 @@
</span><span class="cx"> end
</span><span class="cx"> end
</span><span class="cx">
</span><del>-macro doCallToJavaScript()
</del><ins>+macro doCallToJavaScript(makeCall, doReturn)
</ins><span class="cx"> if X86_64
</span><ins>+ const entry = t5
+ const vmTopCallFrame = t4
+ const protoCallFrame = t1
+ const topOfStack = t2
+
</ins><span class="cx"> const extraStackSpace = 8
</span><span class="cx"> const previousCFR = t0
</span><span class="cx"> const previousPC = t6
</span><del>- const entry = t5
- const newCallFrame = t4
</del><ins>+ const temp1 = t0
+ const temp2 = t3
+ const temp3 = t6
</ins><span class="cx"> elsif ARM64
</span><ins>+ const entry = a0
+ const vmTopCallFrame = a1
+ const protoCallFrame = a2
+ const topOfStack = a3
+
</ins><span class="cx"> const extraStackSpace = 0
</span><span class="cx"> const previousCFR = t4
</span><span class="cx"> const previousPC = lr
</span><del>- const entry = a0
- const newCallFrame = a1
- elsif C_LOOP
- const extraStackSpace = 0
- const previousCFR = t4
- const previousPC = lr
- const entry = a0
- const newCallFrame = a1
</del><ins>+ const temp1 = t3
+ const temp2 = t5
+ const temp3 = t6
</ins><span class="cx"> end
</span><span class="cx">
</span><span class="cx"> if X86_64
</span><span class="lines">@@ -140,19 +146,97 @@
</span><span class="cx"> move cfr, previousCFR
</span><span class="cx"> functionPrologue(extraStackSpace)
</span><span class="cx">
</span><del>- move newCallFrame, cfr
- loadp [cfr], newCallFrame
- storep previousCFR, [newCallFrame]
- storep previousPC, 8[newCallFrame]
</del><ins>+ move topOfStack, cfr
+ subp (CallFrameHeaderSlots-1)*8, cfr
+ storep 0, ArgumentCount[cfr]
+ storep vmTopCallFrame, Callee[cfr]
+ loadp [vmTopCallFrame], temp1
+ storep temp1, ScopeChain[cfr]
+ storep 1, CodeBlock[cfr]
+ storep previousPC, ReturnPC[cfr]
+ storep previousCFR, CallerFrame[cfr]
+ move cfr, temp1
+
+ loadi ProtoCallFrame::paddedArgCount[protoCallFrame], temp2
+ addp CallFrameHeaderSlots, temp2, temp2
+ lshiftp 3, temp2
+ subp temp2, cfr
+ storep temp1, CallerFrame[cfr]
+
+ move 5, temp1
+
+.copyHeaderLoop:
+ subi 1, temp1
+ loadp [protoCallFrame, temp1, 8], temp3
+ storep temp3, CodeBlock[cfr, temp1, 8]
+ btinz temp1, .copyHeaderLoop
+
+ loadi ProtoCallFrame::argCountAndCodeOriginValue[protoCallFrame], temp2
+ subi 1, temp2
+ loadi ProtoCallFrame::paddedArgCount[protoCallFrame], temp3
+ subi 1, temp3
+
+ bieq temp2, temp3, .copyArgs
+ move ValueUndefined, temp1
+.fillExtraArgsLoop:
+ subi 1, temp3
+ storep temp1, ThisArgumentOffset+8[cfr, temp3, 8]
+ bineq temp2, temp3, .fillExtraArgsLoop
+
+.copyArgs:
+ loadp ProtoCallFrame::args[protoCallFrame], temp1
+
+.copyArgsLoop:
+ btiz temp2, .copyArgsDone
+ subi 1, temp2
+ loadp [temp1, temp2, 8], temp3
+ storep temp3, ThisArgumentOffset+8[cfr, temp2, 8]
+ jmp .copyArgsLoop
+
+.copyArgsDone:
+ storep cfr, [vmTopCallFrame]
+
</ins><span class="cx"> move 0xffff000000000000, csr1
</span><span class="cx"> addp 2, csr1, csr2
</span><ins>+
+ makeCall(entry, temp1)
+
+ bpeq CodeBlock[cfr], 1, .calleeFramePopped
+ loadp CallerFrame[cfr], cfr
+
+.calleeFramePopped:
+ loadp Callee[cfr], temp2 # VM.topCallFrame
+ loadp ScopeChain[cfr], temp3
+ storep temp3, [temp2]
+
+ doReturn(extraStackSpace)
+end
+
+macro makeJavaScriptCall(entry, temp)
</ins><span class="cx"> call entry
</span><ins>+end
</ins><span class="cx">
</span><ins>+macro makeHostFunctionCall(entry, temp)
+ move entry, temp
+ if X86_64
+ move cfr, t5
+ elsif ARM64 or C_LOOP
+ move cfr, a0
+ end
+ call temp
+end
+
+macro doReturnFromJavaScript(extraStackSpace)
</ins><span class="cx"> _returnFromJavaScript:
</span><span class="cx"> functionEpilogue(extraStackSpace)
</span><span class="cx"> ret
</span><span class="cx"> end
</span><span class="cx">
</span><ins>+macro doReturnFromHostFunction(extraStackSpace)
+ functionEpilogue(extraStackSpace)
+ ret
+end
+
</ins><span class="cx"> macro prepareStateForCCall()
</span><span class="cx"> leap [PB, PC, 8], PC
</span><span class="cx"> move PB, t3
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeArgListh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/ArgList.h (160093 => 160094)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/ArgList.h        2013-12-04 16:13:53 UTC (rev 160093)
+++ trunk/Source/JavaScriptCore/runtime/ArgList.h        2013-12-04 16:40:17 UTC (rev 160094)
</span><span class="lines">@@ -139,6 +139,7 @@
</span><span class="cx"> };
</span><span class="cx">
</span><span class="cx"> class ArgList {
</span><ins>+ friend class Interpreter;
</ins><span class="cx"> friend class JIT;
</span><span class="cx"> public:
</span><span class="cx"> ArgList()
</span><span class="lines">@@ -172,6 +173,8 @@
</span><span class="cx"> JS_EXPORT_PRIVATE void getSlice(int startIndex, ArgList& result) const;
</span><span class="cx">
</span><span class="cx"> private:
</span><ins>+ JSValue* data() const { return m_args; }
+
</ins><span class="cx"> JSValue* m_args;
</span><span class="cx"> int m_argCount;
</span><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSArraycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSArray.cpp (160093 => 160094)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSArray.cpp        2013-12-04 16:13:53 UTC (rev 160093)
+++ trunk/Source/JavaScriptCore/runtime/JSArray.cpp        2013-12-04 16:40:17 UTC (rev 160094)
</span><span class="lines">@@ -1320,7 +1320,11 @@
</span><span class="cx"> m_cachedCall->setThis(jsUndefined());
</span><span class="cx"> m_cachedCall->setArgument(0, va);
</span><span class="cx"> m_cachedCall->setArgument(1, vb);
</span><ins>+#if ENABLE(LLINT_C_LOOP)
</ins><span class="cx"> compareResult = m_cachedCall->call().toNumber(m_cachedCall->newCallFrame(m_exec));
</span><ins>+#else
+ compareResult = m_cachedCall->call().toNumber(m_exec);
+#endif
</ins><span class="cx"> } else {
</span><span class="cx"> MarkedArgumentBuffer arguments;
</span><span class="cx"> arguments.append(va);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeStringPrototypecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/StringPrototype.cpp (160093 => 160094)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/StringPrototype.cpp        2013-12-04 16:13:53 UTC (rev 160093)
+++ trunk/Source/JavaScriptCore/runtime/StringPrototype.cpp        2013-12-04 16:40:17 UTC (rev 160094)
</span><span class="lines">@@ -504,7 +504,11 @@
</span><span class="cx">
</span><span class="cx"> cachedCall.setThis(jsUndefined());
</span><span class="cx"> JSValue jsResult = cachedCall.call();
</span><ins>+#if ENABLE(LLINT_C_LOOP)
</ins><span class="cx"> replacements.append(jsResult.toString(cachedCall.newCallFrame(exec))->value(exec));
</span><ins>+#else
+ replacements.append(jsResult.toString(exec)->value(exec));
+#endif
</ins><span class="cx"> if (exec->hadException())
</span><span class="cx"> break;
</span><span class="cx">
</span><span class="lines">@@ -543,7 +547,11 @@
</span><span class="cx">
</span><span class="cx"> cachedCall.setThis(jsUndefined());
</span><span class="cx"> JSValue jsResult = cachedCall.call();
</span><ins>+#if ENABLE(LLINT_C_LOOP)
</ins><span class="cx"> replacements.append(jsResult.toString(cachedCall.newCallFrame(exec))->value(exec));
</span><ins>+#else
+ replacements.append(jsResult.toString(exec)->value(exec));
+#endif
</ins><span class="cx"> if (exec->hadException())
</span><span class="cx"> break;
</span><span class="cx">
</span></span></pre>
</div>
</div>
</body>
</html>