Title: [179862] trunk/Source/_javascript_Core
Revision
179862
Author
[email protected]
Date
2015-02-09 19:27:43 -0800 (Mon, 09 Feb 2015)

Log Message

Varargs frame set-up should be factored out for use by other JITs
https://bugs.webkit.org/show_bug.cgi?id=141388

Reviewed by Michael Saboff.
        
Previously the code that dealt with varargs always assumed that we were setting up a varargs call
frame by literally following the execution semantics of op_call_varargs. This isn't how it'll
happen once the DFG and FTL do varargs calls, or when varargs calls get inlined. The DFG and FTL
don't literally execute bytecode; for example their stack frame layout has absolutely nothing in
common with what the bytecode says, and that will never change.
        
This patch makes two changes:
        
Setting up the varargs callee frame can be done in smaller steps: particularly in the case of a
varargs call that gets inlined, we aren't going to actually want to set up a callee frame in
full - we just want to put the arguments somewhere, and that place will not have much (if
anything) in common with the call frame format. This patch factors that out into something called
a loadVarargs. The thing we used to call loadVarargs is now called setupVarargsFrame. This patch
also separates loading varargs from setting this, since the fact that those two things are done
together is a detail made explicit in bytecode but it's not at all required in the higher-tier
engines. In the process of factoring this code out, I found a bunch of off-by-one errors in the
various calculations. I fixed them. The distance from the caller's frame pointer to the callee
frame pointer is always:
        
    numUsedCallerSlots + argCount + 1 + CallFrameSize
        
where numUsedCallerSlots is toLocal(firstFreeRegister) - 1, which simplifies down to just
-firstFreeRegister. The code now speaks of numUsedCallerSlots rather than firstFreeRegister,
since the latter is a bytecode peculiarity that doesn't apply in the DFG or FTL. In the DFG, the
internally-computed frame size, minus the parameter slots, will be used for numUsedCallerSlots.
In the FTL, we will essentially compute numUsedCallerSlots dynamically by subtracting SP from FP.
Eventually, LLVM might give us some cleaner way of doing this, but it probably doesn't matter
very much.
        
The arguments forwarding optimization is factored out of the Baseline JIT: the DFG and FTL will
want to do this optimization as well, but it involves quite a bit of code. So, this code is now
factored out into SetupVarargsFrame.h|cpp, so that other JITs can use it. In the process of factoring
this code out I noticed that the 32-bit and 64-bit code is nearly identical, so I combined them.

* CMakeLists.txt:
* _javascript_Core.vcxproj/_javascript_Core.vcxproj:
* _javascript_Core.xcodeproj/project.pbxproj:
* bytecode/CodeBlock.h:
(JSC::ExecState::r):
(JSC::ExecState::uncheckedR):
* bytecode/VirtualRegister.h:
(JSC::VirtualRegister::operator+):
(JSC::VirtualRegister::operator-):
(JSC::VirtualRegister::operator+=):
(JSC::VirtualRegister::operator-=):
* interpreter/CallFrame.h:
* interpreter/Interpreter.cpp:
(JSC::sizeFrameForVarargs):
(JSC::loadVarargs):
(JSC::setupVarargsFrame):
(JSC::setupVarargsFrameAndSetThis):
* interpreter/Interpreter.h:
* jit/AssemblyHelpers.h:
(JSC::AssemblyHelpers::emitGetFromCallFrameHeaderPtr):
(JSC::AssemblyHelpers::emitGetFromCallFrameHeader32):
(JSC::AssemblyHelpers::emitGetFromCallFrameHeader64):
* jit/JIT.h:
* jit/JITCall.cpp:
(JSC::JIT::compileSetupVarargsFrame):
* jit/JITCall32_64.cpp:
(JSC::JIT::compileSetupVarargsFrame):
* jit/JITInlines.h:
(JSC::JIT::callOperation):
(JSC::JIT::emitGetFromCallFrameHeaderPtr): Deleted.
(JSC::JIT::emitGetFromCallFrameHeader32): Deleted.
(JSC::JIT::emitGetFromCallFrameHeader64): Deleted.
* jit/JITOperations.cpp:
* jit/JITOperations.h:
* jit/SetupVarargsFrame.cpp: Added.
(JSC::emitSetupVarargsFrameFastCase):
* jit/SetupVarargsFrame.h: Added.
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
* runtime/Arguments.cpp:
(JSC::Arguments::copyToArguments):
* runtime/Arguments.h:
* runtime/JSArray.cpp:
(JSC::JSArray::copyToArguments):
* runtime/JSArray.h:

Modified Paths

Added Paths

Diff

Modified: trunk/Source/_javascript_Core/CMakeLists.txt (179861 => 179862)


--- trunk/Source/_javascript_Core/CMakeLists.txt	2015-02-10 01:21:38 UTC (rev 179861)
+++ trunk/Source/_javascript_Core/CMakeLists.txt	2015-02-10 03:27:43 UTC (rev 179862)
@@ -349,6 +349,7 @@
     jit/JITStubs.cpp
     jit/JITThunks.cpp
     jit/JITToDFGDeferredCompilationCallback.cpp
+    jit/SetupVarargsFrame.cpp
     jit/PolymorphicCallStubRoutine.cpp
     jit/Reg.cpp
     jit/RegisterPreservationWrapperGenerator.cpp

Modified: trunk/Source/_javascript_Core/ChangeLog (179861 => 179862)


--- trunk/Source/_javascript_Core/ChangeLog	2015-02-10 01:21:38 UTC (rev 179861)
+++ trunk/Source/_javascript_Core/ChangeLog	2015-02-10 03:27:43 UTC (rev 179862)
@@ -1,5 +1,92 @@
 2015-02-09  Filip Pizlo  <[email protected]>
 
+        Varargs frame set-up should be factored out for use by other JITs
+        https://bugs.webkit.org/show_bug.cgi?id=141388
+
+        Reviewed by Michael Saboff.
+        
+        Previously the code that dealt with varargs always assumed that we were setting up a varargs call
+        frame by literally following the execution semantics of op_call_varargs. This isn't how it'll
+        happen once the DFG and FTL do varargs calls, or when varargs calls get inlined. The DFG and FTL
+        don't literally execute bytecode; for example their stack frame layout has absolutely nothing in
+        common with what the bytecode says, and that will never change.
+        
+        This patch makes two changes:
+        
+        Setting up the varargs callee frame can be done in smaller steps: particularly in the case of a
+        varargs call that gets inlined, we aren't going to actually want to set up a callee frame in
+        full - we just want to put the arguments somewhere, and that place will not have much (if
+        anything) in common with the call frame format. This patch factors that out into something called
+        a loadVarargs. The thing we used to call loadVarargs is now called setupVarargsFrame. This patch
+        also separates loading varargs from setting this, since the fact that those two things are done
+        together is a detail made explicit in bytecode but it's not at all required in the higher-tier
+        engines. In the process of factoring this code out, I found a bunch of off-by-one errors in the
+        various calculations. I fixed them. The distance from the caller's frame pointer to the callee
+        frame pointer is always:
+        
+            numUsedCallerSlots + argCount + 1 + CallFrameSize
+        
+        where numUsedCallerSlots is toLocal(firstFreeRegister) - 1, which simplifies down to just
+        -firstFreeRegister. The code now speaks of numUsedCallerSlots rather than firstFreeRegister,
+        since the latter is a bytecode peculiarity that doesn't apply in the DFG or FTL. In the DFG, the
+        internally-computed frame size, minus the parameter slots, will be used for numUsedCallerSlots.
+        In the FTL, we will essentially compute numUsedCallerSlots dynamically by subtracting SP from FP.
+        Eventually, LLVM might give us some cleaner way of doing this, but it probably doesn't matter
+        very much.
+        
+        The arguments forwarding optimization is factored out of the Baseline JIT: the DFG and FTL will
+        want to do this optimization as well, but it involves quite a bit of code. So, this code is now
+        factored out into SetupVarargsFrame.h|cpp, so that other JITs can use it. In the process of factoring
+        this code out I noticed that the 32-bit and 64-bit code is nearly identical, so I combined them.
+
+        * CMakeLists.txt:
+        * _javascript_Core.vcxproj/_javascript_Core.vcxproj:
+        * _javascript_Core.xcodeproj/project.pbxproj:
+        * bytecode/CodeBlock.h:
+        (JSC::ExecState::r):
+        (JSC::ExecState::uncheckedR):
+        * bytecode/VirtualRegister.h:
+        (JSC::VirtualRegister::operator+):
+        (JSC::VirtualRegister::operator-):
+        (JSC::VirtualRegister::operator+=):
+        (JSC::VirtualRegister::operator-=):
+        * interpreter/CallFrame.h:
+        * interpreter/Interpreter.cpp:
+        (JSC::sizeFrameForVarargs):
+        (JSC::loadVarargs):
+        (JSC::setupVarargsFrame):
+        (JSC::setupVarargsFrameAndSetThis):
+        * interpreter/Interpreter.h:
+        * jit/AssemblyHelpers.h:
+        (JSC::AssemblyHelpers::emitGetFromCallFrameHeaderPtr):
+        (JSC::AssemblyHelpers::emitGetFromCallFrameHeader32):
+        (JSC::AssemblyHelpers::emitGetFromCallFrameHeader64):
+        * jit/JIT.h:
+        * jit/JITCall.cpp:
+        (JSC::JIT::compileSetupVarargsFrame):
+        * jit/JITCall32_64.cpp:
+        (JSC::JIT::compileSetupVarargsFrame):
+        * jit/JITInlines.h:
+        (JSC::JIT::callOperation):
+        (JSC::JIT::emitGetFromCallFrameHeaderPtr): Deleted.
+        (JSC::JIT::emitGetFromCallFrameHeader32): Deleted.
+        (JSC::JIT::emitGetFromCallFrameHeader64): Deleted.
+        * jit/JITOperations.cpp:
+        * jit/JITOperations.h:
+        * jit/SetupVarargsFrame.cpp: Added.
+        (JSC::emitSetupVarargsFrameFastCase):
+        * jit/SetupVarargsFrame.h: Added.
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+        * runtime/Arguments.cpp:
+        (JSC::Arguments::copyToArguments):
+        * runtime/Arguments.h:
+        * runtime/JSArray.cpp:
+        (JSC::JSArray::copyToArguments):
+        * runtime/JSArray.h:
+
+2015-02-09  Filip Pizlo  <[email protected]>
+
         DFG call codegen should resolve the callee operand as late as possible
         https://bugs.webkit.org/show_bug.cgi?id=141398
 

Modified: trunk/Source/_javascript_Core/_javascript_Core.vcxproj/_javascript_Core.vcxproj (179861 => 179862)


--- trunk/Source/_javascript_Core/_javascript_Core.vcxproj/_javascript_Core.vcxproj	2015-02-10 01:21:38 UTC (rev 179861)
+++ trunk/Source/_javascript_Core/_javascript_Core.vcxproj/_javascript_Core.vcxproj	2015-02-10 03:27:43 UTC (rev 179862)
@@ -620,6 +620,7 @@
     <ClCompile Include="..\jit\JITStubs.cpp" />
     <ClCompile Include="..\jit\JITThunks.cpp" />
     <ClCompile Include="..\jit\JITToDFGDeferredCompilationCallback.cpp" />
+    <ClCompile Include="..\jit\SetupVarargsFrame.cpp" />
     <ClCompile Include="..\jit\PolymorphicCallStubRoutine.cpp" />
     <ClCompile Include="..\jit\Reg.cpp" />
     <ClCompile Include="..\jit\RegisterPreservationWrapperGenerator.cpp" />
@@ -1353,6 +1354,7 @@
     <ClInclude Include="..\jit\JITToDFGDeferredCompilationCallback.h" />
     <ClInclude Include="..\jit\JITWriteBarrier.h" />
     <ClInclude Include="..\jit\JSInterfaceJIT.h" />
+    <ClInclude Include="..\jit\SetupVarargsFrame.h" />
     <ClInclude Include="..\jit\PolymorphicCallStubRoutine.h" />
     <ClInclude Include="..\jit\Reg.h" />
     <ClInclude Include="..\jit\RegisterPreservationWrapperGenerator.h" />

Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (179861 => 179862)


--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2015-02-10 01:21:38 UTC (rev 179861)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2015-02-10 03:27:43 UTC (rev 179862)
@@ -632,6 +632,8 @@
 		0FEA0A33170D40BF00BB722C /* DFGJITCode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FEA0A2F170D40BF00BB722C /* DFGJITCode.cpp */; };
 		0FEA0A34170D40BF00BB722C /* DFGJITCode.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FEA0A30170D40BF00BB722C /* DFGJITCode.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0FEB3ECF16237F6C00AB67AD /* MacroAssembler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FEB3ECE16237F6700AB67AD /* MacroAssembler.cpp */; };
+		0FEE98411A8865B700754E93 /* SetupVarargsFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FEE98401A8865B600754E93 /* SetupVarargsFrame.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		0FEE98431A89227500754E93 /* SetupVarargsFrame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FEE98421A89227500754E93 /* SetupVarargsFrame.cpp */; };
 		0FEFC9AA1681A3B300567F53 /* DFGOSRExitJumpPlaceholder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FEFC9A71681A3B000567F53 /* DFGOSRExitJumpPlaceholder.cpp */; };
 		0FEFC9AB1681A3B600567F53 /* DFGOSRExitJumpPlaceholder.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FEFC9A81681A3B000567F53 /* DFGOSRExitJumpPlaceholder.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0FF0F19916B729F6005DF95B /* DFGLongLivedState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FB4B51C16B62772003F696B /* DFGLongLivedState.cpp */; };
@@ -2313,6 +2315,8 @@
 		0FEA0A2F170D40BF00BB722C /* DFGJITCode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGJITCode.cpp; path = dfg/DFGJITCode.cpp; sourceTree = "<group>"; };
 		0FEA0A30170D40BF00BB722C /* DFGJITCode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGJITCode.h; path = dfg/DFGJITCode.h; sourceTree = "<group>"; };
 		0FEB3ECE16237F6700AB67AD /* MacroAssembler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MacroAssembler.cpp; sourceTree = "<group>"; };
+		0FEE98401A8865B600754E93 /* SetupVarargsFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SetupVarargsFrame.h; sourceTree = "<group>"; };
+		0FEE98421A89227500754E93 /* SetupVarargsFrame.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SetupVarargsFrame.cpp; sourceTree = "<group>"; };
 		0FEFC9A71681A3B000567F53 /* DFGOSRExitJumpPlaceholder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGOSRExitJumpPlaceholder.cpp; path = dfg/DFGOSRExitJumpPlaceholder.cpp; sourceTree = "<group>"; };
 		0FEFC9A81681A3B000567F53 /* DFGOSRExitJumpPlaceholder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGOSRExitJumpPlaceholder.h; path = dfg/DFGOSRExitJumpPlaceholder.h; sourceTree = "<group>"; };
 		0FF4272F158EBD44004CB9FF /* Disassembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Disassembler.h; path = disassembler/Disassembler.h; sourceTree = "<group>"; };
@@ -3792,6 +3796,8 @@
 				0FC712E117CD878F008CC93C /* JITToDFGDeferredCompilationCallback.h */,
 				A76F54A213B28AAB00EF2BCE /* JITWriteBarrier.h */,
 				A76C51741182748D00715B05 /* JSInterfaceJIT.h */,
+				0FEE98421A89227500754E93 /* SetupVarargsFrame.cpp */,
+				0FEE98401A8865B600754E93 /* SetupVarargsFrame.h */,
 				0FE834151A6EF97B00D04847 /* PolymorphicCallStubRoutine.cpp */,
 				0FE834161A6EF97B00D04847 /* PolymorphicCallStubRoutine.h */,
 				0FA7A8E918B413C80052371D /* Reg.cpp */,
@@ -5510,6 +5516,7 @@
 				C2FC9BD316644DFB00810D33 /* CopiedBlockInlines.h in Headers */,
 				C2EAA3FA149A835E00FCE112 /* CopiedSpace.h in Headers */,
 				C2C8D02D14A3C6E000578E65 /* CopiedSpaceInlines.h in Headers */,
+				0FEE98411A8865B700754E93 /* SetupVarargsFrame.h in Headers */,
 				0FC3CCFD19ADA410006AC72A /* DFGBlockMapInlines.h in Headers */,
 				0F5A52D017ADD717008ECB2D /* CopyToken.h in Headers */,
 				C2239D1816262BDD005AC5FD /* CopyVisitor.h in Headers */,
@@ -7137,6 +7144,7 @@
 				A7CA3AE717DA41AE006538AF /* JSWeakMap.cpp in Sources */,
 				A7482B9411671147003B0712 /* JSWeakObjectMapRefPrivate.cpp in Sources */,
 				1442566115EDE98D0066A49B /* JSWithScope.cpp in Sources */,
+				0FEE98431A89227500754E93 /* SetupVarargsFrame.cpp in Sources */,
 				86E3C618167BABEE006D760A /* JSWrapperMap.mm in Sources */,
 				14280870107EC1340013E7B2 /* JSWrapperObject.cpp in Sources */,
 				BCFD8C920EEB2EE700283848 /* JumpTable.cpp in Sources */,

Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.h (179861 => 179862)


--- trunk/Source/_javascript_Core/bytecode/CodeBlock.h	2015-02-10 01:21:38 UTC (rev 179861)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.h	2015-02-10 03:27:43 UTC (rev 179862)
@@ -1236,12 +1236,22 @@
     return this[index];
 }
 
+inline Register& ExecState::r(VirtualRegister reg)
+{
+    return r(reg.offset());
+}
+
 inline Register& ExecState::uncheckedR(int index)
 {
     RELEASE_ASSERT(index < FirstConstantRegisterIndex);
     return this[index];
 }
 
+inline Register& ExecState::uncheckedR(VirtualRegister reg)
+{
+    return uncheckedR(reg.offset());
+}
+
 inline JSValue ExecState::argumentAfterCapture(size_t argument)
 {
     if (argument >= argumentCount())

Modified: trunk/Source/_javascript_Core/bytecode/VirtualRegister.h (179861 => 179862)


--- trunk/Source/_javascript_Core/bytecode/VirtualRegister.h	2015-02-10 01:21:38 UTC (rev 179861)
+++ trunk/Source/_javascript_Core/bytecode/VirtualRegister.h	2015-02-10 03:27:43 UTC (rev 179862)
@@ -70,6 +70,23 @@
     bool operator==(const VirtualRegister other) const { return m_virtualRegister == other.m_virtualRegister; }
     bool operator!=(const VirtualRegister other) const { return m_virtualRegister != other.m_virtualRegister; }
     
+    VirtualRegister operator+(int value) const
+    {
+        return VirtualRegister(offset() + value);
+    }
+    VirtualRegister operator-(int value) const
+    {
+        return VirtualRegister(offset() - value);
+    }
+    VirtualRegister& operator+=(int value)
+    {
+        return *this = *this + value;
+    }
+    VirtualRegister& operator-=(int value)
+    {
+        return *this = *this - value;
+    }
+    
     void dump(PrintStream& out) const;
 
 private:

Modified: trunk/Source/_javascript_Core/interpreter/CallFrame.h (179861 => 179862)


--- trunk/Source/_javascript_Core/interpreter/CallFrame.h	2015-02-10 01:21:38 UTC (rev 179861)
+++ trunk/Source/_javascript_Core/interpreter/CallFrame.h	2015-02-10 03:27:43 UTC (rev 179862)
@@ -203,8 +203,10 @@
 
         // Read a register from the codeframe (or constant from the CodeBlock).
         Register& r(int);
+        Register& r(VirtualRegister);
         // Read a register for a non-constant
         Register& uncheckedR(int);
+        Register& uncheckedR(VirtualRegister);
 
         // Access to arguments as passed. (After capture, arguments may move to a different location.)
         size_t argumentCount() const { return argumentCountIncludingThis() - 1; }

Modified: trunk/Source/_javascript_Core/interpreter/Interpreter.cpp (179861 => 179862)


--- trunk/Source/_javascript_Core/interpreter/Interpreter.cpp	2015-02-10 01:21:38 UTC (rev 179861)
+++ trunk/Source/_javascript_Core/interpreter/Interpreter.cpp	2015-02-10 03:27:43 UTC (rev 179862)
@@ -134,7 +134,7 @@
     return interpreter->execute(eval, callFrame, thisValue, callerScopeChain);
 }
 
-CallFrame* sizeFrameForVarargs(CallFrame* callFrame, JSStack* stack, JSValue arguments, int firstFreeRegister, uint32_t firstVarArgOffset)
+CallFrame* sizeFrameForVarargs(CallFrame* callFrame, JSStack* stack, JSValue arguments, unsigned numUsedStackSlots, uint32_t firstVarArgOffset)
 {
     if (!arguments) { // f.apply(x, arguments), with arguments unmodified.
         unsigned argumentCountIncludingThis = callFrame->argumentCountIncludingThis();
@@ -142,7 +142,7 @@
             argumentCountIncludingThis -= firstVarArgOffset;
         else
             argumentCountIncludingThis = 1;
-        unsigned paddedCalleeFrameOffset = WTF::roundUpToMultipleOf(stackAlignmentRegisters(), -firstFreeRegister + argumentCountIncludingThis + JSStack::CallFrameHeaderSize + 1);
+        unsigned paddedCalleeFrameOffset = WTF::roundUpToMultipleOf(stackAlignmentRegisters(), numUsedStackSlots + argumentCountIncludingThis + JSStack::CallFrameHeaderSize);
         CallFrame* newCallFrame = CallFrame::create(callFrame->registers() - paddedCalleeFrameOffset);
         if (argumentCountIncludingThis > Arguments::MaxArguments + 1 || !stack->ensureCapacityFor(newCallFrame->registers())) {
             throwStackOverflowError(callFrame);
@@ -153,7 +153,7 @@
 
     if (arguments.isUndefinedOrNull()) {
         unsigned argumentCountIncludingThis = 1;
-        unsigned paddedCalleeFrameOffset = WTF::roundUpToMultipleOf(stackAlignmentRegisters(),  -firstFreeRegister + argumentCountIncludingThis + JSStack::CallFrameHeaderSize + 1);
+        unsigned paddedCalleeFrameOffset = WTF::roundUpToMultipleOf(stackAlignmentRegisters(),  numUsedStackSlots + argumentCountIncludingThis + JSStack::CallFrameHeaderSize);
         CallFrame* newCallFrame = CallFrame::create(callFrame->registers() - paddedCalleeFrameOffset);
         if (!stack->ensureCapacityFor(newCallFrame->registers())) {
             throwStackOverflowError(callFrame);
@@ -174,7 +174,7 @@
             argCount -= firstVarArgOffset;
         else
             argCount = 0;
-        unsigned paddedCalleeFrameOffset = WTF::roundUpToMultipleOf(stackAlignmentRegisters(), -firstFreeRegister + CallFrame::offsetFor(argCount + 1));
+        unsigned paddedCalleeFrameOffset = WTF::roundUpToMultipleOf(stackAlignmentRegisters(), numUsedStackSlots + argCount + 1 + JSStack::CallFrameHeaderSize);
         CallFrame* newCallFrame = CallFrame::create(callFrame->registers() - paddedCalleeFrameOffset);
         if (argCount > Arguments::MaxArguments || !stack->ensureCapacityFor(newCallFrame->registers())) {
             throwStackOverflowError(callFrame);
@@ -190,7 +190,7 @@
             argCount -= firstVarArgOffset;
         else
             argCount = 0;
-        unsigned paddedCalleeFrameOffset = WTF::roundUpToMultipleOf(stackAlignmentRegisters(), -firstFreeRegister + CallFrame::offsetFor(argCount + 1));
+        unsigned paddedCalleeFrameOffset = WTF::roundUpToMultipleOf(stackAlignmentRegisters(), numUsedStackSlots + argCount + 1 + JSStack::CallFrameHeaderSize);
         CallFrame* newCallFrame = CallFrame::create(callFrame->registers() - paddedCalleeFrameOffset);
         if (argCount > Arguments::MaxArguments || !stack->ensureCapacityFor(newCallFrame->registers())) {
             throwStackOverflowError(callFrame);
@@ -205,7 +205,7 @@
         argCount -= firstVarArgOffset;
     else
         argCount = 0;
-    unsigned paddedCalleeFrameOffset = WTF::roundUpToMultipleOf(stackAlignmentRegisters(), -firstFreeRegister + CallFrame::offsetFor(argCount + 1));
+    unsigned paddedCalleeFrameOffset = WTF::roundUpToMultipleOf(stackAlignmentRegisters(), numUsedStackSlots + argCount + 1 + JSStack::CallFrameHeaderSize);
     CallFrame* newCallFrame = CallFrame::create(callFrame->registers() - paddedCalleeFrameOffset);
     if (argCount > Arguments::MaxArguments || !stack->ensureCapacityFor(newCallFrame->registers())) {
         throwStackOverflowError(callFrame);
@@ -214,7 +214,7 @@
     return newCallFrame;
 }
 
-void loadVarargs(CallFrame* callFrame, CallFrame* newCallFrame, JSValue thisValue, JSValue arguments, uint32_t firstVarArgOffset)
+void loadVarargs(CallFrame* callFrame, VirtualRegister firstElementDest, VirtualRegister countDest, JSValue arguments, uint32_t firstVarArgOffset)
 {
     if (!arguments) { // f.apply(x, arguments), with arguments unmodified.
         unsigned argumentCountIncludingThis = callFrame->argumentCountIncludingThis();
@@ -222,16 +222,14 @@
             argumentCountIncludingThis -= firstVarArgOffset;
         else
             argumentCountIncludingThis = 1;
-        newCallFrame->setArgumentCountIncludingThis(argumentCountIncludingThis);
-        newCallFrame->setThisValue(thisValue);
+        callFrame->r(countDest).payload() = argumentCountIncludingThis;
         for (size_t i = firstVarArgOffset; i < callFrame->argumentCount(); ++i)
-            newCallFrame->setArgument(i - firstVarArgOffset, callFrame->argumentAfterCapture(i));
+            callFrame->r(firstElementDest + i - firstVarArgOffset) = callFrame->argumentAfterCapture(i);
         return;
     }
     
     if (arguments.isUndefinedOrNull()) {
-        newCallFrame->setArgumentCountIncludingThis(1);
-        newCallFrame->setThisValue(thisValue);
+        callFrame->r(countDest).payload() = 1;
         return;
     }
     
@@ -240,11 +238,10 @@
         unsigned argCount = argsObject->length(callFrame);
         if (argCount >= firstVarArgOffset) {
             argCount -= firstVarArgOffset;
-            newCallFrame->setArgumentCountIncludingThis(argCount + 1);
-            argsObject->copyToArguments(callFrame, newCallFrame, argCount, firstVarArgOffset);
+            callFrame->r(countDest).payload() = argCount + 1;
+            argsObject->copyToArguments(callFrame, firstElementDest, argCount, firstVarArgOffset);
         } else
-            newCallFrame->setArgumentCountIncludingThis(1);
-        newCallFrame->setThisValue(thisValue);
+            callFrame->r(countDest).payload() = 1;
         return;
     }
     
@@ -253,11 +250,10 @@
         unsigned argCount = array->length();
         if (argCount >= firstVarArgOffset) {
             argCount -= firstVarArgOffset;
-            newCallFrame->setArgumentCountIncludingThis(argCount + 1);
-            array->copyToArguments(callFrame, newCallFrame, argCount, firstVarArgOffset);
+            callFrame->r(countDest).payload() = argCount + 1;
+            array->copyToArguments(callFrame, firstElementDest, argCount, firstVarArgOffset);
         } else
-            newCallFrame->setArgumentCountIncludingThis(1);
-        newCallFrame->setThisValue(thisValue);
+            callFrame->r(countDest).payload() = 1;
         return;
     }
     
@@ -265,18 +261,34 @@
     unsigned argCount = argObject->get(callFrame, callFrame->propertyNames().length).toUInt32(callFrame);
     if (argCount >= firstVarArgOffset) {
         argCount -= firstVarArgOffset;
-        newCallFrame->setArgumentCountIncludingThis(argCount + 1);
+        callFrame->r(countDest).payload() = argCount + 1;
     } else
-        newCallFrame->setArgumentCountIncludingThis(1);
+        callFrame->r(countDest).payload() = 1;
 
-    newCallFrame->setThisValue(thisValue);
     for (size_t i = 0; i < argCount; ++i) {
-        newCallFrame->setArgument(i, asObject(arguments)->get(callFrame, i + firstVarArgOffset));
+        callFrame->r(firstElementDest + i) = asObject(arguments)->get(callFrame, i + firstVarArgOffset);
         if (UNLIKELY(callFrame->vm().exception()))
             return;
     }
 }
 
+void setupVarargsFrame(CallFrame* callFrame, CallFrame* newCallFrame, JSValue arguments, uint32_t firstVarArgOffset)
+{
+    VirtualRegister calleeFrameOffset(newCallFrame - callFrame);
+    
+    loadVarargs(
+        callFrame,
+        calleeFrameOffset + CallFrame::argumentOffset(0),
+        calleeFrameOffset + JSStack::ArgumentCount,
+        arguments, firstVarArgOffset);
+}
+
+void setupVarargsFrameAndSetThis(CallFrame* callFrame, CallFrame* newCallFrame, JSValue thisValue, JSValue arguments, uint32_t firstVarArgOffset)
+{
+    setupVarargsFrame(callFrame, newCallFrame, arguments, firstVarArgOffset);
+    newCallFrame->setThisValue(thisValue);
+}
+
 Interpreter::Interpreter(VM& vm)
     : m_sampleEntryDepth(0)
     , m_vm(vm)

Modified: trunk/Source/_javascript_Core/interpreter/Interpreter.h (179861 => 179862)


--- trunk/Source/_javascript_Core/interpreter/Interpreter.h	2015-02-10 01:21:38 UTC (rev 179861)
+++ trunk/Source/_javascript_Core/interpreter/Interpreter.h	2015-02-10 03:27:43 UTC (rev 179862)
@@ -298,8 +298,11 @@
     };
 
     JSValue eval(CallFrame*);
-    CallFrame* sizeFrameForVarargs(CallFrame*, JSStack*, JSValue, int, uint32_t firstVarArgOffset);
-    void loadVarargs(CallFrame*, CallFrame*, JSValue, JSValue, uint32_t firstVarArgOffset);
+    CallFrame* sizeFrameForVarargs(CallFrame* exec, JSStack*, JSValue arguments, unsigned numUsedStackSlots, uint32_t firstVarArgOffset);
+    void loadVarargs(CallFrame* execCaller, VirtualRegister firstElementDest, VirtualRegister countDest, JSValue source, uint32_t offset);
+    void setupVarargsFrame(CallFrame* execCaller, CallFrame* execCallee, JSValue arguments, uint32_t firstVarArgOffset);
+    void setupVarargsFrameAndSetThis(CallFrame* execCaller, CallFrame* execCallee, JSValue thisValue, JSValue arguments, uint32_t firstVarArgOffset);
+    
 } // namespace JSC
 
 #endif // Interpreter_h

Modified: trunk/Source/_javascript_Core/jit/AssemblyHelpers.h (179861 => 179862)


--- trunk/Source/_javascript_Core/jit/AssemblyHelpers.h	2015-02-10 01:21:38 UTC (rev 179861)
+++ trunk/Source/_javascript_Core/jit/AssemblyHelpers.h	2015-02-10 03:27:43 UTC (rev 179862)
@@ -253,10 +253,20 @@
     }
 #endif
 
-    void emitGetFromCallFrameHeaderPtr(JSStack::CallFrameHeaderEntry entry, GPRReg to)
+    void emitGetFromCallFrameHeaderPtr(JSStack::CallFrameHeaderEntry entry, GPRReg to, GPRReg from = GPRInfo::callFrameRegister)
     {
-        loadPtr(Address(GPRInfo::callFrameRegister, entry * sizeof(Register)), to);
+        loadPtr(Address(from, entry * sizeof(Register)), to);
     }
+    void emitGetFromCallFrameHeader32(JSStack::CallFrameHeaderEntry entry, GPRReg to, GPRReg from = GPRInfo::callFrameRegister)
+    {
+        load32(Address(from, entry * sizeof(Register)), to);
+    }
+#if USE(JSVALUE64)
+    void emitGetFromCallFrameHeader64(JSStack::CallFrameHeaderEntry entry, GPRReg to, GPRReg from = GPRInfo::callFrameRegister)
+    {
+        load64(Address(from, entry * sizeof(Register)), to);
+    }
+#endif // USE(JSVALUE64)
     void emitPutToCallFrameHeader(GPRReg from, JSStack::CallFrameHeaderEntry entry)
     {
         storePtr(from, Address(GPRInfo::callFrameRegister, entry * sizeof(Register)));

Modified: trunk/Source/_javascript_Core/jit/JIT.h (179861 => 179862)


--- trunk/Source/_javascript_Core/jit/JIT.h	2015-02-10 01:21:38 UTC (rev 179861)
+++ trunk/Source/_javascript_Core/jit/JIT.h	2015-02-10 03:27:43 UTC (rev 179862)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008, 2012, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2012-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -296,7 +296,7 @@
 
         void compileOpCall(OpcodeID, Instruction*, unsigned callLinkInfoIndex);
         void compileOpCallSlowCase(OpcodeID, Instruction*, Vector<SlowCaseEntry>::iterator&, unsigned callLinkInfoIndex);
-        void compileLoadVarargs(Instruction*);
+        void compileSetupVarargsFrame(Instruction*);
         void compileCallEval(Instruction*);
         void compileCallEvalSlowCase(Instruction*, Vector<SlowCaseEntry>::iterator&);
         void emitPutCallResult(Instruction*);
@@ -642,11 +642,6 @@
         void emitInitRegister(int dst);
 
         void emitPutIntToCallFrameHeader(RegisterID from, JSStack::CallFrameHeaderEntry);
-        void emitGetFromCallFrameHeaderPtr(JSStack::CallFrameHeaderEntry, RegisterID to, RegisterID from = callFrameRegister);
-        void emitGetFromCallFrameHeader32(JSStack::CallFrameHeaderEntry, RegisterID to, RegisterID from = callFrameRegister);
-#if USE(JSVALUE64)
-        void emitGetFromCallFrameHeader64(JSStack::CallFrameHeaderEntry, RegisterID to, RegisterID from = callFrameRegister);
-#endif
 
         JSValue getConstantOperand(int src);
         bool isOperandConstantImmediateInt(int src);
@@ -735,7 +730,7 @@
 #endif
         MacroAssembler::Call callOperation(V_JITOperation_EJIdJJ, RegisterID, const Identifier*, RegisterID, RegisterID);
 #if USE(JSVALUE64)
-        MacroAssembler::Call callOperation(F_JITOperation_EFJJZ, RegisterID, RegisterID, RegisterID, int32_t);
+        MacroAssembler::Call callOperation(F_JITOperation_EFJZ, RegisterID, RegisterID, int32_t);
         MacroAssembler::Call callOperation(V_JITOperation_ESsiJJI, StructureStubInfo*, RegisterID, RegisterID, StringImpl*);
 #else
         MacroAssembler::Call callOperation(V_JITOperation_ESsiJJI, StructureStubInfo*, RegisterID, RegisterID, RegisterID, RegisterID, StringImpl*);
@@ -750,7 +745,7 @@
         MacroAssembler::Call callOperationWithCallFrameRollbackOnException(V_JITOperation_ECb, CodeBlock*);
         MacroAssembler::Call callOperationWithCallFrameRollbackOnException(Z_JITOperation_E);
 #if USE(JSVALUE32_64)
-        MacroAssembler::Call callOperation(F_JITOperation_EFJJZ, RegisterID, RegisterID, RegisterID, RegisterID, RegisterID, int32_t);
+        MacroAssembler::Call callOperation(F_JITOperation_EFJZ, RegisterID, RegisterID, RegisterID, int32_t);
         MacroAssembler::Call callOperation(F_JITOperation_EJZZ, GPRReg, GPRReg, int32_t, int32_t);
         MacroAssembler::Call callOperation(J_JITOperation_EAapJ, int, ArrayAllocationProfile*, GPRReg, GPRReg);
         MacroAssembler::Call callOperation(J_JITOperation_EJ, int, GPRReg, GPRReg);

Modified: trunk/Source/_javascript_Core/jit/JITCall.cpp (179861 => 179862)


--- trunk/Source/_javascript_Core/jit/JITCall.cpp	2015-02-10 01:21:38 UTC (rev 179861)
+++ trunk/Source/_javascript_Core/jit/JITCall.cpp	2015-02-10 03:27:43 UTC (rev 179862)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -40,6 +40,7 @@
 #include "RepatchBuffer.h"
 #include "ResultType.h"
 #include "SamplingTool.h"
+#include "SetupVarargsFrame.h"
 #include "StackAlignment.h"
 #include "ThunkGenerators.h"
 #include <wtf/StringPrintStream.h>
@@ -54,7 +55,7 @@
     emitPutVirtualRegister(dst);
 }
 
-void JIT::compileLoadVarargs(Instruction* instruction)
+void JIT::compileSetupVarargsFrame(Instruction* instruction)
 {
     int thisValue = instruction[3].u.operand;
     int arguments = instruction[4].u.operand;
@@ -70,66 +71,27 @@
     if (canOptimize) {
         emitGetVirtualRegister(arguments, regT0);
         slowCase.append(branch64(NotEqual, regT0, TrustedImm64(JSValue::encode(JSValue()))));
-
-        emitGetFromCallFrameHeader32(JSStack::ArgumentCount, regT0);
-        if (firstVarArgOffset) {
-            Jump sufficientArguments = branch32(GreaterThan, regT0, TrustedImm32(firstVarArgOffset + 1));
-            move(TrustedImm32(1), regT0);
-            Jump endVarArgs = jump();
-            sufficientArguments.link(this);
-            sub32(TrustedImm32(firstVarArgOffset), regT0);
-            endVarArgs.link(this);
-        }
-        slowCase.append(branch32(Above, regT0, TrustedImm32(Arguments::MaxArguments + 1)));
-        // regT0: argumentCountIncludingThis
-        move(regT0, regT1);
-        add64(TrustedImm32(-firstFreeRegister + JSStack::CallFrameHeaderSize), regT1);
-        // regT1 now has the required frame size in Register units
-        // Round regT1 to next multiple of stackAlignmentRegisters()
-        add64(TrustedImm32(stackAlignmentRegisters() - 1), regT1);
-        and64(TrustedImm32(~(stackAlignmentRegisters() - 1)), regT1);
-
-        neg64(regT1);
-        lshift64(TrustedImm32(3), regT1);
-        addPtr(callFrameRegister, regT1);
-        // regT1: newCallFrame
-
-        slowCase.append(branchPtr(Above, AbsoluteAddress(m_vm->addressOfStackLimit()), regT1));
-
-        // Initialize ArgumentCount.
-        store32(regT0, Address(regT1, JSStack::ArgumentCount * static_cast<int>(sizeof(Register)) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)));
-
-        // Initialize 'this'.
-        emitGetVirtualRegister(thisValue, regT2);
-        store64(regT2, Address(regT1, CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register))));
-
-        // Copy arguments.
-        signExtend32ToPtr(regT0, regT0);
-        end.append(branchSub64(Zero, TrustedImm32(1), regT0));
-        // regT0: argumentCount
-
-        Label copyLoop = label();
-        load64(BaseIndex(callFrameRegister, regT0, TimesEight, (CallFrame::thisArgumentOffset() + firstVarArgOffset) * static_cast<int>(sizeof(Register))), regT2);
-        store64(regT2, BaseIndex(regT1, regT0, TimesEight, CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register))));
-        branchSub64(NonZero, TrustedImm32(1), regT0).linkTo(copyLoop, this);
-
+        
+        move(TrustedImm32(-firstFreeRegister), regT1);
+        emitSetupVarargsFrameFastCase(*this, regT1, regT0, regT1, regT2, 0, firstVarArgOffset, slowCase);
         end.append(jump());
+        slowCase.link(this);
     }
 
-    if (canOptimize)
-        slowCase.link(this);
-
     emitGetVirtualRegister(arguments, regT1);
-    callOperation(operationSizeFrameForVarargs, regT1, firstFreeRegister, firstVarArgOffset);
+    callOperation(operationSizeFrameForVarargs, regT1, -firstFreeRegister, firstVarArgOffset);
     move(returnValueGPR, stackPointerRegister);
-    emitGetVirtualRegister(thisValue, regT1);
-    emitGetVirtualRegister(arguments, regT2);
-    callOperation(operationLoadVarargs, returnValueGPR, regT1, regT2, firstVarArgOffset);
+    emitGetVirtualRegister(arguments, regT1);
+    callOperation(operationSetupVarargsFrame, returnValueGPR, regT1, firstVarArgOffset);
     move(returnValueGPR, regT1);
 
     if (canOptimize)
         end.link(this);
     
+    // Initialize 'this'.
+    emitGetVirtualRegister(thisValue, regT0);
+    store64(regT0, Address(regT1, CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register))));
+
     addPtr(TrustedImm32(sizeof(CallerFrameAndPC)), regT1, stackPointerRegister);
 }
 
@@ -188,7 +150,7 @@
     COMPILE_ASSERT(OPCODE_LENGTH(op_call) == OPCODE_LENGTH(op_call_varargs), call_and_call_varargs_opcodes_must_be_same_length);
     COMPILE_ASSERT(OPCODE_LENGTH(op_call) == OPCODE_LENGTH(op_construct_varargs), call_and_construct_varargs_opcodes_must_be_same_length);
     if (opcodeID == op_call_varargs || opcodeID == op_construct_varargs)
-        compileLoadVarargs(instruction);
+        compileSetupVarargsFrame(instruction);
     else {
         int argCount = instruction[3].u.operand;
         int registerOffset = -instruction[4].u.operand;

Modified: trunk/Source/_javascript_Core/jit/JITCall32_64.cpp (179861 => 179862)


--- trunk/Source/_javascript_Core/jit/JITCall32_64.cpp	2015-02-10 01:21:38 UTC (rev 179861)
+++ trunk/Source/_javascript_Core/jit/JITCall32_64.cpp	2015-02-10 03:27:43 UTC (rev 179862)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -40,6 +40,7 @@
 #include "RepatchBuffer.h"
 #include "ResultType.h"
 #include "SamplingTool.h"
+#include "SetupVarargsFrame.h"
 #include "StackAlignment.h"
 #include <wtf/StringPrintStream.h>
 
@@ -114,7 +115,7 @@
     compileOpCall(op_construct, currentInstruction, m_callLinkInfoIndex++);
 }
 
-void JIT::compileLoadVarargs(Instruction* instruction)
+void JIT::compileSetupVarargsFrame(Instruction* instruction)
 {
     int thisValue = instruction[3].u.operand;
     int arguments = instruction[4].u.operand;
@@ -130,69 +131,36 @@
     if (canOptimize) {
         emitLoadTag(arguments, regT1);
         slowCase.append(branch32(NotEqual, regT1, TrustedImm32(JSValue::EmptyValueTag)));
-
-        load32(payloadFor(JSStack::ArgumentCount), regT2);
-        if (firstVarArgOffset) {
-            Jump sufficientArguments = branch32(GreaterThan, regT2, TrustedImm32(firstVarArgOffset + 1));
-            move(TrustedImm32(1), regT2);
-            Jump endVarArgs = jump();
-            sufficientArguments.link(this);
-            sub32(TrustedImm32(firstVarArgOffset), regT2);
-            endVarArgs.link(this);
-        }
-        slowCase.append(branch32(Above, regT2, TrustedImm32(Arguments::MaxArguments + 1)));
-        // regT2: argumentCountIncludingThis
-
-        move(regT2, regT3);
-        addPtr(TrustedImm32(-firstFreeRegister + JSStack::CallFrameHeaderSize), regT3);
-        // regT1 now has the required frame size in Register units
-        // Round regT1 to next multiple of stackAlignmentRegisters()
-        addPtr(TrustedImm32(stackAlignmentRegisters() - 1), regT3);
-        andPtr(TrustedImm32(~(stackAlignmentRegisters() - 1)), regT3);
-        neg32(regT3);
-        lshift32(TrustedImm32(3), regT3);
-        addPtr(callFrameRegister, regT3);
-        // regT3: newCallFrame
-
-        slowCase.append(branchPtr(Above, AbsoluteAddress(m_vm->addressOfStackLimit()), regT3));
-
-        // Initialize ArgumentCount.
-        store32(regT2, payloadFor(JSStack::ArgumentCount, regT3));
-
-        // Initialize 'this'.
-        emitLoad(thisValue, regT1, regT0);
-        store32(regT0, Address(regT3, OBJECT_OFFSETOF(JSValue, u.asBits.payload) + (CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register)))));
-        store32(regT1, Address(regT3, OBJECT_OFFSETOF(JSValue, u.asBits.tag) + (CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register)))));
-
-        // Copy arguments.
-        end.append(branchSub32(Zero, TrustedImm32(1), regT2));
-        // regT2: argumentCount;
-
-        Label copyLoop = label();
-        load32(BaseIndex(callFrameRegister, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload) +((CallFrame::thisArgumentOffset() + firstVarArgOffset) * static_cast<int>(sizeof(Register)))), regT0);
-        load32(BaseIndex(callFrameRegister, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag) +((CallFrame::thisArgumentOffset() + firstVarArgOffset) * static_cast<int>(sizeof(Register)))), regT1);
-        store32(regT0, BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload) +(CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register)))));
-        store32(regT1, BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag) +(CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register)))));
-        branchSub32(NonZero, TrustedImm32(1), regT2).linkTo(copyLoop, this);
-
+        
+        move(TrustedImm32(-firstFreeRegister), regT1);
+        emitSetupVarargsFrameFastCase(*this, regT1, regT0, regT1, regT2, 0, firstVarArgOffset, slowCase);
         end.append(jump());
+        slowCase.link(this);
     }
 
-    if (canOptimize)
-        slowCase.link(this);
-
     emitLoad(arguments, regT1, regT0);
-    callOperation(operationSizeFrameForVarargs, regT1, regT0, firstFreeRegister, firstVarArgOffset);
+    callOperation(operationSizeFrameForVarargs, regT1, regT0, -firstFreeRegister, firstVarArgOffset);
+    // This is spectacularly dirty. We want to pass four arguments to operationSetupVarargsFrame. On x86-32 we
+    // will pass them on the stack. We want four stack slots, or 16 bytes. Extending the stack by 8 bytes
+    // over where we planned on pointing the FP gives us enough room. The reason is that the FP gives an
+    // extra CallerFrameAndPC bytes beyond where SP should point prior to the call. So if we just did
+    // move(returnValueGPR, stackPointerRegister), we'd have enough room for passing two args, or 8
+    // bytes - except that we'd have a misaligned stack. So if we subtract *another* CallerFrameAndPC
+    // bytes, we are up to 16 bytes of spare room *and* we have an aligned stack. Gross, but correct!
     addPtr(TrustedImm32(-sizeof(CallerFrameAndPC)), returnValueGPR, stackPointerRegister);
-    emitLoad(thisValue, regT1, regT4);
-    emitLoad(arguments, regT3, regT2);
-    callOperation(operationLoadVarargs, returnValueGPR, regT1, regT4, regT3, regT2, firstVarArgOffset);
-    move(returnValueGPR, regT3);
+    emitLoad(arguments, regT2, regT1);
+    callOperation(operationSetupVarargsFrame, returnValueGPR, regT2, regT1, firstVarArgOffset);
+    move(returnValueGPR, regT1);
 
     if (canOptimize)
         end.link(this);
 
-    addPtr(TrustedImm32(sizeof(CallerFrameAndPC)), regT3, stackPointerRegister);
+    // Initialize 'this'.
+    emitLoad(thisValue, regT2, regT0);
+    store32(regT0, Address(regT1, PayloadOffset + (CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register)))));
+    store32(regT2, Address(regT1, TagOffset + (CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register)))));
+    
+    addPtr(TrustedImm32(sizeof(CallerFrameAndPC)), regT1, stackPointerRegister);
 }
 
 void JIT::compileCallEval(Instruction* instruction)
@@ -251,7 +219,7 @@
     */
     
     if (opcodeID == op_call_varargs || opcodeID == op_construct_varargs)
-        compileLoadVarargs(instruction);
+        compileSetupVarargsFrame(instruction);
     else {
         int argCount = instruction[3].u.operand;
         int registerOffset = -instruction[4].u.operand;

Modified: trunk/Source/_javascript_Core/jit/JITInlines.h (179861 => 179862)


--- trunk/Source/_javascript_Core/jit/JITInlines.h	2015-02-10 01:21:38 UTC (rev 179861)
+++ trunk/Source/_javascript_Core/jit/JITInlines.h	2015-02-10 03:27:43 UTC (rev 179862)
@@ -98,23 +98,6 @@
 #endif
 }
 
-ALWAYS_INLINE void JIT::emitGetFromCallFrameHeaderPtr(JSStack::CallFrameHeaderEntry entry, RegisterID to, RegisterID from)
-{
-    loadPtr(Address(from, entry * sizeof(Register)), to);
-}
-
-ALWAYS_INLINE void JIT::emitGetFromCallFrameHeader32(JSStack::CallFrameHeaderEntry entry, RegisterID to, RegisterID from)
-{
-    load32(Address(from, entry * sizeof(Register)), to);
-}
-
-#if USE(JSVALUE64)
-ALWAYS_INLINE void JIT::emitGetFromCallFrameHeader64(JSStack::CallFrameHeaderEntry entry, RegisterID to, RegisterID from)
-{
-    load64(Address(from, entry * sizeof(Register)), to);
-}
-#endif
-
 ALWAYS_INLINE void JIT::emitLoadCharacterString(RegisterID src, RegisterID dst, JumpList& failures)
 {
     failures.append(branchStructure(NotEqual, Address(src, JSCell::structureIDOffset()), m_vm->stringStructure.get()));
@@ -392,9 +375,9 @@
     return appendCallWithExceptionCheck(operation);
 }
 
-ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(F_JITOperation_EFJJZ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3, int32_t arg4)
+ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(F_JITOperation_EFJZ operation, GPRReg arg1, GPRReg arg2, int32_t arg3)
 {
-    setupArgumentsWithExecState(arg1, arg2, arg3, TrustedImm32(arg4));
+    setupArgumentsWithExecState(arg1, arg2, TrustedImm32(arg3));
     return appendCallWithExceptionCheck(operation);
 }
 
@@ -539,9 +522,9 @@
     return appendCallWithExceptionCheck(operation);
 }
 
-ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(F_JITOperation_EFJJZ operation, GPRReg arg1, GPRReg arg2Tag, GPRReg arg2Payload, GPRReg arg3Tag, GPRReg arg3Payload, int32_t arg4)
+ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(F_JITOperation_EFJZ operation, GPRReg arg1, GPRReg arg2Tag, GPRReg arg2Payload, int32_t arg3)
 {
-    setupArgumentsWithExecState(arg1, arg2Payload, arg2Tag, arg3Payload, arg3Tag, TrustedImm32(arg4));
+    setupArgumentsWithExecState(arg1, arg2Payload, arg2Tag, TrustedImm32(arg3));
     return appendCallWithExceptionCheck(operation);
 }
     

Modified: trunk/Source/_javascript_Core/jit/JITOperations.cpp (179861 => 179862)


--- trunk/Source/_javascript_Core/jit/JITOperations.cpp	2015-02-10 01:21:38 UTC (rev 179861)
+++ trunk/Source/_javascript_Core/jit/JITOperations.cpp	2015-02-10 03:27:43 UTC (rev 179862)
@@ -1604,23 +1604,22 @@
     return JSValue::encode(jsBoolean(result));
 }
 
-CallFrame* JIT_OPERATION operationSizeFrameForVarargs(ExecState* exec, EncodedJSValue encodedArguments, int32_t firstFreeRegister, int32_t firstVarArgOffset)
+CallFrame* JIT_OPERATION operationSizeFrameForVarargs(ExecState* exec, EncodedJSValue encodedArguments, int32_t numUsedStackSlots, int32_t firstVarArgOffset)
 {
     VM& vm = exec->vm();
     NativeCallFrameTracer tracer(&vm, exec);
     JSStack* stack = &exec->interpreter()->stack();
     JSValue arguments = JSValue::decode(encodedArguments);
-    CallFrame* newCallFrame = sizeFrameForVarargs(exec, stack, arguments, firstFreeRegister, firstVarArgOffset);
+    CallFrame* newCallFrame = sizeFrameForVarargs(exec, stack, arguments, numUsedStackSlots, firstVarArgOffset);
     return newCallFrame;
 }
 
-CallFrame* JIT_OPERATION operationLoadVarargs(ExecState* exec, CallFrame* newCallFrame, EncodedJSValue encodedThis, EncodedJSValue encodedArguments, int32_t firstVarArgOffset)
+CallFrame* JIT_OPERATION operationSetupVarargsFrame(ExecState* exec, CallFrame* newCallFrame, EncodedJSValue encodedArguments, int32_t firstVarArgOffset)
 {
     VM& vm = exec->vm();
     NativeCallFrameTracer tracer(&vm, exec);
-    JSValue thisValue = JSValue::decode(encodedThis);
     JSValue arguments = JSValue::decode(encodedArguments);
-    loadVarargs(exec, newCallFrame, thisValue, arguments, firstVarArgOffset);
+    setupVarargsFrame(exec, newCallFrame, arguments, firstVarArgOffset);
     return newCallFrame;
 }
 

Modified: trunk/Source/_javascript_Core/jit/JITOperations.h (179861 => 179862)


--- trunk/Source/_javascript_Core/jit/JITOperations.h	2015-02-10 01:21:38 UTC (rev 179861)
+++ trunk/Source/_javascript_Core/jit/JITOperations.h	2015-02-10 03:27:43 UTC (rev 179862)
@@ -87,7 +87,7 @@
     Z: int32_t
 */
 
-typedef CallFrame* JIT_OPERATION (*F_JITOperation_EFJJZ)(ExecState*, CallFrame*, EncodedJSValue, EncodedJSValue, int32_t);
+typedef CallFrame* JIT_OPERATION (*F_JITOperation_EFJZ)(ExecState*, CallFrame*, EncodedJSValue, int32_t);
 typedef CallFrame* JIT_OPERATION (*F_JITOperation_EJZZ)(ExecState*, EncodedJSValue, int32_t, int32_t);
 typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_E)(ExecState*);
 typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EA)(ExecState*, JSArray*);
@@ -309,8 +309,8 @@
 EncodedJSValue JIT_OPERATION operationDeleteById(ExecState*, EncodedJSValue base, const Identifier*) WTF_INTERNAL;
 JSCell* JIT_OPERATION operationGetPNames(ExecState*, JSObject*) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationInstanceOf(ExecState*, EncodedJSValue, EncodedJSValue proto) WTF_INTERNAL;
-CallFrame* JIT_OPERATION operationSizeFrameForVarargs(ExecState*, EncodedJSValue arguments, int32_t firstFreeRegister, int32_t firstVarArgOffset) WTF_INTERNAL;
-CallFrame* JIT_OPERATION operationLoadVarargs(ExecState*, CallFrame*, EncodedJSValue thisValue, EncodedJSValue arguments, int32_t firstVarArgOffset) WTF_INTERNAL;
+CallFrame* JIT_OPERATION operationSizeFrameForVarargs(ExecState*, EncodedJSValue arguments, int32_t numUsedStackSlots, int32_t firstVarArgOffset) WTF_INTERNAL;
+CallFrame* JIT_OPERATION operationSetupVarargsFrame(ExecState*, CallFrame*, EncodedJSValue arguments, int32_t firstVarArgOffset) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationToObject(ExecState*, EncodedJSValue) WTF_INTERNAL;
 
 char* JIT_OPERATION operationSwitchCharWithUnknownKeyType(ExecState*, EncodedJSValue key, size_t tableIndex) WTF_INTERNAL;

Added: trunk/Source/_javascript_Core/jit/SetupVarargsFrame.cpp (0 => 179862)


--- trunk/Source/_javascript_Core/jit/SetupVarargsFrame.cpp	                        (rev 0)
+++ trunk/Source/_javascript_Core/jit/SetupVarargsFrame.cpp	2015-02-10 03:27:43 UTC (rev 179862)
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2015 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 "SetupVarargsFrame.h"
+
+#if ENABLE(JIT)
+
+#include "Arguments.h"
+#include "JSCInlines.h"
+#include "StackAlignment.h"
+
+namespace JSC {
+
+void emitSetupVarargsFrameFastCase(CCallHelpers& jit, GPRReg numUsedSlotsGPR, GPRReg scratchGPR1, GPRReg scratchGPR2, GPRReg scratchGPR3, int inlineStackOffset, unsigned firstVarArgOffset, CCallHelpers::JumpList& slowCase)
+{
+    CCallHelpers::JumpList end;
+    
+    jit.load32(CCallHelpers::Address(GPRInfo::callFrameRegister, (inlineStackOffset + JSStack::ArgumentCount) * sizeof(Register) + PayloadOffset), scratchGPR1);
+    if (firstVarArgOffset) {
+        CCallHelpers::Jump sufficientArguments = jit.branch32(CCallHelpers::GreaterThan, scratchGPR1, CCallHelpers::TrustedImm32(firstVarArgOffset + 1));
+        jit.move(CCallHelpers::TrustedImm32(1), scratchGPR1);
+        CCallHelpers::Jump endVarArgs = jit.jump();
+        sufficientArguments.link(&jit);
+        jit.sub32(CCallHelpers::TrustedImm32(firstVarArgOffset), scratchGPR1);
+        endVarArgs.link(&jit);
+    }
+    slowCase.append(jit.branch32(CCallHelpers::Above, scratchGPR1, CCallHelpers::TrustedImm32(Arguments::MaxArguments + 1)));
+    // scratchGPR1: argumentCountIncludingThis
+    jit.move(numUsedSlotsGPR, scratchGPR2);
+    jit.addPtr(scratchGPR1, scratchGPR2);
+    jit.addPtr(CCallHelpers::TrustedImm32(JSStack::CallFrameHeaderSize), scratchGPR2);
+    // scratchGPR2 now has the required frame size in Register units
+    // Round scratchGPR2 to next multiple of stackAlignmentRegisters()
+    jit.addPtr(CCallHelpers::TrustedImm32(stackAlignmentRegisters() - 1), scratchGPR2);
+    jit.andPtr(CCallHelpers::TrustedImm32(~(stackAlignmentRegisters() - 1)), scratchGPR2);
+
+    jit.negPtr(scratchGPR2);
+    jit.lshiftPtr(CCallHelpers::Imm32(3), scratchGPR2);
+    jit.addPtr(GPRInfo::callFrameRegister, scratchGPR2);
+    // scratchGPR2: newCallFrame
+
+    slowCase.append(jit.branchPtr(CCallHelpers::Above, CCallHelpers::AbsoluteAddress(jit.vm()->addressOfStackLimit()), scratchGPR2));
+
+    // Initialize ArgumentCount.
+    jit.store32(scratchGPR1, CCallHelpers::Address(scratchGPR2, JSStack::ArgumentCount * static_cast<int>(sizeof(Register)) + PayloadOffset));
+
+    // Copy arguments.
+    jit.signExtend32ToPtr(scratchGPR1, scratchGPR1);
+    CCallHelpers::Jump done = jit.branchSubPtr(CCallHelpers::Zero, CCallHelpers::TrustedImm32(1), scratchGPR1);
+    // scratchGPR1: argumentCount
+
+    CCallHelpers::Label copyLoop = jit.label();
+#if USE(JSVALUE64)
+    jit.load64(CCallHelpers::BaseIndex(GPRInfo::callFrameRegister, scratchGPR1, CCallHelpers::TimesEight, (CallFrame::thisArgumentOffset() + inlineStackOffset + firstVarArgOffset) * static_cast<int>(sizeof(Register))), scratchGPR3);
+    jit.store64(scratchGPR3, CCallHelpers::BaseIndex(scratchGPR2, scratchGPR1, CCallHelpers::TimesEight, CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register))));
+#else // USE(JSVALUE64), so this begins the 32-bit case
+    jit.load32(CCallHelpers::BaseIndex(GPRInfo::callFrameRegister, scratchGPR1, CCallHelpers::TimesEight, (CallFrame::thisArgumentOffset() + inlineStackOffset + firstVarArgOffset) * static_cast<int>(sizeof(Register)) + TagOffset), scratchGPR3);
+    jit.store32(scratchGPR3, CCallHelpers::BaseIndex(scratchGPR2, scratchGPR1, CCallHelpers::TimesEight, CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register)) + TagOffset));
+    jit.load32(CCallHelpers::BaseIndex(GPRInfo::callFrameRegister, scratchGPR1, CCallHelpers::TimesEight, (CallFrame::thisArgumentOffset() + inlineStackOffset + firstVarArgOffset) * static_cast<int>(sizeof(Register)) + PayloadOffset), scratchGPR3);
+    jit.store32(scratchGPR3, CCallHelpers::BaseIndex(scratchGPR2, scratchGPR1, CCallHelpers::TimesEight, CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register)) + PayloadOffset));
+#endif // USE(JSVALUE64), end of 32-bit case
+    jit.branchSubPtr(CCallHelpers::NonZero, CCallHelpers::TrustedImm32(1), scratchGPR1).linkTo(copyLoop, &jit);
+    
+    done.link(&jit);
+}
+
+} // namespace JSC
+
+#endif // ENABLE(JIT)
+

Added: trunk/Source/_javascript_Core/jit/SetupVarargsFrame.h (0 => 179862)


--- trunk/Source/_javascript_Core/jit/SetupVarargsFrame.h	                        (rev 0)
+++ trunk/Source/_javascript_Core/jit/SetupVarargsFrame.h	2015-02-10 03:27:43 UTC (rev 179862)
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2015 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 SetupVarargsFrame_h
+#define SetupVarargsFrame_h
+
+#if ENABLE(JIT)
+
+#include "CCallHelpers.h"
+#include "VirtualRegister.h"
+
+namespace JSC {
+
+// Assumes that SP refers to the last in-use stack location, and after this returns SP will point to
+// the newly created frame plus the native header. scratchGPR2 may be the same as numUsedSlotsGPR.
+void emitSetupVarargsFrameFastCase(CCallHelpers& jit, GPRReg numUsedSlotsGPR, GPRReg scratchGPR1, GPRReg scratchGPR2, GPRReg scratchGPR3, int inlineStackOffset, unsigned firstVarArgOffset, CCallHelpers::JumpList& slowCase);
+
+} // namespace JSC
+
+#endif // ENABLE(JIT)
+
+#endif // SetupVarargsFrame_h
+

Modified: trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp (179861 => 179862)


--- trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp	2015-02-10 01:21:38 UTC (rev 179861)
+++ trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp	2015-02-10 03:27:43 UTC (rev 179862)
@@ -1165,7 +1165,7 @@
     // - Set up a call frame while respecting the variable arguments.
     
     ExecState* execCallee = sizeFrameForVarargs(exec, &vm.interpreter->stack(),
-        LLINT_OP_C(4).jsValue(), pc[5].u.operand, pc[6].u.operand);
+        LLINT_OP_C(4).jsValue(), -pc[5].u.operand, pc[6].u.operand);
     LLINT_CALL_CHECK_EXCEPTION(exec, exec);
     
     vm.newCallFrameReturnValue = execCallee;
@@ -1184,7 +1184,7 @@
     
     ExecState* execCallee = vm.newCallFrameReturnValue;
 
-    loadVarargs(exec, execCallee, LLINT_OP_C(3).jsValue(), LLINT_OP_C(4).jsValue(), pc[6].u.operand);
+    setupVarargsFrameAndSetThis(exec, execCallee, LLINT_OP_C(3).jsValue(), LLINT_OP_C(4).jsValue(), pc[6].u.operand);
     LLINT_CALL_CHECK_EXCEPTION(exec, exec);
     
     execCallee->uncheckedR(JSStack::Callee) = calleeAsValue;
@@ -1205,7 +1205,7 @@
     
     ExecState* execCallee = vm.newCallFrameReturnValue;
     
-    loadVarargs(exec, execCallee, LLINT_OP_C(3).jsValue(), LLINT_OP_C(4).jsValue(), pc[6].u.operand);
+    setupVarargsFrameAndSetThis(exec, execCallee, LLINT_OP_C(3).jsValue(), LLINT_OP_C(4).jsValue(), pc[6].u.operand);
     LLINT_CALL_CHECK_EXCEPTION(exec, exec);
     
     execCallee->uncheckedR(JSStack::Callee) = calleeAsValue;

Modified: trunk/Source/_javascript_Core/runtime/Arguments.cpp (179861 => 179862)


--- trunk/Source/_javascript_Core/runtime/Arguments.cpp	2015-02-10 01:21:38 UTC (rev 179861)
+++ trunk/Source/_javascript_Core/runtime/Arguments.cpp	2015-02-10 03:27:43 UTC (rev 179862)
@@ -1,7 +1,7 @@
 /*
  *  Copyright (C) 1999-2002 Harri Porten ([email protected])
  *  Copyright (C) 2001 Peter Kelly ([email protected])
- *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2015 Apple Inc. All rights reserved.
  *  Copyright (C) 2007 Cameron Zwarich ([email protected])
  *  Copyright (C) 2007 Maks Orlovich
  *
@@ -87,22 +87,25 @@
     
 static EncodedJSValue JSC_HOST_CALL argumentsFuncIterator(ExecState*);
 
-void Arguments::copyToArguments(ExecState* exec, CallFrame* callFrame, uint32_t copyLength, int32_t firstVarArgOffset)
+void Arguments::copyToArguments(ExecState* exec, VirtualRegister firstElementDest, uint32_t copyLength, int32_t firstVarArgOffset)
 {
     uint32_t length = copyLength + firstVarArgOffset;
 
     if (UNLIKELY(m_overrodeLength)) {
         length = min(get(exec, exec->propertyNames().length).toUInt32(exec), length);
         for (unsigned i = firstVarArgOffset; i < length; i++)
-            callFrame->setArgument(i, get(exec, i));
+            exec->r(firstElementDest + i - firstVarArgOffset) = get(exec, i);
         return;
     }
     ASSERT(length == this->length(exec));
     for (size_t i = firstVarArgOffset; i < length; ++i) {
         if (JSValue value = tryGetArgument(i))
-            callFrame->setArgument(i - firstVarArgOffset, value);
-        else
-            callFrame->setArgument(i - firstVarArgOffset, get(exec, i));
+            exec->r(firstElementDest + i - firstVarArgOffset) = value;
+        else {
+            exec->r(firstElementDest + i - firstVarArgOffset) = get(exec, i);
+            if (UNLIKELY(exec->vm().exception()))
+                return;
+        }
     }
 }
 

Modified: trunk/Source/_javascript_Core/runtime/Arguments.h (179861 => 179862)


--- trunk/Source/_javascript_Core/runtime/Arguments.h	2015-02-10 01:21:38 UTC (rev 179861)
+++ trunk/Source/_javascript_Core/runtime/Arguments.h	2015-02-10 03:27:43 UTC (rev 179862)
@@ -1,6 +1,6 @@
 /*
  *  Copyright (C) 1999-2000 Harri Porten ([email protected])
- *  Copyright (C) 2003, 2006, 2007, 2008, 2009, 2014 Apple Inc. All rights reserved.
+ *  Copyright (C) 2003, 2006, 2007, 2008, 2009, 2014, 2015 Apple Inc. All rights reserved.
  *  Copyright (C) 2007 Cameron Zwarich ([email protected])
  *  Copyright (C) 2007 Maks Orlovich
  *
@@ -84,7 +84,7 @@
         return m_numArguments; 
     }
         
-    void copyToArguments(ExecState*, CallFrame*, uint32_t copyLength, int32_t firstArgumentOffset);
+    void copyToArguments(ExecState*, VirtualRegister firstElementDest, uint32_t copyLength, int32_t firstArgumentOffset);
     void tearOff(CallFrame*);
     void tearOff(CallFrame*, InlineCallFrame*);
     void tearOffForCloning(CallFrame*);

Modified: trunk/Source/_javascript_Core/runtime/JSArray.cpp (179861 => 179862)


--- trunk/Source/_javascript_Core/runtime/JSArray.cpp	2015-02-10 01:21:38 UTC (rev 179861)
+++ trunk/Source/_javascript_Core/runtime/JSArray.cpp	2015-02-10 03:27:43 UTC (rev 179862)
@@ -1,6 +1,6 @@
 /*
  *  Copyright (C) 1999-2000 Harri Porten ([email protected])
- *  Copyright (C) 2003, 2007, 2008, 2009, 2012, 2013 Apple Inc. All rights reserved.
+ *  Copyright (C) 2003, 2007, 2008, 2009, 2012, 2013, 2015 Apple Inc. All rights reserved.
  *  Copyright (C) 2003 Peter Kelly ([email protected])
  *  Copyright (C) 2006 Alexey Proskuryakov ([email protected])
  *
@@ -1570,7 +1570,7 @@
         args.append(get(exec, i));
 }
 
-void JSArray::copyToArguments(ExecState* exec, CallFrame* callFrame, uint32_t copyLength, int32_t firstVarArgOffset)
+void JSArray::copyToArguments(ExecState* exec, VirtualRegister firstElementDest, uint32_t copyLength, int32_t firstVarArgOffset)
 {
     unsigned i = firstVarArgOffset;
     WriteBarrier<Unknown>* vector;
@@ -1602,7 +1602,7 @@
             double v = m_butterfly->contiguousDouble()[i];
             if (v != v)
                 break;
-            callFrame->setArgument(i - firstVarArgOffset, JSValue(JSValue::EncodeAsDouble, v));
+            exec->r(firstElementDest + i - firstVarArgOffset) = JSValue(JSValue::EncodeAsDouble, v);
         }
         break;
     }
@@ -1627,11 +1627,14 @@
         WriteBarrier<Unknown>& v = vector[i];
         if (!v)
             break;
-        callFrame->setArgument(i - firstVarArgOffset, v.get());
+        exec->r(firstElementDest + i - firstVarArgOffset) = v.get();
     }
     
-    for (; i < length; ++i)
-        callFrame->setArgument(i - firstVarArgOffset, get(exec, i));
+    for (; i < length; ++i) {
+        exec->r(firstElementDest + i - firstVarArgOffset) = get(exec, i);
+        if (UNLIKELY(exec->vm().exception()))
+            return;
+    }
 }
 
 template<IndexingType arrayIndexingType>

Modified: trunk/Source/_javascript_Core/runtime/JSArray.h (179861 => 179862)


--- trunk/Source/_javascript_Core/runtime/JSArray.h	2015-02-10 01:21:38 UTC (rev 179861)
+++ trunk/Source/_javascript_Core/runtime/JSArray.h	2015-02-10 03:27:43 UTC (rev 179862)
@@ -1,6 +1,6 @@
 /*
  *  Copyright (C) 1999-2000 Harri Porten ([email protected])
- *  Copyright (C) 2003, 2007, 2008, 2009, 2012 Apple Inc. All rights reserved.
+ *  Copyright (C) 2003, 2007, 2008, 2009, 2012, 2015 Apple Inc. All rights reserved.
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Lesser General Public
@@ -132,7 +132,7 @@
     }
 
     JS_EXPORT_PRIVATE void fillArgList(ExecState*, MarkedArgumentBuffer&);
-    JS_EXPORT_PRIVATE void copyToArguments(ExecState*, CallFrame*, uint32_t length, int32_t firstVarArgOffset);
+    JS_EXPORT_PRIVATE void copyToArguments(ExecState*, VirtualRegister firstElementDest, uint32_t length, int32_t firstVarArgOffset);
 
     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype, IndexingType indexingType)
     {
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to