Ignore:
Timestamp:
Aug 11, 2015, 3:02:09 PM (10 years ago)
Author:
Yusuke Suzuki
Message:

Introduce get_by_id like IC into get_by_val when the given name is String or Symbol
https://bugs.webkit.org/show_bug.cgi?id=147480

Reviewed by Filip Pizlo.

Source/JavaScriptCore:

This patch adds get_by_id IC to get_by_val operation by caching the string / symbol id.
The IC site only caches one id. After checking that the given id is the same to the
cached one, we perform the get_by_id IC onto it.
And by collecting IC StructureStubInfo information, we pass it to the DFG and DFG
compiles get_by_val op code into CheckIdent (with edge type check) and GetById related
operations when the given get_by_val leverages the property load with the cached id.

To ensure the incoming value is the expected id, in DFG layer, we use SymbolUse and
StringIdentUse to enforce the type. To use it, this patch implements SymbolUse.
This can be leveraged to optimize symbol operations in DFG.

And since byValInfo is frequently used, we align the byValInfo design to the stubInfo like one.
Allocated by the Bag and operations take the raw byValInfo pointer directly instead of performing
binary search onto m_byValInfos. And by storing ArrayProfile* under the ByValInfo, we replaced the
argument ArrayProfile* in the operations with ByValInfo*.

  • bytecode/ByValInfo.h:

(JSC::ByValInfo::ByValInfo):

  • bytecode/CodeBlock.cpp:

(JSC::CodeBlock::getByValInfoMap):
(JSC::CodeBlock::addByValInfo):

  • bytecode/CodeBlock.h:

(JSC::CodeBlock::getByValInfo): Deleted.
(JSC::CodeBlock::setNumberOfByValInfos): Deleted.
(JSC::CodeBlock::numberOfByValInfos): Deleted.
(JSC::CodeBlock::byValInfo): Deleted.

  • bytecode/ExitKind.cpp:

(JSC::exitKindToString):

  • bytecode/ExitKind.h:
  • bytecode/GetByIdStatus.cpp:

(JSC::GetByIdStatus::computeFor):
(JSC::GetByIdStatus::computeForStubInfo):
(JSC::GetByIdStatus::computeForStubInfoWithoutExitSiteFeedback):

  • bytecode/GetByIdStatus.h:
  • dfg/DFGAbstractInterpreterInlines.h:

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

  • dfg/DFGByteCodeParser.cpp:

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

  • dfg/DFGClobberize.h:

(JSC::DFG::clobberize):

  • dfg/DFGConstantFoldingPhase.cpp:

(JSC::DFG::ConstantFoldingPhase::foldConstants):

  • dfg/DFGDoesGC.cpp:

(JSC::DFG::doesGC):

  • dfg/DFGFixupPhase.cpp:

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

  • dfg/DFGNode.h:

(JSC::DFG::Node::hasUidOperand):
(JSC::DFG::Node::uidOperand):

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

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

  • dfg/DFGSafeToExecute.h:

(JSC::DFG::SafeToExecuteEdge::operator()):
(JSC::DFG::safeToExecute):

  • dfg/DFGSpeculativeJIT.cpp:

(JSC::DFG::SpeculativeJIT::compileCheckIdent):
(JSC::DFG::SpeculativeJIT::speculateSymbol):
(JSC::DFG::SpeculativeJIT::speculate):

  • dfg/DFGSpeculativeJIT.h:
  • dfg/DFGSpeculativeJIT32_64.cpp:

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

  • dfg/DFGSpeculativeJIT64.cpp:

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

  • dfg/DFGUseKind.cpp:

(WTF::printInternal):

  • dfg/DFGUseKind.h:

(JSC::DFG::typeFilterFor):
(JSC::DFG::isCell):

  • ftl/FTLAbstractHeapRepository.h:
  • ftl/FTLCapabilities.cpp:

(JSC::FTL::canCompile):

  • ftl/FTLLowerDFGToLLVM.cpp:

(JSC::FTL::DFG::LowerDFGToLLVM::compileNode):
(JSC::FTL::DFG::LowerDFGToLLVM::compileCheckIdent):
(JSC::FTL::DFG::LowerDFGToLLVM::lowSymbol):
(JSC::FTL::DFG::LowerDFGToLLVM::speculate):
(JSC::FTL::DFG::LowerDFGToLLVM::isNotSymbol):
(JSC::FTL::DFG::LowerDFGToLLVM::speculateSymbol):

  • jit/JIT.cpp:

(JSC::JIT::privateCompile):

  • jit/JIT.h:

(JSC::ByValCompilationInfo::ByValCompilationInfo):
(JSC::JIT::compileGetByValWithCachedId):

  • jit/JITInlines.h:

(JSC::JIT::callOperation):

  • jit/JITOpcodes.cpp:

(JSC::JIT::emit_op_has_indexed_property):
(JSC::JIT::emitSlow_op_has_indexed_property):

  • jit/JITOpcodes32_64.cpp:

(JSC::JIT::emit_op_has_indexed_property):
(JSC::JIT::emitSlow_op_has_indexed_property):

  • jit/JITOperations.cpp:

(JSC::getByVal):

  • jit/JITOperations.h:
  • jit/JITPropertyAccess.cpp:

(JSC::JIT::emit_op_get_by_val):
(JSC::JIT::emitGetByValWithCachedId):
(JSC::JIT::emitSlow_op_get_by_val):
(JSC::JIT::emit_op_put_by_val):
(JSC::JIT::emitSlow_op_put_by_val):
(JSC::JIT::privateCompileGetByVal):
(JSC::JIT::privateCompileGetByValWithCachedId):

  • jit/JITPropertyAccess32_64.cpp:

(JSC::JIT::emit_op_get_by_val):
(JSC::JIT::emitGetByValWithCachedId):
(JSC::JIT::emitSlow_op_get_by_val):
(JSC::JIT::emit_op_put_by_val):
(JSC::JIT::emitSlow_op_put_by_val):

  • runtime/Symbol.h:
  • tests/stress/get-by-val-with-string-constructor.js: Added.

(Hello):
(get Hello.prototype.generate):
(ok):

  • tests/stress/get-by-val-with-string-exit.js: Added.

(shouldBe):
(getByVal):
(getStr1):
(getStr2):

  • tests/stress/get-by-val-with-string-generated.js: Added.

(shouldBe):
(getByVal):
(getStr1):
(getStr2):

  • tests/stress/get-by-val-with-string-getter.js: Added.

(object.get hello):
(ok):

  • tests/stress/get-by-val-with-string.js: Added.

(shouldBe):
(getByVal):
(getStr1):
(getStr2):

  • tests/stress/get-by-val-with-symbol-constructor.js: Added.

(Hello):
(get Hello.prototype.generate):
(ok):

  • tests/stress/get-by-val-with-symbol-exit.js: Added.

(shouldBe):
(getByVal):
(getSym1):
(getSym2):

  • tests/stress/get-by-val-with-symbol-getter.js: Added.

(object.get hello):
(.get ok):

  • tests/stress/get-by-val-with-symbol.js: Added.

(shouldBe):
(getByVal):
(getSym1):
(getSym2):

LayoutTests:

Add synthetic benchmarks that replaces normal property load with symbol/string keyed load.

  • js/regress/get-by-val-with-string-bimorphic-check-structure-elimination-expected.txt: Added.
  • js/regress/get-by-val-with-string-bimorphic-check-structure-elimination-simple-expected.txt: Added.
  • js/regress/get-by-val-with-string-bimorphic-check-structure-elimination-simple.html: Added.
  • js/regress/get-by-val-with-string-bimorphic-check-structure-elimination.html: Added.
  • js/regress/get-by-val-with-string-chain-from-try-block-expected.txt: Added.
  • js/regress/get-by-val-with-string-chain-from-try-block.html: Added.
  • js/regress/get-by-val-with-string-check-structure-elimination-expected.txt: Added.
  • js/regress/get-by-val-with-string-check-structure-elimination.html: Added.
  • js/regress/get-by-val-with-string-proto-or-self-expected.txt: Added.
  • js/regress/get-by-val-with-string-proto-or-self.html: Added.
  • js/regress/get-by-val-with-string-quadmorphic-check-structure-elimination-simple-expected.txt: Added.
  • js/regress/get-by-val-with-string-quadmorphic-check-structure-elimination-simple.html: Added.
  • js/regress/get-by-val-with-string-self-or-proto-expected.txt: Added.
  • js/regress/get-by-val-with-string-self-or-proto.html: Added.
  • js/regress/get-by-val-with-symbol-bimorphic-check-structure-elimination-expected.txt: Added.
  • js/regress/get-by-val-with-symbol-bimorphic-check-structure-elimination-simple-expected.txt: Added.
  • js/regress/get-by-val-with-symbol-bimorphic-check-structure-elimination-simple.html: Added.
  • js/regress/get-by-val-with-symbol-bimorphic-check-structure-elimination.html: Added.
  • js/regress/get-by-val-with-symbol-chain-from-try-block-expected.txt: Added.
  • js/regress/get-by-val-with-symbol-chain-from-try-block.html: Added.
  • js/regress/get-by-val-with-symbol-check-structure-elimination-expected.txt: Added.
  • js/regress/get-by-val-with-symbol-check-structure-elimination.html: Added.
  • js/regress/get-by-val-with-symbol-proto-or-self-expected.txt: Added.
  • js/regress/get-by-val-with-symbol-proto-or-self.html: Added.
  • js/regress/get-by-val-with-symbol-quadmorphic-check-structure-elimination-simple-expected.txt: Added.
  • js/regress/get-by-val-with-symbol-quadmorphic-check-structure-elimination-simple.html: Added.
  • js/regress/get-by-val-with-symbol-self-or-proto-expected.txt: Added.
  • js/regress/get-by-val-with-symbol-self-or-proto.html: Added.
  • js/regress/script-tests/get-by-val-with-string-bimorphic-check-structure-elimination-simple.js: Added.
  • js/regress/script-tests/get-by-val-with-string-bimorphic-check-structure-elimination.js: Added.
  • js/regress/script-tests/get-by-val-with-string-chain-from-try-block.js: Added.

(A):
(B):
(C):
(D):
(E):
(F):
(G):
(foo):

  • js/regress/script-tests/get-by-val-with-string-check-structure-elimination.js: Added.
  • js/regress/script-tests/get-by-val-with-string-proto-or-self.js: Added.

(foo):
(bar):
(Foo):

  • js/regress/script-tests/get-by-val-with-string-quadmorphic-check-structure-elimination-simple.js: Added.
  • js/regress/script-tests/get-by-val-with-string-self-or-proto.js: Added.

(foo):
(bar):
(Foo):

  • js/regress/script-tests/get-by-val-with-symbol-bimorphic-check-structure-elimination-simple.js: Added.
  • js/regress/script-tests/get-by-val-with-symbol-bimorphic-check-structure-elimination.js: Added.
  • js/regress/script-tests/get-by-val-with-symbol-chain-from-try-block.js: Added.

(A):
(B):
(C):
(D):
(E):
(F):
(G):
(foo):

  • js/regress/script-tests/get-by-val-with-symbol-check-structure-elimination.js: Added.
  • js/regress/script-tests/get-by-val-with-symbol-proto-or-self.js: Added.

(foo):
(bar):
(Foo):

  • js/regress/script-tests/get-by-val-with-symbol-quadmorphic-check-structure-elimination-simple.js: Added.
  • js/regress/script-tests/get-by-val-with-symbol-self-or-proto.js: Added.

(foo):
(bar):
(Foo):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/jit/JIT.h

    r188201 r188299  
    150150        ByValCompilationInfo() { }
    151151       
    152         ByValCompilationInfo(unsigned bytecodeIndex, MacroAssembler::PatchableJump badTypeJump, JITArrayMode arrayMode, MacroAssembler::Label doneTarget)
    153             : bytecodeIndex(bytecodeIndex)
     152        ByValCompilationInfo(ByValInfo* byValInfo, unsigned bytecodeIndex, MacroAssembler::PatchableJump notIndexJump, MacroAssembler::PatchableJump badTypeJump, JITArrayMode arrayMode, ArrayProfile* arrayProfile, MacroAssembler::Label doneTarget, MacroAssembler::Label nextHotPathTarget)
     153            : byValInfo(byValInfo)
     154            , bytecodeIndex(bytecodeIndex)
     155            , notIndexJump(notIndexJump)
    154156            , badTypeJump(badTypeJump)
    155157            , arrayMode(arrayMode)
     158            , arrayProfile(arrayProfile)
    156159            , doneTarget(doneTarget)
    157         {
    158         }
    159        
     160            , nextHotPathTarget(nextHotPathTarget)
     161        {
     162        }
     163
     164        ByValInfo* byValInfo;
    160165        unsigned bytecodeIndex;
     166        MacroAssembler::PatchableJump notIndexJump;
    161167        MacroAssembler::PatchableJump badTypeJump;
    162168        JITArrayMode arrayMode;
     169        ArrayProfile* arrayProfile;
    163170        MacroAssembler::Label doneTarget;
     171        MacroAssembler::Label nextHotPathTarget;
    164172        MacroAssembler::Label slowPathTarget;
    165173        MacroAssembler::Call returnAddress;
     
    205213        }
    206214
     215        static void compileGetByValWithCachedId(VM* vm, CodeBlock* codeBlock, ByValInfo* byValInfo, ReturnAddressPtr returnAddress, const Identifier& propertyName)
     216        {
     217            JIT jit(vm, codeBlock);
     218            jit.m_bytecodeOffset = byValInfo->bytecodeIndex;
     219            jit.privateCompileGetByValWithCachedId(byValInfo, returnAddress, propertyName);
     220        }
     221
    207222        static void compilePutByVal(VM* vm, CodeBlock* codeBlock, ByValInfo* byValInfo, ReturnAddressPtr returnAddress, JITArrayMode arrayMode)
    208223        {
     
    247262       
    248263        void privateCompileGetByVal(ByValInfo*, ReturnAddressPtr, JITArrayMode);
     264        void privateCompileGetByValWithCachedId(ByValInfo*, ReturnAddressPtr, const Identifier&);
    249265        void privateCompilePutByVal(ByValInfo*, ReturnAddressPtr, JITArrayMode);
    250266
     
    372388        JumpList emitIntTypedArrayPutByVal(Instruction*, PatchableJump& badType, TypedArrayType);
    373389        JumpList emitFloatTypedArrayPutByVal(Instruction*, PatchableJump& badType, TypedArrayType);
    374        
     390
     391        JITGetByIdGenerator emitGetByValWithCachedId(Instruction*, const Identifier&, Jump& fastDoneCase, Jump& slowDoneCase, JumpList& slowCases);
     392
    375393        enum FinalObjectMode { MayBeFinal, KnownNotFinal };
    376394
     
    703721        MacroAssembler::Call callOperation(J_JITOperation_EJJ, int, GPRReg, GPRReg);
    704722        MacroAssembler::Call callOperation(J_JITOperation_EJJAp, int, GPRReg, GPRReg, ArrayProfile*);
     723        MacroAssembler::Call callOperation(J_JITOperation_EJJBy, int, GPRReg, GPRReg, ByValInfo*);
    705724        MacroAssembler::Call callOperation(C_JITOperation_EJsc, GPRReg);
    706725        MacroAssembler::Call callOperation(J_JITOperation_EJscC, int, GPRReg, JSCell*);
     
    747766        MacroAssembler::Call callOperation(V_JITOperation_EJJJ, RegisterID, RegisterID, RegisterID);
    748767        MacroAssembler::Call callOperation(V_JITOperation_EJJJAp, RegisterID, RegisterID, RegisterID, ArrayProfile*);
     768        MacroAssembler::Call callOperation(V_JITOperation_EJJJBy, RegisterID, RegisterID, RegisterID, ByValInfo*);
    749769        MacroAssembler::Call callOperation(V_JITOperation_EJZJ, RegisterID, int32_t, RegisterID);
    750770        MacroAssembler::Call callOperation(V_JITOperation_EJZ, RegisterID, int32_t);
     
    763783        MacroAssembler::Call callOperation(J_JITOperation_EJJ, int, GPRReg, GPRReg, GPRReg, GPRReg);
    764784        MacroAssembler::Call callOperation(J_JITOperation_EJJAp, int, GPRReg, GPRReg, GPRReg, GPRReg, ArrayProfile*);
     785        MacroAssembler::Call callOperation(J_JITOperation_EJJBy, int, GPRReg, GPRReg, GPRReg, GPRReg, ByValInfo*);
    765786        MacroAssembler::Call callOperation(P_JITOperation_EJS, GPRReg, GPRReg, size_t);
    766787        MacroAssembler::Call callOperation(S_JITOperation_EJ, RegisterID, RegisterID);
     
    770791        MacroAssembler::Call callOperation(V_JITOperation_EJJJ, RegisterID, RegisterID, RegisterID, RegisterID, RegisterID, RegisterID);
    771792        MacroAssembler::Call callOperation(V_JITOperation_EJJJAp, RegisterID, RegisterID, RegisterID, RegisterID, RegisterID, RegisterID, ArrayProfile*);
     793        MacroAssembler::Call callOperation(V_JITOperation_EJJJBy, RegisterID, RegisterID, RegisterID, RegisterID, RegisterID, RegisterID, ByValInfo*);
    772794        MacroAssembler::Call callOperation(V_JITOperation_EJZ, RegisterID, RegisterID, int32_t);
    773795        MacroAssembler::Call callOperation(V_JITOperation_EJZJ, RegisterID, RegisterID, int32_t, RegisterID, RegisterID);
Note: See TracChangeset for help on using the changeset viewer.