⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 279105 in webkit


Ignore:
Timestamp:
Jun 21, 2021, 11:41:14 PM (5 years ago)
Author:
Ross Kirsling
Message:

[JSC] Add JIT ICs for #x in obj feature
https://bugs.webkit.org/show_bug.cgi?id=226146

Reviewed by Saam Barati.

JSTests:

  • microbenchmarks/has-private-brand.js: Added.
  • microbenchmarks/has-private-name.js: Added.

Source/JavaScriptCore:

This patch implements JIT ICs for the new #x in obj feature and turns the feature on by default.
Implementation closely follows InByVal, though HasPrivateBrand has a few subtleties
(namely, it cannot be viewed in terms of a PropertySlot and should not be converted to InById).

Microbenchmarks:

has-private-name 46.5777+-0.1374 6.0589+-0.0296 definitely 7.6875x faster
has-private-brand 25.8823+-0.0561 19.1509+-0.0447 definitely 1.3515x faster

  • bytecode/StructureStubInfo.cpp:

(JSC::StructureStubInfo::reset):

  • bytecode/StructureStubInfo.h:
  • dfg/DFGByteCodeParser.cpp:

(JSC::DFG::ByteCodeParser::handleInByAsMatchStructure):
(JSC::DFG::ByteCodeParser::handleInById):
(JSC::DFG::ByteCodeParser::parseBlock):

  • dfg/DFGSpeculativeJIT.cpp:

(JSC::DFG::SpeculativeJIT::compileInByVal):
(JSC::DFG::SpeculativeJIT::compileHasPrivate):
(JSC::DFG::SpeculativeJIT::compileHasPrivateName):
(JSC::DFG::SpeculativeJIT::compileHasPrivateBrand):

  • dfg/DFGSpeculativeJIT.h:
  • ftl/FTLLowerDFGToB3.cpp:

(JSC::FTL::DFG::LowerDFGToB3::compileCompareStrictEq):

  • jit/JIT.cpp:

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

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

(JSC::JITInByValGenerator::JITInByValGenerator):

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

(JSC::JSC_DEFINE_JIT_OPERATION):

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

(JSC::JIT::emit_op_in_by_val):
(JSC::JIT::emitHasPrivate):
(JSC::JIT::emitHasPrivateSlow):
(JSC::JIT::emit_op_has_private_name):
(JSC::JIT::emitSlow_op_has_private_name):
(JSC::JIT::emit_op_has_private_brand):
(JSC::JIT::emitSlow_op_has_private_brand):

  • jit/JITPropertyAccess32_64.cpp:

(JSC::JIT::emit_op_in_by_val):
(JSC::JIT::emitHasPrivate):
(JSC::JIT::emitHasPrivateSlow):
(JSC::JIT::emit_op_has_private_name):
(JSC::JIT::emitSlow_op_has_private_name):
(JSC::JIT::emit_op_has_private_brand):
(JSC::JIT::emitSlow_op_has_private_brand):

  • jit/Repatch.cpp:

(JSC::appropriateOptimizingInByFunction):
(JSC::appropriateGenericInByFunction):
(JSC::tryCacheInBy):
(JSC::repatchInBy):
(JSC::tryCacheHasPrivateBrand):
(JSC::repatchHasPrivateBrand):
(JSC::resetInBy):
(JSC::resetHasPrivateBrand):

  • jit/Repatch.h:
  • llint/LLIntSlowPaths.cpp:

(JSC::LLInt::LLINT_SLOW_PATH_DECL):

  • llint/LLIntSlowPaths.h:
  • llint/LowLevelInterpreter.asm:
  • runtime/CommonSlowPaths.cpp:
  • runtime/CommonSlowPaths.h:
  • runtime/OptionsList.h:
Location:
trunk
Files:
2 added
24 edited

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r279082 r279105  
     12021-06-21  Ross Kirsling  <ross.kirsling@sony.com>
     2
     3        [JSC] Add JIT ICs for `#x in obj` feature
     4        https://bugs.webkit.org/show_bug.cgi?id=226146
     5
     6        Reviewed by Saam Barati.
     7
     8        * microbenchmarks/has-private-brand.js: Added.
     9        * microbenchmarks/has-private-name.js: Added.
     10
    1112021-06-21  Xan Lopez  <xan@igalia.com>
    212
  • trunk/Source/JavaScriptCore/ChangeLog

    r279096 r279105  
     12021-06-21  Ross Kirsling  <ross.kirsling@sony.com>
     2
     3        [JSC] Add JIT ICs for `#x in obj` feature
     4        https://bugs.webkit.org/show_bug.cgi?id=226146
     5
     6        Reviewed by Saam Barati.
     7
     8        This patch implements JIT ICs for the new `#x in obj` feature and turns the feature on by default.
     9        Implementation closely follows InByVal, though HasPrivateBrand has a few subtleties
     10        (namely, it cannot be viewed in terms of a PropertySlot and should not be converted to InById).
     11
     12        Microbenchmarks:
     13            has-private-name        46.5777+-0.1374     ^      6.0589+-0.0296        ^ definitely 7.6875x faster
     14            has-private-brand       25.8823+-0.0561     ^     19.1509+-0.0447        ^ definitely 1.3515x faster
     15
     16        * bytecode/StructureStubInfo.cpp:
     17        (JSC::StructureStubInfo::reset):
     18        * bytecode/StructureStubInfo.h:
     19        * dfg/DFGByteCodeParser.cpp:
     20        (JSC::DFG::ByteCodeParser::handleInByAsMatchStructure):
     21        (JSC::DFG::ByteCodeParser::handleInById):
     22        (JSC::DFG::ByteCodeParser::parseBlock):
     23        * dfg/DFGSpeculativeJIT.cpp:
     24        (JSC::DFG::SpeculativeJIT::compileInByVal):
     25        (JSC::DFG::SpeculativeJIT::compileHasPrivate):
     26        (JSC::DFG::SpeculativeJIT::compileHasPrivateName):
     27        (JSC::DFG::SpeculativeJIT::compileHasPrivateBrand):
     28        * dfg/DFGSpeculativeJIT.h:
     29        * ftl/FTLLowerDFGToB3.cpp:
     30        (JSC::FTL::DFG::LowerDFGToB3::compileCompareStrictEq):
     31        * jit/JIT.cpp:
     32        (JSC::JIT::privateCompileMainPass):
     33        (JSC::JIT::privateCompileSlowCases):
     34        * jit/JIT.h:
     35        * jit/JITInlineCacheGenerator.cpp:
     36        (JSC::JITInByValGenerator::JITInByValGenerator):
     37        * jit/JITInlineCacheGenerator.h:
     38        * jit/JITOperations.cpp:
     39        (JSC::JSC_DEFINE_JIT_OPERATION):
     40        * jit/JITOperations.h:
     41        * jit/JITPropertyAccess.cpp:
     42        (JSC::JIT::emit_op_in_by_val):
     43        (JSC::JIT::emitHasPrivate):
     44        (JSC::JIT::emitHasPrivateSlow):
     45        (JSC::JIT::emit_op_has_private_name):
     46        (JSC::JIT::emitSlow_op_has_private_name):
     47        (JSC::JIT::emit_op_has_private_brand):
     48        (JSC::JIT::emitSlow_op_has_private_brand):
     49        * jit/JITPropertyAccess32_64.cpp:
     50        (JSC::JIT::emit_op_in_by_val):
     51        (JSC::JIT::emitHasPrivate):
     52        (JSC::JIT::emitHasPrivateSlow):
     53        (JSC::JIT::emit_op_has_private_name):
     54        (JSC::JIT::emitSlow_op_has_private_name):
     55        (JSC::JIT::emit_op_has_private_brand):
     56        (JSC::JIT::emitSlow_op_has_private_brand):
     57        * jit/Repatch.cpp:
     58        (JSC::appropriateOptimizingInByFunction):
     59        (JSC::appropriateGenericInByFunction):
     60        (JSC::tryCacheInBy):
     61        (JSC::repatchInBy):
     62        (JSC::tryCacheHasPrivateBrand):
     63        (JSC::repatchHasPrivateBrand):
     64        (JSC::resetInBy):
     65        (JSC::resetHasPrivateBrand):
     66        * jit/Repatch.h:
     67        * llint/LLIntSlowPaths.cpp:
     68        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
     69        * llint/LLIntSlowPaths.h:
     70        * llint/LowLevelInterpreter.asm:
     71        * runtime/CommonSlowPaths.cpp:
     72        * runtime/CommonSlowPaths.h:
     73        * runtime/OptionsList.h:
     74
    1752021-06-21  Don Olmstead  <don.olmstead@sony.com>
    276
  • trunk/Source/JavaScriptCore/bytecode/StructureStubInfo.cpp

    r278696 r279105  
    280280        resetInBy(codeBlock, *this, InByKind::ByVal);
    281281        break;
     282    case AccessType::HasPrivateName:
     283        resetInBy(codeBlock, *this, InByKind::PrivateName);
     284        break;
     285    case AccessType::HasPrivateBrand:
     286        resetHasPrivateBrand(codeBlock, *this);
     287        break;
    282288    case AccessType::InstanceOf:
    283289        resetInstanceOf(codeBlock, *this);
  • trunk/Source/JavaScriptCore/bytecode/StructureStubInfo.h

    r278656 r279105  
    5858    InById,
    5959    InByVal,
     60    HasPrivateName,
     61    HasPrivateBrand,
    6062    InstanceOf,
    6163    DeleteByID,
  • trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp

    r278696 r279105  
    265265        VirtualRegister destination, Node* base, CacheableIdentifier, unsigned identifierNumber, DeleteByStatus, ECMAMode);
    266266
     267    bool handleInByAsMatchStructure(VirtualRegister destination, Node* base, InByStatus);
    267268    void handleInById(VirtualRegister destination, Node* base, CacheableIdentifier, InByStatus);
    268269
     
    49424943}
    49434944
     4945bool ByteCodeParser::handleInByAsMatchStructure(VirtualRegister destination, Node* base, InByStatus status)
     4946{
     4947    if (!status.isSimple() || !Options::useAccessInlining())
     4948        return false;
     4949
     4950    bool allOK = true;
     4951    MatchStructureData* data = m_graph.m_matchStructureData.add();
     4952    for (const InByVariant& variant : status.variants()) {
     4953        if (!check(variant.conditionSet())) {
     4954            allOK = false;
     4955            break;
     4956        }
     4957        for (Structure* structure : variant.structureSet()) {
     4958            MatchStructureVariant matchVariant;
     4959            matchVariant.structure = m_graph.registerStructure(structure);
     4960            matchVariant.result = variant.isHit();
     4961
     4962            data->variants.append(WTFMove(matchVariant));
     4963        }
     4964    }
     4965
     4966    if (allOK) {
     4967        addToGraph(FilterInByStatus, OpInfo(m_graph.m_plan.recordedStatuses().addInByStatus(currentCodeOrigin(), status)), base);
     4968        set(destination, addToGraph(MatchStructure, OpInfo(data), base));
     4969    }
     4970
     4971    return allOK;
     4972}
     4973
    49444974void ByteCodeParser::handleInById(VirtualRegister destination, Node* base, CacheableIdentifier identifier, InByStatus status)
    49454975{
    4946     if (status.isSimple() && Options::useAccessInlining()) {
    4947         bool allOK = true;
    4948         MatchStructureData* data = m_graph.m_matchStructureData.add();
    4949         for (const InByVariant& variant : status.variants()) {
    4950             if (!check(variant.conditionSet())) {
    4951                 allOK = false;
    4952                 break;
    4953             }
    4954             for (Structure* structure : variant.structureSet()) {
    4955                 MatchStructureVariant matchVariant;
    4956                 matchVariant.structure = m_graph.registerStructure(structure);
    4957                 matchVariant.result = variant.isHit();
    4958 
    4959                 data->variants.append(WTFMove(matchVariant));
    4960             }
    4961         }
    4962 
    4963         if (allOK) {
    4964             addToGraph(FilterInByStatus, OpInfo(m_graph.m_plan.recordedStatuses().addInByStatus(currentCodeOrigin(), status)), base);
    4965             set(destination, addToGraph(MatchStructure, OpInfo(data), base));
    4966             return;
    4967         }
    4968     }
     4976    if (handleInByAsMatchStructure(destination, base, status))
     4977        return;
    49694978
    49704979    set(destination, addToGraph(InById, OpInfo(identifier), base));
     
    83058314       
    83068315        case op_has_private_name: {
    8307             // FIXME: Improve this once InByVal has been optimized.
    8308             // https://bugs.webkit.org/show_bug.cgi?id=226146
    83098316            auto bytecode = currentInstruction->as<OpHasPrivateName>();
    8310             set(bytecode.m_dst, addToGraph(HasPrivateName, get(bytecode.m_base), get(bytecode.m_property)));
     8317            Node* base = get(bytecode.m_base);
     8318            Node* property = get(bytecode.m_property);
     8319            bool compiledAsInById = false;
     8320
     8321            if (!m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadIdent)
     8322                && !m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadType)
     8323                && !m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadConstantValue)) {
     8324
     8325                InByStatus status = InByStatus::computeFor(
     8326                    m_inlineStackTop->m_profiledBlock, m_inlineStackTop->m_baselineMap,
     8327                    m_icContextStack, currentCodeOrigin());
     8328
     8329                if (CacheableIdentifier identifier = status.singleIdentifier()) {
     8330                    m_graph.identifiers().ensure(identifier.uid());
     8331                    ASSERT(identifier.isSymbolCell());
     8332                    FrozenValue* frozen = m_graph.freezeStrong(identifier.cell());
     8333                    addToGraph(CheckIsConstant, OpInfo(frozen), property);
     8334                    handleInById(bytecode.m_dst, base, identifier, status);
     8335                    compiledAsInById = true;
     8336                }
     8337            }
     8338
     8339            if (!compiledAsInById)
     8340                set(bytecode.m_dst, addToGraph(HasPrivateName, base, property));
    83118341            NEXT_OPCODE(op_has_private_name);
    83128342        }
    83138343
    83148344        case op_has_private_brand: {
    8315             // FIXME: Improve this once InByVal has been optimized.
    8316             // https://bugs.webkit.org/show_bug.cgi?id=226146
    83178345            auto bytecode = currentInstruction->as<OpHasPrivateBrand>();
    8318             set(bytecode.m_dst, addToGraph(HasPrivateBrand, get(bytecode.m_base), get(bytecode.m_brand)));
     8346            Node* base = get(bytecode.m_base);
     8347            Node* brand = get(bytecode.m_brand);
     8348            bool compiledAsMatchStructure = false;
     8349
     8350            if (!m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadIdent)
     8351                && !m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadType)
     8352                && !m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadConstantValue)) {
     8353
     8354                InByStatus status = InByStatus::computeFor(
     8355                    m_inlineStackTop->m_profiledBlock, m_inlineStackTop->m_baselineMap,
     8356                    m_icContextStack, currentCodeOrigin());
     8357
     8358                if (CacheableIdentifier identifier = status.singleIdentifier()) {
     8359                    m_graph.identifiers().ensure(identifier.uid());
     8360                    ASSERT(identifier.isSymbolCell());
     8361                    FrozenValue* frozen = m_graph.freezeStrong(identifier.cell());
     8362                    addToGraph(CheckIsConstant, OpInfo(frozen), brand);
     8363                    compiledAsMatchStructure = handleInByAsMatchStructure(bytecode.m_dst, base, status);
     8364                }
     8365            }
     8366
     8367            if (!compiledAsMatchStructure)
     8368                set(bytecode.m_dst, addToGraph(HasPrivateBrand, base, brand));
    83198369            NEXT_OPCODE(op_has_private_brand);
    83208370        }
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp

    r279052 r279105  
    13511351            slowCases, this, gen.stubInfo(), stubInfoGPR, CCallHelpers::Address(stubInfoGPR, StructureStubInfo::offsetOfSlowOperation()), operationInByIdOptimize,
    13521352            NeedToSpill, ExceptionCheckRequirement::CheckNeeded,
    1353             resultRegs, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), stubInfoGPR, CCallHelpers::CellValue(baseGPR), node->cacheableIdentifier().rawBits());
     1353            resultRegs, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(codeOrigin)), stubInfoGPR, CCallHelpers::CellValue(baseGPR), node->cacheableIdentifier().rawBits());
    13541354    } else {
    13551355        slowPath = slowPathCall(
    13561356            slowCases, this, operationInByIdOptimize,
    13571357            NeedToSpill, ExceptionCheckRequirement::CheckNeeded,
    1358             resultRegs, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), gen.stubInfo(), CCallHelpers::CellValue(baseGPR), node->cacheableIdentifier().rawBits());
     1358            resultRegs, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(codeOrigin)), gen.stubInfo(), CCallHelpers::CellValue(baseGPR), node->cacheableIdentifier().rawBits());
    13591359    }
    13601360
     
    13901390    RegisterSet usedRegisters = this->usedRegisters();
    13911391    JITInByValGenerator gen(
    1392         m_jit.codeBlock(), JITType::DFGJIT, codeOrigin, callSite, usedRegisters,
     1392        m_jit.codeBlock(), JITType::DFGJIT, codeOrigin, callSite, AccessType::InByVal, usedRegisters,
    13931393        JSValueRegs::payloadOnly(baseGPR), keyRegs, resultRegs, stubInfoGPR);
    13941394    gen.generateFastPath(m_jit);
     
    14011401            slowCases, this, gen.stubInfo(), stubInfoGPR, CCallHelpers::Address(stubInfoGPR, StructureStubInfo::offsetOfSlowOperation()), operationInByValOptimize,
    14021402            NeedToSpill, ExceptionCheckRequirement::CheckNeeded,
    1403             resultRegs, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), stubInfoGPR, nullptr, CCallHelpers::CellValue(baseGPR), keyRegs);
     1403            resultRegs, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(codeOrigin)), stubInfoGPR, nullptr, CCallHelpers::CellValue(baseGPR), keyRegs);
    14041404    } else {
    14051405        slowPath = slowPathCall(
    14061406            slowCases, this, operationInByValOptimize,
    14071407            NeedToSpill, ExceptionCheckRequirement::CheckNeeded,
    1408             resultRegs, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), gen.stubInfo(), nullptr, CCallHelpers::CellValue(baseGPR), keyRegs);
     1408            resultRegs, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(codeOrigin)), gen.stubInfo(), nullptr, CCallHelpers::CellValue(baseGPR), keyRegs);
    14091409    }
    14101410
     
    14151415}
    14161416
     1417void SpeculativeJIT::compileHasPrivate(Node* node, AccessType type)
     1418{
     1419    SpeculateCellOperand base(this, node->child1());
     1420    SpeculateCellOperand propertyOrBrand(this, node->child2());
     1421    JSValueRegsTemporary result(this, Reuse, base);
     1422    std::optional<GPRTemporary> stubInfo;
     1423
     1424    GPRReg stubInfoGPR = InvalidGPRReg;
     1425    if (JITCode::useDataIC(JITType::DFGJIT)) {
     1426        stubInfo.emplace(this);
     1427        stubInfoGPR = stubInfo->gpr();
     1428    }
     1429    GPRReg baseGPR = base.gpr();
     1430    GPRReg propertyOrBrandGPR = propertyOrBrand.gpr();
     1431    JSValueRegs resultRegs = result.regs();
     1432
     1433    speculateSymbol(node->child2(), propertyOrBrandGPR);
     1434
     1435    base.use();
     1436    propertyOrBrand.use();
     1437
     1438    CCallHelpers::JumpList slowCases;
     1439
     1440    CodeOrigin codeOrigin = node->origin.semantic;
     1441    CallSiteIndex callSite = m_jit.recordCallSiteAndGenerateExceptionHandlingOSRExitIfNeeded(codeOrigin, m_stream->size());
     1442    RegisterSet usedRegisters = this->usedRegisters();
     1443    JITInByValGenerator gen(
     1444        m_jit.codeBlock(), JITType::DFGJIT, codeOrigin, callSite, type, usedRegisters,
     1445        JSValueRegs::payloadOnly(baseGPR), JSValueRegs::payloadOnly(propertyOrBrandGPR), resultRegs, stubInfoGPR);
     1446
     1447    gen.stubInfo()->propertyIsSymbol = true;
     1448    gen.generateFastPath(m_jit);
     1449    if (!JITCode::useDataIC(JITType::DFGJIT))
     1450        slowCases.append(gen.slowPathJump());
     1451
     1452    std::unique_ptr<SlowPathGenerator> slowPath;
     1453    if (JITCode::useDataIC(JITType::DFGJIT)) {
     1454        slowPath = slowPathICCall(
     1455            slowCases, this, gen.stubInfo(), stubInfoGPR, CCallHelpers::Address(stubInfoGPR, StructureStubInfo::offsetOfSlowOperation()), type == AccessType::HasPrivateName ? operationHasPrivateNameOptimize : operationHasPrivateBrandOptimize,
     1456            NeedToSpill, ExceptionCheckRequirement::CheckNeeded,
     1457            resultRegs, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(codeOrigin)), stubInfoGPR, CCallHelpers::CellValue(baseGPR), CCallHelpers::CellValue(propertyOrBrandGPR));
     1458    } else {
     1459        slowPath = slowPathCall(
     1460            slowCases, this, type == AccessType::HasPrivateName ? operationHasPrivateNameOptimize : operationHasPrivateBrandOptimize,
     1461            NeedToSpill, ExceptionCheckRequirement::CheckNeeded,
     1462            resultRegs, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(codeOrigin)), gen.stubInfo(), CCallHelpers::CellValue(baseGPR), CCallHelpers::CellValue(propertyOrBrandGPR));
     1463    }
     1464
     1465    m_jit.addInByVal(gen, slowPath.get());
     1466    addSlowPathGenerator(WTFMove(slowPath));
     1467
     1468    blessedBooleanResult(resultRegs.payloadGPR(), node, UseChildrenCalledExplicitly);
     1469}
     1470
    14171471void SpeculativeJIT::compileHasPrivateName(Node* node)
    14181472{
    1419     SpeculateCellOperand base(this, node->child1());
    1420     SpeculateCellOperand key(this, node->child2());
    1421 
    1422     GPRReg baseGPR = base.gpr();
    1423     GPRReg keyGPR = key.gpr();
    1424 
    1425     speculateSymbol(node->child2(), keyGPR);
    1426 
    1427     base.use();
    1428     key.use();
    1429 
    1430     flushRegisters();
    1431     JSValueRegsFlushedCallResult result(this);
    1432     JSValueRegs resultRegs = result.regs();
    1433     callOperation(operationHasPrivateName, resultRegs, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), baseGPR, CCallHelpers::CellValue(keyGPR));
    1434     m_jit.exceptionCheck();
    1435     blessedBooleanResult(resultRegs.payloadGPR(), node, UseChildrenCalledExplicitly);
     1473    compileHasPrivate(node, AccessType::HasPrivateName);
    14361474}
    14371475
    14381476void SpeculativeJIT::compileHasPrivateBrand(Node* node)
    14391477{
    1440     SpeculateCellOperand base(this, node->child1());
    1441     SpeculateCellOperand brand(this, node->child2());
    1442 
    1443     GPRReg baseGPR = base.gpr();
    1444     GPRReg brandGPR = brand.gpr();
    1445 
    1446     speculateSymbol(node->child2(), brandGPR);
    1447 
    1448     base.use();
    1449     brand.use();
    1450 
    1451     flushRegisters();
    1452     JSValueRegsFlushedCallResult result(this);
    1453     JSValueRegs resultRegs = result.regs();
    1454     callOperation(operationHasPrivateBrand, resultRegs, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), baseGPR, CCallHelpers::CellValue(brandGPR));
    1455     m_jit.exceptionCheck();
    1456     blessedBooleanResult(resultRegs.payloadGPR(), node, UseChildrenCalledExplicitly);
     1478    compileHasPrivate(node, AccessType::HasPrivateBrand);
    14571479}
    14581480
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h

    r279041 r279105  
    739739    void compileInById(Node*);
    740740    void compileInByVal(Node*);
     741    void compileHasPrivate(Node*, AccessType);
    741742    void compileHasPrivateName(Node*);
    742743    void compileHasPrivateBrand(Node*);
    743    
     744
    744745    void nonSpeculativeNonPeepholeCompareNullOrUndefined(Edge operand);
    745746    void nonSpeculativePeepholeBranchNullOrUndefined(Edge operand, Node* branchNode);
  • trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp

    r279029 r279105  
    1242112421    }
    1242212422
    12423     void compileHasPrivateName()
    12424     {
    12425         JSGlobalObject* globalObject = m_graph.globalObjectFor(m_origin.semantic);
    12426         setJSValue(vmCall(Int64, operationHasPrivateName, weakPointer(globalObject), lowCell(m_node->child1()), lowSymbol(m_node->child2())));
    12427     }
    12428 
    12429     void compileHasPrivateBrand()
    12430     {
    12431         JSGlobalObject* globalObject = m_graph.globalObjectFor(m_origin.semantic);
    12432         setJSValue(vmCall(Int64, operationHasPrivateBrand, weakPointer(globalObject), lowCell(m_node->child1()), lowSymbol(m_node->child2())));
    12433     }
    12434 
    12435     template<InByKind kind, typename SubscriptKind>
     12423    template<AccessType type, typename SubscriptKind>
    1243612424    void compileInBy(LValue base, SubscriptKind subscriptValue)
    1243712425    {
     12426        static_assert(type == AccessType::InById || type == AccessType::InByVal || type == AccessType::HasPrivateName || type == AccessType::HasPrivateBrand);
    1243812427        PatchpointValue* patchpoint = m_out.patchpoint(Int64);
    1243912428        patchpoint->appendSomeRegister(base);
    12440         if constexpr (kind != InByKind::ById)
     12429        if constexpr (type != AccessType::InById)
    1244112430            patchpoint->appendSomeRegister(subscriptValue);
    1244212431        patchpoint->append(m_notCellMask, ValueRep::lateReg(GPRInfo::notCellMaskRegister));
     
    1246312452                auto base = JSValueRegs(params[1].gpr());
    1246412453
     12454                constexpr auto optimizationFunction = [&] () {
     12455                    if constexpr (type == AccessType::InById)
     12456                        return operationInByIdOptimize;
     12457                    else if constexpr (type == AccessType::InByVal)
     12458                        return operationInByValOptimize;
     12459                    else if constexpr (type == AccessType::HasPrivateName)
     12460                        return operationHasPrivateNameOptimize;
     12461                    else {
     12462                        static_assert(type == AccessType::HasPrivateBrand);
     12463                        return operationHasPrivateBrandOptimize;
     12464                    }
     12465                }();
     12466
    1246512467                const auto subscript = [&] {
    12466                     if constexpr (kind == InByKind::ById)
     12468                    if constexpr (type == AccessType::InById)
    1246712469                        return CCallHelpers::TrustedImmPtr(subscriptValue.rawBits());
    1246812470                    else
     
    1247112473
    1247212474                const auto generator = [&] {
    12473                     if constexpr (kind == InByKind::ById) {
     12475                    if constexpr (type == AccessType::InById) {
    1247412476                        return Box<JITInByIdGenerator>::create(
    1247512477                            jit.codeBlock(), JITType::FTLJIT, semanticNodeOrigin, callSiteIndex,
     
    1247912481                        return Box<JITInByValGenerator>::create(
    1248012482                            jit.codeBlock(), JITType::FTLJIT, semanticNodeOrigin, callSiteIndex,
    12481                             params.unavailableRegisters(), base, subscript,
     12483                            type, params.unavailableRegisters(), base, subscript,
    1248212484                            JSValueRegs(returnGPR), stubInfoGPR);
    1248312485                    }
     
    1248612488                CCallHelpers::JumpList slowCases;
    1248712489                generator->generateFastPath(jit);
    12488                 if constexpr (kind == InByKind::ById)
     12490                if constexpr (type == AccessType::InById)
    1248912491                    slowCases.append(generator->slowPathJump());
    1249012492                else {
     
    1250112503                        CCallHelpers::Label slowPathBegin = jit.label();
    1250212504                        CCallHelpers::Call slowPathCall;
    12503                         if constexpr (kind == InByKind::ById) {
     12505                        if constexpr (type != AccessType::InByVal) {
    1250412506                            if (JITCode::useDataIC(JITType::FTLJIT)) {
    1250512507                                jit.move(CCallHelpers::TrustedImmPtr(generator->stubInfo()), stubInfoGPR);
    12506                                 generator->stubInfo()->m_slowOperation = operationInByIdOptimize;
     12508                                generator->stubInfo()->m_slowOperation = optimizationFunction;
    1250712509                                slowPathCall = callOperation(
    1250812510                                    *state, params.unavailableRegisters(), jit, semanticNodeOrigin,
     
    1251312515                                slowPathCall = callOperation(
    1251412516                                    *state, params.unavailableRegisters(), jit, semanticNodeOrigin,
    12515                                     exceptions.get(), operationInByIdOptimize, returnGPR,
     12517                                    exceptions.get(), optimizationFunction, returnGPR,
    1251612518                                    jit.codeBlock()->globalObjectFor(semanticNodeOrigin),
    1251712519                                    CCallHelpers::TrustedImmPtr(generator->stubInfo()), base, subscript).call();
     
    1252012522                            if (JITCode::useDataIC(JITType::FTLJIT)) {
    1252112523                                jit.move(CCallHelpers::TrustedImmPtr(generator->stubInfo()), stubInfoGPR);
    12522                                 generator->stubInfo()->m_slowOperation = operationInByValOptimize;
     12524                                generator->stubInfo()->m_slowOperation = optimizationFunction;
    1252312525                                slowPathCall = callOperation(
    1252412526                                    *state, params.unavailableRegisters(), jit, semanticNodeOrigin,
     
    1253012532                                slowPathCall = callOperation(
    1253112533                                    *state, params.unavailableRegisters(), jit, semanticNodeOrigin,
    12532                                     exceptions.get(), operationInByValOptimize, returnGPR,
     12534                                    exceptions.get(), optimizationFunction, returnGPR,
    1253312535                                    jit.codeBlock()->globalObjectFor(semanticNodeOrigin),
    1253412536                                    CCallHelpers::TrustedImmPtr(generator->stubInfo()),
     
    1255212554    void compileInById()
    1255312555    {
    12554         compileInBy<InByKind::ById>(lowCell(m_node->child1()), m_node->cacheableIdentifier());
     12556        compileInBy<AccessType::InById>(lowCell(m_node->child1()), m_node->cacheableIdentifier());
    1255512557    }
    1255612558
    1255712559    void compileInByVal()
    1255812560    {
    12559         compileInBy<InByKind::ByVal>(lowCell(m_node->child1()), lowJSValue(m_node->child2()));
     12561        compileInBy<AccessType::InByVal>(lowCell(m_node->child1()), lowJSValue(m_node->child2()));
     12562    }
     12563
     12564    void compileHasPrivateName()
     12565    {
     12566        compileInBy<AccessType::HasPrivateName>(lowCell(m_node->child1()), lowSymbol(m_node->child2()));
     12567    }
     12568
     12569    void compileHasPrivateBrand()
     12570    {
     12571        compileInBy<AccessType::HasPrivateBrand>(lowCell(m_node->child1()), lowSymbol(m_node->child2()));
    1256012572    }
    1256112573
  • trunk/Source/JavaScriptCore/jit/JIT.cpp

    r279049 r279105  
    286286
    287287        switch (opcodeID) {
    288         DEFINE_SLOW_OP(has_private_name)
    289         DEFINE_SLOW_OP(has_private_brand)
    290288        DEFINE_SLOW_OP(less)
    291289        DEFINE_SLOW_OP(lesseq)
     
    362360        DEFINE_OP(op_in_by_id)
    363361        DEFINE_OP(op_in_by_val)
     362        DEFINE_OP(op_has_private_name)
     363        DEFINE_OP(op_has_private_brand)
    364364        DEFINE_OP(op_get_by_id)
    365365        DEFINE_OP(op_get_by_id_with_this)
     
    573573        DEFINE_SLOWCASE_OP(op_in_by_id)
    574574        DEFINE_SLOWCASE_OP(op_in_by_val)
     575        DEFINE_SLOWCASE_OP(op_has_private_name)
     576        DEFINE_SLOWCASE_OP(op_has_private_brand)
    575577        DEFINE_SLOWCASE_OP(op_get_by_id)
    576578        DEFINE_SLOWCASE_OP(op_get_by_id_with_this)
  • trunk/Source/JavaScriptCore/jit/JIT.h

    r279049 r279105  
    572572        void emit_op_in_by_id(const Instruction*);
    573573        void emit_op_in_by_val(const Instruction*);
     574        void emit_op_has_private_name(const Instruction*);
     575        void emit_op_has_private_brand(const Instruction*);
    574576        void emit_op_init_lazy_reg(const Instruction*);
    575577        void emit_op_overrides_has_instance(const Instruction*);
     
    706708        void emitSlow_op_in_by_id(const Instruction*, Vector<SlowCaseEntry>::iterator&);
    707709        void emitSlow_op_in_by_val(const Instruction*, Vector<SlowCaseEntry>::iterator&);
     710        void emitSlow_op_has_private_name(const Instruction*, Vector<SlowCaseEntry>::iterator&);
     711        void emitSlow_op_has_private_brand(const Instruction*, Vector<SlowCaseEntry>::iterator&);
    708712        void emitSlow_op_instanceof(const Instruction*, Vector<SlowCaseEntry>::iterator&);
    709713        void emitSlow_op_instanceof_custom(const Instruction*, Vector<SlowCaseEntry>::iterator&);
     
    754758        void emitRightShiftSlowCase(const Instruction*, Vector<SlowCaseEntry>::iterator&, bool isUnsigned);
    755759
     760        void emitHasPrivate(VirtualRegister dst, VirtualRegister base, VirtualRegister propertyOrBrand, AccessType);
     761        void emitHasPrivateSlow(VirtualRegister dst, AccessType);
     762
    756763        template<typename Op>
    757764        void emitNewFuncCommon(const Instruction*);
  • trunk/Source/JavaScriptCore/jit/JITInlineCacheGenerator.cpp

    r278698 r279105  
    250250}
    251251
    252 JITInByValGenerator::JITInByValGenerator(CodeBlock* codeBlock, JITType jitType, CodeOrigin codeOrigin, CallSiteIndex callSiteIndex, const RegisterSet& usedRegisters, JSValueRegs base, JSValueRegs property, JSValueRegs result, GPRReg stubInfoGPR)
    253     : Base(codeBlock, jitType, codeOrigin, callSiteIndex, AccessType::InByVal, usedRegisters)
     252JITInByValGenerator::JITInByValGenerator(CodeBlock* codeBlock, JITType jitType, CodeOrigin codeOrigin, CallSiteIndex callSiteIndex, AccessType accessType, const RegisterSet& usedRegisters, JSValueRegs base, JSValueRegs property, JSValueRegs result, GPRReg stubInfoGPR)
     253    : Base(codeBlock, jitType, codeOrigin, callSiteIndex, accessType, usedRegisters)
    254254{
    255255    m_stubInfo->hasConstantIdentifier = false;
  • trunk/Source/JavaScriptCore/jit/JITInlineCacheGenerator.h

    r278656 r279105  
    203203
    204204    JITInByValGenerator(
    205         CodeBlock*, JITType, CodeOrigin, CallSiteIndex, const RegisterSet& usedRegisters,
     205        CodeBlock*, JITType, CodeOrigin, CallSiteIndex, AccessType, const RegisterSet& usedRegisters,
    206206        JSValueRegs base, JSValueRegs property, JSValueRegs result, GPRReg stubInfoGPR);
    207207
  • trunk/Source/JavaScriptCore/jit/JITOperations.cpp

    r278696 r279105  
    509509}
    510510
    511 JSC_DEFINE_JIT_OPERATION(operationHasPrivateName, EncodedJSValue, (JSGlobalObject* globalObject, JSCell* base, EncodedJSValue key))
     511JSC_DEFINE_JIT_OPERATION(operationHasPrivateNameOptimize, EncodedJSValue, (JSGlobalObject* globalObject, StructureStubInfo* stubInfo, EncodedJSValue encodedBase, EncodedJSValue encodedProperty))
    512512{
    513513    SuperSamplerScope superSamplerScope(false);
    514    
    515     VM& vm = globalObject->vm();
    516     CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
    517     JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
    518 
    519     auto scope = DECLARE_THROW_SCOPE(vm);
    520     if (!base->isObject()) {
    521         throwException(globalObject, scope, createInvalidInParameterError(globalObject, base));
     514
     515    VM& vm = globalObject->vm();
     516    CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
     517    JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
     518    auto scope = DECLARE_THROW_SCOPE(vm);
     519
     520    JSValue baseValue = JSValue::decode(encodedBase);
     521    if (!baseValue.isObject()) {
     522        throwException(globalObject, scope, createInvalidInParameterError(globalObject, baseValue));
    522523        return encodedJSValue();
    523524    }
    524 
    525     JSValue propertyValue = JSValue::decode(key);
     525    JSObject* baseObject = asObject(baseValue);
     526
     527    JSValue propertyValue = JSValue::decode(encodedProperty);
    526528    ASSERT(propertyValue.isSymbol());
    527529    auto property = propertyValue.toPropertyKey(globalObject);
    528530    EXCEPTION_ASSERT(!scope.exception());
    529531
    530     return JSValue::encode(jsBoolean(asObject(base)->hasPrivateField(globalObject, property)));
    531 }
    532 
    533 JSC_DEFINE_JIT_OPERATION(operationHasPrivateBrand, EncodedJSValue, (JSGlobalObject* globalObject, JSCell* base, EncodedJSValue brand))
     532    PropertySlot slot(baseObject, PropertySlot::InternalMethodType::HasProperty);
     533    bool found = JSObject::getPrivateFieldSlot(baseObject, globalObject, property, slot);
     534
     535    ASSERT(CacheableIdentifier::isCacheableIdentifierCell(propertyValue));
     536    CodeBlock* codeBlock = callFrame->codeBlock();
     537    CacheableIdentifier identifier = CacheableIdentifier::createFromCell(propertyValue.asCell());
     538    if (stubInfo->considerCachingBy(vm, codeBlock, baseObject->structure(vm), identifier))
     539        repatchInBy(globalObject, codeBlock, baseObject, identifier, found, slot, *stubInfo, InByKind::PrivateName);
     540
     541    return JSValue::encode(jsBoolean(found));
     542}
     543
     544JSC_DEFINE_JIT_OPERATION(operationHasPrivateNameGeneric, EncodedJSValue, (JSGlobalObject* globalObject, StructureStubInfo* stubInfo, EncodedJSValue encodedBase, EncodedJSValue encodedProperty))
    534545{
    535546    SuperSamplerScope superSamplerScope(false);
    536    
    537     VM& vm = globalObject->vm();
    538     CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
    539     JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
    540 
    541     auto scope = DECLARE_THROW_SCOPE(vm);
    542     if (!base->isObject()) {
    543         throwException(globalObject, scope, createInvalidInParameterError(globalObject, base));
     547
     548    VM& vm = globalObject->vm();
     549    CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
     550    JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
     551    auto scope = DECLARE_THROW_SCOPE(vm);
     552
     553    stubInfo->tookSlowPath = true;
     554
     555    JSValue baseValue = JSValue::decode(encodedBase);
     556    if (!baseValue.isObject()) {
     557        throwException(globalObject, scope, createInvalidInParameterError(globalObject, baseValue));
    544558        return encodedJSValue();
    545559    }
    546560
    547     return JSValue::encode(jsBoolean(asObject(base)->hasPrivateBrand(globalObject, JSValue::decode(brand))));
     561    JSValue propertyValue = JSValue::decode(encodedProperty);
     562    ASSERT(propertyValue.isSymbol());
     563    auto property = propertyValue.toPropertyKey(globalObject);
     564    EXCEPTION_ASSERT(!scope.exception());
     565
     566    return JSValue::encode(jsBoolean(asObject(baseValue)->hasPrivateField(globalObject, property)));
     567}
     568
     569JSC_DEFINE_JIT_OPERATION(operationHasPrivateBrandOptimize, EncodedJSValue, (JSGlobalObject* globalObject, StructureStubInfo* stubInfo, EncodedJSValue encodedBase, EncodedJSValue encodedBrand))
     570{
     571    SuperSamplerScope superSamplerScope(false);
     572
     573    VM& vm = globalObject->vm();
     574    CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
     575    JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
     576    auto scope = DECLARE_THROW_SCOPE(vm);
     577
     578    JSValue baseValue = JSValue::decode(encodedBase);
     579    if (!baseValue.isObject()) {
     580        throwException(globalObject, scope, createInvalidInParameterError(globalObject, baseValue));
     581        return encodedJSValue();
     582    }
     583    JSObject* baseObject = asObject(baseValue);
     584
     585    JSValue brand = JSValue::decode(encodedBrand);
     586    bool found = asObject(baseValue)->hasPrivateBrand(globalObject, brand);
     587
     588    ASSERT(CacheableIdentifier::isCacheableIdentifierCell(brand));
     589    CodeBlock* codeBlock = callFrame->codeBlock();
     590    CacheableIdentifier identifier = CacheableIdentifier::createFromCell(brand.asCell());
     591    if (stubInfo->considerCachingBy(vm, codeBlock, baseObject->structure(vm), identifier))
     592        repatchHasPrivateBrand(globalObject, codeBlock, baseObject, identifier, found, *stubInfo);
     593
     594    return JSValue::encode(jsBoolean(found));
     595}
     596
     597JSC_DEFINE_JIT_OPERATION(operationHasPrivateBrandGeneric, EncodedJSValue, (JSGlobalObject* globalObject, StructureStubInfo* stubInfo, EncodedJSValue encodedBase, EncodedJSValue encodedBrand))
     598{
     599    SuperSamplerScope superSamplerScope(false);
     600
     601    VM& vm = globalObject->vm();
     602    CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
     603    JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
     604    auto scope = DECLARE_THROW_SCOPE(vm);
     605
     606    stubInfo->tookSlowPath = true;
     607
     608    JSValue baseValue = JSValue::decode(encodedBase);
     609    if (!baseValue.isObject()) {
     610        throwException(globalObject, scope, createInvalidInParameterError(globalObject, baseValue));
     611        return encodedJSValue();
     612    }
     613
     614    return JSValue::encode(jsBoolean(asObject(baseValue)->hasPrivateBrand(globalObject, JSValue::decode(encodedBrand))));
    548615}
    549616
  • trunk/Source/JavaScriptCore/jit/JITOperations.h

    r278445 r279105  
    179179JSC_DECLARE_JIT_OPERATION(operationInByValGeneric, EncodedJSValue, (JSGlobalObject*, StructureStubInfo*, ArrayProfile*, EncodedJSValue, EncodedJSValue));
    180180JSC_DECLARE_JIT_OPERATION(operationInByValOptimize, EncodedJSValue, (JSGlobalObject*, StructureStubInfo*, ArrayProfile*, EncodedJSValue, EncodedJSValue));
    181 JSC_DECLARE_JIT_OPERATION(operationHasPrivateName, EncodedJSValue, (JSGlobalObject*, JSCell*, EncodedJSValue));
    182 JSC_DECLARE_JIT_OPERATION(operationHasPrivateBrand, EncodedJSValue, (JSGlobalObject*, JSCell*, EncodedJSValue));
     181JSC_DECLARE_JIT_OPERATION(operationHasPrivateNameGeneric, EncodedJSValue, (JSGlobalObject*, StructureStubInfo*, EncodedJSValue, EncodedJSValue));
     182JSC_DECLARE_JIT_OPERATION(operationHasPrivateNameOptimize, EncodedJSValue, (JSGlobalObject*, StructureStubInfo*, EncodedJSValue, EncodedJSValue));
     183JSC_DECLARE_JIT_OPERATION(operationHasPrivateBrandGeneric, EncodedJSValue, (JSGlobalObject*, StructureStubInfo*, EncodedJSValue, EncodedJSValue));
     184JSC_DECLARE_JIT_OPERATION(operationHasPrivateBrandOptimize, EncodedJSValue, (JSGlobalObject*, StructureStubInfo*, EncodedJSValue, EncodedJSValue));
    183185
    184186JSC_DECLARE_JIT_OPERATION(operationPutByIdStrict, void, (JSGlobalObject*, StructureStubInfo*, EncodedJSValue encodedValue, EncodedJSValue encodedBase, uintptr_t));
  • trunk/Source/JavaScriptCore/jit/JITPropertyAccess.cpp

    r278656 r279105  
    17111711
    17121712    JITInByValGenerator gen(
    1713         m_codeBlock, JITType::BaselineJIT, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), RegisterSet::stubUnavailableRegisters(),
     1713        m_codeBlock, JITType::BaselineJIT, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), AccessType::InByVal, RegisterSet::stubUnavailableRegisters(),
    17141714        JSValueRegs(regT0), JSValueRegs(regT1), JSValueRegs(regT0), regT2);
    17151715    gen.generateFastPath(*this);
     
    17711771
    17721772    gen.reportSlowPathCall(coldPathBegin, call);
     1773}
     1774
     1775void JIT::emitHasPrivate(VirtualRegister dst, VirtualRegister base, VirtualRegister propertyOrBrand, AccessType type)
     1776{
     1777    emitGetVirtualRegister(base, regT0);
     1778    emitJumpSlowCaseIfNotJSCell(regT0, base);
     1779    emitGetVirtualRegister(propertyOrBrand, regT1);
     1780
     1781    JITInByValGenerator gen(
     1782        m_codeBlock, JITType::BaselineJIT, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), type, RegisterSet::stubUnavailableRegisters(),
     1783        JSValueRegs(regT0), JSValueRegs(regT1), JSValueRegs(regT0), regT2);
     1784    gen.generateFastPath(*this);
     1785    if (!JITCode::useDataIC(JITType::BaselineJIT))
     1786        addSlowCase(gen.slowPathJump());
     1787    else
     1788        addSlowCase();
     1789    m_inByVals.append(gen);
     1790
     1791    emitPutVirtualRegister(dst);
     1792}
     1793
     1794void JIT::emitHasPrivateSlow(VirtualRegister dst, AccessType type)
     1795{
     1796    ASSERT(type == AccessType::HasPrivateName || type == AccessType::HasPrivateBrand);
     1797
     1798    JITInByValGenerator& gen = m_inByVals[m_inByValIndex++];
     1799    Label coldPathBegin = label();
     1800
     1801#if !ENABLE(EXTRA_CTI_THUNKS)
     1802    Call call = callOperation(type == AccessType::HasPrivateName ? operationHasPrivateNameOptimize : operationHasPrivateBrandOptimize, dst, TrustedImmPtr(m_codeBlock->globalObject()), gen.stubInfo(), regT0, regT1);
     1803#else
     1804    VM& vm = this->vm();
     1805    uint32_t bytecodeOffset = m_bytecodeIndex.offset();
     1806    ASSERT(BytecodeIndex(bytecodeOffset) == m_bytecodeIndex);
     1807
     1808    constexpr GPRReg bytecodeOffsetGPR = argumentGPR3;
     1809    move(TrustedImm32(bytecodeOffset), bytecodeOffsetGPR);
     1810
     1811    constexpr GPRReg stubInfoGPR = argumentGPR2;
     1812    constexpr GPRReg baseGPR = regT0;
     1813    constexpr GPRReg propertyOrBrandGPR = regT1;
     1814    static_assert(baseGPR == argumentGPR0 || !isARM64());
     1815    static_assert(propertyOrBrandGPR == argumentGPR1);
     1816
     1817    move(TrustedImmPtr(gen.stubInfo()), stubInfoGPR);
     1818    static_assert(std::is_same<decltype(operationHasPrivateNameOptimize), decltype(operationGetPrivateNameOptimize)>::value);
     1819    static_assert(std::is_same<decltype(operationHasPrivateBrandOptimize), decltype(operationGetPrivateNameOptimize)>::value);
     1820    emitNakedNearCall(vm.getCTIStub(slow_op_get_private_name_prepareCallGenerator).retaggedCode<NoPtrTag>());
     1821
     1822    Call call;
     1823    if (JITCode::useDataIC(JITType::BaselineJIT))
     1824        gen.stubInfo()->m_slowOperation = type == AccessType::HasPrivateName ? operationHasPrivateNameOptimize : operationHasPrivateBrandOptimize;
     1825    else
     1826        call = appendCall(type == AccessType::HasPrivateName ? operationHasPrivateNameOptimize : operationHasPrivateBrandOptimize);
     1827    emitNakedNearCall(vm.getCTIStub(checkExceptionGenerator).retaggedCode<NoPtrTag>());
     1828
     1829    emitPutVirtualRegister(dst, returnValueGPR);
     1830#endif // ENABLE(EXTRA_CTI_THUNKS)
     1831
     1832    gen.reportSlowPathCall(coldPathBegin, call);
     1833}
     1834
     1835void JIT::emit_op_has_private_name(const Instruction* currentInstruction)
     1836{
     1837    auto bytecode = currentInstruction->as<OpHasPrivateName>();
     1838    emitHasPrivate(bytecode.m_dst, bytecode.m_base, bytecode.m_property, AccessType::HasPrivateName);
     1839}
     1840
     1841void JIT::emitSlow_op_has_private_name(const Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
     1842{
     1843    linkAllSlowCases(iter);
     1844
     1845    auto bytecode = currentInstruction->as<OpHasPrivateName>();
     1846    emitHasPrivateSlow(bytecode.m_dst, AccessType::HasPrivateName);
     1847}
     1848
     1849void JIT::emit_op_has_private_brand(const Instruction* currentInstruction)
     1850{
     1851    auto bytecode = currentInstruction->as<OpHasPrivateBrand>();
     1852    emitHasPrivate(bytecode.m_dst, bytecode.m_base, bytecode.m_brand, AccessType::HasPrivateBrand);
     1853}
     1854
     1855void JIT::emitSlow_op_has_private_brand(const Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
     1856{
     1857    linkAllSlowCases(iter);
     1858
     1859    auto bytecode = currentInstruction->as<OpHasPrivateBrand>();
     1860    emitHasPrivateSlow(bytecode.m_dst, AccessType::HasPrivateBrand);
    17731861}
    17741862
  • trunk/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp

    r278656 r279105  
    925925
    926926    JITInByValGenerator gen(
    927         m_codeBlock, JITType::BaselineJIT, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), RegisterSet::stubUnavailableRegisters(),
     927        m_codeBlock, JITType::BaselineJIT, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), AccessType::InByVal, RegisterSet::stubUnavailableRegisters(),
    928928        JSValueRegs::payloadOnly(regT0), JSValueRegs(regT3, regT2), JSValueRegs(regT1, regT0), InvalidGPRReg);
    929929    gen.generateFastPath(*this);
     
    950950
    951951    gen.reportSlowPathCall(coldPathBegin, call);
     952}
     953
     954void JIT::emitHasPrivate(VirtualRegister dst, VirtualRegister base, VirtualRegister propertyOrBrand, AccessType type)
     955{
     956    emitLoad2(base, regT1, regT0, propertyOrBrand, regT3, regT2);
     957    emitJumpSlowCaseIfNotJSCell(base, regT1);
     958
     959    JITInByValGenerator gen(
     960        m_codeBlock, JITType::BaselineJIT, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), type, RegisterSet::stubUnavailableRegisters(),
     961        JSValueRegs::payloadOnly(regT0), JSValueRegs(regT3, regT2), JSValueRegs(regT1, regT0), InvalidGPRReg);
     962    gen.generateFastPath(*this);
     963    addSlowCase(gen.slowPathJump());
     964    m_inByVals.append(gen);
     965
     966    emitStore(dst, regT1, regT0);
     967}
     968
     969void JIT::emitHasPrivateSlow(VirtualRegister dst, AccessType type)
     970{
     971    ASSERT(type == AccessType::HasPrivateName || type == AccessType::HasPrivateBrand);
     972
     973    JITInByValGenerator& gen = m_inByVals[m_inByValIndex++];
     974    Label coldPathBegin = label();
     975
     976    Call call = callOperation(type == AccessType::HasPrivateName ? operationHasPrivateNameOptimize : operationHasPrivateBrandOptimize, dst, TrustedImmPtr(m_codeBlock->globalObject()), gen.stubInfo(), JSValueRegs(regT1, regT0), JSValueRegs(regT3, regT2));
     977
     978    gen.reportSlowPathCall(coldPathBegin, call);
     979}
     980
     981void JIT::emit_op_has_private_name(const Instruction* currentInstruction)
     982{
     983    auto bytecode = currentInstruction->as<OpHasPrivateName>();
     984    emitHasPrivate(bytecode.m_dst, bytecode.m_base, bytecode.m_property, AccessType::HasPrivateName);
     985}
     986
     987void JIT::emitSlow_op_has_private_name(const Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
     988{
     989    linkAllSlowCases(iter);
     990
     991    auto bytecode = currentInstruction->as<OpHasPrivateName>();
     992    emitHasPrivateSlow(bytecode.m_dst, AccessType::HasPrivateName);
     993}
     994
     995void JIT::emit_op_has_private_brand(const Instruction* currentInstruction)
     996{
     997    auto bytecode = currentInstruction->as<OpHasPrivateBrand>();
     998    emitHasPrivate(bytecode.m_dst, bytecode.m_base, bytecode.m_brand, AccessType::HasPrivateBrand);
     999}
     1000
     1001void JIT::emitSlow_op_has_private_brand(const Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
     1002{
     1003    linkAllSlowCases(iter);
     1004
     1005    auto bytecode = currentInstruction->as<OpHasPrivateBrand>();
     1006    emitHasPrivateSlow(bytecode.m_dst, AccessType::HasPrivateBrand);
    9521007}
    9531008
  • trunk/Source/JavaScriptCore/jit/Repatch.cpp

    r278696 r279105  
    923923}
    924924
     925inline FunctionPtr<CFunctionPtrTag> appropriateOptimizingInByFunction(InByKind kind)
     926{
     927    switch (kind) {
     928    case InByKind::ById:
     929        return operationInByIdOptimize;
     930    case InByKind::ByVal:
     931        return operationInByValOptimize;
     932    case InByKind::PrivateName:
     933        return operationHasPrivateNameOptimize;
     934    }
     935    RELEASE_ASSERT_NOT_REACHED();
     936}
     937
     938inline FunctionPtr<CFunctionPtrTag> appropriateGenericInByFunction(InByKind kind)
     939{
     940    switch (kind) {
     941    case InByKind::ById:
     942        return operationInByIdGeneric;
     943    case InByKind::ByVal:
     944        return operationInByValGeneric;
     945    case InByKind::PrivateName:
     946        return operationHasPrivateNameGeneric;
     947    }
     948    RELEASE_ASSERT_NOT_REACHED();
     949}
     950
    925951static InlineCacheAction tryCacheInBy(
    926952    JSGlobalObject* globalObject, CodeBlock* codeBlock, JSObject* base, CacheableIdentifier propertyName,
     
    10171043        if (result.generatedSomeCode()) {
    10181044            LOG_IC((ICEvent::InReplaceWithJump, structure->classInfo(), ident, slot.slotBase() == base));
    1019            
     1045
    10201046            RELEASE_ASSERT(result.code());
    1021 
    1022             switch (kind) {
    1023             case InByKind::ById:
     1047            if (kind == InByKind::ById)
    10241048                InlineAccess::rewireStubAsJumpInAccess(codeBlock, stubInfo, CodeLocationLabel<JITStubRoutinePtrTag>(result.code()));
    1025                 break;
    1026             case InByKind::ByVal:
     1049            else
    10271050                InlineAccess::rewireStubAsJumpInAccessNotUsingInlineAccess(codeBlock, stubInfo, CodeLocationLabel<JITStubRoutinePtrTag>(result.code()));
    1028                 break;
    1029             }
    10301051        }
    10311052    }
     
    10431064    if (tryCacheInBy(globalObject, codeBlock, baseObject, propertyName, wasFound, slot, stubInfo, kind) == GiveUpOnCache) {
    10441065        LOG_IC((ICEvent::InReplaceWithGeneric, baseObject->classInfo(globalObject->vm()), Identifier::fromUid(vm, propertyName.uid())));
    1045         if (kind == InByKind::ById)
    1046             repatchSlowPathCall(codeBlock, stubInfo, operationInByIdGeneric);
    1047         else
    1048             repatchSlowPathCall(codeBlock, stubInfo, operationInByValGeneric);
    1049     }
     1066        repatchSlowPathCall(codeBlock, stubInfo, appropriateGenericInByFunction(kind));
     1067    }
     1068}
     1069
     1070static InlineCacheAction tryCacheHasPrivateBrand(JSGlobalObject* globalObject, CodeBlock* codeBlock, JSObject* base, CacheableIdentifier brandID, bool wasFound, StructureStubInfo& stubInfo)
     1071{
     1072    VM& vm = globalObject->vm();
     1073    AccessGenerationResult result;
     1074    Identifier ident = Identifier::fromUid(vm, brandID.uid());
     1075
     1076    {
     1077        GCSafeConcurrentJSLocker locker(codeBlock->m_lock, vm.heap);
     1078        if (forceICFailure(globalObject))
     1079            return GiveUpOnCache;
     1080
     1081        Structure* structure = base->structure(vm);
     1082
     1083        InlineCacheAction action = actionForCell(vm, base);
     1084        if (action != AttemptToCache)
     1085            return action;
     1086
     1087        bool isBaseProperty = true;
     1088        LOG_IC((ICEvent::InAddAccessCase, structure->classInfo(), ident, isBaseProperty));
     1089
     1090        Ref<AccessCase> newCase = AccessCase::create(vm, codeBlock, wasFound ? AccessCase::InHit : AccessCase::InMiss, brandID, invalidOffset, structure, { }, { });
     1091
     1092        result = stubInfo.addAccessCase(locker, globalObject, codeBlock, ECMAMode::strict(), brandID, WTFMove(newCase));
     1093
     1094        if (result.generatedSomeCode()) {
     1095            LOG_IC((ICEvent::InReplaceWithJump, structure->classInfo(), ident, isBaseProperty));
     1096
     1097            RELEASE_ASSERT(result.code());
     1098            InlineAccess::rewireStubAsJumpInAccessNotUsingInlineAccess(codeBlock, stubInfo, CodeLocationLabel<JITStubRoutinePtrTag>(result.code()));
     1099        }
     1100    }
     1101
     1102    fireWatchpointsAndClearStubIfNeeded(vm, stubInfo, codeBlock, result);
     1103
     1104    return result.shouldGiveUpNow() ? GiveUpOnCache : RetryCacheLater;
     1105}
     1106
     1107void repatchHasPrivateBrand(JSGlobalObject* globalObject, CodeBlock* codeBlock, JSObject* baseObject, CacheableIdentifier brandID, bool wasFound, StructureStubInfo& stubInfo)
     1108{
     1109    SuperSamplerScope superSamplerScope(false);
     1110
     1111    if (tryCacheHasPrivateBrand(globalObject, codeBlock, baseObject, brandID, wasFound, stubInfo) == GiveUpOnCache)
     1112        repatchSlowPathCall(codeBlock, stubInfo, operationHasPrivateBrandGeneric);
    10501113}
    10511114
     
    17291792void resetInBy(CodeBlock* codeBlock, StructureStubInfo& stubInfo, InByKind kind)
    17301793{
    1731     switch (kind) {
    1732     case InByKind::ById:
    1733         repatchSlowPathCall(codeBlock, stubInfo, operationInByIdOptimize);
     1794    repatchSlowPathCall(codeBlock, stubInfo, appropriateOptimizingInByFunction(kind));
     1795    if (kind == InByKind::ById)
    17341796        InlineAccess::resetStubAsJumpInAccess(codeBlock, stubInfo);
    1735         break;
    1736     case InByKind::ByVal:
    1737         repatchSlowPathCall(codeBlock, stubInfo, operationInByValOptimize);
     1797    else
    17381798        InlineAccess::resetStubAsJumpInAccessNotUsingInlineAccess(codeBlock, stubInfo);
    1739         break;
    1740     }
     1799}
     1800
     1801void resetHasPrivateBrand(CodeBlock* codeBlock, StructureStubInfo& stubInfo)
     1802{
     1803    repatchSlowPathCall(codeBlock, stubInfo, operationHasPrivateBrandOptimize);
     1804    InlineAccess::resetStubAsJumpInAccessNotUsingInlineAccess(codeBlock, stubInfo);
    17411805}
    17421806
  • trunk/Source/JavaScriptCore/jit/Repatch.h

    r278696 r279105  
    5151enum class InByKind {
    5252    ById,
    53     ByVal
     53    ByVal,
     54    PrivateName
    5455};
    5556
     
    5960void repatchDeleteBy(JSGlobalObject*, CodeBlock*, DeletePropertySlot&, JSValue, Structure*, CacheableIdentifier, StructureStubInfo&, DelByKind, ECMAMode);
    6061void repatchInBy(JSGlobalObject*, CodeBlock*, JSObject*, CacheableIdentifier, bool wasFound, const PropertySlot&, StructureStubInfo&, InByKind);
     62void repatchHasPrivateBrand(JSGlobalObject*, CodeBlock*, JSObject*, CacheableIdentifier, bool wasFound,  StructureStubInfo&);
    6163void repatchCheckPrivateBrand(JSGlobalObject*, CodeBlock*, JSObject*, CacheableIdentifier, StructureStubInfo&);
    6264void repatchSetPrivateBrand(JSGlobalObject*, CodeBlock*, JSObject*, Structure*, CacheableIdentifier, StructureStubInfo&);
     
    7173void resetDelBy(CodeBlock*, StructureStubInfo&, DelByKind);
    7274void resetInBy(CodeBlock*, StructureStubInfo&, InByKind);
     75void resetHasPrivateBrand(CodeBlock*, StructureStubInfo&);
    7376void resetInstanceOf(CodeBlock*, StructureStubInfo&);
    7477void resetCheckPrivateBrand(CodeBlock*, StructureStubInfo&);
  • trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp

    r278591 r279105  
    14331433}
    14341434
     1435LLINT_SLOW_PATH_DECL(slow_path_has_private_name)
     1436{
     1437    LLINT_BEGIN();
     1438
     1439    auto bytecode = pc->as<OpHasPrivateName>();
     1440    auto baseValue = getOperand(callFrame, bytecode.m_base);
     1441    if (!baseValue.isObject())
     1442        LLINT_THROW(createInvalidInParameterError(globalObject, baseValue));
     1443
     1444    auto propertyValue = getOperand(callFrame, bytecode.m_property);
     1445    ASSERT(propertyValue.isSymbol());
     1446    auto property = propertyValue.toPropertyKey(globalObject);
     1447    EXCEPTION_ASSERT(!throwScope.exception());
     1448
     1449    LLINT_RETURN(jsBoolean(asObject(baseValue)->hasPrivateField(globalObject, property)));
     1450}
     1451
     1452LLINT_SLOW_PATH_DECL(slow_path_has_private_brand)
     1453{
     1454    LLINT_BEGIN();
     1455
     1456    auto bytecode = pc->as<OpHasPrivateBrand>();
     1457    auto baseValue = getOperand(callFrame, bytecode.m_base);
     1458    if (!baseValue.isObject())
     1459        LLINT_THROW(createInvalidInParameterError(globalObject, baseValue));
     1460
     1461    LLINT_RETURN(jsBoolean(asObject(baseValue)->hasPrivateBrand(globalObject, getOperand(callFrame, bytecode.m_brand))));
     1462}
     1463
    14351464LLINT_SLOW_PATH_DECL(slow_path_put_getter_by_id)
    14361465{
  • trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.h

    r278445 r279105  
    7474LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_in_by_id);
    7575LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_in_by_val);
     76LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_has_private_name);
     77LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_has_private_brand);
    7678LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_del_by_id);
    7779LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_get_by_val);
  • trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm

    r278591 r279105  
    20112011end
    20122012
    2013 slowPathOp(has_private_name)
    2014 slowPathOp(has_private_brand)
    20152013slowPathOp(is_callable)
    20162014slowPathOp(is_constructor)
     
    20452043llintSlowPathOp(in_by_id)
    20462044llintSlowPathOp(in_by_val)
     2045llintSlowPathOp(has_private_name)
     2046llintSlowPathOp(has_private_brand)
    20472047llintSlowPathOp(del_by_id)
    20482048llintSlowPathOp(del_by_val)
  • trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp

    r278445 r279105  
    831831}
    832832
    833 JSC_DEFINE_COMMON_SLOW_PATH(slow_path_has_private_name)
    834 {
    835     BEGIN();
    836 
    837     auto bytecode = pc->as<OpHasPrivateName>();
    838     auto baseValue = GET_C(bytecode.m_base).jsValue();
    839     if (!baseValue.isObject())
    840         THROW(createInvalidInParameterError(globalObject, baseValue));
    841 
    842     auto propertyValue = GET_C(bytecode.m_property).jsValue();
    843     ASSERT(propertyValue.isSymbol());
    844     auto property = propertyValue.toPropertyKey(globalObject);
    845     EXCEPTION_ASSERT(!throwScope.exception());
    846 
    847     RETURN(jsBoolean(asObject(baseValue)->hasPrivateField(globalObject, property)));
    848 }
    849 
    850 JSC_DEFINE_COMMON_SLOW_PATH(slow_path_has_private_brand)
    851 {
    852     BEGIN();
    853 
    854     auto bytecode = pc->as<OpHasPrivateBrand>();
    855     auto baseValue = GET_C(bytecode.m_base).jsValue();
    856     if (!baseValue.isObject())
    857         THROW(createInvalidInParameterError(globalObject, baseValue));
    858 
    859     RETURN(jsBoolean(asObject(baseValue)->hasPrivateBrand(globalObject, GET_C(bytecode.m_brand).jsValue())));
    860 }
    861 
    862833template<OpcodeSize width>
    863834ALWAYS_INLINE SlowPathReturnType iteratorOpenTryFastImpl(VM& vm, JSGlobalObject* globalObject, CodeBlock* codeBlock, CallFrame* callFrame, const Instruction* pc)
  • trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.h

    r278445 r279105  
    252252JSC_DECLARE_COMMON_SLOW_PATH(slow_path_is_callable);
    253253JSC_DECLARE_COMMON_SLOW_PATH(slow_path_is_constructor);
    254 JSC_DECLARE_COMMON_SLOW_PATH(slow_path_has_private_name);
    255 JSC_DECLARE_COMMON_SLOW_PATH(slow_path_has_private_brand);
    256254JSC_DECLARE_COMMON_SLOW_PATH(slow_path_strcat);
    257255JSC_DECLARE_COMMON_SLOW_PATH(slow_path_to_primitive);
  • trunk/Source/JavaScriptCore/runtime/OptionsList.h

    r279048 r279105  
    530530    v(Bool, usePrivateClassFields, true, Normal, "If true, the parser will understand private data fields inside classes.") \
    531531    v(Bool, usePrivateMethods, true, Normal, "If true, the parser will understand private methods inside classes.") \
    532     v(Bool, usePrivateIn, false, Normal, "If true, the parser will understand private member existence checks with the `in` operator.") \
     532    v(Bool, usePrivateIn, true, Normal, "If true, the parser will understand private member existence checks with the `in` operator.") \
    533533    v(Bool, useWebAssemblyStreaming, true, Normal, "Allow to run WebAssembly's Streaming API") \
    534534    v(Bool, useWebAssemblyReferences, true, Normal, "Allow types from the wasm references spec.") \
Note: See TracChangeset for help on using the changeset viewer.