Ignore:
Timestamp:
Aug 6, 2015, 7:08:07 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

    r187969 r188105  
    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)
     153            : byValInfo(byValInfo)
     154            , bytecodeIndex(bytecodeIndex)
     155            , notIndexJump(notIndexJump)
    154156            , badTypeJump(badTypeJump)
    155157            , arrayMode(arrayMode)
     158            , arrayProfile(arrayProfile)
    156159            , doneTarget(doneTarget)
    157160        {
    158161        }
    159        
     162
     163        ByValInfo* byValInfo;
    160164        unsigned bytecodeIndex;
     165        MacroAssembler::PatchableJump notIndexJump;
    161166        MacroAssembler::PatchableJump badTypeJump;
    162167        JITArrayMode arrayMode;
     168        ArrayProfile* arrayProfile;
    163169        MacroAssembler::Label doneTarget;
    164170        MacroAssembler::Label slowPathTarget;
     
    205211        }
    206212
     213        static void compileGetByValWithCachedId(VM* vm, CodeBlock* codeBlock, ByValInfo* byValInfo, ReturnAddressPtr returnAddress, const Identifier& propertyName)
     214        {
     215            JIT jit(vm, codeBlock);
     216            jit.m_bytecodeOffset = byValInfo->bytecodeIndex;
     217            jit.privateCompileGetByValWithCachedId(byValInfo, returnAddress, propertyName);
     218        }
     219
    207220        static void compilePutByVal(VM* vm, CodeBlock* codeBlock, ByValInfo* byValInfo, ReturnAddressPtr returnAddress, JITArrayMode arrayMode)
    208221        {
     
    247260       
    248261        void privateCompileGetByVal(ByValInfo*, ReturnAddressPtr, JITArrayMode);
     262        void privateCompileGetByValWithCachedId(ByValInfo*, ReturnAddressPtr, const Identifier&);
    249263        void privateCompilePutByVal(ByValInfo*, ReturnAddressPtr, JITArrayMode);
    250264
     
    372386        JumpList emitIntTypedArrayPutByVal(Instruction*, PatchableJump& badType, TypedArrayType);
    373387        JumpList emitFloatTypedArrayPutByVal(Instruction*, PatchableJump& badType, TypedArrayType);
    374        
     388
     389        JITGetByIdGenerator emitGetByValWithCachedId(Instruction*, const Identifier&, JumpList& doneCases, JumpList& slowCases);
     390
    375391        enum FinalObjectMode { MayBeFinal, KnownNotFinal };
    376392
     
    702718        MacroAssembler::Call callOperation(J_JITOperation_EJJ, int, GPRReg, GPRReg);
    703719        MacroAssembler::Call callOperation(J_JITOperation_EJJAp, int, GPRReg, GPRReg, ArrayProfile*);
     720        MacroAssembler::Call callOperation(J_JITOperation_EJJBy, int, GPRReg, GPRReg, ByValInfo*);
    704721        MacroAssembler::Call callOperation(C_JITOperation_EJsc, GPRReg);
    705722        MacroAssembler::Call callOperation(J_JITOperation_EJscC, int, GPRReg, JSCell*);
     
    746763        MacroAssembler::Call callOperation(V_JITOperation_EJJJ, RegisterID, RegisterID, RegisterID);
    747764        MacroAssembler::Call callOperation(V_JITOperation_EJJJAp, RegisterID, RegisterID, RegisterID, ArrayProfile*);
     765        MacroAssembler::Call callOperation(V_JITOperation_EJJJBy, RegisterID, RegisterID, RegisterID, ByValInfo*);
    748766        MacroAssembler::Call callOperation(V_JITOperation_EJZJ, RegisterID, int32_t, RegisterID);
    749767        MacroAssembler::Call callOperation(V_JITOperation_EJZ, RegisterID, int32_t);
     
    762780        MacroAssembler::Call callOperation(J_JITOperation_EJJ, int, GPRReg, GPRReg, GPRReg, GPRReg);
    763781        MacroAssembler::Call callOperation(J_JITOperation_EJJAp, int, GPRReg, GPRReg, GPRReg, GPRReg, ArrayProfile*);
     782        MacroAssembler::Call callOperation(J_JITOperation_EJJBy, int, GPRReg, GPRReg, GPRReg, GPRReg, ByValInfo*);
    764783        MacroAssembler::Call callOperation(P_JITOperation_EJS, GPRReg, GPRReg, size_t);
    765784        MacroAssembler::Call callOperation(S_JITOperation_EJ, RegisterID, RegisterID);
     
    769788        MacroAssembler::Call callOperation(V_JITOperation_EJJJ, RegisterID, RegisterID, RegisterID, RegisterID, RegisterID, RegisterID);
    770789        MacroAssembler::Call callOperation(V_JITOperation_EJJJAp, RegisterID, RegisterID, RegisterID, RegisterID, RegisterID, RegisterID, ArrayProfile*);
     790        MacroAssembler::Call callOperation(V_JITOperation_EJJJBy, RegisterID, RegisterID, RegisterID, RegisterID, RegisterID, RegisterID, ByValInfo*);
    771791        MacroAssembler::Call callOperation(V_JITOperation_EJZ, RegisterID, RegisterID, int32_t);
    772792        MacroAssembler::Call callOperation(V_JITOperation_EJZJ, RegisterID, RegisterID, int32_t, RegisterID, RegisterID);
Note: See TracChangeset for help on using the changeset viewer.