Ignore:
Timestamp:
Jul 27, 2011, 4:48:56 PM (14 years ago)
Author:
[email protected]
Message:

https://bugs.webkit.org/show_bug.cgi?id=65294
DFG JIT - may speculate based on wrong arguments.

Reviewed by Oliver Hunt

In the case of a DFG compiled function calling to and compiling a second function that
also compiles through the DFG JIT (i.e. compilation triggered with DFGOperations.cpp),
we call compileFor passing the caller functions exec state, rather than the callee's.
This may lead to mis-optimization, since the DFG compiler will example the exec state's
arguments on the assumption that these will be passed to the callee - it is wanting the
callee exec state, not the caller's exec state.

Fixing this for all cases of compilation is tricksy, due to the way the numeric sort
function is compiled, & the structure of the calls in the Interpreter::execute methods.
Only fix for compilation from the JIT, in other calls don't speculate based on arguments
for now.

  • dfg/DFGOperations.cpp:
  • runtime/Executable.cpp:

(JSC::tryDFGCompile):
(JSC::tryDFGCompileFunction):
(JSC::FunctionExecutable::compileForCallInternal):

  • runtime/Executable.h:

(JSC::FunctionExecutable::compileForCall):
(JSC::FunctionExecutable::compileFor):

File:
1 edited

Legend:

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

    r91194 r91883  
    406406        }
    407407
    408         JSObject* compileForCall(ExecState* exec, ScopeChainNode* scopeChainNode)
     408        JSObject* compileForCall(ExecState* exec, ScopeChainNode* scopeChainNode, ExecState* calleeArgsExec = 0)
    409409        {
    410410            ASSERT(exec->globalData().dynamicGlobalObject);
    411411            JSObject* error = 0;
    412412            if (!m_codeBlockForCall)
    413                 error = compileForCallInternal(exec, scopeChainNode);
     413                error = compileForCallInternal(exec, scopeChainNode, calleeArgsExec);
    414414            ASSERT(!error == !!m_codeBlockForCall);
    415415            return error;
     
    450450        JSObject* compileFor(ExecState* exec, ScopeChainNode* scopeChainNode, CodeSpecializationKind kind)
    451451        {
     452            // compileFor should only be called with a callframe set up to call this function,
     453            // since we will make speculative optimizations based on the arguments.
     454            ASSERT(exec->callee());
     455            ASSERT(exec->callee()->inherits(&JSFunction::s_info));
     456            ASSERT(asFunction(exec->callee())->jsExecutable() == this);
     457
    452458            if (kind == CodeForCall)
    453                 return compileForCall(exec, scopeChainNode);
     459                return compileForCall(exec, scopeChainNode, exec);
    454460            ASSERT(kind == CodeForConstruct);
    455461            return compileForConstruct(exec, scopeChainNode);
     
    492498        FunctionExecutable(ExecState*, const Identifier& name, const SourceCode&, bool forceUsesArguments, FunctionParameters*, bool, int firstLine, int lastLine);
    493499
    494         JSObject* compileForCallInternal(ExecState*, ScopeChainNode*);
     500        JSObject* compileForCallInternal(ExecState*, ScopeChainNode*, ExecState* calleeArgsExec);
    495501        JSObject* compileForConstructInternal(ExecState*, ScopeChainNode*);
    496502       
Note: See TracChangeset for help on using the changeset viewer.