Ignore:
Timestamp:
May 23, 2012, 1:52:42 PM (13 years ago)
Author:
[email protected]
Message:

DFG should be able to inline functions that use arguments reflectively
https://bugs.webkit.org/show_bug.cgi?id=86132

Reviewed by Oliver Hunt.

Merged r116838 from dfgopt.

This turns on inlining of functions that use arguments reflectively, but it
does not do any of the obvious optimizations that this exposes. I'll save that
for another patch - the important thing for now is that this contains all of
the plumbing necessary to make this kind of inlining sound even in bizarro
cases like an inline callee escaping the arguments object to parts of the
inline caller where the arguments are otherwise dead. Or even more fun cases
like where you've inlined to an inline stack that is three-deep, and the
function on top of the inline stack reflectively accesses the arguments of a
function that is in the middle of the inline stack. Any subsequent
optimizations that we do for the obvious cases of arguments usage in inline
functions will have to take care not to break the baseline functionality that
this patch plumbs together.

  • bytecode/CodeBlock.cpp:

(JSC::CodeBlock::printCallOp):
(JSC::CodeBlock::dump):

  • bytecode/CodeBlock.h:
  • dfg/DFGAssemblyHelpers.h:

(JSC::DFG::AssemblyHelpers::argumentsRegisterFor):
(AssemblyHelpers):

  • dfg/DFGByteCodeParser.cpp:

(InlineStackEntry):
(JSC::DFG::ByteCodeParser::handleCall):
(JSC::DFG::ByteCodeParser::handleInlining):
(JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
(JSC::DFG::ByteCodeParser::parse):

  • dfg/DFGCCallHelpers.h:

(JSC::DFG::CCallHelpers::setupArgumentsWithExecState):
(CCallHelpers):

  • dfg/DFGCapabilities.h:

(JSC::DFG::canInlineOpcode):

  • dfg/DFGDriver.cpp:

(JSC::DFG::compile):

  • dfg/DFGFixupPhase.cpp:

(JSC::DFG::FixupPhase::fixupNode):

  • dfg/DFGOperations.cpp:
  • dfg/DFGOperations.h:
  • dfg/DFGSpeculativeJIT.h:

(JSC::DFG::SpeculativeJIT::callOperation):

  • dfg/DFGSpeculativeJIT32_64.cpp:

(JSC::DFG::SpeculativeJIT::compile):

  • dfg/DFGSpeculativeJIT64.cpp:

(JSC::DFG::SpeculativeJIT::compile):

  • interpreter/CallFrame.cpp:

(JSC):
(JSC::CallFrame::someCodeBlockForPossiblyInlinedCode):

  • interpreter/CallFrame.h:

(ExecState):
(JSC::ExecState::someCodeBlockForPossiblyInlinedCode):

  • interpreter/Interpreter.cpp:

(JSC::Interpreter::retrieveArgumentsFromVMCode):

  • runtime/Arguments.cpp:

(JSC::Arguments::tearOff):
(JSC):
(JSC::Arguments::tearOffForInlineCallFrame):

  • runtime/Arguments.h:

(Arguments):
(JSC::Arguments::create):
(JSC::Arguments::finishCreation):
(JSC):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/runtime/Arguments.h

    r118030 r118240  
    6868            return arguments;
    6969        }
     70       
     71        static Arguments* create(JSGlobalData& globalData, CallFrame* callFrame, InlineCallFrame* inlineCallFrame)
     72        {
     73            Arguments* arguments = new (NotNull, allocateCell<Arguments>(globalData.heap)) Arguments(callFrame);
     74            arguments->finishCreation(callFrame, inlineCallFrame);
     75            return arguments;
     76        }
    7077
    7178        enum { MaxArguments = 0x10000 };
     
    7683        Arguments(CallFrame*);
    7784        Arguments(CallFrame*, NoParametersType);
     85       
     86        void tearOffForInlineCallFrame(JSGlobalData& globalData, Register*, InlineCallFrame*);
    7887
    7988    public:
     
    93102        void copyToArguments(ExecState*, CallFrame*, uint32_t length);
    94103        void tearOff(CallFrame*);
     104        void tearOff(CallFrame*, InlineCallFrame*);
    95105        bool isTornOff() const { return d->registerArray; }
    96106        void didTearOffActivation(JSGlobalData& globalData, JSActivation* activation)
     
    113123
    114124        void finishCreation(CallFrame*);
     125        void finishCreation(CallFrame*, InlineCallFrame*);
    115126
    116127    private:
     
    180191    }
    181192
     193    inline void Arguments::finishCreation(CallFrame* callFrame, InlineCallFrame* inlineCallFrame)
     194    {
     195        Base::finishCreation(callFrame->globalData());
     196        ASSERT(inherits(&s_info));
     197
     198        JSFunction* callee = inlineCallFrame->callee.get();
     199        d->numArguments = inlineCallFrame->arguments.size() - 1;
     200        d->registers = reinterpret_cast<WriteBarrier<Unknown>*>(callFrame->registers()) + inlineCallFrame->stackOffset;
     201        d->callee.set(callFrame->globalData(), this, callee);
     202        d->overrodeLength = false;
     203        d->overrodeCallee = false;
     204        d->overrodeCaller = false;
     205        d->isStrictMode = jsCast<FunctionExecutable*>(inlineCallFrame->executable.get())->isStrictMode();
     206
     207        // The bytecode generator omits op_tear_off_activation in cases of no
     208        // declared parameters, so we need to tear off immediately.
     209        if (d->isStrictMode || !callee->jsExecutable()->parameterCount())
     210            tearOff(callFrame, inlineCallFrame);
     211    }
     212
    182213} // namespace JSC
    183214
Note: See TracChangeset for help on using the changeset viewer.