Ignore:
Timestamp:
Feb 9, 2015, 7:27:43 PM (10 years ago)
Author:
[email protected]
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:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/runtime/JSArray.cpp

    r178928 r179862  
    11/*
    22 *  Copyright (C) 1999-2000 Harri Porten ([email protected])
    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 ([email protected])
    55 *  Copyright (C) 2006 Alexey Proskuryakov ([email protected])
     
    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
Note: See TracChangeset for help on using the changeset viewer.