Changeset 268794 in webkit
- Timestamp:
- Oct 21, 2020, 7:06:02 AM (6 years ago)
- Location:
- trunk
- Files:
-
- 14 added
- 26 edited
-
JSTests/ChangeLog (modified) (1 diff)
-
JSTests/microbenchmarks/class-fields-private/monomorphic-get-private-field.js (added)
-
JSTests/microbenchmarks/class-fields-private/polymorphic-get-private-field.js (added)
-
JSTests/stress/dfg-get-private-name-by-id-generic.js (added)
-
JSTests/stress/dfg-get-private-name-by-id-osr-bad-identifier.js (added)
-
JSTests/stress/dfg-get-private-name-by-id.js (added)
-
JSTests/stress/dfg-get-private-name-by-offset-osr-bad-identifier.js (added)
-
JSTests/stress/dfg-get-private-name-by-offset-osr-bad-structure.js (added)
-
JSTests/stress/dfg-get-private-name-by-offset.js (added)
-
JSTests/stress/dfg-get-private-name-by-val-generic.js (added)
-
JSTests/stress/ftl-get-private-name-by-id.js (added)
-
JSTests/stress/ftl-get-private-name-by-offset-multi.js (added)
-
JSTests/stress/get-private-name-with-constant-ident.js (added)
-
JSTests/stress/get-private-name-with-constant-symbol.js (added)
-
JSTests/stress/get-private-name-with-different-symbol.js (added)
-
Source/JavaScriptCore/ChangeLog (modified) (1 diff)
-
Source/JavaScriptCore/bytecode/GetByStatus.cpp (modified) (1 diff)
-
Source/JavaScriptCore/bytecode/StructureStubInfo.h (modified) (2 diffs)
-
Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h (modified) (2 diffs)
-
Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp (modified) (5 diffs)
-
Source/JavaScriptCore/dfg/DFGClobberize.h (modified) (1 diff)
-
Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp (modified) (1 diff)
-
Source/JavaScriptCore/dfg/DFGDoesGC.cpp (modified) (1 diff)
-
Source/JavaScriptCore/dfg/DFGFixupPhase.cpp (modified) (1 diff)
-
Source/JavaScriptCore/dfg/DFGNode.h (modified) (4 diffs)
-
Source/JavaScriptCore/dfg/DFGNodeType.h (modified) (1 diff)
-
Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp (modified) (1 diff)
-
Source/JavaScriptCore/dfg/DFGSafeToExecute.h (modified) (1 diff)
-
Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp (modified) (1 diff)
-
Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h (modified) (1 diff)
-
Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp (modified) (1 diff)
-
Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp (modified) (1 diff)
-
Source/JavaScriptCore/ftl/FTLCapabilities.cpp (modified) (1 diff)
-
Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp (modified) (2 diffs)
-
Source/JavaScriptCore/jit/ICStats.h (modified) (1 diff)
-
Source/JavaScriptCore/jit/JITOperations.cpp (modified) (3 diffs)
-
Source/JavaScriptCore/jit/JITOperations.h (modified) (1 diff)
-
Source/JavaScriptCore/jit/Repatch.cpp (modified) (3 diffs)
-
Source/JavaScriptCore/jit/Repatch.h (modified) (1 diff)
-
Source/JavaScriptCore/runtime/OptionsList.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/JSTests/ChangeLog
r268783 r268794 1 2020-10-21 Caitlin Potter <caitp@igalia.com> 2 3 [JSC] support op_get_private_name in DFG and FTL 4 https://bugs.webkit.org/show_bug.cgi?id=214861 5 6 Reviewed by Filip Pizlo. 7 8 * microbenchmarks/class-fields-private/monomorphic-get-private-field.js: Added. 9 * microbenchmarks/class-fields-private/polymorphic-get-private-field.js: Added. 10 * stress/dfg-get-private-name-by-id-generic.js: Added. 11 * stress/dfg-get-private-name-by-id-osr-bad-identifier.js: Added. 12 * stress/dfg-get-private-name-by-id.js: Added. 13 * stress/dfg-get-private-name-by-offset-osr-bad-identifier.js: Added. 14 * stress/dfg-get-private-name-by-offset-osr-bad-structure.js: Added. 15 * stress/dfg-get-private-name-by-offset.js: Added. 16 * stress/dfg-get-private-name-by-val-generic.js: Added. 17 * stress/ftl-get-private-name-by-id.js: Added. 18 * stress/ftl-get-private-name-by-offset-multi.js: Added. 19 * stress/get-private-name-with-constant-ident.js: Added. 20 * stress/get-private-name-with-constant-symbol.js: Added. 21 * stress/get-private-name-with-different-symbol.js: Added. 22 1 23 2020-10-20 Saam Barati <sbarati@apple.com> 2 24 -
trunk/Source/JavaScriptCore/ChangeLog
r268783 r268794 1 2020-10-21 Caitlin Potter <caitp@igalia.com> 2 3 [JSC] support op_get_private_name in DFG and FTL 4 https://bugs.webkit.org/show_bug.cgi?id=214861 5 6 Reviewed by Filip Pizlo. 7 8 Adds DFG/FTL support for op_get_private_name. 9 10 During DFG bytecode parsing, we will attempt, if deemed possible by 11 the information available, to output a GetByOffset operation. If a 12 single private field identifier is used in all cases (the common case), 13 but there are too many structure variants, a GetPrivateNameById 14 operation is emitted instead. Failing that, the GetPrivateName 15 operation is produced, which produces a GetByVal IC like in the 16 baseline JIT. 17 18 In FTL, GetPrivateNameByID can be reduced to [Multi]GetByOffset in the 19 DFGConstantFoldingPhase, or a GetByID IC when lowering to B3. 20 21 * bytecode/GetByStatus.cpp: 22 (JSC::GetByStatus::computeFromLLInt): 23 * bytecode/StructureStubInfo.h: 24 (JSC::appropriateOptimizingGetByIdFunction): 25 (JSC::appropriateGenericGetByIdFunction): 26 * dfg/DFGAbstractInterpreterInlines.h: 27 (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects): 28 * dfg/DFGByteCodeParser.cpp: 29 (JSC::DFG::ByteCodeParser::simplifyGetByStatus): 30 (JSC::DFG::ByteCodeParser::handleGetById): 31 (JSC::DFG::ByteCodeParser::handleGetPrivateNameById): 32 (JSC::DFG::ByteCodeParser::parseBlock): 33 * dfg/DFGClobberize.h: 34 (JSC::DFG::clobberize): 35 * dfg/DFGConstantFoldingPhase.cpp: 36 (JSC::DFG::ConstantFoldingPhase::foldConstants): 37 * dfg/DFGDoesGC.cpp: 38 (JSC::DFG::doesGC): 39 * dfg/DFGFixupPhase.cpp: 40 (JSC::DFG::FixupPhase::fixupNode): 41 * dfg/DFGNode.h: 42 (JSC::DFG::Node::convertToGetByOffset): 43 (JSC::DFG::Node::convertToMultiGetByOffset): 44 (JSC::DFG::Node::hasCacheableIdentifier): 45 (JSC::DFG::Node::hasHeapPrediction): 46 * dfg/DFGNodeType.h: 47 * dfg/DFGPredictionPropagationPhase.cpp: 48 * dfg/DFGSafeToExecute.h: 49 (JSC::DFG::safeToExecute): 50 * dfg/DFGSpeculativeJIT.cpp: 51 (JSC::DFG::SpeculativeJIT::compileGetPrivateName): 52 (JSC::DFG::SpeculativeJIT::compileGetPrivateNameByVal): 53 (JSC::DFG::SpeculativeJIT::compileGetPrivateNameById): 54 * dfg/DFGSpeculativeJIT.h: 55 * dfg/DFGSpeculativeJIT32_64.cpp: 56 (JSC::DFG::SpeculativeJIT::compile): 57 * dfg/DFGSpeculativeJIT64.cpp: 58 (JSC::DFG::SpeculativeJIT::compile): 59 * ftl/FTLCapabilities.cpp: 60 (JSC::FTL::canCompile): 61 * ftl/FTLLowerDFGToB3.cpp: 62 (JSC::FTL::DFG::LowerDFGToB3::compileNode): 63 (JSC::FTL::DFG::LowerDFGToB3::getPrivateName): 64 (JSC::FTL::DFG::LowerDFGToB3::compileGetPrivateName): 65 (JSC::FTL::DFG::LowerDFGToB3::compileGetPrivateNameById): 66 * jit/ICStats.h: 67 * jit/JITOperations.cpp: 68 (JSC::getPrivateName): 69 (JSC::JSC_DEFINE_JIT_OPERATION): 70 * jit/JITOperations.h: 71 * jit/Repatch.cpp: 72 (JSC::appropriateOptimizingGetByFunction): 73 (JSC::appropriateGetByFunction): 74 (JSC::tryCacheGetBy): 75 * jit/Repatch.h: 76 * runtime/OptionsList.h: 77 1 78 2020-10-20 Saam Barati <sbarati@apple.com> 2 79 -
trunk/Source/JavaScriptCore/bytecode/GetByStatus.cpp
r261755 r268794 108 108 break; 109 109 } 110 111 case op_get_private_name: 112 // FIXME: Consider using LLInt caches or IC information to populate GetByStatus 113 // https://bugs.webkit.org/show_bug.cgi?id=217245 114 return GetByStatus(NoInformation, false); 110 115 111 116 default: { -
trunk/Source/JavaScriptCore/bytecode/StructureStubInfo.h
r266359 r268794 405 405 case AccessType::GetByIdDirect: 406 406 return operationGetByIdDirectOptimize; 407 case AccessType::GetPrivateName: 408 return operationGetPrivateNameByIdOptimize; 407 409 case AccessType::GetByIdWithThis: 408 410 default: … … 421 423 case AccessType::GetByIdDirect: 422 424 return operationGetByIdDirectGeneric; 425 case AccessType::GetPrivateName: 426 return operationGetPrivateNameByIdGeneric; 423 427 case AccessType::GetByIdWithThis: 424 428 default: -
trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h
r267754 r268794 3349 3349 break; 3350 3350 3351 case GetPrivateNameById: 3351 3352 case GetByIdDirect: 3352 3353 case GetByIdDirectFlush: … … 3384 3385 } 3385 3386 3387 case GetPrivateName: 3386 3388 case GetByValWithThis: 3387 3389 case GetByIdWithThis: -
trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
r267754 r268794 245 245 template<typename Op> 246 246 void parseGetById(const Instruction*); 247 void simplifyGetByStatus(Node* base, GetByStatus&); 247 248 void handleGetById( 248 249 VirtualRegister destination, SpeculatedType, Node* base, CacheableIdentifier, unsigned identifierNumber, GetByStatus, AccessType, BytecodeIndex osrExitIndex); 250 void handleGetPrivateNameById( 251 VirtualRegister destination, SpeculatedType prediction, Node* base, CacheableIdentifier, unsigned identifierNumber, GetByStatus); 249 252 void emitPutById( 250 253 Node* base, CacheableIdentifier, Node* value, const PutByIdStatus&, bool isDirect, ECMAMode); … … 4531 4534 } 4532 4535 4533 void ByteCodeParser::handleGetById( 4534 VirtualRegister destination, SpeculatedType prediction, Node* base, CacheableIdentifier identifier, unsigned identifierNumber, 4535 GetByStatus getByStatus, AccessType type, BytecodeIndex osrExitIndex) 4536 void ByteCodeParser::simplifyGetByStatus(Node* base, GetByStatus& getByStatus) 4536 4537 { 4537 4538 // Attempt to reduce the set of things in the GetByStatus. … … 4550 4551 getByStatus.filter(base->structure().get()); 4551 4552 } 4553 } 4554 4555 void ByteCodeParser::handleGetById( 4556 VirtualRegister destination, SpeculatedType prediction, Node* base, CacheableIdentifier identifier, unsigned identifierNumber, 4557 GetByStatus getByStatus, AccessType type, BytecodeIndex osrExitIndex) 4558 { 4559 simplifyGetByStatus(base, getByStatus); 4552 4560 4553 4561 NodeType getById; … … 4715 4723 destination, Call, InlineCallFrame::GetterCall, osrExitIndex, 4716 4724 getter, numberOfParameters - 1, registerOffset, *variant.callLinkStatus(), prediction); 4725 } 4726 4727 // A variant on handleGetById which is more limited in scope 4728 void ByteCodeParser::handleGetPrivateNameById( 4729 VirtualRegister destination, SpeculatedType prediction, Node* base, CacheableIdentifier identifier, unsigned identifierNumber, GetByStatus getByStatus) 4730 { 4731 simplifyGetByStatus(base, getByStatus); 4732 4733 ASSERT(!getByStatus.isCustom()); 4734 ASSERT(!getByStatus.makesCalls()); 4735 if (!getByStatus.isSimple() || !getByStatus.numVariants() || !Options::useAccessInlining()) { 4736 set(destination, 4737 addToGraph(GetPrivateNameById, OpInfo(identifier), OpInfo(prediction), base, nullptr)); 4738 return; 4739 } 4740 4741 if (getByStatus.numVariants() > 1) { 4742 if (!m_graph.m_plan.isFTL() 4743 || !Options::usePolymorphicAccessInlining() 4744 || getByStatus.numVariants() > Options::maxPolymorphicAccessInliningListSize()) { 4745 set(destination, 4746 addToGraph(GetPrivateNameById, OpInfo(identifier), OpInfo(prediction), base, nullptr)); 4747 return; 4748 } 4749 4750 addToGraph(FilterGetByStatus, OpInfo(m_graph.m_plan.recordedStatuses().addGetByStatus(currentCodeOrigin(), getByStatus)), base); 4751 4752 Vector<MultiGetByOffsetCase, 2> cases; 4753 4754 for (const GetByIdVariant& variant : getByStatus.variants()) { 4755 ASSERT(variant.intrinsic() == NoIntrinsic); 4756 ASSERT(variant.conditionSet().isEmpty()); 4757 4758 GetByOffsetMethod method = GetByOffsetMethod::load(variant.offset()); 4759 cases.append(MultiGetByOffsetCase(*m_graph.addStructureSet(variant.structureSet()), method)); 4760 } 4761 4762 if (UNLIKELY(m_graph.compilation())) 4763 m_graph.compilation()->noticeInlinedGetById(); 4764 4765 // 2) Emit a MultiGetByOffset 4766 MultiGetByOffsetData* data = m_graph.m_multiGetByOffsetData.add(); 4767 data->cases = cases; 4768 data->identifierNumber = identifierNumber; 4769 set(destination, 4770 addToGraph(MultiGetByOffset, OpInfo(data), OpInfo(prediction), base)); 4771 return; 4772 } 4773 4774 // FIXME: If we use the GetByStatus for anything then we should record it and insert a node 4775 // after everything else (like the GetByOffset or whatever) that will filter the recorded 4776 // GetByStatus. That means that the constant folder also needs to do the same! 4777 addToGraph(FilterGetByStatus, OpInfo(m_graph.m_plan.recordedStatuses().addGetByStatus(currentCodeOrigin(), getByStatus)), base); 4778 4779 ASSERT(getByStatus.numVariants() == 1); 4780 GetByIdVariant variant = getByStatus[0]; 4781 4782 Node* loadedValue = load(prediction, base, identifierNumber, variant); 4783 if (!loadedValue) { 4784 set(destination, 4785 addToGraph(GetPrivateNameById, OpInfo(identifier), OpInfo(prediction), base, nullptr)); 4786 return; 4787 } 4788 4789 if (UNLIKELY(m_graph.compilation())) 4790 m_graph.compilation()->noticeInlinedGetById(); 4791 4792 ASSERT(!variant.callLinkStatus()); 4793 if (variant.intrinsic() == NoIntrinsic) 4794 set(destination, loadedValue); 4717 4795 } 4718 4796 … … 6344 6422 handlePutAccessorByVal(PutSetterByVal, currentInstruction->as<OpPutSetterByVal>()); 6345 6423 NEXT_OPCODE(op_put_setter_by_val); 6424 } 6425 6426 case op_get_private_name: { 6427 auto bytecode = currentInstruction->as<OpGetPrivateName>(); 6428 SpeculatedType prediction = getPredictionWithoutOSRExit(); 6429 Node* base = get(bytecode.m_base); 6430 Node* property = get(bytecode.m_property); 6431 bool compileSingleIdentifier = false; 6432 6433 GetByStatus getByStatus = GetByStatus::computeFor(m_inlineStackTop->m_profiledBlock, m_inlineStackTop->m_baselineMap, m_icContextStack, currentCodeOrigin()); 6434 6435 CacheableIdentifier identifier; 6436 unsigned identifierNumber = 0; 6437 if (!m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadIdent) 6438 && !m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadType) 6439 && !m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadConstantValue)) { 6440 6441 identifier = getByStatus.singleIdentifier(); 6442 if (identifier) { 6443 identifierNumber = m_graph.identifiers().ensure(identifier.uid()); 6444 ASSERT(identifier.isSymbolCell()); 6445 FrozenValue* frozen = m_graph.freezeStrong(identifier.cell()); 6446 addToGraph(CheckIsConstant, OpInfo(frozen), property); 6447 compileSingleIdentifier = true; 6448 } 6449 } 6450 6451 if (compileSingleIdentifier) 6452 handleGetPrivateNameById(bytecode.m_dst, prediction, base, identifier, identifierNumber, getByStatus); 6453 else { 6454 Node* node = addToGraph(GetPrivateName, OpInfo(), OpInfo(prediction), base, property); 6455 m_exitOK = false; 6456 set(bytecode.m_dst, node); 6457 } 6458 NEXT_OPCODE(op_get_private_name); 6346 6459 } 6347 6460 -
trunk/Source/JavaScriptCore/dfg/DFGClobberize.h
r267726 r268794 674 674 case PutPrivateName: 675 675 case PutPrivateNameById: 676 case GetPrivateName: 677 case GetPrivateNameById: 676 678 case DefineDataProperty: 677 679 case DefineAccessorProperty: -
trunk/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp
r267624 r268794 600 600 case GetByIdDirectFlush: 601 601 case GetById: 602 case GetByIdFlush: { 602 case GetByIdFlush: 603 case GetPrivateNameById: { 603 604 Edge childEdge = node->child1(); 604 605 Node* child = childEdge.node(); -
trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp
r267726 r268794 325 325 case PutPrivateName: 326 326 case PutPrivateNameById: 327 case GetPrivateName: 328 case GetPrivateNameById: 327 329 case PutStack: 328 330 case PutToArguments: -
trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
r268656 r268794 1780 1780 break; 1781 1781 } 1782 1783 case GetPrivateName: 1784 case GetPrivateNameById: 1785 if (node->child1()->shouldSpeculateCell()) 1786 fixEdge<CellUse>(node->child1()); 1787 else 1788 fixEdge<UntypedUse>(node->child1()); 1789 1790 if (!node->hasCacheableIdentifier()) 1791 fixEdge<SymbolUse>(node->child2()); 1792 break; 1782 1793 1783 1794 case DeleteByVal: { -
trunk/Source/JavaScriptCore/dfg/DFGNode.h
r267489 r268794 598 598 void convertToGetByOffset(StorageAccessData& data, Edge storage, Edge base) 599 599 { 600 ASSERT(m_op == GetById || m_op == GetByIdFlush || m_op == GetByIdDirect || m_op == GetByIdDirectFlush || m_op == MultiGetByOffset);600 ASSERT(m_op == GetById || m_op == GetByIdFlush || m_op == GetByIdDirect || m_op == GetByIdDirectFlush || m_op == GetPrivateNameById || m_op == MultiGetByOffset); 601 601 m_opInfo = &data; 602 602 children.setChild1(storage); … … 608 608 void convertToMultiGetByOffset(MultiGetByOffsetData* data) 609 609 { 610 RELEASE_ASSERT(m_op == GetById || m_op == GetByIdFlush || m_op == GetByIdDirect || m_op == GetByIdDirectFlush );610 RELEASE_ASSERT(m_op == GetById || m_op == GetByIdFlush || m_op == GetByIdDirect || m_op == GetByIdDirectFlush || m_op == GetPrivateNameById); 611 611 m_opInfo = data; 612 612 child1().setUseKind(CellUse); … … 1083 1083 case GetByIdDirect: 1084 1084 case GetByIdDirectFlush: 1085 case GetPrivateNameById: 1085 1086 case DeleteById: 1086 1087 case InById: … … 1767 1768 case GetByVal: 1768 1769 case GetByValWithThis: 1770 case GetPrivateName: 1771 case GetPrivateNameById: 1769 1772 case Call: 1770 1773 case DirectCall: -
trunk/Source/JavaScriptCore/dfg/DFGNodeType.h
r267726 r268794 243 243 macro(CheckArray, NodeMustGenerate) \ 244 244 macro(CheckArrayOrEmpty, NodeMustGenerate) \ 245 macro(GetPrivateName, NodeResultJS | NodeMustGenerate) \ 246 macro(GetPrivateNameById, NodeResultJS | NodeMustGenerate) \ 245 247 /* This checks if the edge is a typed array and if it is neutered. */ \ 246 248 macro(CheckNeutered, NodeMustGenerate) \ -
trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
r267726 r268794 876 876 case GetByValWithThis: 877 877 case GetByOffset: 878 case GetPrivateName: 879 case GetPrivateNameById: 878 880 case MultiGetByOffset: 879 881 case GetDirectPname: -
trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h
r267726 r268794 530 530 case PutPrivateName: 531 531 case PutPrivateNameById: 532 case GetPrivateName: 533 case GetPrivateNameById: 532 534 case DefineDataProperty: 533 535 case DefineAccessorProperty: -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
r268656 r268794 3467 3467 3468 3468 jsValueResult(resultRegs, node); 3469 } 3470 3471 void SpeculativeJIT::compileGetPrivateName(Node* node) 3472 { 3473 if (node->hasCacheableIdentifier()) 3474 return compileGetPrivateNameById(node); 3475 3476 switch (m_graph.child(node, 0).useKind()) { 3477 case CellUse: { 3478 SpeculateCellOperand base(this, m_graph.child(node, 0)); 3479 SpeculateCellOperand property(this, m_graph.child(node, 1)); 3480 3481 compileGetPrivateNameByVal(node, JSValueRegs::payloadOnly(base.gpr()), JSValueRegs::payloadOnly(property.gpr())); 3482 break; 3483 } 3484 case UntypedUse: { 3485 JSValueOperand base(this, m_graph.child(node, 0)); 3486 SpeculateCellOperand property(this, m_graph.child(node, 1)); 3487 3488 compileGetPrivateNameByVal(node, base.jsValueRegs(), JSValueRegs::payloadOnly(property.gpr())); 3489 break; 3490 } 3491 default: 3492 DFG_CRASH(m_jit.graph(), node, "Bad use kind"); 3493 } 3494 } 3495 3496 void SpeculativeJIT::compileGetPrivateNameByVal(Node* node, JSValueRegs base, JSValueRegs property) 3497 { 3498 DFG_ASSERT(m_jit.graph(), node, node->op() == GetPrivateName); 3499 DFG_ASSERT(m_jit.graph(), node, m_graph.child(node, 1).useKind() == SymbolUse); 3500 speculateSymbol(m_graph.child(node, 1)); 3501 3502 JSValueRegsTemporary result(this); 3503 CodeOrigin codeOrigin = node->origin.semantic; 3504 CallSiteIndex callSite = m_jit.recordCallSiteAndGenerateExceptionHandlingOSRExitIfNeeded(codeOrigin, m_stream->size()); 3505 RegisterSet usedRegisters = this->usedRegisters(); 3506 3507 JITCompiler::JumpList slowCases; 3508 const bool baseIsKnownCell = m_state.forNode(m_graph.child(node, 0)).isType(SpecCell); 3509 if (!baseIsKnownCell) 3510 slowCases.append(m_jit.branchIfNotCell(base)); 3511 3512 JITGetByValGenerator gen( 3513 m_jit.codeBlock(), codeOrigin, callSite, AccessType::GetPrivateName, usedRegisters, 3514 base, property, result.regs()); 3515 gen.stubInfo()->propertyIsSymbol = true; 3516 gen.generateFastPath(m_jit); 3517 3518 slowCases.append(gen.slowPathJump()); 3519 3520 auto makeSlowPathCall = [&](auto base) { 3521 return slowPathCall( 3522 slowCases, this, operationGetPrivateNameOptimize, 3523 result.regs(), TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(codeOrigin)), gen.stubInfo(), 3524 base, CCallHelpers::CellValue(property.payloadGPR())); 3525 }; 3526 3527 std::unique_ptr<SlowPathGenerator> slowPath = baseIsKnownCell 3528 ? makeSlowPathCall(CCallHelpers::CellValue(base.payloadGPR())) 3529 : makeSlowPathCall(base); 3530 3531 m_jit.addGetByVal(gen, slowPath.get()); 3532 addSlowPathGenerator(WTFMove(slowPath)); 3533 3534 jsValueResult(result.regs(), node, DataFormatJS); 3535 } 3536 3537 void SpeculativeJIT::compileGetPrivateNameById(Node* node) 3538 { 3539 switch (m_graph.child(node, 0).useKind()) { 3540 case CellUse: { 3541 SpeculateCellOperand base(this, m_graph.child(node, 0)); 3542 JSValueRegsTemporary result(this, Reuse, base); 3543 3544 JSValueRegs baseRegs = JSValueRegs::payloadOnly(base.gpr()); 3545 JSValueRegs resultRegs = result.regs(); 3546 3547 cachedGetById(node->origin.semantic, baseRegs, resultRegs, node->cacheableIdentifier(), JITCompiler::Jump(), NeedToSpill, AccessType::GetPrivateName); 3548 3549 jsValueResult(resultRegs, node, DataFormatJS); 3550 break; 3551 } 3552 3553 case UntypedUse: { 3554 JSValueOperand base(this, m_graph.child(node, 0)); 3555 JSValueRegsTemporary result(this, Reuse, base); 3556 3557 JSValueRegs baseRegs = base.jsValueRegs(); 3558 JSValueRegs resultRegs = result.regs(); 3559 3560 JITCompiler::Jump notCell = m_jit.branchIfNotCell(baseRegs); 3561 3562 cachedGetById(node->origin.semantic, baseRegs, resultRegs, node->cacheableIdentifier(), notCell, NeedToSpill, AccessType::GetPrivateName); 3563 3564 jsValueResult(resultRegs, node, DataFormatJS); 3565 break; 3566 } 3567 3568 default: 3569 DFG_CRASH(m_jit.graph(), node, "Bad use kind"); 3570 break; 3571 } 3469 3572 } 3470 3573 -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
r267489 r268794 1283 1283 void compileGetByValOnDirectArguments(Node*); 1284 1284 void compileGetByValOnScopedArguments(Node*); 1285 1285 1286 void compileGetPrivateName(Node*); 1287 void compileGetPrivateNameById(Node*); 1288 void compileGetPrivateNameByVal(Node*, JSValueRegs base, JSValueRegs property); 1289 1286 1290 void compileGetScope(Node*); 1287 1291 void compileSkipScope(Node*); -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
r267726 r268794 2239 2239 case ArrayifyToStructure: { 2240 2240 arrayify(node); 2241 break; 2242 } 2243 2244 case GetPrivateName: 2245 case GetPrivateNameById: { 2246 compileGetPrivateName(node); 2241 2247 break; 2242 2248 } -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
r267726 r268794 2615 2615 case ArrayifyToStructure: { 2616 2616 arrayify(node); 2617 break; 2618 } 2619 2620 case GetPrivateName: 2621 case GetPrivateNameById: { 2622 compileGetPrivateName(node); 2617 2623 break; 2618 2624 } -
trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp
r267726 r268794 398 398 case PutPrivateName: 399 399 case PutPrivateNameById: 400 case GetPrivateName: 401 case GetPrivateNameById: 400 402 case MatchStructure: 401 403 case FilterCallLinkStatus: -
trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp
r268783 r268794 949 949 compileGetById(AccessType::GetByIdDirect); 950 950 break; 951 case GetPrivateName: 952 compileGetPrivateName(); 953 break; 954 case GetPrivateNameById: 955 compileGetPrivateNameById(); 956 break; 951 957 case InById: 952 958 compileInById(); … … 3940 3946 LValue result = vmCall(Int64, operationGetByValWithThis, weakPointer(globalObject), base, thisValue, subscript); 3941 3947 setJSValue(result); 3948 } 3949 3950 LValue getPrivateName(LValue base, LValue property) 3951 { 3952 Node* node = m_node; 3953 PatchpointValue* patchpoint = m_out.patchpoint(Int64); 3954 patchpoint->appendSomeRegister(base); 3955 patchpoint->appendSomeRegister(property); 3956 patchpoint->append(m_notCellMask, ValueRep::lateReg(GPRInfo::notCellMaskRegister)); 3957 patchpoint->append(m_numberTag, ValueRep::lateReg(GPRInfo::numberTagRegister)); 3958 patchpoint->clobber(RegisterSet::macroScratchRegisters()); 3959 3960 RefPtr<PatchpointExceptionHandle> exceptionHandle = preparePatchpointForExceptions(patchpoint); 3961 3962 State* state = &m_ftlState; 3963 bool baseIsCell = abstractValue(node->child1()).isType(SpecCell); 3964 patchpoint->setGenerator([=] (CCallHelpers& jit, const StackmapGenerationParams& params) { 3965 AllowMacroScratchRegisterUsage allowScratch(jit); 3966 3967 CallSiteIndex callSiteIndex = state->jitCode->common.codeOrigins->addUniqueCallSiteIndex(node->origin.semantic); 3968 3969 // This is the direct exit target for operation calls. 3970 Box<CCallHelpers::JumpList> exceptions = exceptionHandle->scheduleExitCreation(params)->jumps(jit); 3971 3972 // This is the exit for call IC's created by the IC for getters. We don't have 3973 // to do anything weird other than call this, since it will associate the exit with 3974 // the callsite index. 3975 exceptionHandle->scheduleExitCreationForUnwind(params, callSiteIndex); 3976 3977 GPRReg resultGPR = params[0].gpr(); 3978 GPRReg baseGPR = params[1].gpr(); 3979 GPRReg propertyGPR = params[2].gpr(); 3980 3981 auto generator = Box<JITGetByValGenerator>::create( 3982 jit.codeBlock(), node->origin.semantic, callSiteIndex, AccessType::GetPrivateName, 3983 params.unavailableRegisters(), JSValueRegs(baseGPR), JSValueRegs(propertyGPR), JSValueRegs(resultGPR)); 3984 3985 CCallHelpers::Jump notCell; 3986 if (!baseIsCell) 3987 notCell = jit.branchIfNotCell(baseGPR); 3988 3989 generator->generateFastPath(jit); 3990 CCallHelpers::Label done = jit.label(); 3991 3992 params.addLatePath([=] (CCallHelpers& jit) { 3993 AllowMacroScratchRegisterUsage allowScratch(jit); 3994 3995 if (notCell.isSet()) 3996 notCell.link(&jit); 3997 generator->slowPathJump().link(&jit); 3998 CCallHelpers::Label slowPathBegin = jit.label(); 3999 CCallHelpers::Call slowPathCall = callOperation( 4000 *state, params.unavailableRegisters(), jit, node->origin.semantic, 4001 exceptions.get(), operationGetPrivateNameOptimize, resultGPR, 4002 jit.codeBlock()->globalObjectFor(node->origin.semantic), 4003 CCallHelpers::TrustedImmPtr(generator->stubInfo()), baseGPR, propertyGPR).call(); 4004 jit.jump().linkTo(done, &jit); 4005 4006 generator->reportSlowPathCall(slowPathBegin, slowPathCall); 4007 4008 jit.addLinkTask([=] (LinkBuffer& linkBuffer) { 4009 generator->finalize(linkBuffer, linkBuffer); 4010 }); 4011 }); 4012 }); 4013 4014 return patchpoint; 4015 } 4016 4017 void compileGetPrivateName() 4018 { 4019 if (m_node->child1().useKind() == CellUse) 4020 setJSValue(getPrivateName(lowCell(m_node->child1()), lowSymbol(m_node->child2()))); 4021 else { 4022 LValue base = lowJSValue(m_node->child1()); 4023 LValue property = lowSymbol(m_node->child2()); 4024 4025 LBasicBlock baseCellCase = m_out.newBlock(); 4026 LBasicBlock notCellCase = m_out.newBlock(); 4027 LBasicBlock continuation = m_out.newBlock(); 4028 4029 m_out.branch( 4030 isCell(base, provenType(m_node->child1())), unsure(baseCellCase), unsure(notCellCase)); 4031 4032 LBasicBlock lastNext = m_out.appendTo(baseCellCase, notCellCase); 4033 4034 ValueFromBlock cellResult = m_out.anchor(getPrivateName(base, property)); 4035 m_out.jump(continuation); 4036 4037 m_out.appendTo(notCellCase, continuation); 4038 JSGlobalObject* globalObject = m_graph.globalObjectFor(m_origin.semantic); 4039 ValueFromBlock notCellResult = m_out.anchor(vmCall( 4040 Int64, operationGetPrivateName, 4041 weakPointer(globalObject), m_out.constIntPtr(0), base, 4042 property)); 4043 m_out.jump(continuation); 4044 4045 m_out.appendTo(continuation, lastNext); 4046 setJSValue(m_out.phi(Int64, cellResult, notCellResult)); 4047 } 4048 } 4049 4050 void compileGetPrivateNameById() 4051 { 4052 JSGlobalObject* globalObject = m_graph.globalObjectFor(m_node->origin.semantic); 4053 if (m_node->child1().useKind() == CellUse) 4054 setJSValue(getById(lowCell(m_node->child1()), AccessType::GetPrivateName)); 4055 else { 4056 LValue base = lowJSValue(m_node->child1()); 4057 4058 LBasicBlock baseCellCase = m_out.newBlock(); 4059 LBasicBlock notCellCase = m_out.newBlock(); 4060 LBasicBlock continuation = m_out.newBlock(); 4061 4062 m_out.branch( 4063 isCell(base, provenType(m_node->child1())), unsure(baseCellCase), unsure(notCellCase)); 4064 4065 LBasicBlock lastNext = m_out.appendTo(baseCellCase, notCellCase); 4066 4067 ValueFromBlock cellResult = m_out.anchor(getById(base, AccessType::GetPrivateName)); 4068 m_out.jump(continuation); 4069 4070 m_out.appendTo(notCellCase, continuation); 4071 ValueFromBlock notCellResult = m_out.anchor(vmCall( 4072 Int64, operationGetPrivateNameByIdGeneric, 4073 weakPointer(globalObject), base, 4074 m_out.constIntPtr(m_node->cacheableIdentifier().rawBits()))); 4075 m_out.jump(continuation); 4076 4077 m_out.appendTo(continuation, lastNext); 4078 setJSValue(m_out.phi(Int64, cellResult, notCellResult)); 4079 } 3942 4080 } 3943 4081 -
trunk/Source/JavaScriptCore/jit/ICStats.h
r268077 r268794 73 73 macro(DelByReplaceWithJump) \ 74 74 macro(DelByReplaceWithGeneric) \ 75 macro(OperationGetPrivateNameOptimize) 75 macro(OperationGetPrivateNameOptimize) \ 76 macro(OperationGetPrivateNameById) \ 77 macro(OperationGetPrivateNameByIdOptimize) \ 78 macro(OperationGetPrivateNameByIdGeneric) 76 79 77 80 class ICEvent { -
trunk/Source/JavaScriptCore/jit/JITOperations.cpp
r268656 r268794 2262 2262 } 2263 2263 2264 ALWAYS_INLINE static JSValue getPrivateName(JSGlobalObject* globalObject, CallFrame* callFrame, JSValue baseValue, Identifier fieldName) 2265 { 2266 ASSERT(fieldName.isPrivateName()); 2267 UNUSED_PARAM(callFrame); 2268 VM& vm = globalObject->vm(); 2269 auto scope = DECLARE_THROW_SCOPE(vm); 2270 2271 baseValue.requireObjectCoercible(globalObject); 2272 RETURN_IF_EXCEPTION(scope, JSValue()); 2273 2274 JSObject* base = baseValue.toObject(globalObject); 2275 PropertySlot slot(base, PropertySlot::InternalMethodType::GetOwnProperty); 2276 base->getPrivateField(globalObject, fieldName, slot); 2277 RETURN_IF_EXCEPTION(scope, JSValue()); 2278 2279 return slot.getValue(globalObject, fieldName); 2280 } 2281 2264 2282 JSC_DEFINE_JIT_OPERATION(operationGetPrivateNameOptimize, EncodedJSValue, (JSGlobalObject* globalObject, StructureStubInfo* stubInfo, EncodedJSValue encodedBase, EncodedJSValue encodedFieldName)) 2265 2283 { … … 2281 2299 2282 2300 JSObject* base = jsCast<JSObject*>(baseValue.asCell()); 2283 RETURN_IF_EXCEPTION(scope, encodedJSValue());2284 2301 2285 2302 PropertySlot slot(base, PropertySlot::InternalMethodType::GetOwnProperty); … … 2307 2324 JSValue fieldNameValue = JSValue::decode(encodedFieldName); 2308 2325 2326 if (stubInfo) 2327 stubInfo->tookSlowPath = true; 2328 2329 return JSValue::encode(getPrivateName(globalObject, callFrame, baseValue, fieldNameValue)); 2330 } 2331 2332 JSC_DEFINE_JIT_OPERATION(operationGetPrivateNameById, EncodedJSValue, (JSGlobalObject* globalObject, StructureStubInfo* stubInfo, EncodedJSValue base, uintptr_t rawCacheableIdentifier)) 2333 { 2334 SuperSamplerScope superSamplerScope(false); 2335 2336 VM& vm = globalObject->vm(); 2337 CallFrame* callFrame = DECLARE_CALL_FRAME(vm); 2338 JITOperationPrologueCallFrameTracer tracer(vm, callFrame); 2339 2309 2340 stubInfo->tookSlowPath = true; 2310 2341 2311 return JSValue::encode(getPrivateName(globalObject, callFrame, baseValue, fieldNameValue)); 2342 JSValue baseValue = JSValue::decode(base); 2343 CacheableIdentifier identifier = CacheableIdentifier::createFromRawBits(rawCacheableIdentifier); 2344 Identifier fieldName = Identifier::fromUid(vm, identifier.uid()); 2345 2346 JSValue result = getPrivateName(globalObject, callFrame, baseValue, fieldName); 2347 2348 LOG_IC((ICEvent::OperationGetPrivateNameById, baseValue.classInfoOrNull(vm), fieldName, true)); 2349 2350 return JSValue::encode(result); 2351 } 2352 2353 JSC_DEFINE_JIT_OPERATION(operationGetPrivateNameByIdOptimize, EncodedJSValue, (JSGlobalObject* globalObject, StructureStubInfo* stubInfo, EncodedJSValue base, uintptr_t rawCacheableIdentifier)) 2354 { 2355 SuperSamplerScope superSamplerScope(false); 2356 2357 VM& vm = globalObject->vm(); 2358 CallFrame* callFrame = DECLARE_CALL_FRAME(vm); 2359 JITOperationPrologueCallFrameTracer tracer(vm, callFrame); 2360 CacheableIdentifier identifier = CacheableIdentifier::createFromRawBits(rawCacheableIdentifier); 2361 auto scope = DECLARE_THROW_SCOPE(vm); 2362 2363 JSValue baseValue = JSValue::decode(base); 2364 auto fieldName = Identifier::fromUid(vm, identifier.uid()); 2365 2366 if (baseValue.isObject()) { 2367 JSObject* base = jsCast<JSObject*>(baseValue.asCell()); 2368 2369 PropertySlot slot(base, PropertySlot::InternalMethodType::GetOwnProperty); 2370 base->getPrivateField(globalObject, fieldName, slot); 2371 RETURN_IF_EXCEPTION(scope, encodedJSValue()); 2372 2373 LOG_IC((ICEvent::OperationGetPrivateNameOptimize, baseValue.classInfoOrNull(vm), fieldName, true)); 2374 2375 CodeBlock* codeBlock = callFrame->codeBlock(); 2376 if (stubInfo->considerCachingBy(vm, codeBlock, baseValue.structureOrNull(vm), identifier)) 2377 repatchGetBy(globalObject, codeBlock, baseValue, identifier, slot, *stubInfo, GetByKind::PrivateNameById); 2378 return JSValue::encode(slot.getValue(globalObject, fieldName)); 2379 } 2380 2381 return JSValue::encode(getPrivateName(globalObject, callFrame, baseValue, fieldName)); 2382 } 2383 2384 JSC_DEFINE_JIT_OPERATION(operationGetPrivateNameByIdGeneric, EncodedJSValue, (JSGlobalObject* globalObject, EncodedJSValue base, uintptr_t rawCacheableIdentifier)) 2385 { 2386 SuperSamplerScope superSamplerScope(false); 2387 2388 VM& vm = globalObject->vm(); 2389 CallFrame* callFrame = DECLARE_CALL_FRAME(vm); 2390 JITOperationPrologueCallFrameTracer tracer(vm, callFrame); 2391 2392 JSValue baseValue = JSValue::decode(base); 2393 CacheableIdentifier identifier = CacheableIdentifier::createFromRawBits(rawCacheableIdentifier); 2394 Identifier fieldName = Identifier::fromUid(vm, identifier.uid()); 2395 2396 JSValue result = getPrivateName(globalObject, callFrame, baseValue, fieldName); 2397 2398 LOG_IC((ICEvent::OperationGetPrivateNameByIdGeneric, baseValue.classInfoOrNull(vm), fieldName, true)); 2399 2400 return JSValue::encode(result); 2312 2401 } 2313 2402 -
trunk/Source/JavaScriptCore/jit/JITOperations.h
r268385 r268794 270 270 JSC_DECLARE_JIT_OPERATION(operationGetPrivateName, EncodedJSValue, (JSGlobalObject*, StructureStubInfo*, EncodedJSValue encodedBase, EncodedJSValue encodedFieldName)); 271 271 JSC_DECLARE_JIT_OPERATION(operationGetPrivateNameOptimize, EncodedJSValue, (JSGlobalObject*, StructureStubInfo*, EncodedJSValue encodedBase, EncodedJSValue encodedFieldName)); 272 JSC_DECLARE_JIT_OPERATION(operationGetPrivateNameById, EncodedJSValue, (JSGlobalObject*, StructureStubInfo*, EncodedJSValue, uintptr_t)); 273 JSC_DECLARE_JIT_OPERATION(operationGetPrivateNameByIdOptimize, EncodedJSValue, (JSGlobalObject*, StructureStubInfo*, EncodedJSValue, uintptr_t)); 274 JSC_DECLARE_JIT_OPERATION(operationGetPrivateNameByIdGeneric, EncodedJSValue, (JSGlobalObject*, EncodedJSValue, uintptr_t)); 272 275 273 276 JSC_DECLARE_JIT_OPERATION(operationSwitchCharWithUnknownKeyType, char*, (JSGlobalObject*, EncodedJSValue key, size_t tableIndex)); -
trunk/Source/JavaScriptCore/jit/Repatch.cpp
r268247 r268794 166 166 case GetByKind::PrivateName: 167 167 return operationGetPrivateNameOptimize; 168 case GetByKind::PrivateNameById: 169 return operationGetPrivateNameByIdOptimize; 168 170 } 169 171 RELEASE_ASSERT_NOT_REACHED(); … … 185 187 case GetByKind::PrivateName: 186 188 return operationGetPrivateName; 189 case GetByKind::PrivateNameById: 190 return operationGetPrivateNameById; 187 191 } 188 192 RELEASE_ASSERT_NOT_REACHED(); … … 204 208 return GiveUpOnCache; 205 209 JSCell* baseCell = baseValue.asCell(); 206 const bool isPrivate = kind == GetByKind::PrivateName ;210 const bool isPrivate = kind == GetByKind::PrivateName || kind == GetByKind::PrivateNameById; 207 211 208 212 std::unique_ptr<AccessCase> newCase; -
trunk/Source/JavaScriptCore/jit/Repatch.h
r265000 r268794 41 41 Direct, 42 42 PrivateName, 43 PrivateNameById, 43 44 }; 44 45 -
trunk/Source/JavaScriptCore/runtime/OptionsList.h
r268760 r268794 572 572 573 573 #define FOR_EACH_JSC_EXPERIMENTAL_OPTION(v) \ 574 v(usePrivateClassFields, LLIntAndBaselineOnly, "https://bugs.webkit.org/show_bug.cgi?id=212781", "https://bugs.webkit.org/show_bug.cgi?id=212784")574 v(usePrivateClassFields, SupportsFTL | SupportsDFG, "https://bugs.webkit.org/show_bug.cgi?id=212781", "https://bugs.webkit.org/show_bug.cgi?id=212784") 575 575 576 576 constexpr size_t countNumberOfJSCOptions()
Note:
See TracChangeset
for help on using the changeset viewer.