Changeset 172808 in webkit


Ignore:
Timestamp:
Aug 20, 2014 1:47:45 PM (10 years ago)
Author:
oliver@apple.com
Message:

Stop implicitly skipping a function's own activation when walking the scope chain
https://bugs.webkit.org/show_bug.cgi?id=136118

Reviewed by Geoffrey Garen.

Remove the current logic that implicitly skips a function's
own activation when walking the scope chain. This is ground
work for ensuring that all closed variable access is made
through the function's activation. This leads to a further
10% regression on earley, but we're already tracking the
overall performance regression.

  • bytecode/CodeBlock.cpp:

(JSC::CodeBlock::CodeBlock):

  • dfg/DFGAbstractInterpreterInlines.h:

(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):

  • dfg/DFGByteCodeParser.cpp:

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

  • dfg/DFGClobberize.h:

(JSC::DFG::clobberize):

  • dfg/DFGDoesGC.cpp:

(JSC::DFG::doesGC):

  • dfg/DFGFixupPhase.cpp:

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

  • dfg/DFGHeapLocation.cpp:

(WTF::printInternal):

  • dfg/DFGHeapLocation.h:
  • dfg/DFGNodeType.h:
  • dfg/DFGPredictionPropagationPhase.cpp:

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

  • dfg/DFGSafeToExecute.h:

(JSC::DFG::safeToExecute):

  • dfg/DFGSpeculativeJIT32_64.cpp:

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

  • dfg/DFGSpeculativeJIT64.cpp:

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

  • jit/JITPropertyAccess.cpp:

(JSC::JIT::emitResolveClosure):

  • llint/LowLevelInterpreter32_64.asm:
  • llint/LowLevelInterpreter64.asm:
  • runtime/JSScope.cpp:

(JSC::JSScope::abstractResolve):

  • runtime/JSScope.h:
Location:
trunk/Source/JavaScriptCore
Files:
19 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r172807 r172808  
     12014-08-20  Oliver Hunt  <oliver@apple.com>
     2
     3        Stop implicitly skipping a function's own activation when walking the scope chain
     4        https://bugs.webkit.org/show_bug.cgi?id=136118
     5
     6        Reviewed by Geoffrey Garen.
     7
     8        Remove the current logic that implicitly skips a function's
     9        own activation when walking the scope chain. This is ground
     10        work for ensuring that all closed variable access is made
     11        through the function's activation. This leads to a further
     12        10% regression on earley, but we're already tracking the
     13        overall performance regression.
     14
     15        * bytecode/CodeBlock.cpp:
     16        (JSC::CodeBlock::CodeBlock):
     17        * dfg/DFGAbstractInterpreterInlines.h:
     18        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
     19        * dfg/DFGByteCodeParser.cpp:
     20        (JSC::DFG::ByteCodeParser::getScope):
     21        (JSC::DFG::ByteCodeParser::parseBlock):
     22        * dfg/DFGClobberize.h:
     23        (JSC::DFG::clobberize):
     24        * dfg/DFGDoesGC.cpp:
     25        (JSC::DFG::doesGC):
     26        * dfg/DFGFixupPhase.cpp:
     27        (JSC::DFG::FixupPhase::fixupNode):
     28        * dfg/DFGHeapLocation.cpp:
     29        (WTF::printInternal):
     30        * dfg/DFGHeapLocation.h:
     31        * dfg/DFGNodeType.h:
     32        * dfg/DFGPredictionPropagationPhase.cpp:
     33        (JSC::DFG::PredictionPropagationPhase::propagate):
     34        * dfg/DFGSafeToExecute.h:
     35        (JSC::DFG::safeToExecute):
     36        * dfg/DFGSpeculativeJIT32_64.cpp:
     37        (JSC::DFG::SpeculativeJIT::compile):
     38        * dfg/DFGSpeculativeJIT64.cpp:
     39        (JSC::DFG::SpeculativeJIT::compile):
     40        * jit/JITPropertyAccess.cpp:
     41        (JSC::JIT::emitResolveClosure):
     42        * llint/LowLevelInterpreter32_64.asm:
     43        * llint/LowLevelInterpreter64.asm:
     44        * runtime/JSScope.cpp:
     45        (JSC::JSScope::abstractResolve):
     46        * runtime/JSScope.h:
     47
    1482014-08-20  Michael Saboff  <msaboff@apple.com>
    249
  • trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp

    r172665 r172808  
    19451945            ResolveType type = static_cast<ResolveType>(pc[3].u.operand);
    19461946
    1947             ResolveOp op = JSScope::abstractResolve(m_globalObject->globalExec(), scope, ident, Get, type);
     1947            ResolveOp op = JSScope::abstractResolve(m_globalObject->globalExec(), needsActivation(), scope, ident, Get, type);
    19481948            instructions[i + 3].u.operand = op.type;
    19491949            instructions[i + 4].u.operand = op.depth;
     
    19621962            const Identifier& ident = identifier(pc[3].u.operand);
    19631963            ResolveModeAndType modeAndType = ResolveModeAndType(pc[4].u.operand);
    1964             ResolveOp op = JSScope::abstractResolve(m_globalObject->globalExec(), scope, ident, Get, modeAndType.type());
     1964            ResolveOp op = JSScope::abstractResolve(m_globalObject->globalExec(), needsActivation(), scope, ident, Get, modeAndType.type());
    19651965
    19661966            instructions[i + 4].u.operand = ResolveModeAndType(modeAndType.mode(), op.type).operand();
     
    19781978            const Identifier& ident = identifier(pc[2].u.operand);
    19791979            ResolveModeAndType modeAndType = ResolveModeAndType(pc[4].u.operand);
    1980             ResolveOp op = JSScope::abstractResolve(m_globalObject->globalExec(), scope, ident, Put, modeAndType.type());
     1980            ResolveOp op = JSScope::abstractResolve(m_globalObject->globalExec(), needsActivation(), scope, ident, Put, modeAndType.type());
    19811981
    19821982            instructions[i + 4].u.operand = ResolveModeAndType(modeAndType.mode(), op.type).operand();
     
    20092009                const Identifier& ident = identifier(pc[4].u.operand);
    20102010                ResolveType type = static_cast<ResolveType>(pc[5].u.operand);
    2011                 ResolveOp op = JSScope::abstractResolve(m_globalObject->globalExec(), scope, ident, (flag == ProfileTypesBytecodeGetFromScope ? Get : Put), type);
     2011                ResolveOp op = JSScope::abstractResolve(m_globalObject->globalExec(), needsActivation(), scope, ident, (flag == ProfileTypesBytecodeGetFromScope ? Get : Put), type);
    20122012
    20132013                // FIXME: handle other values for op.type here, and also consider what to do when we can't statically determine the globalID
  • trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h

    r172737 r172808  
    13871387    case GetScope: // FIXME: We could get rid of these if we know that the JSFunction is a constant. https://bugs.webkit.org/show_bug.cgi?id=106202
    13881388    case GetMyScope:
    1389     case SkipTopScope:
    13901389        forNode(node).setType(SpecObjectOther);
    13911390        break;
  • trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp

    r172176 r172808  
    199199    void emitChecks(const ConstantStructureCheckVector&);
    200200
    201     Node* getScope(bool skipTop, unsigned skipCount);
     201    Node* getScope(unsigned skipCount);
    202202   
    203203    // Prepare to parse a block.
     
    20242024}
    20252025
    2026 Node* ByteCodeParser::getScope(bool skipTop, unsigned skipCount)
     2026Node* ByteCodeParser::getScope(unsigned skipCount)
    20272027{
    20282028    Node* localBase = get(VirtualRegister(JSStack::ScopeChain));
    2029     if (skipTop) {
    2030         ASSERT(!inlineCallFrame());
    2031         localBase = addToGraph(SkipTopScope, localBase);
    2032     }
    20332029    for (unsigned n = skipCount; n--;)
    20342030        localBase = addToGraph(SkipScope, localBase);
     
    29302926                    break;
    29312927                }
    2932                 set(VirtualRegister(dst),
    2933                     getScope(m_inlineStackTop->m_codeBlock->needsActivation(), depth));
     2928                set(VirtualRegister(dst), getScope(depth));
    29342929                break;
    29352930            }
  • trunk/Source/JavaScriptCore/dfg/DFGClobberize.h

    r172176 r172808  
    749749        return;
    750750       
    751     case SkipTopScope:
    752         read(AbstractHeap(Variables, graph.activationRegister()));
    753         def(HeapLocation(SkipTopScopeLoc, AbstractHeap(Variables, graph.activationRegister()), node->child1()), node);
    754         return;
    755        
    756751    case GetClosureRegisters:
    757752        read(JSVariableObject_registers);
  • trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp

    r172176 r172808  
    9797    case GetScope:
    9898    case GetMyScope:
    99     case SkipTopScope:
    10099    case SkipScope:
    101100    case GetClosureRegisters:
  • trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp

    r172737 r172808  
    854854
    855855        case GetClosureRegisters:
    856         case SkipTopScope:
    857856        case SkipScope:
    858857        case GetScope:
  • trunk/Source/JavaScriptCore/dfg/DFGHeapLocation.cpp

    r172176 r172808  
    137137        return;
    138138       
    139     case SkipTopScopeLoc:
    140         out.print("SkipTopScopeLoc");
    141         return;
    142        
    143139    case TypedArrayByteOffsetLoc:
    144140        out.print("TypedArrayByteOffsetLoc");
  • trunk/Source/JavaScriptCore/dfg/DFGHeapLocation.h

    r172176 r172808  
    5656    NamedPropertyLoc,
    5757    SetterLoc,
    58     SkipTopScopeLoc,
    5958    TypeOfLoc,
    6059    TypedArrayByteOffsetLoc,
  • trunk/Source/JavaScriptCore/dfg/DFGNodeType.h

    r172176 r172808  
    176176    macro(GetScope, NodeResultJS) \
    177177    macro(GetMyScope, NodeResultJS) \
    178     macro(SkipTopScope, NodeResultJS) \
    179178    macro(SkipScope, NodeResultJS) \
    180179    macro(GetClosureRegisters, NodeResultStorage) \
  • trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp

    r172176 r172808  
    461461           
    462462        case GetMyScope:
    463         case SkipTopScope:
    464463        case SkipScope: {
    465464            changed |= setPrediction(SpecObjectOther);
  • trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h

    r172176 r172808  
    167167    case GetScope:
    168168    case GetMyScope:
    169     case SkipTopScope:
    170169    case SkipScope:
    171170    case GetClosureRegisters:
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp

    r172598 r172808  
    35133513    }
    35143514       
    3515     case SkipTopScope: {
    3516         SpeculateCellOperand scope(this, node->child1());
    3517         GPRTemporary result(this, Reuse, scope);
    3518         GPRReg resultGPR = result.gpr();
    3519         m_jit.move(scope.gpr(), resultGPR);
    3520         m_jit.loadPtr(JITCompiler::Address(resultGPR, JSScope::offsetOfNext()), resultGPR);
    3521         cellResult(resultGPR, node);
    3522         break;
    3523     }
    3524        
    35253515    case SkipScope: {
    35263516        SpeculateCellOperand scope(this, node->child1());
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp

    r172598 r172808  
    36233623    }
    36243624       
    3625     case SkipTopScope: {
    3626         SpeculateCellOperand scope(this, node->child1());
    3627         GPRTemporary result(this, Reuse, scope);
    3628         GPRReg resultGPR = result.gpr();
    3629         m_jit.move(scope.gpr(), resultGPR);
    3630         m_jit.loadPtr(JITCompiler::Address(resultGPR, JSScope::offsetOfNext()), resultGPR);
    3631         cellResult(resultGPR, node);
    3632         break;
    3633     }
    3634        
    36353625    case SkipScope: {
    36363626        SpeculateCellOperand scope(this, node->child1());
  • trunk/Source/JavaScriptCore/jit/JITPropertyAccess.cpp

    r172598 r172808  
    595595    emitVarInjectionCheck(needsVarInjectionChecks);
    596596    emitGetVirtualRegister(JSStack::ScopeChain, regT0);
    597     if (m_codeBlock->needsActivation()) {
    598         emitGetVirtualRegister(m_codeBlock->activationRegister(), regT1);
    599         loadPtr(Address(regT0, JSScope::offsetOfNext()), regT0);
    600     }
    601597    for (unsigned i = 0; i < depth; ++i)
    602598        loadPtr(Address(regT0, JSScope::offsetOfNext()), regT0);
  • trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm

    r172746 r172808  
    22022202    loadp CodeBlock[cfr], t0
    22032203    loadisFromInstruction(4, t2)
    2204     btbz CodeBlock::m_needsActivation[t0], .resolveScopeAfterActivationCheck
    2205     loadis CodeBlock::m_activationRegister[t0], t1
    2206     addi 1, t2
    2207 
    2208 .resolveScopeAfterActivationCheck:
     2204
    22092205    loadp ScopeChain[cfr], t0
    22102206    btiz t2, .resolveScopeLoopEnd
  • trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm

    r172665 r172808  
    20352035    loadp CodeBlock[cfr], t0
    20362036    loadisFromInstruction(4, t2)
    2037     btbz CodeBlock::m_needsActivation[t0], .resolveScopeAfterActivationCheck
    2038     loadis CodeBlock::m_activationRegister[t0], t1
    2039     addi 1, t2
    2040 
    2041 .resolveScopeAfterActivationCheck:
    20422037    loadp ScopeChain[cfr], t0
    20432038    btiz t2, .resolveScopeLoopEnd
  • trunk/Source/JavaScriptCore/runtime/JSScope.cpp

    r172129 r172808  
    149149}
    150150
    151 ResolveOp JSScope::abstractResolve(ExecState* exec, JSScope* scope, const Identifier& ident, GetOrPut getOrPut, ResolveType unlinkedType)
     151ResolveOp JSScope::abstractResolve(ExecState* exec, bool hasTopActivation, JSScope* scope, const Identifier& ident, GetOrPut getOrPut, ResolveType unlinkedType)
    152152{
    153153    ResolveOp op(Dynamic, 0, 0, 0, 0, 0);
     
    155155        return op;
    156156
    157     size_t depth = 0;
     157    size_t depth = hasTopActivation ? 1 : 0;
    158158    bool needsVarInjectionChecks = JSC::needsVarInjectionChecks(unlinkedType);
    159159    for (; scope; scope = scope->next()) {
  • trunk/Source/JavaScriptCore/runtime/JSScope.h

    r172372 r172808  
    154154
    155155    static JSValue resolve(ExecState*, JSScope*, const Identifier&);
    156     static ResolveOp abstractResolve(ExecState*, JSScope*, const Identifier&, GetOrPut, ResolveType);
     156    static ResolveOp abstractResolve(ExecState*, bool hasTopActivation, JSScope*, const Identifier&, GetOrPut, ResolveType);
    157157
    158158    static void visitChildren(JSCell*, SlotVisitor&);
Note: See TracChangeset for help on using the changeset viewer.