Ignore:
Timestamp:
Jun 15, 2012, 3:14:53 PM (13 years ago)
Author:
[email protected]
Message:

DFG should be able to set watchpoints on structure transitions in the
method check prototype chain
https://bugs.webkit.org/show_bug.cgi?id=89058

Source/JavaScriptCore:

Reviewed by Gavin Barraclough.

This adds the ability to set watchpoints on Structures, and then does
the most modest thing we can do with this ability: the DFG now sets
watchpoints on structure transitions in the prototype chain of method
checks.

This appears to be a >1% speed-up on V8.

  • bytecode/PutByIdStatus.cpp:

(JSC::PutByIdStatus::computeFromLLInt):
(JSC::PutByIdStatus::computeFor):

  • bytecode/StructureSet.h:

(JSC::StructureSet::containsOnly):
(StructureSet):

  • bytecode/Watchpoint.cpp:

(JSC::WatchpointSet::WatchpointSet):
(JSC::InlineWatchpointSet::add):
(JSC):
(JSC::InlineWatchpointSet::inflateSlow):
(JSC::InlineWatchpointSet::freeFat):

  • bytecode/Watchpoint.h:

(WatchpointSet):
(JSC):
(InlineWatchpointSet):
(JSC::InlineWatchpointSet::InlineWatchpointSet):
(JSC::InlineWatchpointSet::~InlineWatchpointSet):
(JSC::InlineWatchpointSet::hasBeenInvalidated):
(JSC::InlineWatchpointSet::isStillValid):
(JSC::InlineWatchpointSet::startWatching):
(JSC::InlineWatchpointSet::notifyWrite):
(JSC::InlineWatchpointSet::isFat):
(JSC::InlineWatchpointSet::fat):
(JSC::InlineWatchpointSet::inflate):

  • dfg/DFGAbstractState.cpp:

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

  • dfg/DFGByteCodeParser.cpp:

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

  • dfg/DFGCSEPhase.cpp:

(JSC::DFG::CSEPhase::structureTransitionWatchpointElimination):
(CSEPhase):
(JSC::DFG::CSEPhase::performNodeCSE):

  • dfg/DFGCommon.h:
  • dfg/DFGGraph.cpp:

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

  • dfg/DFGGraph.h:

(JSC::DFG::Graph::isCellConstant):

  • dfg/DFGJITCompiler.h:

(JSC::DFG::JITCompiler::addWeakReferences):
(JITCompiler):

  • dfg/DFGNode.h:

(JSC::DFG::Node::hasStructure):
(Node):
(JSC::DFG::Node::structure):

  • dfg/DFGNodeType.h:

(DFG):

  • dfg/DFGPredictionPropagationPhase.cpp:

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

  • dfg/DFGRepatch.cpp:

(JSC::DFG::emitPutTransitionStub):

  • dfg/DFGSpeculativeJIT64.cpp:

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

  • jit/JITStubs.cpp:

(JSC::JITThunks::tryCachePutByID):

  • llint/LLIntSlowPaths.cpp:

(JSC::LLInt::LLINT_SLOW_PATH_DECL):

  • runtime/Structure.cpp:

(JSC::Structure::Structure):

  • runtime/Structure.h:

(JSC::Structure::transitionWatchpointSetHasBeenInvalidated):
(Structure):
(JSC::Structure::transitionWatchpointSetIsStillValid):
(JSC::Structure::addTransitionWatchpoint):
(JSC::Structure::notifyTransitionFromThisStructure):
(JSC::JSCell::setStructure):

  • runtime/SymbolTable.cpp:

(JSC::SymbolTableEntry::attemptToWatch):

LayoutTests:

Rubber stamped by Gavin Barraclough.

  • fast/js/dfg-call-method-hit-watchpoint-expected.txt: Added.
  • fast/js/dfg-call-method-hit-watchpoint.html: Added.
  • fast/js/script-tests/dfg-call-method-hit-watchpoint.js: Added.

(Thingy):
(Thingy.prototype.foo):
(callFoo):
(.Thingy.prototype.foo):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp

    r120244 r120499  
    751751    }
    752752   
     753    void addStructureTransitionCheck(JSCell* object, Structure* structure)
     754    {
     755        // Add a weak JS constant for the object regardless, since the code should
     756        // be jettisoned if the object ever dies.
     757        NodeIndex objectIndex = cellConstant(object);
     758       
     759        if (object->structure() == structure && structure->transitionWatchpointSetIsStillValid()) {
     760            addToGraph(StructureTransitionWatchpoint, OpInfo(structure), objectIndex);
     761            return;
     762        }
     763       
     764        addToGraph(CheckStructure, OpInfo(m_graph.addStructureSet(structure)), objectIndex);
     765    }
     766   
    753767    SpeculatedType getPredictionWithoutOSRExit(NodeIndex nodeIndex, unsigned bytecodeIndex)
    754768    {
     
    21052119
    21062120                addToGraph(CheckStructure, OpInfo(m_graph.addStructureSet(methodCallStatus.structure())), base);
    2107                 if (methodCallStatus.needsPrototypeCheck())
    2108                     addToGraph(CheckStructure, OpInfo(m_graph.addStructureSet(methodCallStatus.prototypeStructure())), cellConstant(methodCallStatus.prototype()));
    2109                
     2121                if (methodCallStatus.needsPrototypeCheck()) {
     2122                    addStructureTransitionCheck(
     2123                        methodCallStatus.prototype(), methodCallStatus.prototypeStructure());
     2124                    addToGraph(Phantom, base);
     2125                }
    21102126                set(getInstruction[1].u.operand, cellConstant(methodCallStatus.function()));
    21112127            } else {
     
    22122228                    }
    22132229                }
     2230                ASSERT(putByIdStatus.oldStructure()->transitionWatchpointSetHasBeenInvalidated());
    22142231                addToGraph(
    22152232                    PutStructure,
Note: See TracChangeset for help on using the changeset viewer.