Ignore:
Timestamp:
Nov 13, 2012, 11:22:57 PM (13 years ago)
Author:
[email protected]
Message:

DFG CreateThis should be able to statically account for the structure of the object it creates, if profiling indicates that this structure is always the same
https://bugs.webkit.org/show_bug.cgi?id=102017

Reviewed by Geoffrey Garen.

This adds a watchpoint in JSFunction on the cached inheritor ID. It also changes
NewObject to take a structure as an operand (previously it implicitly used the owning
global object's empty object structure). Any GetCallee where the callee is predictable
is turned into a CheckFunction + WeakJSConstant, and any CreateThis on a WeakJSConstant
where the inheritor ID watchpoint is still valid is turned into an InheritorIDWatchpoint
followed by a NewObject. NewObject already accounts for the structure it uses for object
creation in the CFA.

  • dfg/DFGAbstractState.cpp:

(JSC::DFG::AbstractState::execute):

  • dfg/DFGByteCodeParser.cpp:

(JSC::DFG::ByteCodeParser::parseBlock):

  • dfg/DFGCSEPhase.cpp:

(JSC::DFG::CSEPhase::checkFunctionElimination):

  • dfg/DFGGraph.cpp:

(JSC::DFG::Graph::dump):

  • dfg/DFGNode.h:

(JSC::DFG::Node::hasFunction):
(JSC::DFG::Node::function):
(JSC::DFG::Node::hasStructure):

  • dfg/DFGNodeType.h:

(DFG):

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

(JSC::DFG::PredictionPropagationPhase::propagate):

  • dfg/DFGSpeculativeJIT.h:

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

  • dfg/DFGSpeculativeJIT32_64.cpp:

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

  • dfg/DFGSpeculativeJIT64.cpp:

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

  • runtime/Executable.h:

(JSC::JSFunction::JSFunction):

  • runtime/JSBoundFunction.cpp:

(JSC):

  • runtime/JSFunction.cpp:

(JSC::JSFunction::JSFunction):
(JSC::JSFunction::put):
(JSC::JSFunction::defineOwnProperty):

  • runtime/JSFunction.h:

(JSC::JSFunction::tryGetKnownInheritorID):
(JSFunction):
(JSC::JSFunction::addInheritorIDWatchpoint):

File:
1 edited

Legend:

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

    r134460 r134555  
    8484    , m_executable()
    8585    , m_scope(exec->globalData(), this, globalObject)
     86    // We initialize blind so that changes to the prototype after function creation but before
     87    // the optimizer kicks in don't disable optimizations. Once the optimizer kicks in, the
     88    // watchpoint will start watching and any changes will both force deoptimization and disable
     89    // future attempts to optimize. This is necessary because we are guaranteed that the
     90    // inheritorID is changed exactly once prior to optimizations kicking in. We could be
     91    // smarter and count the number of times the prototype is clobbered and only optimize if it
     92    // was clobbered exactly once, but that seems like overkill. In almost all cases it will be
     93    // clobbered once, and if it's clobbered more than once, that will probably only occur
     94    // before we started optimizing, anyway.
     95    , m_inheritorIDWatchpoint(InitializedBlind)
    8696{
    8797}
     
    344354        thisObject->methodTable()->getOwnPropertySlot(thisObject, exec, propertyName, slot);
    345355        thisObject->m_cachedInheritorID.clear();
     356        thisObject->m_inheritorIDWatchpoint.notifyWrite();
    346357        // Don't allow this to be cached, since a [[Put]] must clear m_cachedInheritorID.
    347358        PutPropertySlot dontCache;
     
    390401        thisObject->methodTable()->getOwnPropertySlot(thisObject, exec, propertyName, slot);
    391402        thisObject->m_cachedInheritorID.clear();
     403        thisObject->m_inheritorIDWatchpoint.notifyWrite();
    392404        return Base::defineOwnProperty(object, exec, propertyName, descriptor, throwException);
    393405    }
Note: See TracChangeset for help on using the changeset viewer.