⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 179862 in webkit


Ignore:
Timestamp:
Feb 9, 2015, 7:27:43 PM (12 years ago)
Author:
fpizlo@apple.com
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.

(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:
Location:
trunk/Source/JavaScriptCore
Files:
2 added
21 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/CMakeLists.txt

    r179503 r179862  
    350350    jit/JITThunks.cpp
    351351    jit/JITToDFGDeferredCompilationCallback.cpp
     352    jit/SetupVarargsFrame.cpp
    352353    jit/PolymorphicCallStubRoutine.cpp
    353354    jit/Reg.cpp
  • trunk/Source/JavaScriptCore/ChangeLog

    r179851 r179862  
     12015-02-09  Filip Pizlo  <fpizlo@apple.com>
     2
     3        Varargs frame set-up should be factored out for use by other JITs
     4        https://bugs.webkit.org/show_bug.cgi?id=141388
     5
     6        Reviewed by Michael Saboff.
     7       
     8        Previously the code that dealt with varargs always assumed that we were setting up a varargs call
     9        frame by literally following the execution semantics of op_call_varargs. This isn't how it'll
     10        happen once the DFG and FTL do varargs calls, or when varargs calls get inlined. The DFG and FTL
     11        don't literally execute bytecode; for example their stack frame layout has absolutely nothing in
     12        common with what the bytecode says, and that will never change.
     13       
     14        This patch makes two changes:
     15       
     16        Setting up the varargs callee frame can be done in smaller steps: particularly in the case of a
     17        varargs call that gets inlined, we aren't going to actually want to set up a callee frame in
     18        full - we just want to put the arguments somewhere, and that place will not have much (if
     19        anything) in common with the call frame format. This patch factors that out into something called
     20        a loadVarargs. The thing we used to call loadVarargs is now called setupVarargsFrame. This patch
     21        also separates loading varargs from setting this, since the fact that those two things are done
     22        together is a detail made explicit in bytecode but it's not at all required in the higher-tier
     23        engines. In the process of factoring this code out, I found a bunch of off-by-one errors in the
     24        various calculations. I fixed them. The distance from the caller's frame pointer to the callee
     25        frame pointer is always:
     26       
     27            numUsedCallerSlots + argCount + 1 + CallFrameSize
     28       
     29        where numUsedCallerSlots is toLocal(firstFreeRegister) - 1, which simplifies down to just
     30        -firstFreeRegister. The code now speaks of numUsedCallerSlots rather than firstFreeRegister,
     31        since the latter is a bytecode peculiarity that doesn't apply in the DFG or FTL. In the DFG, the
     32        internally-computed frame size, minus the parameter slots, will be used for numUsedCallerSlots.
     33        In the FTL, we will essentially compute numUsedCallerSlots dynamically by subtracting SP from FP.
     34        Eventually, LLVM might give us some cleaner way of doing this, but it probably doesn't matter
     35        very much.
     36       
     37        The arguments forwarding optimization is factored out of the Baseline JIT: the DFG and FTL will
     38        want to do this optimization as well, but it involves quite a bit of code. So, this code is now
     39        factored out into SetupVarargsFrame.h|cpp, so that other JITs can use it. In the process of factoring
     40        this code out I noticed that the 32-bit and 64-bit code is nearly identical, so I combined them.
     41
     42        * CMakeLists.txt:
     43        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
     44        * JavaScriptCore.xcodeproj/project.pbxproj:
     45        * bytecode/CodeBlock.h:
     46        (JSC::ExecState::r):
     47        (JSC::ExecState::uncheckedR):
     48        * bytecode/VirtualRegister.h:
     49        (JSC::VirtualRegister::operator+):
     50        (JSC::VirtualRegister::operator-):
     51        (JSC::VirtualRegister::operator+=):
     52        (JSC::VirtualRegister::operator-=):
     53        * interpreter/CallFrame.h:
     54        * interpreter/Interpreter.cpp:
     55        (JSC::sizeFrameForVarargs):
     56        (JSC::loadVarargs):
     57        (JSC::setupVarargsFrame):
     58        (JSC::setupVarargsFrameAndSetThis):
     59        * interpreter/Interpreter.h:
     60        * jit/AssemblyHelpers.h:
     61        (JSC::AssemblyHelpers::emitGetFromCallFrameHeaderPtr):
     62        (JSC::AssemblyHelpers::emitGetFromCallFrameHeader32):
     63        (JSC::AssemblyHelpers::emitGetFromCallFrameHeader64):
     64        * jit/JIT.h:
     65        * jit/JITCall.cpp:
     66        (JSC::JIT::compileSetupVarargsFrame):
     67        * jit/JITCall32_64.cpp:
     68        (JSC::JIT::compileSetupVarargsFrame):
     69        * jit/JITInlines.h:
     70        (JSC::JIT::callOperation):
     71        (JSC::JIT::emitGetFromCallFrameHeaderPtr): Deleted.
     72        (JSC::JIT::emitGetFromCallFrameHeader32): Deleted.
     73        (JSC::JIT::emitGetFromCallFrameHeader64): Deleted.
     74        * jit/JITOperations.cpp:
     75        * jit/JITOperations.h:
     76        * jit/SetupVarargsFrame.cpp: Added.
     77        (JSC::emitSetupVarargsFrameFastCase):
     78        * jit/SetupVarargsFrame.h: Added.
     79        * llint/LLIntSlowPaths.cpp:
     80        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
     81        * runtime/Arguments.cpp:
     82        (JSC::Arguments::copyToArguments):
     83        * runtime/Arguments.h:
     84        * runtime/JSArray.cpp:
     85        (JSC::JSArray::copyToArguments):
     86        * runtime/JSArray.h:
     87
    1882015-02-09  Filip Pizlo  <fpizlo@apple.com>
    289
  • trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj

    r179728 r179862  
    621621    <ClCompile Include="..\jit\JITThunks.cpp" />
    622622    <ClCompile Include="..\jit\JITToDFGDeferredCompilationCallback.cpp" />
     623    <ClCompile Include="..\jit\SetupVarargsFrame.cpp" />
    623624    <ClCompile Include="..\jit\PolymorphicCallStubRoutine.cpp" />
    624625    <ClCompile Include="..\jit\Reg.cpp" />
     
    13541355    <ClInclude Include="..\jit\JITWriteBarrier.h" />
    13551356    <ClInclude Include="..\jit\JSInterfaceJIT.h" />
     1357    <ClInclude Include="..\jit\SetupVarargsFrame.h" />
    13561358    <ClInclude Include="..\jit\PolymorphicCallStubRoutine.h" />
    13571359    <ClInclude Include="..\jit\Reg.h" />
  • trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r179728 r179862  
    633633                0FEA0A34170D40BF00BB722C /* DFGJITCode.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FEA0A30170D40BF00BB722C /* DFGJITCode.h */; settings = {ATTRIBUTES = (Private, ); }; };
    634634                0FEB3ECF16237F6C00AB67AD /* MacroAssembler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FEB3ECE16237F6700AB67AD /* MacroAssembler.cpp */; };
     635                0FEE98411A8865B700754E93 /* SetupVarargsFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FEE98401A8865B600754E93 /* SetupVarargsFrame.h */; settings = {ATTRIBUTES = (Private, ); }; };
     636                0FEE98431A89227500754E93 /* SetupVarargsFrame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FEE98421A89227500754E93 /* SetupVarargsFrame.cpp */; };
    635637                0FEFC9AA1681A3B300567F53 /* DFGOSRExitJumpPlaceholder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FEFC9A71681A3B000567F53 /* DFGOSRExitJumpPlaceholder.cpp */; };
    636638                0FEFC9AB1681A3B600567F53 /* DFGOSRExitJumpPlaceholder.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FEFC9A81681A3B000567F53 /* DFGOSRExitJumpPlaceholder.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    23142316                0FEA0A30170D40BF00BB722C /* DFGJITCode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGJITCode.h; path = dfg/DFGJITCode.h; sourceTree = "<group>"; };
    23152317                0FEB3ECE16237F6700AB67AD /* MacroAssembler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MacroAssembler.cpp; sourceTree = "<group>"; };
     2318                0FEE98401A8865B600754E93 /* SetupVarargsFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SetupVarargsFrame.h; sourceTree = "<group>"; };
     2319                0FEE98421A89227500754E93 /* SetupVarargsFrame.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SetupVarargsFrame.cpp; sourceTree = "<group>"; };
    23162320                0FEFC9A71681A3B000567F53 /* DFGOSRExitJumpPlaceholder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGOSRExitJumpPlaceholder.cpp; path = dfg/DFGOSRExitJumpPlaceholder.cpp; sourceTree = "<group>"; };
    23172321                0FEFC9A81681A3B000567F53 /* DFGOSRExitJumpPlaceholder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGOSRExitJumpPlaceholder.h; path = dfg/DFGOSRExitJumpPlaceholder.h; sourceTree = "<group>"; };
     
    37933797                                A76F54A213B28AAB00EF2BCE /* JITWriteBarrier.h */,
    37943798                                A76C51741182748D00715B05 /* JSInterfaceJIT.h */,
     3799                                0FEE98421A89227500754E93 /* SetupVarargsFrame.cpp */,
     3800                                0FEE98401A8865B600754E93 /* SetupVarargsFrame.h */,
    37953801                                0FE834151A6EF97B00D04847 /* PolymorphicCallStubRoutine.cpp */,
    37963802                                0FE834161A6EF97B00D04847 /* PolymorphicCallStubRoutine.h */,
     
    55115517                                C2EAA3FA149A835E00FCE112 /* CopiedSpace.h in Headers */,
    55125518                                C2C8D02D14A3C6E000578E65 /* CopiedSpaceInlines.h in Headers */,
     5519                                0FEE98411A8865B700754E93 /* SetupVarargsFrame.h in Headers */,
    55135520                                0FC3CCFD19ADA410006AC72A /* DFGBlockMapInlines.h in Headers */,
    55145521                                0F5A52D017ADD717008ECB2D /* CopyToken.h in Headers */,
     
    71387145                                A7482B9411671147003B0712 /* JSWeakObjectMapRefPrivate.cpp in Sources */,
    71397146                                1442566115EDE98D0066A49B /* JSWithScope.cpp in Sources */,
     7147                                0FEE98431A89227500754E93 /* SetupVarargsFrame.cpp in Sources */,
    71407148                                86E3C618167BABEE006D760A /* JSWrapperMap.mm in Sources */,
    71417149                                14280870107EC1340013E7B2 /* JSWrapperObject.cpp in Sources */,
  • trunk/Source/JavaScriptCore/bytecode/CodeBlock.h

    r179503 r179862  
    12371237}
    12381238
     1239inline Register& ExecState::r(VirtualRegister reg)
     1240{
     1241    return r(reg.offset());
     1242}
     1243
    12391244inline Register& ExecState::uncheckedR(int index)
    12401245{
    12411246    RELEASE_ASSERT(index < FirstConstantRegisterIndex);
    12421247    return this[index];
     1248}
     1249
     1250inline Register& ExecState::uncheckedR(VirtualRegister reg)
     1251{
     1252    return uncheckedR(reg.offset());
    12431253}
    12441254
  • trunk/Source/JavaScriptCore/bytecode/VirtualRegister.h

    r179503 r179862  
    7171    bool operator!=(const VirtualRegister other) const { return m_virtualRegister != other.m_virtualRegister; }
    7272   
     73    VirtualRegister operator+(int value) const
     74    {
     75        return VirtualRegister(offset() + value);
     76    }
     77    VirtualRegister operator-(int value) const
     78    {
     79        return VirtualRegister(offset() - value);
     80    }
     81    VirtualRegister& operator+=(int value)
     82    {
     83        return *this = *this + value;
     84    }
     85    VirtualRegister& operator-=(int value)
     86    {
     87        return *this = *this - value;
     88    }
     89   
    7390    void dump(PrintStream& out) const;
    7491
  • trunk/Source/JavaScriptCore/interpreter/CallFrame.h

    r178143 r179862  
    204204        // Read a register from the codeframe (or constant from the CodeBlock).
    205205        Register& r(int);
     206        Register& r(VirtualRegister);
    206207        // Read a register for a non-constant
    207208        Register& uncheckedR(int);
     209        Register& uncheckedR(VirtualRegister);
    208210
    209211        // Access to arguments as passed. (After capture, arguments may move to a different location.)
  • trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp

    r179429 r179862  
    135135}
    136136
    137 CallFrame* sizeFrameForVarargs(CallFrame* callFrame, JSStack* stack, JSValue arguments, int firstFreeRegister, uint32_t firstVarArgOffset)
     137CallFrame* sizeFrameForVarargs(CallFrame* callFrame, JSStack* stack, JSValue arguments, unsigned numUsedStackSlots, uint32_t firstVarArgOffset)
    138138{
    139139    if (!arguments) { // f.apply(x, arguments), with arguments unmodified.
     
    143143        else
    144144            argumentCountIncludingThis = 1;
    145         unsigned paddedCalleeFrameOffset = WTF::roundUpToMultipleOf(stackAlignmentRegisters(), -firstFreeRegister + argumentCountIncludingThis + JSStack::CallFrameHeaderSize + 1);
     145        unsigned paddedCalleeFrameOffset = WTF::roundUpToMultipleOf(stackAlignmentRegisters(), numUsedStackSlots + argumentCountIncludingThis + JSStack::CallFrameHeaderSize);
    146146        CallFrame* newCallFrame = CallFrame::create(callFrame->registers() - paddedCalleeFrameOffset);
    147147        if (argumentCountIncludingThis > Arguments::MaxArguments + 1 || !stack->ensureCapacityFor(newCallFrame->registers())) {
     
    154154    if (arguments.isUndefinedOrNull()) {
    155155        unsigned argumentCountIncludingThis = 1;
    156         unsigned paddedCalleeFrameOffset = WTF::roundUpToMultipleOf(stackAlignmentRegisters(),  -firstFreeRegister + argumentCountIncludingThis + JSStack::CallFrameHeaderSize + 1);
     156        unsigned paddedCalleeFrameOffset = WTF::roundUpToMultipleOf(stackAlignmentRegisters(),  numUsedStackSlots + argumentCountIncludingThis + JSStack::CallFrameHeaderSize);
    157157        CallFrame* newCallFrame = CallFrame::create(callFrame->registers() - paddedCalleeFrameOffset);
    158158        if (!stack->ensureCapacityFor(newCallFrame->registers())) {
     
    175175        else
    176176            argCount = 0;
    177         unsigned paddedCalleeFrameOffset = WTF::roundUpToMultipleOf(stackAlignmentRegisters(), -firstFreeRegister + CallFrame::offsetFor(argCount + 1));
     177        unsigned paddedCalleeFrameOffset = WTF::roundUpToMultipleOf(stackAlignmentRegisters(), numUsedStackSlots + argCount + 1 + JSStack::CallFrameHeaderSize);
    178178        CallFrame* newCallFrame = CallFrame::create(callFrame->registers() - paddedCalleeFrameOffset);
    179179        if (argCount > Arguments::MaxArguments || !stack->ensureCapacityFor(newCallFrame->registers())) {
     
    191191        else
    192192            argCount = 0;
    193         unsigned paddedCalleeFrameOffset = WTF::roundUpToMultipleOf(stackAlignmentRegisters(), -firstFreeRegister + CallFrame::offsetFor(argCount + 1));
     193        unsigned paddedCalleeFrameOffset = WTF::roundUpToMultipleOf(stackAlignmentRegisters(), numUsedStackSlots + argCount + 1 + JSStack::CallFrameHeaderSize);
    194194        CallFrame* newCallFrame = CallFrame::create(callFrame->registers() - paddedCalleeFrameOffset);
    195195        if (argCount > Arguments::MaxArguments || !stack->ensureCapacityFor(newCallFrame->registers())) {
     
    206206    else
    207207        argCount = 0;
    208     unsigned paddedCalleeFrameOffset = WTF::roundUpToMultipleOf(stackAlignmentRegisters(), -firstFreeRegister + CallFrame::offsetFor(argCount + 1));
     208    unsigned paddedCalleeFrameOffset = WTF::roundUpToMultipleOf(stackAlignmentRegisters(), numUsedStackSlots + argCount + 1 + JSStack::CallFrameHeaderSize);
    209209    CallFrame* newCallFrame = CallFrame::create(callFrame->registers() - paddedCalleeFrameOffset);
    210210    if (argCount > Arguments::MaxArguments || !stack->ensureCapacityFor(newCallFrame->registers())) {
     
    215215}
    216216
    217 void loadVarargs(CallFrame* callFrame, CallFrame* newCallFrame, JSValue thisValue, JSValue arguments, uint32_t firstVarArgOffset)
     217void loadVarargs(CallFrame* callFrame, VirtualRegister firstElementDest, VirtualRegister countDest, JSValue arguments, uint32_t firstVarArgOffset)
    218218{
    219219    if (!arguments) { // f.apply(x, arguments), with arguments unmodified.
     
    223223        else
    224224            argumentCountIncludingThis = 1;
    225         newCallFrame->setArgumentCountIncludingThis(argumentCountIncludingThis);
    226         newCallFrame->setThisValue(thisValue);
     225        callFrame->r(countDest).payload() = argumentCountIncludingThis;
    227226        for (size_t i = firstVarArgOffset; i < callFrame->argumentCount(); ++i)
    228             newCallFrame->setArgument(i - firstVarArgOffset, callFrame->argumentAfterCapture(i));
     227            callFrame->r(firstElementDest + i - firstVarArgOffset) = callFrame->argumentAfterCapture(i);
    229228        return;
    230229    }
    231230   
    232231    if (arguments.isUndefinedOrNull()) {
    233         newCallFrame->setArgumentCountIncludingThis(1);
    234         newCallFrame->setThisValue(thisValue);
     232        callFrame->r(countDest).payload() = 1;
    235233        return;
    236234    }
     
    241239        if (argCount >= firstVarArgOffset) {
    242240            argCount -= firstVarArgOffset;
    243             newCallFrame->setArgumentCountIncludingThis(argCount + 1);
    244             argsObject->copyToArguments(callFrame, newCallFrame, argCount, firstVarArgOffset);
     241            callFrame->r(countDest).payload() = argCount + 1;
     242            argsObject->copyToArguments(callFrame, firstElementDest, argCount, firstVarArgOffset);
    245243        } else
    246             newCallFrame->setArgumentCountIncludingThis(1);
    247         newCallFrame->setThisValue(thisValue);
     244            callFrame->r(countDest).payload() = 1;
    248245        return;
    249246    }
     
    254251        if (argCount >= firstVarArgOffset) {
    255252            argCount -= firstVarArgOffset;
    256             newCallFrame->setArgumentCountIncludingThis(argCount + 1);
    257             array->copyToArguments(callFrame, newCallFrame, argCount, firstVarArgOffset);
     253            callFrame->r(countDest).payload() = argCount + 1;
     254            array->copyToArguments(callFrame, firstElementDest, argCount, firstVarArgOffset);
    258255        } else
    259             newCallFrame->setArgumentCountIncludingThis(1);
    260         newCallFrame->setThisValue(thisValue);
     256            callFrame->r(countDest).payload() = 1;
    261257        return;
    262258    }
     
    266262    if (argCount >= firstVarArgOffset) {
    267263        argCount -= firstVarArgOffset;
    268         newCallFrame->setArgumentCountIncludingThis(argCount + 1);
     264        callFrame->r(countDest).payload() = argCount + 1;
    269265    } else
    270         newCallFrame->setArgumentCountIncludingThis(1);
    271 
    272     newCallFrame->setThisValue(thisValue);
     266        callFrame->r(countDest).payload() = 1;
     267
    273268    for (size_t i = 0; i < argCount; ++i) {
    274         newCallFrame->setArgument(i, asObject(arguments)->get(callFrame, i + firstVarArgOffset));
     269        callFrame->r(firstElementDest + i) = asObject(arguments)->get(callFrame, i + firstVarArgOffset);
    275270        if (UNLIKELY(callFrame->vm().exception()))
    276271            return;
    277272    }
     273}
     274
     275void setupVarargsFrame(CallFrame* callFrame, CallFrame* newCallFrame, JSValue arguments, uint32_t firstVarArgOffset)
     276{
     277    VirtualRegister calleeFrameOffset(newCallFrame - callFrame);
     278   
     279    loadVarargs(
     280        callFrame,
     281        calleeFrameOffset + CallFrame::argumentOffset(0),
     282        calleeFrameOffset + JSStack::ArgumentCount,
     283        arguments, firstVarArgOffset);
     284}
     285
     286void setupVarargsFrameAndSetThis(CallFrame* callFrame, CallFrame* newCallFrame, JSValue thisValue, JSValue arguments, uint32_t firstVarArgOffset)
     287{
     288    setupVarargsFrame(callFrame, newCallFrame, arguments, firstVarArgOffset);
     289    newCallFrame->setThisValue(thisValue);
    278290}
    279291
  • trunk/Source/JavaScriptCore/interpreter/Interpreter.h

    r176533 r179862  
    299299
    300300    JSValue eval(CallFrame*);
    301     CallFrame* sizeFrameForVarargs(CallFrame*, JSStack*, JSValue, int, uint32_t firstVarArgOffset);
    302     void loadVarargs(CallFrame*, CallFrame*, JSValue, JSValue, uint32_t firstVarArgOffset);
     301    CallFrame* sizeFrameForVarargs(CallFrame* exec, JSStack*, JSValue arguments, unsigned numUsedStackSlots, uint32_t firstVarArgOffset);
     302    void loadVarargs(CallFrame* execCaller, VirtualRegister firstElementDest, VirtualRegister countDest, JSValue source, uint32_t offset);
     303    void setupVarargsFrame(CallFrame* execCaller, CallFrame* execCallee, JSValue arguments, uint32_t firstVarArgOffset);
     304    void setupVarargsFrameAndSetThis(CallFrame* execCaller, CallFrame* execCallee, JSValue thisValue, JSValue arguments, uint32_t firstVarArgOffset);
     305   
    303306} // namespace JSC
    304307
  • trunk/Source/JavaScriptCore/jit/AssemblyHelpers.h

    r179538 r179862  
    254254#endif
    255255
    256     void emitGetFromCallFrameHeaderPtr(JSStack::CallFrameHeaderEntry entry, GPRReg to)
    257     {
    258         loadPtr(Address(GPRInfo::callFrameRegister, entry * sizeof(Register)), to);
    259     }
     256    void emitGetFromCallFrameHeaderPtr(JSStack::CallFrameHeaderEntry entry, GPRReg to, GPRReg from = GPRInfo::callFrameRegister)
     257    {
     258        loadPtr(Address(from, entry * sizeof(Register)), to);
     259    }
     260    void emitGetFromCallFrameHeader32(JSStack::CallFrameHeaderEntry entry, GPRReg to, GPRReg from = GPRInfo::callFrameRegister)
     261    {
     262        load32(Address(from, entry * sizeof(Register)), to);
     263    }
     264#if USE(JSVALUE64)
     265    void emitGetFromCallFrameHeader64(JSStack::CallFrameHeaderEntry entry, GPRReg to, GPRReg from = GPRInfo::callFrameRegister)
     266    {
     267        load64(Address(from, entry * sizeof(Register)), to);
     268    }
     269#endif // USE(JSVALUE64)
    260270    void emitPutToCallFrameHeader(GPRReg from, JSStack::CallFrameHeaderEntry entry)
    261271    {
  • trunk/Source/JavaScriptCore/jit/JIT.h

    r179372 r179862  
    11/*
    2  * Copyright (C) 2008, 2012, 2013, 2014 Apple Inc. All rights reserved.
     2 * Copyright (C) 2008, 2012-2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    297297        void compileOpCall(OpcodeID, Instruction*, unsigned callLinkInfoIndex);
    298298        void compileOpCallSlowCase(OpcodeID, Instruction*, Vector<SlowCaseEntry>::iterator&, unsigned callLinkInfoIndex);
    299         void compileLoadVarargs(Instruction*);
     299        void compileSetupVarargsFrame(Instruction*);
    300300        void compileCallEval(Instruction*);
    301301        void compileCallEvalSlowCase(Instruction*, Vector<SlowCaseEntry>::iterator&);
     
    643643
    644644        void emitPutIntToCallFrameHeader(RegisterID from, JSStack::CallFrameHeaderEntry);
    645         void emitGetFromCallFrameHeaderPtr(JSStack::CallFrameHeaderEntry, RegisterID to, RegisterID from = callFrameRegister);
    646         void emitGetFromCallFrameHeader32(JSStack::CallFrameHeaderEntry, RegisterID to, RegisterID from = callFrameRegister);
    647 #if USE(JSVALUE64)
    648         void emitGetFromCallFrameHeader64(JSStack::CallFrameHeaderEntry, RegisterID to, RegisterID from = callFrameRegister);
    649 #endif
    650645
    651646        JSValue getConstantOperand(int src);
     
    736731        MacroAssembler::Call callOperation(V_JITOperation_EJIdJJ, RegisterID, const Identifier*, RegisterID, RegisterID);
    737732#if USE(JSVALUE64)
    738         MacroAssembler::Call callOperation(F_JITOperation_EFJJZ, RegisterID, RegisterID, RegisterID, int32_t);
     733        MacroAssembler::Call callOperation(F_JITOperation_EFJZ, RegisterID, RegisterID, int32_t);
    739734        MacroAssembler::Call callOperation(V_JITOperation_ESsiJJI, StructureStubInfo*, RegisterID, RegisterID, StringImpl*);
    740735#else
     
    751746        MacroAssembler::Call callOperationWithCallFrameRollbackOnException(Z_JITOperation_E);
    752747#if USE(JSVALUE32_64)
    753         MacroAssembler::Call callOperation(F_JITOperation_EFJJZ, RegisterID, RegisterID, RegisterID, RegisterID, RegisterID, int32_t);
     748        MacroAssembler::Call callOperation(F_JITOperation_EFJZ, RegisterID, RegisterID, RegisterID, int32_t);
    754749        MacroAssembler::Call callOperation(F_JITOperation_EJZZ, GPRReg, GPRReg, int32_t, int32_t);
    755750        MacroAssembler::Call callOperation(J_JITOperation_EAapJ, int, ArrayAllocationProfile*, GPRReg, GPRReg);
  • trunk/Source/JavaScriptCore/jit/JITCall.cpp

    r179478 r179862  
    11/*
    2  * Copyright (C) 2008, 2013, 2014 Apple Inc. All rights reserved.
     2 * Copyright (C) 2008, 2013-2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    4141#include "ResultType.h"
    4242#include "SamplingTool.h"
     43#include "SetupVarargsFrame.h"
    4344#include "StackAlignment.h"
    4445#include "ThunkGenerators.h"
     
    5556}
    5657
    57 void JIT::compileLoadVarargs(Instruction* instruction)
     58void JIT::compileSetupVarargsFrame(Instruction* instruction)
    5859{
    5960    int thisValue = instruction[3].u.operand;
     
    7172        emitGetVirtualRegister(arguments, regT0);
    7273        slowCase.append(branch64(NotEqual, regT0, TrustedImm64(JSValue::encode(JSValue()))));
    73 
    74         emitGetFromCallFrameHeader32(JSStack::ArgumentCount, regT0);
    75         if (firstVarArgOffset) {
    76             Jump sufficientArguments = branch32(GreaterThan, regT0, TrustedImm32(firstVarArgOffset + 1));
    77             move(TrustedImm32(1), regT0);
    78             Jump endVarArgs = jump();
    79             sufficientArguments.link(this);
    80             sub32(TrustedImm32(firstVarArgOffset), regT0);
    81             endVarArgs.link(this);
    82         }
    83         slowCase.append(branch32(Above, regT0, TrustedImm32(Arguments::MaxArguments + 1)));
    84         // regT0: argumentCountIncludingThis
    85         move(regT0, regT1);
    86         add64(TrustedImm32(-firstFreeRegister + JSStack::CallFrameHeaderSize), regT1);
    87         // regT1 now has the required frame size in Register units
    88         // Round regT1 to next multiple of stackAlignmentRegisters()
    89         add64(TrustedImm32(stackAlignmentRegisters() - 1), regT1);
    90         and64(TrustedImm32(~(stackAlignmentRegisters() - 1)), regT1);
    91 
    92         neg64(regT1);
    93         lshift64(TrustedImm32(3), regT1);
    94         addPtr(callFrameRegister, regT1);
    95         // regT1: newCallFrame
    96 
    97         slowCase.append(branchPtr(Above, AbsoluteAddress(m_vm->addressOfStackLimit()), regT1));
    98 
    99         // Initialize ArgumentCount.
    100         store32(regT0, Address(regT1, JSStack::ArgumentCount * static_cast<int>(sizeof(Register)) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)));
    101 
    102         // Initialize 'this'.
    103         emitGetVirtualRegister(thisValue, regT2);
    104         store64(regT2, Address(regT1, CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register))));
    105 
    106         // Copy arguments.
    107         signExtend32ToPtr(regT0, regT0);
    108         end.append(branchSub64(Zero, TrustedImm32(1), regT0));
    109         // regT0: argumentCount
    110 
    111         Label copyLoop = label();
    112         load64(BaseIndex(callFrameRegister, regT0, TimesEight, (CallFrame::thisArgumentOffset() + firstVarArgOffset) * static_cast<int>(sizeof(Register))), regT2);
    113         store64(regT2, BaseIndex(regT1, regT0, TimesEight, CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register))));
    114         branchSub64(NonZero, TrustedImm32(1), regT0).linkTo(copyLoop, this);
    115 
     74       
     75        move(TrustedImm32(-firstFreeRegister), regT1);
     76        emitSetupVarargsFrameFastCase(*this, regT1, regT0, regT1, regT2, 0, firstVarArgOffset, slowCase);
    11677        end.append(jump());
     78        slowCase.link(this);
    11779    }
    11880
    119     if (canOptimize)
    120         slowCase.link(this);
    121 
    12281    emitGetVirtualRegister(arguments, regT1);
    123     callOperation(operationSizeFrameForVarargs, regT1, firstFreeRegister, firstVarArgOffset);
     82    callOperation(operationSizeFrameForVarargs, regT1, -firstFreeRegister, firstVarArgOffset);
    12483    move(returnValueGPR, stackPointerRegister);
    125     emitGetVirtualRegister(thisValue, regT1);
    126     emitGetVirtualRegister(arguments, regT2);
    127     callOperation(operationLoadVarargs, returnValueGPR, regT1, regT2, firstVarArgOffset);
     84    emitGetVirtualRegister(arguments, regT1);
     85    callOperation(operationSetupVarargsFrame, returnValueGPR, regT1, firstVarArgOffset);
    12886    move(returnValueGPR, regT1);
    12987
     
    13189        end.link(this);
    13290   
     91    // Initialize 'this'.
     92    emitGetVirtualRegister(thisValue, regT0);
     93    store64(regT0, Address(regT1, CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register))));
     94
    13395    addPtr(TrustedImm32(sizeof(CallerFrameAndPC)), regT1, stackPointerRegister);
    13496}
     
    189151    COMPILE_ASSERT(OPCODE_LENGTH(op_call) == OPCODE_LENGTH(op_construct_varargs), call_and_construct_varargs_opcodes_must_be_same_length);
    190152    if (opcodeID == op_call_varargs || opcodeID == op_construct_varargs)
    191         compileLoadVarargs(instruction);
     153        compileSetupVarargsFrame(instruction);
    192154    else {
    193155        int argCount = instruction[3].u.operand;
  • trunk/Source/JavaScriptCore/jit/JITCall32_64.cpp

    r179478 r179862  
    11/*
    2  * Copyright (C) 2008, 2013, 2014 Apple Inc. All rights reserved.
     2 * Copyright (C) 2008, 2013-2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    4141#include "ResultType.h"
    4242#include "SamplingTool.h"
     43#include "SetupVarargsFrame.h"
    4344#include "StackAlignment.h"
    4445#include <wtf/StringPrintStream.h>
     
    115116}
    116117
    117 void JIT::compileLoadVarargs(Instruction* instruction)
     118void JIT::compileSetupVarargsFrame(Instruction* instruction)
    118119{
    119120    int thisValue = instruction[3].u.operand;
     
    131132        emitLoadTag(arguments, regT1);
    132133        slowCase.append(branch32(NotEqual, regT1, TrustedImm32(JSValue::EmptyValueTag)));
    133 
    134         load32(payloadFor(JSStack::ArgumentCount), regT2);
    135         if (firstVarArgOffset) {
    136             Jump sufficientArguments = branch32(GreaterThan, regT2, TrustedImm32(firstVarArgOffset + 1));
    137             move(TrustedImm32(1), regT2);
    138             Jump endVarArgs = jump();
    139             sufficientArguments.link(this);
    140             sub32(TrustedImm32(firstVarArgOffset), regT2);
    141             endVarArgs.link(this);
    142         }
    143         slowCase.append(branch32(Above, regT2, TrustedImm32(Arguments::MaxArguments + 1)));
    144         // regT2: argumentCountIncludingThis
    145 
    146         move(regT2, regT3);
    147         addPtr(TrustedImm32(-firstFreeRegister + JSStack::CallFrameHeaderSize), regT3);
    148         // regT1 now has the required frame size in Register units
    149         // Round regT1 to next multiple of stackAlignmentRegisters()
    150         addPtr(TrustedImm32(stackAlignmentRegisters() - 1), regT3);
    151         andPtr(TrustedImm32(~(stackAlignmentRegisters() - 1)), regT3);
    152         neg32(regT3);
    153         lshift32(TrustedImm32(3), regT3);
    154         addPtr(callFrameRegister, regT3);
    155         // regT3: newCallFrame
    156 
    157         slowCase.append(branchPtr(Above, AbsoluteAddress(m_vm->addressOfStackLimit()), regT3));
    158 
    159         // Initialize ArgumentCount.
    160         store32(regT2, payloadFor(JSStack::ArgumentCount, regT3));
    161 
    162         // Initialize 'this'.
    163         emitLoad(thisValue, regT1, regT0);
    164         store32(regT0, Address(regT3, OBJECT_OFFSETOF(JSValue, u.asBits.payload) + (CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register)))));
    165         store32(regT1, Address(regT3, OBJECT_OFFSETOF(JSValue, u.asBits.tag) + (CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register)))));
    166 
    167         // Copy arguments.
    168         end.append(branchSub32(Zero, TrustedImm32(1), regT2));
    169         // regT2: argumentCount;
    170 
    171         Label copyLoop = label();
    172         load32(BaseIndex(callFrameRegister, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload) +((CallFrame::thisArgumentOffset() + firstVarArgOffset) * static_cast<int>(sizeof(Register)))), regT0);
    173         load32(BaseIndex(callFrameRegister, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag) +((CallFrame::thisArgumentOffset() + firstVarArgOffset) * static_cast<int>(sizeof(Register)))), regT1);
    174         store32(regT0, BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload) +(CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register)))));
    175         store32(regT1, BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag) +(CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register)))));
    176         branchSub32(NonZero, TrustedImm32(1), regT2).linkTo(copyLoop, this);
    177 
     134       
     135        move(TrustedImm32(-firstFreeRegister), regT1);
     136        emitSetupVarargsFrameFastCase(*this, regT1, regT0, regT1, regT2, 0, firstVarArgOffset, slowCase);
    178137        end.append(jump());
     138        slowCase.link(this);
    179139    }
    180140
    181     if (canOptimize)
    182         slowCase.link(this);
    183 
    184141    emitLoad(arguments, regT1, regT0);
    185     callOperation(operationSizeFrameForVarargs, regT1, regT0, firstFreeRegister, firstVarArgOffset);
     142    callOperation(operationSizeFrameForVarargs, regT1, regT0, -firstFreeRegister, firstVarArgOffset);
     143    // This is spectacularly dirty. We want to pass four arguments to operationSetupVarargsFrame. On x86-32 we
     144    // will pass them on the stack. We want four stack slots, or 16 bytes. Extending the stack by 8 bytes
     145    // over where we planned on pointing the FP gives us enough room. The reason is that the FP gives an
     146    // extra CallerFrameAndPC bytes beyond where SP should point prior to the call. So if we just did
     147    // move(returnValueGPR, stackPointerRegister), we'd have enough room for passing two args, or 8
     148    // bytes - except that we'd have a misaligned stack. So if we subtract *another* CallerFrameAndPC
     149    // bytes, we are up to 16 bytes of spare room *and* we have an aligned stack. Gross, but correct!
    186150    addPtr(TrustedImm32(-sizeof(CallerFrameAndPC)), returnValueGPR, stackPointerRegister);
    187     emitLoad(thisValue, regT1, regT4);
    188     emitLoad(arguments, regT3, regT2);
    189     callOperation(operationLoadVarargs, returnValueGPR, regT1, regT4, regT3, regT2, firstVarArgOffset);
    190     move(returnValueGPR, regT3);
     151    emitLoad(arguments, regT2, regT1);
     152    callOperation(operationSetupVarargsFrame, returnValueGPR, regT2, regT1, firstVarArgOffset);
     153    move(returnValueGPR, regT1);
    191154
    192155    if (canOptimize)
    193156        end.link(this);
    194157
    195     addPtr(TrustedImm32(sizeof(CallerFrameAndPC)), regT3, stackPointerRegister);
     158    // Initialize 'this'.
     159    emitLoad(thisValue, regT2, regT0);
     160    store32(regT0, Address(regT1, PayloadOffset + (CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register)))));
     161    store32(regT2, Address(regT1, TagOffset + (CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register)))));
     162   
     163    addPtr(TrustedImm32(sizeof(CallerFrameAndPC)), regT1, stackPointerRegister);
    196164}
    197165
     
    252220   
    253221    if (opcodeID == op_call_varargs || opcodeID == op_construct_varargs)
    254         compileLoadVarargs(instruction);
     222        compileSetupVarargsFrame(instruction);
    255223    else {
    256224        int argCount = instruction[3].u.operand;
  • trunk/Source/JavaScriptCore/jit/JITInlines.h

    r178143 r179862  
    9999}
    100100
    101 ALWAYS_INLINE void JIT::emitGetFromCallFrameHeaderPtr(JSStack::CallFrameHeaderEntry entry, RegisterID to, RegisterID from)
    102 {
    103     loadPtr(Address(from, entry * sizeof(Register)), to);
    104 }
    105 
    106 ALWAYS_INLINE void JIT::emitGetFromCallFrameHeader32(JSStack::CallFrameHeaderEntry entry, RegisterID to, RegisterID from)
    107 {
    108     load32(Address(from, entry * sizeof(Register)), to);
    109 }
    110 
    111 #if USE(JSVALUE64)
    112 ALWAYS_INLINE void JIT::emitGetFromCallFrameHeader64(JSStack::CallFrameHeaderEntry entry, RegisterID to, RegisterID from)
    113 {
    114     load64(Address(from, entry * sizeof(Register)), to);
    115 }
    116 #endif
    117 
    118101ALWAYS_INLINE void JIT::emitLoadCharacterString(RegisterID src, RegisterID dst, JumpList& failures)
    119102{
     
    393376}
    394377
    395 ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(F_JITOperation_EFJJZ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3, int32_t arg4)
    396 {
    397     setupArgumentsWithExecState(arg1, arg2, arg3, TrustedImm32(arg4));
     378ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(F_JITOperation_EFJZ operation, GPRReg arg1, GPRReg arg2, int32_t arg3)
     379{
     380    setupArgumentsWithExecState(arg1, arg2, TrustedImm32(arg3));
    398381    return appendCallWithExceptionCheck(operation);
    399382}
     
    540523}
    541524
    542 ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(F_JITOperation_EFJJZ operation, GPRReg arg1, GPRReg arg2Tag, GPRReg arg2Payload, GPRReg arg3Tag, GPRReg arg3Payload, int32_t arg4)
    543 {
    544     setupArgumentsWithExecState(arg1, arg2Payload, arg2Tag, arg3Payload, arg3Tag, TrustedImm32(arg4));
     525ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(F_JITOperation_EFJZ operation, GPRReg arg1, GPRReg arg2Tag, GPRReg arg2Payload, int32_t arg3)
     526{
     527    setupArgumentsWithExecState(arg1, arg2Payload, arg2Tag, TrustedImm32(arg3));
    545528    return appendCallWithExceptionCheck(operation);
    546529}
  • trunk/Source/JavaScriptCore/jit/JITOperations.cpp

    r179478 r179862  
    16051605}
    16061606
    1607 CallFrame* JIT_OPERATION operationSizeFrameForVarargs(ExecState* exec, EncodedJSValue encodedArguments, int32_t firstFreeRegister, int32_t firstVarArgOffset)
     1607CallFrame* JIT_OPERATION operationSizeFrameForVarargs(ExecState* exec, EncodedJSValue encodedArguments, int32_t numUsedStackSlots, int32_t firstVarArgOffset)
    16081608{
    16091609    VM& vm = exec->vm();
     
    16111611    JSStack* stack = &exec->interpreter()->stack();
    16121612    JSValue arguments = JSValue::decode(encodedArguments);
    1613     CallFrame* newCallFrame = sizeFrameForVarargs(exec, stack, arguments, firstFreeRegister, firstVarArgOffset);
     1613    CallFrame* newCallFrame = sizeFrameForVarargs(exec, stack, arguments, numUsedStackSlots, firstVarArgOffset);
    16141614    return newCallFrame;
    16151615}
    16161616
    1617 CallFrame* JIT_OPERATION operationLoadVarargs(ExecState* exec, CallFrame* newCallFrame, EncodedJSValue encodedThis, EncodedJSValue encodedArguments, int32_t firstVarArgOffset)
    1618 {
    1619     VM& vm = exec->vm();
    1620     NativeCallFrameTracer tracer(&vm, exec);
    1621     JSValue thisValue = JSValue::decode(encodedThis);
     1617CallFrame* JIT_OPERATION operationSetupVarargsFrame(ExecState* exec, CallFrame* newCallFrame, EncodedJSValue encodedArguments, int32_t firstVarArgOffset)
     1618{
     1619    VM& vm = exec->vm();
     1620    NativeCallFrameTracer tracer(&vm, exec);
    16221621    JSValue arguments = JSValue::decode(encodedArguments);
    1623     loadVarargs(exec, newCallFrame, thisValue, arguments, firstVarArgOffset);
     1622    setupVarargsFrame(exec, newCallFrame, arguments, firstVarArgOffset);
    16241623    return newCallFrame;
    16251624}
  • trunk/Source/JavaScriptCore/jit/JITOperations.h

    r179478 r179862  
    8888*/
    8989
    90 typedef CallFrame* JIT_OPERATION (*F_JITOperation_EFJJZ)(ExecState*, CallFrame*, EncodedJSValue, EncodedJSValue, int32_t);
     90typedef CallFrame* JIT_OPERATION (*F_JITOperation_EFJZ)(ExecState*, CallFrame*, EncodedJSValue, int32_t);
    9191typedef CallFrame* JIT_OPERATION (*F_JITOperation_EJZZ)(ExecState*, EncodedJSValue, int32_t, int32_t);
    9292typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_E)(ExecState*);
     
    310310JSCell* JIT_OPERATION operationGetPNames(ExecState*, JSObject*) WTF_INTERNAL;
    311311EncodedJSValue JIT_OPERATION operationInstanceOf(ExecState*, EncodedJSValue, EncodedJSValue proto) WTF_INTERNAL;
    312 CallFrame* JIT_OPERATION operationSizeFrameForVarargs(ExecState*, EncodedJSValue arguments, int32_t firstFreeRegister, int32_t firstVarArgOffset) WTF_INTERNAL;
    313 CallFrame* JIT_OPERATION operationLoadVarargs(ExecState*, CallFrame*, EncodedJSValue thisValue, EncodedJSValue arguments, int32_t firstVarArgOffset) WTF_INTERNAL;
     312CallFrame* JIT_OPERATION operationSizeFrameForVarargs(ExecState*, EncodedJSValue arguments, int32_t numUsedStackSlots, int32_t firstVarArgOffset) WTF_INTERNAL;
     313CallFrame* JIT_OPERATION operationSetupVarargsFrame(ExecState*, CallFrame*, EncodedJSValue arguments, int32_t firstVarArgOffset) WTF_INTERNAL;
    314314EncodedJSValue JIT_OPERATION operationToObject(ExecState*, EncodedJSValue) WTF_INTERNAL;
    315315
  • trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp

    r179478 r179862  
    11661166   
    11671167    ExecState* execCallee = sizeFrameForVarargs(exec, &vm.interpreter->stack(),
    1168         LLINT_OP_C(4).jsValue(), pc[5].u.operand, pc[6].u.operand);
     1168        LLINT_OP_C(4).jsValue(), -pc[5].u.operand, pc[6].u.operand);
    11691169    LLINT_CALL_CHECK_EXCEPTION(exec, exec);
    11701170   
     
    11851185    ExecState* execCallee = vm.newCallFrameReturnValue;
    11861186
    1187     loadVarargs(exec, execCallee, LLINT_OP_C(3).jsValue(), LLINT_OP_C(4).jsValue(), pc[6].u.operand);
     1187    setupVarargsFrameAndSetThis(exec, execCallee, LLINT_OP_C(3).jsValue(), LLINT_OP_C(4).jsValue(), pc[6].u.operand);
    11881188    LLINT_CALL_CHECK_EXCEPTION(exec, exec);
    11891189   
     
    12061206    ExecState* execCallee = vm.newCallFrameReturnValue;
    12071207   
    1208     loadVarargs(exec, execCallee, LLINT_OP_C(3).jsValue(), LLINT_OP_C(4).jsValue(), pc[6].u.operand);
     1208    setupVarargsFrameAndSetThis(exec, execCallee, LLINT_OP_C(3).jsValue(), LLINT_OP_C(4).jsValue(), pc[6].u.operand);
    12091209    LLINT_CALL_CHECK_EXCEPTION(exec, exec);
    12101210   
  • trunk/Source/JavaScriptCore/runtime/Arguments.cpp

    r178928 r179862  
    22 *  Copyright (C) 1999-2002 Harri Porten (porten@kde.org)
    33 *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
    4  *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
     4 *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2015 Apple Inc. All rights reserved.
    55 *  Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
    66 *  Copyright (C) 2007 Maks Orlovich
     
    8888static EncodedJSValue JSC_HOST_CALL argumentsFuncIterator(ExecState*);
    8989
    90 void Arguments::copyToArguments(ExecState* exec, CallFrame* callFrame, uint32_t copyLength, int32_t firstVarArgOffset)
     90void Arguments::copyToArguments(ExecState* exec, VirtualRegister firstElementDest, uint32_t copyLength, int32_t firstVarArgOffset)
    9191{
    9292    uint32_t length = copyLength + firstVarArgOffset;
     
    9595        length = min(get(exec, exec->propertyNames().length).toUInt32(exec), length);
    9696        for (unsigned i = firstVarArgOffset; i < length; i++)
    97             callFrame->setArgument(i, get(exec, i));
     97            exec->r(firstElementDest + i - firstVarArgOffset) = get(exec, i);
    9898        return;
    9999    }
     
    101101    for (size_t i = firstVarArgOffset; i < length; ++i) {
    102102        if (JSValue value = tryGetArgument(i))
    103             callFrame->setArgument(i - firstVarArgOffset, value);
    104         else
    105             callFrame->setArgument(i - firstVarArgOffset, get(exec, i));
     103            exec->r(firstElementDest + i - firstVarArgOffset) = value;
     104        else {
     105            exec->r(firstElementDest + i - firstVarArgOffset) = get(exec, i);
     106            if (UNLIKELY(exec->vm().exception()))
     107                return;
     108        }
    106109    }
    107110}
  • trunk/Source/JavaScriptCore/runtime/Arguments.h

    r178517 r179862  
    11/*
    22 *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
    3  *  Copyright (C) 2003, 2006, 2007, 2008, 2009, 2014 Apple Inc. All rights reserved.
     3 *  Copyright (C) 2003, 2006, 2007, 2008, 2009, 2014, 2015 Apple Inc. All rights reserved.
    44 *  Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
    55 *  Copyright (C) 2007 Maks Orlovich
     
    8585    }
    8686       
    87     void copyToArguments(ExecState*, CallFrame*, uint32_t copyLength, int32_t firstArgumentOffset);
     87    void copyToArguments(ExecState*, VirtualRegister firstElementDest, uint32_t copyLength, int32_t firstArgumentOffset);
    8888    void tearOff(CallFrame*);
    8989    void tearOff(CallFrame*, InlineCallFrame*);
  • trunk/Source/JavaScriptCore/runtime/JSArray.cpp

    r178928 r179862  
    11/*
    22 *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
    3  *  Copyright (C) 2003, 2007, 2008, 2009, 2012, 2013 Apple Inc. All rights reserved.
     3 *  Copyright (C) 2003, 2007, 2008, 2009, 2012, 2013, 2015 Apple Inc. All rights reserved.
    44 *  Copyright (C) 2003 Peter Kelly (pmk@post.com)
    55 *  Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com)
     
    15711571}
    15721572
    1573 void JSArray::copyToArguments(ExecState* exec, CallFrame* callFrame, uint32_t copyLength, int32_t firstVarArgOffset)
     1573void JSArray::copyToArguments(ExecState* exec, VirtualRegister firstElementDest, uint32_t copyLength, int32_t firstVarArgOffset)
    15741574{
    15751575    unsigned i = firstVarArgOffset;
     
    16031603            if (v != v)
    16041604                break;
    1605             callFrame->setArgument(i - firstVarArgOffset, JSValue(JSValue::EncodeAsDouble, v));
     1605            exec->r(firstElementDest + i - firstVarArgOffset) = JSValue(JSValue::EncodeAsDouble, v);
    16061606        }
    16071607        break;
     
    16281628        if (!v)
    16291629            break;
    1630         callFrame->setArgument(i - firstVarArgOffset, v.get());
    1631     }
    1632    
    1633     for (; i < length; ++i)
    1634         callFrame->setArgument(i - firstVarArgOffset, get(exec, i));
     1630        exec->r(firstElementDest + i - firstVarArgOffset) = v.get();
     1631    }
     1632   
     1633    for (; i < length; ++i) {
     1634        exec->r(firstElementDest + i - firstVarArgOffset) = get(exec, i);
     1635        if (UNLIKELY(exec->vm().exception()))
     1636            return;
     1637    }
    16351638}
    16361639
  • trunk/Source/JavaScriptCore/runtime/JSArray.h

    r175365 r179862  
    11/*
    22 *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
    3  *  Copyright (C) 2003, 2007, 2008, 2009, 2012 Apple Inc. All rights reserved.
     3 *  Copyright (C) 2003, 2007, 2008, 2009, 2012, 2015 Apple Inc. All rights reserved.
    44 *
    55 *  This library is free software; you can redistribute it and/or
     
    133133
    134134    JS_EXPORT_PRIVATE void fillArgList(ExecState*, MarkedArgumentBuffer&);
    135     JS_EXPORT_PRIVATE void copyToArguments(ExecState*, CallFrame*, uint32_t length, int32_t firstVarArgOffset);
     135    JS_EXPORT_PRIVATE void copyToArguments(ExecState*, VirtualRegister firstElementDest, uint32_t length, int32_t firstVarArgOffset);
    136136
    137137    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype, IndexingType indexingType)
Note: See TracChangeset for help on using the changeset viewer.