Changeset 232047 in webkit


Ignore:
Timestamp:
May 21, 2018 9:54:31 PM (6 years ago)
Author:
Yusuke Suzuki
Message:

Unreviewed, reland InById cache
https://bugs.webkit.org/show_bug.cgi?id=185682

JSTests:

  • stress/in-by-id-accessors.js: Added.

(shouldBe):
(test):
(protoGetter.proto.get hello):
(protoSetter.proto.set hello):
(i.shouldBe.test.get hello):
(i.shouldBe.test.set hello):

  • stress/in-by-id-ai.js: Added.

(shouldBe):
(test):

  • stress/in-by-id-custom-accessors.js: Added.

(shouldBe):
(test1):
(test2):

  • stress/in-by-id-custom-values.js: Added.

(shouldBe):
(test):

  • stress/in-by-id-operation.js: Added.

(shouldBe):
(test):
(selfCache):

  • stress/in-by-id-proxy.js: Added.

(shouldBe):
(test):
(handler.has):

Source/JavaScriptCore:

Includes Dominik's 32bit fix.

  • bytecode/AccessCase.cpp:

(JSC::AccessCase::fromStructureStubInfo):
(JSC::AccessCase::generateWithGuard):
(JSC::AccessCase::generateImpl):

  • bytecode/BytecodeDumper.cpp:

(JSC::BytecodeDumper<Block>::printInByIdCacheStatus):
(JSC::BytecodeDumper<Block>::dumpBytecode):

  • bytecode/BytecodeDumper.h:
  • bytecode/BytecodeList.json:
  • bytecode/BytecodeUseDef.h:

(JSC::computeUsesForBytecodeOffset):
(JSC::computeDefsForBytecodeOffset):

  • bytecode/CodeBlock.cpp:

(JSC::CodeBlock::finishCreation):

  • bytecode/InlineAccess.cpp:

(JSC::InlineAccess::generateSelfInAccess):

  • bytecode/InlineAccess.h:
  • bytecode/StructureStubInfo.cpp:

(JSC::StructureStubInfo::initInByIdSelf):
(JSC::StructureStubInfo::deref):
(JSC::StructureStubInfo::aboutToDie):
(JSC::StructureStubInfo::reset):
(JSC::StructureStubInfo::visitWeakReferences):
(JSC::StructureStubInfo::propagateTransitions):

  • bytecode/StructureStubInfo.h:

(JSC::StructureStubInfo::patchableJump):

  • bytecompiler/BytecodeGenerator.cpp:

(JSC::BytecodeGenerator::emitInByVal):
(JSC::BytecodeGenerator::emitInById):
(JSC::BytecodeGenerator::emitIn): Deleted.

  • bytecompiler/BytecodeGenerator.h:
  • bytecompiler/NodesCodegen.cpp:

(JSC::InNode::emitBytecode):

  • dfg/DFGAbstractInterpreterInlines.h:

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

  • dfg/DFGByteCodeParser.cpp:

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

  • dfg/DFGCapabilities.cpp:

(JSC::DFG::capabilityLevel):

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

  • dfg/DFGJITCompiler.cpp:

(JSC::DFG::JITCompiler::link):

  • dfg/DFGJITCompiler.h:

(JSC::DFG::JITCompiler::addInById):
(JSC::DFG::InRecord::InRecord): Deleted.
(JSC::DFG::JITCompiler::addIn): Deleted.

  • dfg/DFGNode.h:

(JSC::DFG::Node::convertToInById):
(JSC::DFG::Node::hasIdentifier):
(JSC::DFG::Node::hasArrayMode):

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

(JSC::DFG::safeToExecute):

  • dfg/DFGSpeculativeJIT.cpp:

(JSC::DFG::SpeculativeJIT::compileInById):
(JSC::DFG::SpeculativeJIT::compileInByVal):
(JSC::DFG::SpeculativeJIT::compileIn): Deleted.

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

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

  • dfg/DFGSpeculativeJIT64.cpp:

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

  • ftl/FTLCapabilities.cpp:

(JSC::FTL::canCompile):

  • ftl/FTLLowerDFGToB3.cpp:

(JSC::FTL::DFG::LowerDFGToB3::compileNode):
(JSC::FTL::DFG::LowerDFGToB3::compileInByVal):
(JSC::FTL::DFG::LowerDFGToB3::compileInById):
(JSC::FTL::DFG::LowerDFGToB3::compileIn): Deleted.

  • jit/AssemblyHelpers.h:

(JSC::AssemblyHelpers::boxBoolean):

  • jit/ICStats.h:
  • jit/JIT.cpp:

(JSC::JIT::JIT):
(JSC::JIT::privateCompileMainPass):
(JSC::JIT::privateCompileSlowCases):
(JSC::JIT::link):

  • jit/JIT.h:
  • jit/JITInlineCacheGenerator.cpp:

(JSC::JITInByIdGenerator::JITInByIdGenerator):
(JSC::JITInByIdGenerator::generateFastPath):

  • jit/JITInlineCacheGenerator.h:

(JSC::JITInByIdGenerator::JITInByIdGenerator):

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

(JSC::JIT::emit_op_in_by_id):
(JSC::JIT::emitSlow_op_in_by_id):

  • jit/JITPropertyAccess32_64.cpp:

(JSC::JIT::emit_op_in_by_id):
(JSC::JIT::emitSlow_op_in_by_id):

  • jit/Repatch.cpp:

(JSC::tryCacheInByID):
(JSC::repatchInByID):
(JSC::resetInByID):
(JSC::tryCacheIn): Deleted.
(JSC::repatchIn): Deleted.
(JSC::resetIn): Deleted.

  • jit/Repatch.h:
  • llint/LowLevelInterpreter.asm:
  • llint/LowLevelInterpreter64.asm:
  • parser/NodeConstructors.h:

(JSC::InNode::InNode):

  • runtime/CommonSlowPaths.cpp:

(JSC::SLOW_PATH_DECL):

  • runtime/CommonSlowPaths.h:

(JSC::CommonSlowPaths::opInByVal):
(JSC::CommonSlowPaths::opIn): Deleted.

Location:
trunk
Files:
6 added
51 edited

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r232029 r232047  
     12018-05-21  Yusuke Suzuki  <utatane.tea@gmail.com>
     2
     3        Unreviewed, reland InById cache
     4        https://bugs.webkit.org/show_bug.cgi?id=185682
     5
     6        * stress/in-by-id-accessors.js: Added.
     7        (shouldBe):
     8        (test):
     9        (protoGetter.__proto__.get hello):
     10        (protoSetter.__proto__.set hello):
     11        (i.shouldBe.test.get hello):
     12        (i.shouldBe.test.set hello):
     13        * stress/in-by-id-ai.js: Added.
     14        (shouldBe):
     15        (test):
     16        * stress/in-by-id-custom-accessors.js: Added.
     17        (shouldBe):
     18        (test1):
     19        (test2):
     20        * stress/in-by-id-custom-values.js: Added.
     21        (shouldBe):
     22        (test):
     23        * stress/in-by-id-operation.js: Added.
     24        (shouldBe):
     25        (test):
     26        (selfCache):
     27        * stress/in-by-id-proxy.js: Added.
     28        (shouldBe):
     29        (test):
     30        (handler.has):
     31
    1322018-05-21  Commit Queue  <commit-queue@webkit.org>
    233
  • trunk/Source/JavaScriptCore/ChangeLog

    r232029 r232047  
     12018-05-21  Yusuke Suzuki  <utatane.tea@gmail.com>
     2
     3        Unreviewed, reland InById cache
     4        https://bugs.webkit.org/show_bug.cgi?id=185682
     5
     6        Includes Dominik's 32bit fix.
     7
     8        * bytecode/AccessCase.cpp:
     9        (JSC::AccessCase::fromStructureStubInfo):
     10        (JSC::AccessCase::generateWithGuard):
     11        (JSC::AccessCase::generateImpl):
     12        * bytecode/BytecodeDumper.cpp:
     13        (JSC::BytecodeDumper<Block>::printInByIdCacheStatus):
     14        (JSC::BytecodeDumper<Block>::dumpBytecode):
     15        * bytecode/BytecodeDumper.h:
     16        * bytecode/BytecodeList.json:
     17        * bytecode/BytecodeUseDef.h:
     18        (JSC::computeUsesForBytecodeOffset):
     19        (JSC::computeDefsForBytecodeOffset):
     20        * bytecode/CodeBlock.cpp:
     21        (JSC::CodeBlock::finishCreation):
     22        * bytecode/InlineAccess.cpp:
     23        (JSC::InlineAccess::generateSelfInAccess):
     24        * bytecode/InlineAccess.h:
     25        * bytecode/StructureStubInfo.cpp:
     26        (JSC::StructureStubInfo::initInByIdSelf):
     27        (JSC::StructureStubInfo::deref):
     28        (JSC::StructureStubInfo::aboutToDie):
     29        (JSC::StructureStubInfo::reset):
     30        (JSC::StructureStubInfo::visitWeakReferences):
     31        (JSC::StructureStubInfo::propagateTransitions):
     32        * bytecode/StructureStubInfo.h:
     33        (JSC::StructureStubInfo::patchableJump):
     34        * bytecompiler/BytecodeGenerator.cpp:
     35        (JSC::BytecodeGenerator::emitInByVal):
     36        (JSC::BytecodeGenerator::emitInById):
     37        (JSC::BytecodeGenerator::emitIn): Deleted.
     38        * bytecompiler/BytecodeGenerator.h:
     39        * bytecompiler/NodesCodegen.cpp:
     40        (JSC::InNode::emitBytecode):
     41        * dfg/DFGAbstractInterpreterInlines.h:
     42        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
     43        * dfg/DFGByteCodeParser.cpp:
     44        (JSC::DFG::ByteCodeParser::parseBlock):
     45        * dfg/DFGCapabilities.cpp:
     46        (JSC::DFG::capabilityLevel):
     47        * dfg/DFGClobberize.h:
     48        (JSC::DFG::clobberize):
     49        * dfg/DFGConstantFoldingPhase.cpp:
     50        (JSC::DFG::ConstantFoldingPhase::foldConstants):
     51        * dfg/DFGDoesGC.cpp:
     52        (JSC::DFG::doesGC):
     53        * dfg/DFGFixupPhase.cpp:
     54        (JSC::DFG::FixupPhase::fixupNode):
     55        * dfg/DFGJITCompiler.cpp:
     56        (JSC::DFG::JITCompiler::link):
     57        * dfg/DFGJITCompiler.h:
     58        (JSC::DFG::JITCompiler::addInById):
     59        (JSC::DFG::InRecord::InRecord): Deleted.
     60        (JSC::DFG::JITCompiler::addIn): Deleted.
     61        * dfg/DFGNode.h:
     62        (JSC::DFG::Node::convertToInById):
     63        (JSC::DFG::Node::hasIdentifier):
     64        (JSC::DFG::Node::hasArrayMode):
     65        * dfg/DFGNodeType.h:
     66        * dfg/DFGPredictionPropagationPhase.cpp:
     67        * dfg/DFGSafeToExecute.h:
     68        (JSC::DFG::safeToExecute):
     69        * dfg/DFGSpeculativeJIT.cpp:
     70        (JSC::DFG::SpeculativeJIT::compileInById):
     71        (JSC::DFG::SpeculativeJIT::compileInByVal):
     72        (JSC::DFG::SpeculativeJIT::compileIn): Deleted.
     73        * dfg/DFGSpeculativeJIT.h:
     74        * dfg/DFGSpeculativeJIT32_64.cpp:
     75        (JSC::DFG::SpeculativeJIT::compile):
     76        * dfg/DFGSpeculativeJIT64.cpp:
     77        (JSC::DFG::SpeculativeJIT::compile):
     78        * ftl/FTLCapabilities.cpp:
     79        (JSC::FTL::canCompile):
     80        * ftl/FTLLowerDFGToB3.cpp:
     81        (JSC::FTL::DFG::LowerDFGToB3::compileNode):
     82        (JSC::FTL::DFG::LowerDFGToB3::compileInByVal):
     83        (JSC::FTL::DFG::LowerDFGToB3::compileInById):
     84        (JSC::FTL::DFG::LowerDFGToB3::compileIn): Deleted.
     85        * jit/AssemblyHelpers.h:
     86        (JSC::AssemblyHelpers::boxBoolean):
     87        * jit/ICStats.h:
     88        * jit/JIT.cpp:
     89        (JSC::JIT::JIT):
     90        (JSC::JIT::privateCompileMainPass):
     91        (JSC::JIT::privateCompileSlowCases):
     92        (JSC::JIT::link):
     93        * jit/JIT.h:
     94        * jit/JITInlineCacheGenerator.cpp:
     95        (JSC::JITInByIdGenerator::JITInByIdGenerator):
     96        (JSC::JITInByIdGenerator::generateFastPath):
     97        * jit/JITInlineCacheGenerator.h:
     98        (JSC::JITInByIdGenerator::JITInByIdGenerator):
     99        * jit/JITOperations.cpp:
     100        * jit/JITOperations.h:
     101        * jit/JITPropertyAccess.cpp:
     102        (JSC::JIT::emit_op_in_by_id):
     103        (JSC::JIT::emitSlow_op_in_by_id):
     104        * jit/JITPropertyAccess32_64.cpp:
     105        (JSC::JIT::emit_op_in_by_id):
     106        (JSC::JIT::emitSlow_op_in_by_id):
     107        * jit/Repatch.cpp:
     108        (JSC::tryCacheInByID):
     109        (JSC::repatchInByID):
     110        (JSC::resetInByID):
     111        (JSC::tryCacheIn): Deleted.
     112        (JSC::repatchIn): Deleted.
     113        (JSC::resetIn): Deleted.
     114        * jit/Repatch.h:
     115        * llint/LowLevelInterpreter.asm:
     116        * llint/LowLevelInterpreter64.asm:
     117        * parser/NodeConstructors.h:
     118        (JSC::InNode::InNode):
     119        * runtime/CommonSlowPaths.cpp:
     120        (JSC::SLOW_PATH_DECL):
     121        * runtime/CommonSlowPaths.h:
     122        (JSC::CommonSlowPaths::opInByVal):
     123        (JSC::CommonSlowPaths::opIn): Deleted.
     124
    11252018-05-21  Commit Queue  <commit-queue@webkit.org>
    2126
  • trunk/Source/JavaScriptCore/bytecode/AccessCase.cpp

    r232029 r232047  
    118118    case CacheType::PutByIdReplace:
    119119        return AccessCase::create(vm, owner, Replace, stubInfo.u.byIdSelf.offset, stubInfo.u.byIdSelf.baseObjectStructure.get());
     120
     121    case CacheType::InByIdSelf:
     122        return AccessCase::create(vm, owner, InHit, stubInfo.u.byIdSelf.offset, stubInfo.u.byIdSelf.baseObjectStructure.get());
    120123
    121124    default:
     
    556559       
    557560        CCallHelpers::Label loop(&jit);
    558         failAndIgnore = jit.branch8(
    559             CCallHelpers::Equal,
    560             CCallHelpers::Address(valueGPR, JSCell::typeInfoTypeOffset()),
    561             CCallHelpers::TrustedImm32(ProxyObjectType));
     561        failAndIgnore = jit.branchIfType(valueGPR, ProxyObjectType);
    562562       
    563563        jit.emitLoadStructure(vm, valueGPR, scratch2GPR, scratchGPR);
     
    681681    case InHit:
    682682    case InMiss:
    683         jit.boxBooleanPayload(m_type == InHit, valueRegs.payloadGPR());
     683        jit.boxBoolean(m_type == InHit, valueRegs);
    684684        state.succeed();
    685685        return;
  • trunk/Source/JavaScriptCore/bytecode/BytecodeDumper.cpp

    r232029 r232047  
    548548    }
    549549#else
     550    UNUSED_PARAM(map);
     551#endif
     552}
     553
     554template<class Block>
     555void BytecodeDumper<Block>::printInByIdCacheStatus(PrintStream& out, int location, const StubInfoMap& map)
     556{
     557    const auto* instruction = instructionsBegin() + location;
     558
     559    const Identifier& ident = identifier(instruction[3].u.operand);
     560
     561    UNUSED_PARAM(ident); // tell the compiler to shut up in certain platform configurations.
     562
     563#if ENABLE(JIT)
     564    if (StructureStubInfo* stubPtr = map.get(CodeOrigin(location))) {
     565        StructureStubInfo& stubInfo = *stubPtr;
     566        if (stubInfo.resetByGC)
     567            out.print(" (Reset By GC)");
     568
     569        out.printf(" jit(");
     570
     571        Structure* baseStructure = nullptr;
     572        PolymorphicAccess* stub = nullptr;
     573
     574        switch (stubInfo.cacheType) {
     575        case CacheType::InByIdSelf:
     576            out.printf("self");
     577            baseStructure = stubInfo.u.byIdSelf.baseObjectStructure.get();
     578            break;
     579        case CacheType::Stub:
     580            out.printf("stub");
     581            stub = stubInfo.u.stub;
     582            break;
     583        case CacheType::Unset:
     584            out.printf("unset");
     585            break;
     586        default:
     587            RELEASE_ASSERT_NOT_REACHED();
     588            break;
     589        }
     590
     591        if (baseStructure) {
     592            out.printf(", ");
     593            dumpStructure(out, "struct", baseStructure, ident);
     594        }
     595
     596        if (stub)
     597            out.print(", ", *stub);
     598
     599        out.printf(")");
     600    }
     601#else
     602    UNUSED_PARAM(out);
    550603    UNUSED_PARAM(map);
    551604#endif
     
    10131066        break;
    10141067    }
    1015     case op_in: {
    1016         printBinaryOp(out, location, it, "in");
     1068    case op_in_by_id: {
     1069        int r0 = (++it)->u.operand;
     1070        int r1 = (++it)->u.operand;
     1071        int id0 = (++it)->u.operand;
     1072        printLocationAndOp(out, location, it, "in_by_id");
     1073        out.printf("%s, %s, %s", registerName(r0).data(), registerName(r1).data(), idName(id0, identifier(id0)).data());
     1074        printInByIdCacheStatus(out, location, stubInfos);
     1075        break;
     1076    }
     1077    case op_in_by_val: {
     1078        printBinaryOp(out, location, it, "in_by_val");
    10171079        dumpArrayProfiling(out, it, hasPrintedProfiling);
    10181080        break;
  • trunk/Source/JavaScriptCore/bytecode/BytecodeDumper.h

    r232029 r232047  
    7272    void printGetByIdCacheStatus(PrintStream& out, int location, const StubInfoMap&);
    7373    void printPutByIdCacheStatus(PrintStream& out, int location, const StubInfoMap&);
     74    void printInByIdCacheStatus(PrintStream& out, int location, const StubInfoMap&);
    7475    enum CacheDumpMode { DumpCaches, DontDumpCaches };
    7576    void printCallOp(PrintStream& out, int location, const Instruction*& it, const char* op, CacheDumpMode, bool& hasPrintedProfiling, const CallLinkInfoMap&);
  • trunk/Source/JavaScriptCore/bytecode/BytecodeList.json

    r232029 r232047  
    8181            { "name" : "op_is_function", "length" : 3 },
    8282            { "name" : "op_is_cell_with_type", "length" : 4 },
    83             { "name" : "op_in", "length" : 5 },
     83            { "name" : "op_in_by_val", "length" : 5 },
     84            { "name" : "op_in_by_id", "length" : 4 },
    8485            { "name" : "op_get_array_length", "length" : 9 },
    8586            { "name" : "op_get_by_id", "length" : 9  },
  • trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.h

    r232029 r232047  
    187187    case op_get_by_id_direct:
    188188    case op_get_array_length:
     189    case op_in_by_id:
    189190    case op_typeof:
    190191    case op_is_empty:
     
    227228    case op_enumerator_generic_pname:
    228229    case op_get_by_val:
    229     case op_in:
     230    case op_in_by_val:
    230231    case op_overrides_has_instance:
    231232    case op_instanceof:
     
    455456    case op_is_cell_with_type:
    456457    case op_is_function:
    457     case op_in:
     458    case op_in_by_id:
     459    case op_in_by_val:
    458460    case op_to_number:
    459461    case op_to_string:
  • trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp

    r232029 r232047  
    590590        }
    591591
    592         case op_in:
     592        case op_in_by_val:
    593593        case op_put_by_val:
    594594        case op_put_by_val_direct: {
  • trunk/Source/JavaScriptCore/bytecode/InlineAccess.cpp

    r232029 r232047  
    277277}
    278278
     279bool InlineAccess::generateSelfInAccess(StructureStubInfo& stubInfo, Structure* structure)
     280{
     281    CCallHelpers jit;
     282
     283    GPRReg base = static_cast<GPRReg>(stubInfo.patch.baseGPR);
     284    JSValueRegs value = stubInfo.valueRegs();
     285
     286    auto branchToSlowPath = jit.patchableBranch32(
     287        MacroAssembler::NotEqual,
     288        MacroAssembler::Address(base, JSCell::structureIDOffset()),
     289        MacroAssembler::TrustedImm32(bitwise_cast<uint32_t>(structure->id())));
     290    jit.boxBoolean(true, value);
     291
     292    bool linkedCodeInline = linkCodeInline("in access", jit, stubInfo, [&] (LinkBuffer& linkBuffer) {
     293        linkBuffer.link(branchToSlowPath, stubInfo.slowPathStartLocation());
     294    });
     295    return linkedCodeInline;
     296}
     297
    279298void InlineAccess::rewireStubAsJump(StructureStubInfo& stubInfo, CodeLocationLabel<JITStubRoutinePtrTag> target)
    280299{
  • trunk/Source/JavaScriptCore/bytecode/InlineAccess.h

    r232029 r232047  
    117117    static bool generateArrayLength(StructureStubInfo&, JSArray*);
    118118    static void rewireStubAsJump(StructureStubInfo&, CodeLocationLabel<JITStubRoutinePtrTag>);
     119    static bool generateSelfInAccess(StructureStubInfo&, Structure*);
    119120
    120121    // This is helpful when determining the size of an IC on
  • trunk/Source/JavaScriptCore/bytecode/StructureStubInfo.cpp

    r232029 r232047  
    8383}
    8484
     85void StructureStubInfo::initInByIdSelf(CodeBlock* codeBlock, Structure* baseObjectStructure, PropertyOffset offset)
     86{
     87    cacheType = CacheType::InByIdSelf;
     88
     89    u.byIdSelf.baseObjectStructure.set(
     90        *codeBlock->vm(), codeBlock, baseObjectStructure);
     91    u.byIdSelf.offset = offset;
     92}
     93
    8594void StructureStubInfo::deref()
    8695{
     
    92101    case CacheType::GetByIdSelf:
    93102    case CacheType::PutByIdReplace:
     103    case CacheType::InByIdSelf:
    94104    case CacheType::ArrayLength:
    95105        return;
     
    108118    case CacheType::GetByIdSelf:
    109119    case CacheType::PutByIdReplace:
     120    case CacheType::InByIdSelf:
    110121    case CacheType::ArrayLength:
    111122        return;
     
    238249        break;
    239250    case AccessType::In:
    240         resetIn(*this);
     251        resetInByID(codeBlock, *this);
    241252        break;
    242253    case AccessType::InstanceOf:
     
    261272    case CacheType::GetByIdSelf:
    262273    case CacheType::PutByIdReplace:
     274    case CacheType::InByIdSelf:
    263275        if (Heap::isMarked(u.byIdSelf.baseObjectStructure.get()))
    264276            return;
     
    284296    case CacheType::GetByIdSelf:
    285297    case CacheType::PutByIdReplace:
     298    case CacheType::InByIdSelf:
    286299        return u.byIdSelf.baseObjectStructure->markIfCheap(visitor);
    287300    case CacheType::Stub:
  • trunk/Source/JavaScriptCore/bytecode/StructureStubInfo.h

    r232029 r232047  
    5959    GetByIdSelf,
    6060    PutByIdReplace,
     61    InByIdSelf,
    6162    Stub,
    6263    ArrayLength
     
    7374    void initArrayLength();
    7475    void initPutByIdReplace(CodeBlock*, Structure* baseObjectStructure, PropertyOffset);
     76    void initInByIdSelf(CodeBlock*, Structure* baseObjectStructure, PropertyOffset);
    7577
    7678    AccessGenerationResult addAccessCase(const GCSafeConcurrentJSLocker&, CodeBlock*, const Identifier&, std::unique_ptr<AccessCase>);
     
    177179   
    178180    struct {
    179         CodeLocationLabel<JITStubRoutinePtrTag> start; // This is either the start of the inline IC for *byId caches, or the location of patchable jump for 'in' and 'instanceof' caches.
     181        CodeLocationLabel<JITStubRoutinePtrTag> start; // This is either the start of the inline IC for *byId caches. or the location of patchable jump for 'instanceof' caches.
    180182        RegisterSet usedRegisters;
    181183        uint32_t inlineSize;
     
    198200    CodeLocationJump<JSInternalPtrTag> patchableJump()
    199201    {
    200         ASSERT(accessType == AccessType::In || accessType == AccessType::InstanceOf);
     202        ASSERT(accessType == AccessType::InstanceOf);
    201203        return patch.start.jumpAtOffset<JSInternalPtrTag>(0);
    202204    }
  • trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp

    r232029 r232047  
    26682668}
    26692669
    2670 RegisterID* BytecodeGenerator::emitIn(RegisterID* dst, RegisterID* property, RegisterID* base)
     2670RegisterID* BytecodeGenerator::emitInByVal(RegisterID* dst, RegisterID* property, RegisterID* base)
    26712671{
    26722672    UnlinkedArrayProfile arrayProfile = newArrayProfile();
    2673     emitOpcode(op_in);
     2673    emitOpcode(op_in_by_val);
    26742674    instructions().append(dst->index());
    26752675    instructions().append(base->index());
    26762676    instructions().append(property->index());
    26772677    instructions().append(arrayProfile);
     2678    return dst;
     2679}
     2680
     2681RegisterID* BytecodeGenerator::emitInById(RegisterID* dst, RegisterID* base, const Identifier& property)
     2682{
     2683    emitOpcode(op_in_by_id);
     2684    instructions().append(dst->index());
     2685    instructions().append(base->index());
     2686    instructions().append(addConstant(property));
    26782687    return dst;
    26792688}
  • trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h

    r232029 r232047  
    695695        RegisterID* emitInstanceOfCustom(RegisterID* dst, RegisterID* value, RegisterID* constructor, RegisterID* hasInstanceValue);
    696696        RegisterID* emitTypeOf(RegisterID* dst, RegisterID* src) { return emitUnaryOp(op_typeof, dst, src); }
    697         RegisterID* emitIn(RegisterID* dst, RegisterID* property, RegisterID* base);
     697        RegisterID* emitInByVal(RegisterID* dst, RegisterID* property, RegisterID* base);
     698        RegisterID* emitInById(RegisterID* dst, RegisterID* base, const Identifier& property);
    698699
    699700        RegisterID* emitTryGetById(RegisterID* dst, RegisterID* base, const Identifier& property);
  • trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp

    r232029 r232047  
    22812281RegisterID* InNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
    22822282{
     2283    if (isNonIndexStringElement(*m_expr1)) {
     2284        RefPtr<RegisterID> base = generator.emitNode(m_expr2);
     2285        generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
     2286        return generator.emitInById(generator.finalDestination(dst, base.get()), base.get(), static_cast<StringNode*>(m_expr1)->value());
     2287    }
     2288
    22832289    RefPtr<RegisterID> key = generator.emitNodeForLeftHandSide(m_expr1, m_rightHasAssignments, m_expr2->isPure(generator));
    22842290    RefPtr<RegisterID> base = generator.emitNode(m_expr2);
    22852291    generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
    2286     return generator.emitIn(generator.finalDestination(dst, key.get()), key.get(), base.get());
     2292    return generator.emitInByVal(generator.finalDestination(dst, key.get()), key.get(), base.get());
    22872293}
    22882294
  • trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h

    r232029 r232047  
    32603260        break;
    32613261       
    3262     case In: {
     3262    case InById: {
    32633263        // FIXME: We can determine when the property definitely exists based on abstract
    32643264        // value information.
    32653265        clobberWorld();
     3266        filter(node->child1(), SpecObject);
     3267        setNonCellTypeForNode(node, SpecBoolean);
     3268        break;
     3269    }
     3270
     3271    case InByVal: {
     3272        AbstractValue& property = forNode(node->child2());
     3273        if (JSValue constant = property.value()) {
     3274            if (constant.isString()) {
     3275                JSString* string = asString(constant);
     3276                const StringImpl* impl = string->tryGetValueImpl();
     3277                if (impl && impl->isAtomic())
     3278                    m_state.setFoundConstants(true);
     3279            }
     3280        }
     3281
     3282        // FIXME: We can determine when the property definitely exists based on abstract
     3283        // value information.
     3284        clobberWorld();
     3285        filter(node->child1(), SpecObject);
    32663286        setNonCellTypeForNode(node, SpecBoolean);
    32673287        break;
  • trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp

    r232029 r232047  
    63936393        }
    63946394
    6395         case op_in: {
    6396             ArrayMode arrayMode = getArrayMode(currentInstruction[OPCODE_LENGTH(op_in) - 1].u.arrayProfile);
     6395        case op_in_by_val: {
     6396            ArrayMode arrayMode = getArrayMode(currentInstruction[OPCODE_LENGTH(op_in_by_val) - 1].u.arrayProfile);
    63976397            set(VirtualRegister(currentInstruction[1].u.operand),
    6398                 addToGraph(In, OpInfo(arrayMode.asWord()), get(VirtualRegister(currentInstruction[2].u.operand)), get(VirtualRegister(currentInstruction[3].u.operand))));
    6399             NEXT_OPCODE(op_in);
     6398                addToGraph(InByVal, OpInfo(arrayMode.asWord()), get(VirtualRegister(currentInstruction[2].u.operand)), get(VirtualRegister(currentInstruction[3].u.operand))));
     6399            NEXT_OPCODE(op_in_by_val);
     6400        }
     6401
     6402        case op_in_by_id: {
     6403            Node* base = get(VirtualRegister(currentInstruction[2].u.operand));
     6404            unsigned identifierNumber = m_inlineStackTop->m_identifierRemap[currentInstruction[3].u.operand];
     6405            set(VirtualRegister(currentInstruction[1].u.operand),
     6406                addToGraph(InById, OpInfo(identifierNumber), base));
     6407            NEXT_OPCODE(op_in_by_id);
     6408            break;
    64006409        }
    64016410
  • trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp

    r232029 r232047  
    237237    case op_switch_imm:
    238238    case op_switch_char:
    239     case op_in:
     239    case op_in_by_val:
     240    case op_in_by_id:
    240241    case op_get_scope:
    241242    case op_get_from_scope:
  • trunk/Source/JavaScriptCore/dfg/DFGClobberize.h

    r232029 r232047  
    624624    case ConstructForwardVarargs:
    625625    case ToPrimitive:
    626     case In:
     626    case InByVal:
     627    case InById:
    627628    case HasOwnProperty:
    628629    case ValueAdd:
  • trunk/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp

    r232029 r232047  
    652652            }
    653653
     654            case InByVal: {
     655                AbstractValue& property = m_state.forNode(node->child2());
     656                if (JSValue constant = property.value()) {
     657                    if (constant.isString()) {
     658                        JSString* string = asString(constant);
     659                        const StringImpl* impl = string->tryGetValueImpl();
     660                        if (impl && impl->isAtomic()) {
     661                            unsigned identifierNumber = m_graph.identifiers().ensure(const_cast<UniquedStringImpl*>(static_cast<const UniquedStringImpl*>(impl)));
     662                            node->convertToInById(identifierNumber);
     663                            changed = true;
     664                            break;
     665                        }
     666                    }
     667                }
     668                break;
     669            }
     670
    654671            case ToPrimitive: {
    655672                if (m_state.forNode(node->child1()).m_type & ~(SpecFullNumber | SpecBoolean | SpecString | SpecSymbol | SpecBigInt))
  • trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp

    r232029 r232047  
    194194    case NumberToStringWithRadix:
    195195    case NumberToStringWithValidRadixConstant:
    196     case In:
     196    case InByVal:
     197    case InById:
    197198    case HasOwnProperty:
    198199    case Jump:
  • trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp

    r232029 r232047  
    14771477            break;
    14781478
    1479         case In: {
     1479        case InById: {
     1480            fixEdge<CellUse>(node->child1());
     1481            break;
     1482        }
     1483
     1484        case InByVal: {
    14801485            if (node->child2()->shouldSpeculateInt32()) {
    14811486                convertToHasIndexedProperty(node);
  • trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp

    r232029 r232047  
    266266    finalizeInlineCaches(m_getByIdsWithThis, linkBuffer);
    267267    finalizeInlineCaches(m_putByIds, linkBuffer);
     268    finalizeInlineCaches(m_inByIds, linkBuffer);
    268269    finalizeInlineCaches(m_instanceOfs, linkBuffer);
    269270
    270     for (unsigned i = 0; i < m_ins.size(); ++i) {
    271         StructureStubInfo& info = *m_ins[i].m_stubInfo;
    272 
    273         CodeLocationLabel<JITStubRoutinePtrTag> start = linkBuffer.locationOf<JITStubRoutinePtrTag>(m_ins[i].m_jump);
    274         info.patch.start = start;
    275 
    276         ptrdiff_t inlineSize = MacroAssembler::differenceBetweenCodePtr(
    277             start, linkBuffer.locationOf<JSInternalPtrTag>(m_ins[i].m_done));
    278         RELEASE_ASSERT(inlineSize >= 0);
    279         info.patch.inlineSize = inlineSize;
    280 
    281         info.patch.deltaFromStartToSlowPathCallLocation = MacroAssembler::differenceBetweenCodePtr(
    282             start, linkBuffer.locationOf<JSInternalPtrTag>(m_ins[i].m_slowPathGenerator->call()));
    283 
    284         info.patch.deltaFromStartToSlowPathStart = MacroAssembler::differenceBetweenCodePtr(
    285             start, linkBuffer.locationOf<JSInternalPtrTag>(m_ins[i].m_slowPathGenerator->label()));
    286     }
    287    
    288271    auto linkCallThunk = FunctionPtr<NoPtrTag>(vm()->getCTIStub(linkCallThunkGenerator).retaggedCode<NoPtrTag>());
    289272    for (auto& record : m_jsCalls) {
  • trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.h

    r232029 r232047  
    7777};
    7878
    79 struct InRecord {
    80     InRecord(
    81         MacroAssembler::PatchableJump jump, MacroAssembler::Label done,
    82         SlowPathGenerator* slowPathGenerator, StructureStubInfo* stubInfo)
    83         : m_jump(jump)
    84         , m_done(done)
    85         , m_slowPathGenerator(slowPathGenerator)
    86         , m_stubInfo(stubInfo)
    87     {
    88     }
    89    
    90     MacroAssembler::PatchableJump m_jump;
    91     MacroAssembler::Label m_done;
    92     SlowPathGenerator* m_slowPathGenerator;
    93     StructureStubInfo* m_stubInfo;
    94 };
    95 
    9679// === JITCompiler ===
    9780//
     
    210193    }
    211194
    212     void addIn(const InRecord& record)
    213     {
    214         m_ins.append(record);
    215     }
    216    
     195    void addInById(const JITInByIdGenerator& gen, SlowPathGenerator* slowPath)
     196    {
     197        m_inByIds.append(InlineCacheWrapper<JITInByIdGenerator>(gen, slowPath));
     198    }
     199
    217200    void addJSCall(Call fastCall, Call slowCall, DataLabelPtr targetToCheck, CallLinkInfo* info)
    218201    {
     
    360343    Vector<InlineCacheWrapper<JITGetByIdWithThisGenerator>, 4> m_getByIdsWithThis;
    361344    Vector<InlineCacheWrapper<JITPutByIdGenerator>, 4> m_putByIds;
     345    Vector<InlineCacheWrapper<JITInByIdGenerator>, 4> m_inByIds;
    362346    Vector<InlineCacheWrapper<JITInstanceOfGenerator>, 4> m_instanceOfs;
    363     Vector<InRecord, 4> m_ins;
    364347    Vector<JSCallRecord, 4> m_jsCalls;
    365348    Vector<JSDirectCallRecord, 4> m_jsDirectCalls;
  • trunk/Source/JavaScriptCore/dfg/DFGNode.h

    r232029 r232047  
    753753        m_opInfo = false;
    754754    }
     755
     756    void convertToInById(unsigned identifierNumber)
     757    {
     758        ASSERT(m_op == InByVal);
     759        setOpAndDefaultFlags(InById);
     760        children.setChild2(Edge());
     761        m_opInfo = identifierNumber;
     762        m_opInfo2 = OpInfoWrapper();
     763    }
    755764   
    756765    JSValue asJSValue()
     
    10201029        case PutGetterSetterById:
    10211030        case DeleteById:
     1031        case InById:
    10221032        case GetDynamicVar:
    10231033        case PutDynamicVar:
     
    19881998        case GetArrayLength:
    19891999        case GetVectorLength:
    1990         case In:
     2000        case InByVal:
    19912001        case PutByValDirect:
    19922002        case PutByVal:
  • trunk/Source/JavaScriptCore/dfg/DFGNodeType.h

    r232029 r232047  
    371371    macro(NewStringObject, NodeResultJS) \
    372372    macro(MakeRope, NodeResultJS) \
    373     macro(In, NodeResultBoolean | NodeMustGenerate) \
     373    macro(InByVal, NodeResultBoolean | NodeMustGenerate) \
     374    macro(InById, NodeResultBoolean | NodeMustGenerate) \
    374375    macro(ProfileType, NodeMustGenerate) \
    375376    macro(ProfileControlFlow, NodeMustGenerate) \
  • trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp

    r232029 r232047  
    982982            break;
    983983
    984         case In:
     984        case InByVal:
     985        case InById:
    985986            setPrediction(SpecBoolean);
    986987            break;
  • trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h

    r232029 r232047  
    333333    case NewStringObject:
    334334    case MakeRope:
    335     case In:
     335    case InByVal:
     336    case InById:
    336337    case HasOwnProperty:
    337338    case PushWithScope:
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp

    r232029 r232047  
    10571057}
    10581058
    1059 void SpeculativeJIT::compileIn(Node* node)
     1059void SpeculativeJIT::compileInById(Node* node)
    10601060{
    10611061    SpeculateCellOperand base(this, node->child1());
     1062    JSValueRegsTemporary result(this, Reuse, base, PayloadWord);
     1063
    10621064    GPRReg baseGPR = base.gpr();
    1063    
    1064     if (JSString* string = node->child2()->dynamicCastConstant<JSString*>(*m_jit.vm())) {
    1065         if (string->tryGetValueImpl() && string->tryGetValueImpl()->isAtomic()) {
    1066             StructureStubInfo* stubInfo = m_jit.codeBlock()->addStubInfo(AccessType::In);
    1067            
    1068             GPRTemporary result(this);
    1069             GPRReg resultGPR = result.gpr();
    1070 
    1071             use(node->child2());
    1072            
    1073             MacroAssembler::PatchableJump jump = m_jit.patchableJump();
    1074             MacroAssembler::Label done = m_jit.label();
    1075            
    1076             // Since this block is executed only when the result of string->tryGetValueImpl() is atomic,
    1077             // we can cast it to const AtomicStringImpl* safely.
    1078             auto slowPath = slowPathCall(
    1079                 jump.m_jump, this, operationInOptimize,
    1080                 JSValueRegs::payloadOnly(resultGPR), stubInfo, baseGPR,
    1081                 static_cast<const AtomicStringImpl*>(string->tryGetValueImpl()));
    1082            
    1083             stubInfo->callSiteIndex = m_jit.addCallSite(node->origin.semantic);
    1084             stubInfo->codeOrigin = node->origin.semantic;
    1085             stubInfo->patch.baseGPR = static_cast<int8_t>(baseGPR);
    1086             stubInfo->patch.valueGPR = static_cast<int8_t>(resultGPR);
    1087             stubInfo->patch.thisGPR = static_cast<int8_t>(InvalidGPRReg);
    1088 #if USE(JSVALUE32_64)
    1089             stubInfo->patch.valueTagGPR = static_cast<int8_t>(InvalidGPRReg);
    1090             stubInfo->patch.baseTagGPR = static_cast<int8_t>(InvalidGPRReg);
    1091             stubInfo->patch.thisTagGPR = static_cast<int8_t>(InvalidGPRReg);
    1092 #endif
    1093             stubInfo->patch.usedRegisters = usedRegisters();
    1094 
    1095             m_jit.addIn(InRecord(jump, done, slowPath.get(), stubInfo));
    1096             addSlowPathGenerator(WTFMove(slowPath));
    1097 
    1098             base.use();
    1099 
    1100             blessedBooleanResult(resultGPR, node, UseChildrenCalledExplicitly);
    1101             return;
    1102         }
    1103     }
    1104 
     1065    JSValueRegs resultRegs = result.regs();
     1066
     1067    base.use();
     1068
     1069    CodeOrigin codeOrigin = node->origin.semantic;
     1070    CallSiteIndex callSite = m_jit.recordCallSiteAndGenerateExceptionHandlingOSRExitIfNeeded(codeOrigin, m_stream->size());
     1071    RegisterSet usedRegisters = this->usedRegisters();
     1072    JITInByIdGenerator gen(
     1073        m_jit.codeBlock(), codeOrigin, callSite, usedRegisters, identifierUID(node->identifierNumber()),
     1074        JSValueRegs::payloadOnly(baseGPR), resultRegs);
     1075    gen.generateFastPath(m_jit);
     1076
     1077    auto slowPath = slowPathCall(
     1078        gen.slowPathJump(), this, operationInByIdOptimize,
     1079        NeedToSpill, ExceptionCheckRequirement::CheckNeeded,
     1080        resultRegs, gen.stubInfo(), CCallHelpers::CellValue(baseGPR), identifierUID(node->identifierNumber()));
     1081
     1082    m_jit.addInById(gen, slowPath.get());
     1083    addSlowPathGenerator(WTFMove(slowPath));
     1084
     1085    blessedBooleanResult(resultRegs.payloadGPR(), node, UseChildrenCalledExplicitly);
     1086}
     1087
     1088void SpeculativeJIT::compileInByVal(Node* node)
     1089{
     1090    SpeculateCellOperand base(this, node->child1());
    11051091    JSValueOperand key(this, node->child2());
     1092
     1093    GPRReg baseGPR = base.gpr();
    11061094    JSValueRegs regs = key.jsValueRegs();
    1107        
    1108     GPRFlushedCallResult result(this);
    1109     GPRReg resultGPR = result.gpr();
    1110        
     1095
    11111096    base.use();
    11121097    key.use();
    1113        
     1098
    11141099    flushRegisters();
    1115     callOperation(
    1116         operationGenericIn, extractResult(JSValueRegs::payloadOnly(resultGPR)),
    1117         baseGPR, regs);
     1100    JSValueRegsFlushedCallResult result(this);
     1101    JSValueRegs resultRegs = result.regs();
     1102    callOperation(operationInByVal, resultRegs, baseGPR, regs);
    11181103    m_jit.exceptionCheck();
    1119     blessedBooleanResult(resultGPR, node, UseChildrenCalledExplicitly);
     1104    blessedBooleanResult(resultRegs.payloadGPR(), node, UseChildrenCalledExplicitly);
    11201105}
    11211106
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h

    r232029 r232047  
    736736    void compileGetById(Node*, AccessType);
    737737    void compileGetByIdFlush(Node*, AccessType);
    738     void compileIn(Node*);
     738    void compileInById(Node*);
     739    void compileInByVal(Node*);
    739740   
    740741    void nonSpeculativeNonPeepholeCompareNullOrUndefined(Edge operand);
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp

    r232029 r232047  
    37573757        break;
    37583758
    3759     case In:
    3760         compileIn(node);
     3759    case InById:
     3760        compileInById(node);
     3761        break;
     3762
     3763    case InByVal:
     3764        compileInByVal(node);
    37613765        break;
    37623766
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp

    r232029 r232047  
    43074307        break;
    43084308
    4309     case In:
    4310         compileIn(node);
     4309    case InById:
     4310        compileInById(node);
     4311        break;
     4312
     4313    case InByVal:
     4314        compileInByVal(node);
    43114315        break;
    43124316
  • trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp

    r232029 r232047  
    206206    case ThrowStaticError:
    207207    case Unreachable:
    208     case In:
     208    case InByVal:
     209    case InById:
    209210    case HasOwnProperty:
    210211    case IsCellWithType:
  • trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp

    r232029 r232047  
    709709            compileGetById(AccessType::GetDirect);
    710710            break;
    711         case In:
    712             compileIn();
     711        case InById:
     712            compileInById();
     713            break;
     714        case InByVal:
     715            compileInByVal();
    713716            break;
    714717        case HasOwnProperty:
     
    97149717    }
    97159718   
    9716     void compileIn()
    9717     {
    9718         DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == CellUse, m_node->child1().useKind());
    9719 
     9719    void compileInByVal()
     9720    {
     9721        setJSValue(vmCall(Int64, m_out.operation(operationInByVal), m_callFrame, lowCell(m_node->child1()), lowJSValue(m_node->child2())));
     9722    }
     9723
     9724    void compileInById()
     9725    {
    97209726        Node* node = m_node;
    9721         Edge base = node->child1();
    9722         LValue cell = lowCell(base);
    9723         if (JSString* string = node->child2()->dynamicCastConstant<JSString*>(vm())) {
    9724             if (string->tryGetValueImpl() && string->tryGetValueImpl()->isAtomic()) {
    9725                 UniquedStringImpl* str = bitwise_cast<UniquedStringImpl*>(string->tryGetValueImpl());
    9726                 PatchpointValue* patchpoint = m_out.patchpoint(Int64);
    9727                 patchpoint->appendSomeRegister(cell);
    9728                 patchpoint->append(m_tagMask, ValueRep::lateReg(GPRInfo::tagMaskRegister));
    9729                 patchpoint->append(m_tagTypeNumber, ValueRep::lateReg(GPRInfo::tagTypeNumberRegister));
    9730                 patchpoint->clobber(RegisterSet::macroScratchRegisters());
    9731 
    9732                 RefPtr<PatchpointExceptionHandle> exceptionHandle = preparePatchpointForExceptions(patchpoint);
    9733 
    9734                 State* state = &m_ftlState;
    9735                 patchpoint->setGenerator(
    9736                     [=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
     9727        UniquedStringImpl* uid = m_graph.identifiers()[node->identifierNumber()];
     9728        LValue base = lowCell(m_node->child1());
     9729
     9730        PatchpointValue* patchpoint = m_out.patchpoint(Int64);
     9731        patchpoint->appendSomeRegister(base);
     9732        patchpoint->append(m_tagMask, ValueRep::lateReg(GPRInfo::tagMaskRegister));
     9733        patchpoint->append(m_tagTypeNumber, ValueRep::lateReg(GPRInfo::tagTypeNumberRegister));
     9734
     9735        patchpoint->clobber(RegisterSet::macroScratchRegisters());
     9736
     9737        RefPtr<PatchpointExceptionHandle> exceptionHandle =
     9738            preparePatchpointForExceptions(patchpoint);
     9739
     9740        State* state = &m_ftlState;
     9741        patchpoint->setGenerator(
     9742            [=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
     9743                AllowMacroScratchRegisterUsage allowScratch(jit);
     9744
     9745                CallSiteIndex callSiteIndex =
     9746                    state->jitCode->common.addUniqueCallSiteIndex(node->origin.semantic);
     9747
     9748                // This is the direct exit target for operation calls.
     9749                Box<CCallHelpers::JumpList> exceptions =
     9750                    exceptionHandle->scheduleExitCreation(params)->jumps(jit);
     9751
     9752                auto generator = Box<JITInByIdGenerator>::create(
     9753                    jit.codeBlock(), node->origin.semantic, callSiteIndex,
     9754                    params.unavailableRegisters(), uid, JSValueRegs(params[1].gpr()),
     9755                    JSValueRegs(params[0].gpr()));
     9756
     9757                generator->generateFastPath(jit);
     9758                CCallHelpers::Label done = jit.label();
     9759
     9760                params.addLatePath(
     9761                    [=] (CCallHelpers& jit) {
    97379762                        AllowMacroScratchRegisterUsage allowScratch(jit);
    97389763
    9739                         // This is the direct exit target for operation calls. We don't need a JS exceptionHandle because we don't
    9740                         // cache Proxy objects.
    9741                         Box<CCallHelpers::JumpList> exceptions = exceptionHandle->scheduleExitCreation(params)->jumps(jit);
    9742 
    9743                         GPRReg baseGPR = params[1].gpr();
    9744                         GPRReg resultGPR = params[0].gpr();
    9745 
    9746                         StructureStubInfo* stubInfo =
    9747                             jit.codeBlock()->addStubInfo(AccessType::In);
    9748                         stubInfo->callSiteIndex =
    9749                             state->jitCode->common.addCodeOrigin(node->origin.semantic);
    9750                         stubInfo->codeOrigin = node->origin.semantic;
    9751                         stubInfo->patch.baseGPR = static_cast<int8_t>(baseGPR);
    9752                         stubInfo->patch.valueGPR = static_cast<int8_t>(resultGPR);
    9753                         stubInfo->patch.thisGPR = static_cast<int8_t>(InvalidGPRReg);
    9754                         stubInfo->patch.usedRegisters = params.unavailableRegisters();
    9755 
    9756                         CCallHelpers::PatchableJump jump = jit.patchableJump();
    9757                         CCallHelpers::Label done = jit.label();
    9758 
    9759                         params.addLatePath(
    9760                             [=] (CCallHelpers& jit) {
    9761                                 AllowMacroScratchRegisterUsage allowScratch(jit);
    9762 
    9763                                 jump.m_jump.link(&jit);
    9764                                 CCallHelpers::Label slowPathBegin = jit.label();
    9765                                 CCallHelpers::Call slowPathCall = callOperation(
    9766                                     *state, params.unavailableRegisters(), jit,
    9767                                     node->origin.semantic, exceptions.get(), operationInOptimize,
    9768                                     resultGPR, CCallHelpers::TrustedImmPtr(stubInfo), baseGPR,
    9769                                     CCallHelpers::TrustedImmPtr(str)).call();
    9770                                 jit.jump().linkTo(done, &jit);
    9771 
    9772                                 jit.addLinkTask(
    9773                                     [=] (LinkBuffer& linkBuffer) {
    9774                                         CodeLocationLabel<JITStubRoutinePtrTag> start = linkBuffer.locationOf<JITStubRoutinePtrTag>(jump);
    9775                                         stubInfo->patch.start = start;
    9776                                         ptrdiff_t inlineSize = MacroAssembler::differenceBetweenCodePtr(
    9777                                             start, linkBuffer.locationOf<NoPtrTag>(done));
    9778                                         RELEASE_ASSERT(inlineSize >= 0);
    9779                                         stubInfo->patch.inlineSize = inlineSize;
    9780 
    9781                                         stubInfo->patch.deltaFromStartToSlowPathCallLocation = MacroAssembler::differenceBetweenCodePtr(
    9782                                             start, linkBuffer.locationOf<NoPtrTag>(slowPathCall));
    9783 
    9784                                         stubInfo->patch.deltaFromStartToSlowPathStart = MacroAssembler::differenceBetweenCodePtr(
    9785                                             start, linkBuffer.locationOf<NoPtrTag>(slowPathBegin));
    9786 
    9787                                     });
     9764                        generator->slowPathJump().link(&jit);
     9765                        CCallHelpers::Label slowPathBegin = jit.label();
     9766                        CCallHelpers::Call slowPathCall = callOperation(
     9767                            *state, params.unavailableRegisters(), jit, node->origin.semantic,
     9768                            exceptions.get(), operationInByIdOptimize, params[0].gpr(),
     9769                            CCallHelpers::TrustedImmPtr(generator->stubInfo()), params[1].gpr(),
     9770                            CCallHelpers::TrustedImmPtr(uid)).call();
     9771                        jit.jump().linkTo(done, &jit);
     9772
     9773                        generator->reportSlowPathCall(slowPathBegin, slowPathCall);
     9774
     9775                        jit.addLinkTask(
     9776                            [=] (LinkBuffer& linkBuffer) {
     9777                                generator->finalize(linkBuffer, linkBuffer);
    97889778                            });
    97899779                    });
    9790 
    9791                 setJSValue(patchpoint);
    9792                 return;
    9793             }
    9794         }
    9795 
    9796         setJSValue(vmCall(Int64, m_out.operation(operationGenericIn), m_callFrame, cell, lowJSValue(m_node->child2())));
     9780            });
     9781
     9782        setJSValue(patchpoint);
    97979783    }
    97989784
  • trunk/Source/JavaScriptCore/jit/AssemblyHelpers.h

    r231905 r232047  
    13321332    {
    13331333        boxBooleanPayload(boolGPR, boxedRegs.payloadGPR());
     1334#if USE(JSVALUE32_64)
     1335        move(TrustedImm32(JSValue::BooleanTag), boxedRegs.tagGPR());
     1336#endif
     1337    }
     1338
     1339    void boxBoolean(bool value, JSValueRegs boxedRegs)
     1340    {
     1341        boxBooleanPayload(value, boxedRegs.payloadGPR());
    13341342#if USE(JSVALUE32_64)
    13351343        move(TrustedImm32(JSValue::BooleanTag), boxedRegs.tagGPR());
  • trunk/Source/JavaScriptCore/jit/ICStats.h

    r232029 r232047  
    5151    macro(OperationGetByIdOptimize) \
    5252    macro(OperationGetByIdWithThisOptimize) \
    53     macro(OperationInOptimize) \
    54     macro(OperationIn) \
    5553    macro(OperationGenericIn) \
     54    macro(OperationInById) \
     55    macro(OperationInByIdGeneric) \
     56    macro(OperationInByIdOptimize) \
    5657    macro(OperationPutByIdStrict) \
    5758    macro(OperationPutByIdNonStrict) \
     
    6869    macro(PutByIdAddAccessCase) \
    6970    macro(PutByIdReplaceWithJump) \
    70     macro(PutByIdSelfPatch)
     71    macro(PutByIdSelfPatch) \
     72    macro(InByIdSelfPatch)
    7173
    7274class ICEvent {
  • trunk/Source/JavaScriptCore/jit/JIT.cpp

    r232029 r232047  
    7979    , m_labels(codeBlock ? codeBlock->numberOfInstructions() : 0)
    8080    , m_bytecodeOffset(std::numeric_limits<unsigned>::max())
    81     , m_getByIdIndex(UINT_MAX)
    82     , m_getByIdWithThisIndex(UINT_MAX)
    83     , m_putByIdIndex(UINT_MAX)
    84     , m_byValInstructionIndex(UINT_MAX)
    85     , m_callLinkInfoIndex(UINT_MAX)
    8681    , m_pcToCodeOriginMapBuilder(*vm)
    8782    , m_canBeOptimized(false)
     
    278273
    279274        switch (opcodeID) {
    280         DEFINE_SLOW_OP(in)
     275        DEFINE_SLOW_OP(in_by_val)
    281276        DEFINE_SLOW_OP(less)
    282277        DEFINE_SLOW_OP(lesseq)
     
    342337        DEFINE_OP(op_beloweq)
    343338        DEFINE_OP(op_try_get_by_id)
     339        DEFINE_OP(op_in_by_id)
    344340        case op_get_array_length:
    345341        case op_get_by_id_proto_load:
     
    479475    m_getByIdWithThisIndex = 0;
    480476    m_putByIdIndex = 0;
     477    m_inByIdIndex = 0;
    481478    m_instanceOfIndex = 0;
    482479    m_byValInstructionIndex = 0;
     
    522519        DEFINE_SLOWCASE_OP(op_eq)
    523520        DEFINE_SLOWCASE_OP(op_try_get_by_id)
     521        DEFINE_SLOWCASE_OP(op_in_by_id)
    524522        case op_get_array_length:
    525523        case op_get_by_id_proto_load:
     
    601599    RELEASE_ASSERT(m_getByIdWithThisIndex == m_getByIdsWithThis.size());
    602600    RELEASE_ASSERT(m_putByIdIndex == m_putByIds.size());
     601    RELEASE_ASSERT(m_inByIdIndex == m_inByIds.size());
    603602    RELEASE_ASSERT(m_instanceOfIndex == m_instanceOfs.size());
    604603    RELEASE_ASSERT(m_callLinkInfoIndex == m_callCompilationInfo.size());
     
    843842    finalizeInlineCaches(m_getByIdsWithThis, patchBuffer);
    844843    finalizeInlineCaches(m_putByIds, patchBuffer);
     844    finalizeInlineCaches(m_inByIds, patchBuffer);
    845845    finalizeInlineCaches(m_instanceOfs, patchBuffer);
    846846
  • trunk/Source/JavaScriptCore/jit/JIT.h

    r232029 r232047  
    501501        void emit_op_get_by_val(Instruction*);
    502502        void emit_op_get_argument_by_val(Instruction*);
     503        void emit_op_in_by_id(Instruction*);
    503504        void emit_op_init_lazy_reg(Instruction*);
    504505        void emit_op_overrides_has_instance(Instruction*);
     
    612613        void emitSlow_op_get_by_val(Instruction*, Vector<SlowCaseEntry>::iterator&);
    613614        void emitSlow_op_get_argument_by_val(Instruction*, Vector<SlowCaseEntry>::iterator&);
     615        void emitSlow_op_in_by_id(Instruction*, Vector<SlowCaseEntry>::iterator&);
    614616        void emitSlow_op_instanceof(Instruction*, Vector<SlowCaseEntry>::iterator&);
    615617        void emitSlow_op_instanceof_custom(Instruction*, Vector<SlowCaseEntry>::iterator&);
     
    866868        Vector<JITGetByIdWithThisGenerator> m_getByIdsWithThis;
    867869        Vector<JITPutByIdGenerator> m_putByIds;
     870        Vector<JITInByIdGenerator> m_inByIds;
    868871        Vector<JITInstanceOfGenerator> m_instanceOfs;
    869872        Vector<ByValCompilationInfo> m_byValCompilationInfo;
     
    879882        Label m_exceptionHandler;
    880883
    881         unsigned m_getByIdIndex;
    882         unsigned m_getByIdWithThisIndex;
    883         unsigned m_putByIdIndex;
    884         unsigned m_instanceOfIndex;
    885         unsigned m_byValInstructionIndex;
    886         unsigned m_callLinkInfoIndex;
     884        unsigned m_getByIdIndex { UINT_MAX };
     885        unsigned m_getByIdWithThisIndex { UINT_MAX };
     886        unsigned m_putByIdIndex { UINT_MAX };
     887        unsigned m_inByIdIndex { UINT_MAX };
     888        unsigned m_instanceOfIndex { UINT_MAX };
     889        unsigned m_byValInstructionIndex { UINT_MAX };
     890        unsigned m_callLinkInfoIndex { UINT_MAX };
    887891       
    888892        Label m_arityCheck;
  • trunk/Source/JavaScriptCore/jit/JITInlineCacheGenerator.cpp

    r232029 r232047  
    167167}
    168168
     169JITInByIdGenerator::JITInByIdGenerator(
     170    CodeBlock* codeBlock, CodeOrigin codeOrigin, CallSiteIndex callSite, const RegisterSet& usedRegisters,
     171    UniquedStringImpl* propertyName, JSValueRegs base, JSValueRegs value)
     172    : JITByIdGenerator(codeBlock, codeOrigin, callSite, AccessType::In, usedRegisters, base, value)
     173{
     174    // FIXME: We are not supporting fast path for "length" property.
     175    UNUSED_PARAM(propertyName);
     176    RELEASE_ASSERT(base.payloadGPR() != value.tagGPR());
     177}
     178
     179void JITInByIdGenerator::generateFastPath(MacroAssembler& jit)
     180{
     181    generateFastCommon(jit, InlineAccess::sizeForPropertyAccess());
     182}
     183
    169184JITInstanceOfGenerator::JITInstanceOfGenerator(
    170185    CodeBlock* codeBlock, CodeOrigin codeOrigin, CallSiteIndex callSiteIndex,
  • trunk/Source/JavaScriptCore/jit/JITInlineCacheGenerator.h

    r232029 r232047  
    144144};
    145145
     146class JITInByIdGenerator : public JITByIdGenerator {
     147public:
     148    JITInByIdGenerator() { }
     149
     150    JITInByIdGenerator(
     151        CodeBlock*, CodeOrigin, CallSiteIndex, const RegisterSet& usedRegisters, UniquedStringImpl* propertyName,
     152        JSValueRegs base, JSValueRegs value);
     153
     154    void generateFastPath(MacroAssembler&);
     155};
     156
    146157class JITInstanceOfGenerator : public JITInlineCacheGenerator {
    147158public:
  • trunk/Source/JavaScriptCore/jit/JITOperations.cpp

    r232029 r232047  
    378378}
    379379
    380 EncodedJSValue JIT_OPERATION operationInOptimize(ExecState* exec, StructureStubInfo* stubInfo, JSCell* base, UniquedStringImpl* key)
     380EncodedJSValue JIT_OPERATION operationInById(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue base, UniquedStringImpl* uid)
    381381{
    382382    SuperSamplerScope superSamplerScope(false);
    383    
    384     VM* vm = &exec->vm();
    385     NativeCallFrameTracer tracer(vm, exec);
    386     auto scope = DECLARE_THROW_SCOPE(*vm);
    387 
    388     if (!base->isObject()) {
    389         throwException(exec, scope, createInvalidInParameterError(exec, base));
     383
     384    VM& vm = exec->vm();
     385    NativeCallFrameTracer tracer(&vm, exec);
     386    auto scope = DECLARE_THROW_SCOPE(vm);
     387
     388    stubInfo->tookSlowPath = true;
     389
     390    Identifier ident = Identifier::fromUid(&vm, uid);
     391
     392    JSValue baseValue = JSValue::decode(base);
     393    if (!baseValue.isObject()) {
     394        throwException(exec, scope, createInvalidInParameterError(exec, baseValue));
    390395        return JSValue::encode(jsUndefined());
    391396    }
    392    
    393     AccessType accessType = static_cast<AccessType>(stubInfo->accessType);
    394 
    395     Identifier ident = Identifier::fromUid(vm, key);
    396     LOG_IC((ICEvent::OperationInOptimize, base->classInfo(*vm), ident));
    397     PropertySlot slot(base, PropertySlot::InternalMethodType::HasProperty);
    398     bool result = asObject(base)->getPropertySlot(exec, ident, slot);
    399     RETURN_IF_EXCEPTION(scope, encodedJSValue());
    400    
    401     RELEASE_ASSERT(accessType == stubInfo->accessType);
    402    
    403     if (stubInfo->considerCaching(exec->codeBlock(), asObject(base)->structure()))
    404         repatchIn(exec, base, ident, result, slot, *stubInfo);
    405    
    406     return JSValue::encode(jsBoolean(result));
    407 }
    408 
    409 EncodedJSValue JIT_OPERATION operationIn(ExecState* exec, StructureStubInfo* stubInfo, JSCell* base, UniquedStringImpl* key)
     397    JSObject* baseObject = asObject(baseValue);
     398
     399    LOG_IC((ICEvent::OperationInById, baseObject->classInfo(vm), ident));
     400
     401    scope.release();
     402    PropertySlot slot(baseObject, PropertySlot::InternalMethodType::HasProperty);
     403    return JSValue::encode(jsBoolean(baseObject->getPropertySlot(exec, ident, slot)));
     404}
     405
     406EncodedJSValue JIT_OPERATION operationInByIdGeneric(ExecState* exec, EncodedJSValue base, UniquedStringImpl* uid)
    410407{
    411408    SuperSamplerScope superSamplerScope(false);
    412    
    413     VM* vm = &exec->vm();
    414     NativeCallFrameTracer tracer(vm, exec);
    415     auto scope = DECLARE_THROW_SCOPE(*vm);
    416 
    417     stubInfo->tookSlowPath = true;
    418 
    419     if (!base->isObject()) {
    420         throwException(exec, scope, createInvalidInParameterError(exec, base));
     409
     410    VM& vm = exec->vm();
     411    NativeCallFrameTracer tracer(&vm, exec);
     412    auto scope = DECLARE_THROW_SCOPE(vm);
     413
     414    Identifier ident = Identifier::fromUid(&vm, uid);
     415
     416    JSValue baseValue = JSValue::decode(base);
     417    if (!baseValue.isObject()) {
     418        throwException(exec, scope, createInvalidInParameterError(exec, baseValue));
    421419        return JSValue::encode(jsUndefined());
    422420    }
    423 
    424     Identifier ident = Identifier::fromUid(vm, key);
    425     LOG_IC((ICEvent::OperationIn, base->classInfo(*vm), ident));
     421    JSObject* baseObject = asObject(baseValue);
     422
     423    LOG_IC((ICEvent::OperationInByIdGeneric, baseObject->classInfo(vm), ident));
     424
    426425    scope.release();
    427     return JSValue::encode(jsBoolean(asObject(base)->hasProperty(exec, ident)));
    428 }
    429 
    430 EncodedJSValue JIT_OPERATION operationGenericIn(ExecState* exec, JSCell* base, EncodedJSValue key)
     426    PropertySlot slot(baseObject, PropertySlot::InternalMethodType::HasProperty);
     427    return JSValue::encode(jsBoolean(baseObject->getPropertySlot(exec, ident, slot)));
     428}
     429
     430EncodedJSValue JIT_OPERATION operationInByIdOptimize(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue base, UniquedStringImpl* uid)
    431431{
    432432    SuperSamplerScope superSamplerScope(false);
    433    
    434     VM* vm = &exec->vm();
    435     NativeCallFrameTracer tracer(vm, exec);
    436 
    437     return JSValue::encode(jsBoolean(CommonSlowPaths::opIn(exec, base, JSValue::decode(key))));
     433
     434    VM& vm = exec->vm();
     435    NativeCallFrameTracer tracer(&vm, exec);
     436    auto scope = DECLARE_THROW_SCOPE(vm);
     437
     438    Identifier ident = Identifier::fromUid(&vm, uid);
     439
     440    JSValue baseValue = JSValue::decode(base);
     441    if (!baseValue.isObject()) {
     442        throwException(exec, scope, createInvalidInParameterError(exec, baseValue));
     443        return JSValue::encode(jsUndefined());
     444    }
     445    JSObject* baseObject = asObject(baseValue);
     446
     447    LOG_IC((ICEvent::OperationInByIdOptimize, baseObject->classInfo(vm), ident));
     448
     449    scope.release();
     450    PropertySlot slot(baseObject, PropertySlot::InternalMethodType::HasProperty);
     451    bool found = baseObject->getPropertySlot(exec, ident, slot);
     452    if (stubInfo->considerCaching(exec->codeBlock(), baseObject->structure(vm)))
     453        repatchInByID(exec, baseObject, ident, found, slot, *stubInfo);
     454    return JSValue::encode(jsBoolean(found));
     455}
     456
     457EncodedJSValue JIT_OPERATION operationInByVal(ExecState* exec, JSCell* base, EncodedJSValue key)
     458{
     459    SuperSamplerScope superSamplerScope(false);
     460   
     461    VM* vm = &exec->vm();
     462    NativeCallFrameTracer tracer(vm, exec);
     463
     464    return JSValue::encode(jsBoolean(CommonSlowPaths::opInByVal(exec, base, JSValue::decode(key))));
    438465}
    439466
  • trunk/Source/JavaScriptCore/jit/JITOperations.h

    r232029 r232047  
    372372EncodedJSValue JIT_OPERATION operationGetByIdDirectGeneric(ExecState*, EncodedJSValue, UniquedStringImpl*) WTF_INTERNAL;
    373373EncodedJSValue JIT_OPERATION operationGetByIdDirectOptimize(ExecState*, StructureStubInfo*, EncodedJSValue, UniquedStringImpl*) WTF_INTERNAL;
     374EncodedJSValue JIT_OPERATION operationInById(ExecState*, StructureStubInfo*, EncodedJSValue, UniquedStringImpl*) WTF_INTERNAL;
     375EncodedJSValue JIT_OPERATION operationInByIdGeneric(ExecState*, EncodedJSValue, UniquedStringImpl*) WTF_INTERNAL;
     376EncodedJSValue JIT_OPERATION operationInByIdOptimize(ExecState*, StructureStubInfo*, EncodedJSValue, UniquedStringImpl*) WTF_INTERNAL;
    374377EncodedJSValue JIT_OPERATION operationInOptimize(ExecState*, StructureStubInfo*, JSCell*, UniquedStringImpl*) WTF_INTERNAL;
    375378EncodedJSValue JIT_OPERATION operationIn(ExecState*, StructureStubInfo*, JSCell*, UniquedStringImpl*) WTF_INTERNAL;
    376 EncodedJSValue JIT_OPERATION operationGenericIn(ExecState*, JSCell*, EncodedJSValue) WTF_INTERNAL;
     379EncodedJSValue JIT_OPERATION operationInByVal(ExecState*, JSCell*, EncodedJSValue) WTF_INTERNAL;
    377380void JIT_OPERATION operationPutByIdStrict(ExecState*, StructureStubInfo*, EncodedJSValue encodedValue, EncodedJSValue encodedBase, UniquedStringImpl*) WTF_INTERNAL;
    378381void JIT_OPERATION operationPutByIdNonStrict(ExecState*, StructureStubInfo*, EncodedJSValue encodedValue, EncodedJSValue encodedBase, UniquedStringImpl*) WTF_INTERNAL;
  • trunk/Source/JavaScriptCore/jit/JITPropertyAccess.cpp

    r232029 r232047  
    748748
    749749    Call call = callOperation(gen.slowPathFunction(), gen.stubInfo(), regT1, regT0, ident->impl());
     750
     751    gen.reportSlowPathCall(coldPathBegin, call);
     752}
     753
     754void JIT::emit_op_in_by_id(Instruction* currentInstruction)
     755{
     756    int resultVReg = currentInstruction[1].u.operand;
     757    int baseVReg = currentInstruction[2].u.operand;
     758    const Identifier* ident = &(m_codeBlock->identifier(currentInstruction[3].u.operand));
     759
     760    emitGetVirtualRegister(baseVReg, regT0);
     761
     762    emitJumpSlowCaseIfNotJSCell(regT0, baseVReg);
     763
     764    JITInByIdGenerator gen(
     765        m_codeBlock, CodeOrigin(m_bytecodeOffset), CallSiteIndex(m_bytecodeOffset), RegisterSet::stubUnavailableRegisters(),
     766        ident->impl(), JSValueRegs(regT0), JSValueRegs(regT0));
     767    gen.generateFastPath(*this);
     768    addSlowCase(gen.slowPathJump());
     769    m_inByIds.append(gen);
     770
     771    emitPutVirtualRegister(resultVReg);
     772}
     773
     774void JIT::emitSlow_op_in_by_id(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
     775{
     776    linkAllSlowCases(iter);
     777
     778    int resultVReg = currentInstruction[1].u.operand;
     779    const Identifier* ident = &(m_codeBlock->identifier(currentInstruction[3].u.operand));
     780
     781    JITInByIdGenerator& gen = m_inByIds[m_inByIdIndex++];
     782
     783    Label coldPathBegin = label();
     784
     785    Call call = callOperation(operationInByIdOptimize, resultVReg, gen.stubInfo(), regT0, ident->impl());
    750786
    751787    gen.reportSlowPathCall(coldPathBegin, call);
  • trunk/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp

    r232029 r232047  
    769769        gen.slowPathFunction(), gen.stubInfo(), JSValueRegs(regT3, regT2), JSValueRegs(regT1, regT0), ident->impl());
    770770   
     771    gen.reportSlowPathCall(coldPathBegin, call);
     772}
     773
     774void JIT::emit_op_in_by_id(Instruction* currentInstruction)
     775{
     776    int dst = currentInstruction[1].u.operand;
     777    int base = currentInstruction[2].u.operand;
     778    const Identifier* ident = &(m_codeBlock->identifier(currentInstruction[3].u.operand));
     779
     780    emitLoad(base, regT1, regT0);
     781    emitJumpSlowCaseIfNotJSCell(base, regT1);
     782
     783    JITInByIdGenerator gen(
     784        m_codeBlock, CodeOrigin(m_bytecodeOffset), CallSiteIndex(currentInstruction), RegisterSet::stubUnavailableRegisters(),
     785        ident->impl(), JSValueRegs::payloadOnly(regT0), JSValueRegs(regT1, regT0));
     786    gen.generateFastPath(*this);
     787    addSlowCase(gen.slowPathJump());
     788    m_inByIds.append(gen);
     789
     790    emitStore(dst, regT1, regT0);
     791}
     792
     793void JIT::emitSlow_op_in_by_id(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
     794{
     795    linkAllSlowCases(iter);
     796
     797    int resultVReg = currentInstruction[1].u.operand;
     798    const Identifier* ident = &(m_codeBlock->identifier(currentInstruction[3].u.operand));
     799
     800    JITInByIdGenerator& gen = m_inByIds[m_inByIdIndex++];
     801
     802    Label coldPathBegin = label();
     803
     804    Call call = callOperation(operationInByIdOptimize, resultVReg, gen.stubInfo(), JSValueRegs(regT1, regT0), ident->impl());
     805
    771806    gen.reportSlowPathCall(coldPathBegin, call);
    772807}
  • trunk/Source/JavaScriptCore/jit/Repatch.cpp

    r232029 r232047  
    606606}
    607607
    608 static InlineCacheAction tryCacheIn(
    609     ExecState* exec, JSCell* base, const Identifier& ident,
     608static InlineCacheAction tryCacheInByID(
     609    ExecState* exec, JSObject* base, const Identifier& ident,
    610610    bool wasFound, const PropertySlot& slot, StructureStubInfo& stubInfo)
    611611{
     
    632632        ObjectPropertyConditionSet conditionSet;
    633633        if (wasFound) {
     634            InlineCacheAction action = actionForCell(vm, base);
     635            if (action != AttemptToCache)
     636                return action;
     637
     638            // Optimize self access.
     639            if (stubInfo.cacheType == CacheType::Unset
     640                && slot.isCacheableValue()
     641                && slot.slotBase() == base
     642                && !slot.watchpointSet()
     643                && !structure->needImpurePropertyWatchpoint()) {
     644                bool generatedCodeInline = InlineAccess::generateSelfInAccess(stubInfo, structure);
     645                if (generatedCodeInline) {
     646                    LOG_IC((ICEvent::InByIdSelfPatch, structure->classInfo(), ident));
     647                    structure->startWatchingPropertyForReplacements(vm, slot.cachedOffset());
     648                    ftlThunkAwareRepatchCall(codeBlock, stubInfo.slowPathCallLocation(), operationInByIdOptimize);
     649                    stubInfo.initInByIdSelf(codeBlock, structure, slot.cachedOffset());
     650                    return RetryCacheLater;
     651                }
     652            }
     653
    634654            if (slot.slotBase() != base) {
    635655                bool usesPolyProto;
     
    665685
    666686        std::unique_ptr<AccessCase> newCase = AccessCase::create(
    667             vm, codeBlock, wasFound ? AccessCase::InHit : AccessCase::InMiss, invalidOffset, structure, conditionSet, WTFMove(prototypeAccessChain));
     687            vm, codeBlock, wasFound ? AccessCase::InHit : AccessCase::InMiss, wasFound ? slot.cachedOffset() : invalidOffset, structure, conditionSet, WTFMove(prototypeAccessChain));
    668688
    669689        result = stubInfo.addAccessCase(locker, codeBlock, ident, WTFMove(newCase));
     
    673693           
    674694            RELEASE_ASSERT(result.code());
    675 
    676             MacroAssembler::repatchJump(
    677                 stubInfo.patchableJump(),
    678                 CodeLocationLabel<JITStubRoutinePtrTag>(result.code()));
     695            InlineAccess::rewireStubAsJump(stubInfo, CodeLocationLabel<JITStubRoutinePtrTag>(result.code()));
    679696        }
    680697    }
     
    685702}
    686703
    687 void repatchIn(
    688     ExecState* exec, JSCell* base, const Identifier& ident, bool wasFound,
    689     const PropertySlot& slot, StructureStubInfo& stubInfo)
     704void repatchInByID(ExecState* exec, JSObject* baseObject, const Identifier& propertyName, bool wasFound, const PropertySlot& slot, StructureStubInfo& stubInfo)
    690705{
    691706    SuperSamplerScope superSamplerScope(false);
    692     if (tryCacheIn(exec, base, ident, wasFound, slot, stubInfo) == GiveUpOnCache)
    693         ftlThunkAwareRepatchCall(exec->codeBlock(), stubInfo.slowPathCallLocation(), operationIn);
     707
     708    if (tryCacheInByID(exec, baseObject, propertyName, wasFound, slot, stubInfo) == GiveUpOnCache) {
     709        CodeBlock* codeBlock = exec->codeBlock();
     710        ftlThunkAwareRepatchCall(codeBlock, stubInfo.slowPathCallLocation(), operationInById);
     711    }
    694712}
    695713
     
    12371255}
    12381256
    1239 void resetIn(StructureStubInfo& stubInfo)
     1257void resetInByID(CodeBlock* codeBlock, StructureStubInfo& stubInfo)
     1258{
     1259    ftlThunkAwareRepatchCall(codeBlock, stubInfo.slowPathCallLocation(), operationInByIdOptimize);
     1260    InlineAccess::rewireStubAsJump(stubInfo, stubInfo.slowPathStartLocation());
     1261}
     1262
     1263void resetInstanceOf(StructureStubInfo& stubInfo)
    12401264{
    12411265    resetPatchableJump(stubInfo);
    12421266}
    12431267
    1244 void resetInstanceOf(StructureStubInfo& stubInfo)
    1245 {
    1246     resetPatchableJump(stubInfo);
    1247 }
    1248 
    12491268} // namespace JSC
    12501269
  • trunk/Source/JavaScriptCore/jit/Repatch.h

    r232029 r232047  
    4545void repatchPutByID(ExecState*, JSValue, Structure*, const Identifier&, const PutPropertySlot&, StructureStubInfo&, PutKind);
    4646void buildPutByIdList(ExecState*, JSValue, Structure*, const Identifier&, const PutPropertySlot&, StructureStubInfo&, PutKind);
    47 void repatchIn(ExecState*, JSCell*, const Identifier&, bool wasFound, const PropertySlot&, StructureStubInfo&);
     47void repatchInByID(ExecState*, JSObject*, const Identifier&, bool wasFound, const PropertySlot&, StructureStubInfo&);
    4848void repatchInstanceOf(ExecState*, JSValue value, JSValue prototype, StructureStubInfo&, bool wasFound);
    4949void linkFor(ExecState*, CallLinkInfo&, CodeBlock*, JSObject* callee, MacroAssemblerCodePtr<JSEntryPtrTag>);
     
    5555void resetGetByID(CodeBlock*, StructureStubInfo&, GetByIDKind);
    5656void resetPutByID(CodeBlock*, StructureStubInfo&);
    57 void resetIn(StructureStubInfo&);
     57void resetInByID(CodeBlock*, StructureStubInfo&);
    5858void resetInstanceOf(StructureStubInfo&);
    5959void ftlThunkAwareRepatchCall(CodeBlock*, CodeLocationCall<JSInternalPtrTag>, FunctionPtr<CFunctionPtrTag> newCalleeFunction);
  • trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm

    r232029 r232047  
    15081508
    15091509
    1510 _llint_op_in:
    1511     traceExecution()
    1512     callSlowPath(_slow_path_in)
    1513     dispatch(constexpr op_in_length)
     1510_llint_op_in_by_id:
     1511    traceExecution()
     1512    callSlowPath(_slow_path_in_by_id)
     1513    dispatch(constexpr op_in_by_id_length)
     1514
     1515
     1516_llint_op_in_by_val:
     1517    traceExecution()
     1518    callSlowPath(_slow_path_in_by_val)
     1519    dispatch(constexpr op_in_by_val_length)
    15141520
    15151521
  • trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm

    r232029 r232047  
    15521552    callSlowPath(_llint_slow_path_put_by_id)
    15531553    dispatch(constexpr op_put_by_id_length)
     1554
    15541555
    15551556macro finishGetByVal(result, scratch)
  • trunk/Source/JavaScriptCore/parser/NodeConstructors.h

    r232029 r232047  
    624624
    625625    inline InNode::InNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
    626         : ThrowableBinaryOpNode(location, expr1, expr2, op_in, rightHasAssignments)
     626        : ThrowableBinaryOpNode(location, expr1, expr2, op_in_by_val, rightHasAssignments)
    627627    {
    628628    }
  • trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp

    r232029 r232047  
    649649}
    650650
    651 SLOW_PATH_DECL(slow_path_in)
    652 {
    653     BEGIN();
    654     RETURN(jsBoolean(CommonSlowPaths::opIn(exec, OP_C(2).jsValue(), OP_C(3).jsValue(), pc[4].u.arrayProfile)));
     651SLOW_PATH_DECL(slow_path_in_by_val)
     652{
     653    BEGIN();
     654    RETURN(jsBoolean(CommonSlowPaths::opInByVal(exec, OP_C(2).jsValue(), OP_C(3).jsValue(), pc[4].u.arrayProfile)));
     655}
     656
     657SLOW_PATH_DECL(slow_path_in_by_id)
     658{
     659    BEGIN();
     660
     661    JSValue baseValue = OP_C(2).jsValue();
     662    if (!baseValue.isObject())
     663        THROW(createInvalidInParameterError(exec, baseValue));
     664
     665    RETURN(jsBoolean(asObject(baseValue)->hasProperty(exec, exec->codeBlock()->identifier(pc[3].u.operand))));
    655666}
    656667
  • trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.h

    r232029 r232047  
    8686}
    8787
    88 inline bool opIn(ExecState* exec, JSValue baseVal, JSValue propName, ArrayProfile* arrayProfile = nullptr)
     88inline bool opInByVal(ExecState* exec, JSValue baseVal, JSValue propName, ArrayProfile* arrayProfile = nullptr)
    8989{
    9090    VM& vm = exec->vm();
     
    309309SLOW_PATH_HIDDEN_DECL(slow_path_is_object_or_null);
    310310SLOW_PATH_HIDDEN_DECL(slow_path_is_function);
    311 SLOW_PATH_HIDDEN_DECL(slow_path_in);
     311SLOW_PATH_HIDDEN_DECL(slow_path_in_by_id);
     312SLOW_PATH_HIDDEN_DECL(slow_path_in_by_val);
    312313SLOW_PATH_HIDDEN_DECL(slow_path_del_by_val);
    313314SLOW_PATH_HIDDEN_DECL(slow_path_strcat);
Note: See TracChangeset for help on using the changeset viewer.