Ignore:
Timestamp:
Nov 27, 2013, 11:10:10 PM (12 years ago)
Author:
[email protected]
Message:

Infer one-time scopes
https://bugs.webkit.org/show_bug.cgi?id=124812

Source/JavaScriptCore:

Reviewed by Oliver Hunt.

This detects JSActivations that are created only once. The JSActivation pointer is then
baked into the machine code.

This takes advantage of the one-time scope inference to reduce the number of
indirections needed to get to a closure variable in case where the scope is only
allocated once. This isn't really a speed-up since in the common case the total number
of instruction bytes needed to load the scope from the stack is about equal to the
number of instruction bytes needed to materialize the absolute address of a scoped
variable. But, this is a necessary prerequisite to
https://bugs.webkit.org/show_bug.cgi?id=124630, so it's probably a good idea anyway.

  • bytecode/CodeBlock.cpp:

(JSC::CodeBlock::dumpBytecode):
(JSC::CodeBlock::CodeBlock):
(JSC::CodeBlock::finalizeUnconditionally):

  • bytecode/Instruction.h:
  • bytecode/Opcode.h:

(JSC::padOpcodeName):

  • bytecode/Watchpoint.h:

(JSC::WatchpointSet::notifyWrite):
(JSC::InlineWatchpointSet::notifyWrite):

  • bytecompiler/BytecodeGenerator.cpp:

(JSC::BytecodeGenerator::emitResolveScope):

  • dfg/DFGAbstractInterpreterInlines.h:

(JSC::DFG::::executeEffects):

  • dfg/DFGByteCodeParser.cpp:

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

  • dfg/DFGCSEPhase.cpp:

(JSC::DFG::CSEPhase::scopedVarLoadElimination):
(JSC::DFG::CSEPhase::scopedVarStoreElimination):
(JSC::DFG::CSEPhase::getLocalLoadElimination):
(JSC::DFG::CSEPhase::setLocalStoreElimination):

  • dfg/DFGClobberize.h:

(JSC::DFG::clobberize):

  • dfg/DFGFixupPhase.cpp:

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

  • dfg/DFGGraph.cpp:

(JSC::DFG::Graph::tryGetRegisters):

  • dfg/DFGGraph.h:
  • dfg/DFGNode.h:

(JSC::DFG::Node::varNumber):
(JSC::DFG::Node::hasSymbolTable):
(JSC::DFG::Node::symbolTable):

  • 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):

  • dfg/DFGWatchpointCollectionPhase.cpp:

(JSC::DFG::WatchpointCollectionPhase::handle):

  • ftl/FTLCapabilities.cpp:

(JSC::FTL::canCompile):

  • ftl/FTLLowerDFGToLLVM.cpp:

(JSC::FTL::LowerDFGToLLVM::compileNode):
(JSC::FTL::LowerDFGToLLVM::compileGetClosureRegisters):

  • llint/LowLevelInterpreter32_64.asm:
  • llint/LowLevelInterpreter64.asm:
  • runtime/JSActivation.h:

(JSC::JSActivation::create):

  • runtime/JSScope.cpp:

(JSC::abstractAccess):
(JSC::JSScope::abstractResolve):

  • runtime/JSScope.h:

(JSC::ResolveOp::ResolveOp):

  • runtime/JSVariableObject.h:

(JSC::JSVariableObject::registers):

  • runtime/SymbolTable.cpp:

(JSC::SymbolTable::SymbolTable):

  • runtime/SymbolTable.h:

LayoutTests:

Reviewed by Oliver Hunt.

  • js/regress/infer-one-time-closure-expected.txt: Added.
  • js/regress/infer-one-time-closure-ten-vars-expected.txt: Added.
  • js/regress/infer-one-time-closure-ten-vars.html: Added.
  • js/regress/infer-one-time-closure-two-vars-expected.txt: Added.
  • js/regress/infer-one-time-closure-two-vars.html: Added.
  • js/regress/infer-one-time-closure.html: Added.
  • js/regress/infer-one-time-deep-closure-expected.txt: Added.
  • js/regress/infer-one-time-deep-closure.html: Added.
  • js/regress/script-tests/infer-one-time-closure-ten-vars.js: Added.
  • js/regress/script-tests/infer-one-time-closure-two-vars.js: Added.
  • js/regress/script-tests/infer-one-time-closure.js: Added.
  • js/regress/script-tests/infer-one-time-deep-closure.js: Added.
File:
1 edited

Legend:

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

    r159545 r159834  
    5454        if (ident == exec->propertyNames().arguments) {
    5555            // We know the property will be at this activation scope, but we don't know how to cache it.
    56             op = ResolveOp(Dynamic, 0, 0, 0, 0);
     56            op = ResolveOp(Dynamic, 0, 0, 0, 0, 0);
    5757            return true;
    5858        }
     
    6161        if (entry.isReadOnly() && getOrPut == Put) {
    6262            // We know the property will be at this activation scope, but we don't know how to cache it.
    63             op = ResolveOp(Dynamic, 0, 0, 0, 0);
     63            op = ResolveOp(Dynamic, 0, 0, 0, 0, 0);
    6464            return true;
    6565        }
    6666
    6767        if (!entry.isNull()) {
    68             op = ResolveOp(makeType(ClosureVar, needsVarInjectionChecks), depth, activation->structure(), 0, entry.getIndex());
     68            op = ResolveOp(makeType(ClosureVar, needsVarInjectionChecks), depth, 0, activation, 0, entry.getIndex());
    6969            return true;
    7070        }
     
    8080            if (getOrPut == Put && entry.isReadOnly()) {
    8181                // We know the property will be at global scope, but we don't know how to cache it.
    82                 op = ResolveOp(Dynamic, 0, 0, 0, 0);
     82                op = ResolveOp(Dynamic, 0, 0, 0, 0, 0);
    8383                return true;
    8484            }
    8585
    8686            op = ResolveOp(
    87                 makeType(GlobalVar, needsVarInjectionChecks), depth, 0, entry.watchpointSet(),
     87                makeType(GlobalVar, needsVarInjectionChecks), depth, 0, 0, entry.watchpointSet(),
    8888                reinterpret_cast<uintptr_t>(globalObject->registerAt(entry.getIndex()).slot()));
    8989            return true;
     
    9797            // We know the property will be at global scope, but we don't know how to cache it.
    9898            ASSERT(!scope->next());
    99             op = ResolveOp(makeType(GlobalProperty, needsVarInjectionChecks), depth, 0, 0, 0);
     99            op = ResolveOp(makeType(GlobalProperty, needsVarInjectionChecks), depth, 0, 0, 0, 0);
    100100            return true;
    101101        }
    102102
    103         op = ResolveOp(makeType(GlobalProperty, needsVarInjectionChecks), depth, globalObject->structure(), 0, slot.cachedOffset());
     103        op = ResolveOp(makeType(GlobalProperty, needsVarInjectionChecks), depth, globalObject->structure(), 0, 0, slot.cachedOffset());
    104104        return true;
    105105    }
    106106
    107     op = ResolveOp(Dynamic, 0, 0, 0, 0);
     107    op = ResolveOp(Dynamic, 0, 0, 0, 0, 0);
    108108    return true;
    109109}
     
    143143ResolveOp JSScope::abstractResolve(ExecState* exec, JSScope* scope, const Identifier& ident, GetOrPut getOrPut, ResolveType unlinkedType)
    144144{
    145     ResolveOp op(Dynamic, 0, 0, 0, 0);
     145    ResolveOp op(Dynamic, 0, 0, 0, 0, 0);
    146146    if (unlinkedType == Dynamic)
    147147        return op;
Note: See TracChangeset for help on using the changeset viewer.