Changeset 279105 in webkit
- Timestamp:
- Jun 21, 2021, 11:41:14 PM (5 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 24 edited
-
JSTests/ChangeLog (modified) (1 diff)
-
JSTests/microbenchmarks/has-private-brand.js (added)
-
JSTests/microbenchmarks/has-private-name.js (added)
-
Source/JavaScriptCore/ChangeLog (modified) (1 diff)
-
Source/JavaScriptCore/bytecode/StructureStubInfo.cpp (modified) (1 diff)
-
Source/JavaScriptCore/bytecode/StructureStubInfo.h (modified) (1 diff)
-
Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp (modified) (3 diffs)
-
Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp (modified) (4 diffs)
-
Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h (modified) (1 diff)
-
Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp (modified) (10 diffs)
-
Source/JavaScriptCore/jit/JIT.cpp (modified) (3 diffs)
-
Source/JavaScriptCore/jit/JIT.h (modified) (3 diffs)
-
Source/JavaScriptCore/jit/JITInlineCacheGenerator.cpp (modified) (1 diff)
-
Source/JavaScriptCore/jit/JITInlineCacheGenerator.h (modified) (1 diff)
-
Source/JavaScriptCore/jit/JITOperations.cpp (modified) (1 diff)
-
Source/JavaScriptCore/jit/JITOperations.h (modified) (1 diff)
-
Source/JavaScriptCore/jit/JITPropertyAccess.cpp (modified) (2 diffs)
-
Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp (modified) (2 diffs)
-
Source/JavaScriptCore/jit/Repatch.cpp (modified) (4 diffs)
-
Source/JavaScriptCore/jit/Repatch.h (modified) (3 diffs)
-
Source/JavaScriptCore/llint/LLIntSlowPaths.cpp (modified) (1 diff)
-
Source/JavaScriptCore/llint/LLIntSlowPaths.h (modified) (1 diff)
-
Source/JavaScriptCore/llint/LowLevelInterpreter.asm (modified) (2 diffs)
-
Source/JavaScriptCore/runtime/CommonSlowPaths.cpp (modified) (1 diff)
-
Source/JavaScriptCore/runtime/CommonSlowPaths.h (modified) (1 diff)
-
Source/JavaScriptCore/runtime/OptionsList.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/JSTests/ChangeLog
r279082 r279105 1 2021-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 1 11 2021-06-21 Xan Lopez <xan@igalia.com> 2 12 -
trunk/Source/JavaScriptCore/ChangeLog
r279096 r279105 1 2021-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 1 75 2021-06-21 Don Olmstead <don.olmstead@sony.com> 2 76 -
trunk/Source/JavaScriptCore/bytecode/StructureStubInfo.cpp
r278696 r279105 280 280 resetInBy(codeBlock, *this, InByKind::ByVal); 281 281 break; 282 case AccessType::HasPrivateName: 283 resetInBy(codeBlock, *this, InByKind::PrivateName); 284 break; 285 case AccessType::HasPrivateBrand: 286 resetHasPrivateBrand(codeBlock, *this); 287 break; 282 288 case AccessType::InstanceOf: 283 289 resetInstanceOf(codeBlock, *this); -
trunk/Source/JavaScriptCore/bytecode/StructureStubInfo.h
r278656 r279105 58 58 InById, 59 59 InByVal, 60 HasPrivateName, 61 HasPrivateBrand, 60 62 InstanceOf, 61 63 DeleteByID, -
trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
r278696 r279105 265 265 VirtualRegister destination, Node* base, CacheableIdentifier, unsigned identifierNumber, DeleteByStatus, ECMAMode); 266 266 267 bool handleInByAsMatchStructure(VirtualRegister destination, Node* base, InByStatus); 267 268 void handleInById(VirtualRegister destination, Node* base, CacheableIdentifier, InByStatus); 268 269 … … 4942 4943 } 4943 4944 4945 bool 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 4944 4974 void ByteCodeParser::handleInById(VirtualRegister destination, Node* base, CacheableIdentifier identifier, InByStatus status) 4945 4975 { 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; 4969 4978 4970 4979 set(destination, addToGraph(InById, OpInfo(identifier), base)); … … 8305 8314 8306 8315 case op_has_private_name: { 8307 // FIXME: Improve this once InByVal has been optimized.8308 // https://bugs.webkit.org/show_bug.cgi?id=2261468309 8316 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)); 8311 8341 NEXT_OPCODE(op_has_private_name); 8312 8342 } 8313 8343 8314 8344 case op_has_private_brand: { 8315 // FIXME: Improve this once InByVal has been optimized.8316 // https://bugs.webkit.org/show_bug.cgi?id=2261468317 8345 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)); 8319 8369 NEXT_OPCODE(op_has_private_brand); 8320 8370 } -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
r279052 r279105 1351 1351 slowCases, this, gen.stubInfo(), stubInfoGPR, CCallHelpers::Address(stubInfoGPR, StructureStubInfo::offsetOfSlowOperation()), operationInByIdOptimize, 1352 1352 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()); 1354 1354 } else { 1355 1355 slowPath = slowPathCall( 1356 1356 slowCases, this, operationInByIdOptimize, 1357 1357 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()); 1359 1359 } 1360 1360 … … 1390 1390 RegisterSet usedRegisters = this->usedRegisters(); 1391 1391 JITInByValGenerator gen( 1392 m_jit.codeBlock(), JITType::DFGJIT, codeOrigin, callSite, usedRegisters,1392 m_jit.codeBlock(), JITType::DFGJIT, codeOrigin, callSite, AccessType::InByVal, usedRegisters, 1393 1393 JSValueRegs::payloadOnly(baseGPR), keyRegs, resultRegs, stubInfoGPR); 1394 1394 gen.generateFastPath(m_jit); … … 1401 1401 slowCases, this, gen.stubInfo(), stubInfoGPR, CCallHelpers::Address(stubInfoGPR, StructureStubInfo::offsetOfSlowOperation()), operationInByValOptimize, 1402 1402 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); 1404 1404 } else { 1405 1405 slowPath = slowPathCall( 1406 1406 slowCases, this, operationInByValOptimize, 1407 1407 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); 1409 1409 } 1410 1410 … … 1415 1415 } 1416 1416 1417 void 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 1417 1471 void SpeculativeJIT::compileHasPrivateName(Node* node) 1418 1472 { 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); 1436 1474 } 1437 1475 1438 1476 void SpeculativeJIT::compileHasPrivateBrand(Node* node) 1439 1477 { 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); 1457 1479 } 1458 1480 -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
r279041 r279105 739 739 void compileInById(Node*); 740 740 void compileInByVal(Node*); 741 void compileHasPrivate(Node*, AccessType); 741 742 void compileHasPrivateName(Node*); 742 743 void compileHasPrivateBrand(Node*); 743 744 744 745 void nonSpeculativeNonPeepholeCompareNullOrUndefined(Edge operand); 745 746 void nonSpeculativePeepholeBranchNullOrUndefined(Edge operand, Node* branchNode); -
trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp
r279029 r279105 12421 12421 } 12422 12422 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> 12436 12424 void compileInBy(LValue base, SubscriptKind subscriptValue) 12437 12425 { 12426 static_assert(type == AccessType::InById || type == AccessType::InByVal || type == AccessType::HasPrivateName || type == AccessType::HasPrivateBrand); 12438 12427 PatchpointValue* patchpoint = m_out.patchpoint(Int64); 12439 12428 patchpoint->appendSomeRegister(base); 12440 if constexpr ( kind != InByKind::ById)12429 if constexpr (type != AccessType::InById) 12441 12430 patchpoint->appendSomeRegister(subscriptValue); 12442 12431 patchpoint->append(m_notCellMask, ValueRep::lateReg(GPRInfo::notCellMaskRegister)); … … 12463 12452 auto base = JSValueRegs(params[1].gpr()); 12464 12453 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 12465 12467 const auto subscript = [&] { 12466 if constexpr ( kind == InByKind::ById)12468 if constexpr (type == AccessType::InById) 12467 12469 return CCallHelpers::TrustedImmPtr(subscriptValue.rawBits()); 12468 12470 else … … 12471 12473 12472 12474 const auto generator = [&] { 12473 if constexpr ( kind == InByKind::ById) {12475 if constexpr (type == AccessType::InById) { 12474 12476 return Box<JITInByIdGenerator>::create( 12475 12477 jit.codeBlock(), JITType::FTLJIT, semanticNodeOrigin, callSiteIndex, … … 12479 12481 return Box<JITInByValGenerator>::create( 12480 12482 jit.codeBlock(), JITType::FTLJIT, semanticNodeOrigin, callSiteIndex, 12481 params.unavailableRegisters(), base, subscript,12483 type, params.unavailableRegisters(), base, subscript, 12482 12484 JSValueRegs(returnGPR), stubInfoGPR); 12483 12485 } … … 12486 12488 CCallHelpers::JumpList slowCases; 12487 12489 generator->generateFastPath(jit); 12488 if constexpr ( kind == InByKind::ById)12490 if constexpr (type == AccessType::InById) 12489 12491 slowCases.append(generator->slowPathJump()); 12490 12492 else { … … 12501 12503 CCallHelpers::Label slowPathBegin = jit.label(); 12502 12504 CCallHelpers::Call slowPathCall; 12503 if constexpr ( kind == InByKind::ById) {12505 if constexpr (type != AccessType::InByVal) { 12504 12506 if (JITCode::useDataIC(JITType::FTLJIT)) { 12505 12507 jit.move(CCallHelpers::TrustedImmPtr(generator->stubInfo()), stubInfoGPR); 12506 generator->stubInfo()->m_slowOperation = op erationInByIdOptimize;12508 generator->stubInfo()->m_slowOperation = optimizationFunction; 12507 12509 slowPathCall = callOperation( 12508 12510 *state, params.unavailableRegisters(), jit, semanticNodeOrigin, … … 12513 12515 slowPathCall = callOperation( 12514 12516 *state, params.unavailableRegisters(), jit, semanticNodeOrigin, 12515 exceptions.get(), op erationInByIdOptimize, returnGPR,12517 exceptions.get(), optimizationFunction, returnGPR, 12516 12518 jit.codeBlock()->globalObjectFor(semanticNodeOrigin), 12517 12519 CCallHelpers::TrustedImmPtr(generator->stubInfo()), base, subscript).call(); … … 12520 12522 if (JITCode::useDataIC(JITType::FTLJIT)) { 12521 12523 jit.move(CCallHelpers::TrustedImmPtr(generator->stubInfo()), stubInfoGPR); 12522 generator->stubInfo()->m_slowOperation = op erationInByValOptimize;12524 generator->stubInfo()->m_slowOperation = optimizationFunction; 12523 12525 slowPathCall = callOperation( 12524 12526 *state, params.unavailableRegisters(), jit, semanticNodeOrigin, … … 12530 12532 slowPathCall = callOperation( 12531 12533 *state, params.unavailableRegisters(), jit, semanticNodeOrigin, 12532 exceptions.get(), op erationInByValOptimize, returnGPR,12534 exceptions.get(), optimizationFunction, returnGPR, 12533 12535 jit.codeBlock()->globalObjectFor(semanticNodeOrigin), 12534 12536 CCallHelpers::TrustedImmPtr(generator->stubInfo()), … … 12552 12554 void compileInById() 12553 12555 { 12554 compileInBy< InByKind::ById>(lowCell(m_node->child1()), m_node->cacheableIdentifier());12556 compileInBy<AccessType::InById>(lowCell(m_node->child1()), m_node->cacheableIdentifier()); 12555 12557 } 12556 12558 12557 12559 void compileInByVal() 12558 12560 { 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())); 12560 12572 } 12561 12573 -
trunk/Source/JavaScriptCore/jit/JIT.cpp
r279049 r279105 286 286 287 287 switch (opcodeID) { 288 DEFINE_SLOW_OP(has_private_name)289 DEFINE_SLOW_OP(has_private_brand)290 288 DEFINE_SLOW_OP(less) 291 289 DEFINE_SLOW_OP(lesseq) … … 362 360 DEFINE_OP(op_in_by_id) 363 361 DEFINE_OP(op_in_by_val) 362 DEFINE_OP(op_has_private_name) 363 DEFINE_OP(op_has_private_brand) 364 364 DEFINE_OP(op_get_by_id) 365 365 DEFINE_OP(op_get_by_id_with_this) … … 573 573 DEFINE_SLOWCASE_OP(op_in_by_id) 574 574 DEFINE_SLOWCASE_OP(op_in_by_val) 575 DEFINE_SLOWCASE_OP(op_has_private_name) 576 DEFINE_SLOWCASE_OP(op_has_private_brand) 575 577 DEFINE_SLOWCASE_OP(op_get_by_id) 576 578 DEFINE_SLOWCASE_OP(op_get_by_id_with_this) -
trunk/Source/JavaScriptCore/jit/JIT.h
r279049 r279105 572 572 void emit_op_in_by_id(const Instruction*); 573 573 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*); 574 576 void emit_op_init_lazy_reg(const Instruction*); 575 577 void emit_op_overrides_has_instance(const Instruction*); … … 706 708 void emitSlow_op_in_by_id(const Instruction*, Vector<SlowCaseEntry>::iterator&); 707 709 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&); 708 712 void emitSlow_op_instanceof(const Instruction*, Vector<SlowCaseEntry>::iterator&); 709 713 void emitSlow_op_instanceof_custom(const Instruction*, Vector<SlowCaseEntry>::iterator&); … … 754 758 void emitRightShiftSlowCase(const Instruction*, Vector<SlowCaseEntry>::iterator&, bool isUnsigned); 755 759 760 void emitHasPrivate(VirtualRegister dst, VirtualRegister base, VirtualRegister propertyOrBrand, AccessType); 761 void emitHasPrivateSlow(VirtualRegister dst, AccessType); 762 756 763 template<typename Op> 757 764 void emitNewFuncCommon(const Instruction*); -
trunk/Source/JavaScriptCore/jit/JITInlineCacheGenerator.cpp
r278698 r279105 250 250 } 251 251 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)252 JITInByValGenerator::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) 254 254 { 255 255 m_stubInfo->hasConstantIdentifier = false; -
trunk/Source/JavaScriptCore/jit/JITInlineCacheGenerator.h
r278656 r279105 203 203 204 204 JITInByValGenerator( 205 CodeBlock*, JITType, CodeOrigin, CallSiteIndex, const RegisterSet& usedRegisters,205 CodeBlock*, JITType, CodeOrigin, CallSiteIndex, AccessType, const RegisterSet& usedRegisters, 206 206 JSValueRegs base, JSValueRegs property, JSValueRegs result, GPRReg stubInfoGPR); 207 207 -
trunk/Source/JavaScriptCore/jit/JITOperations.cpp
r278696 r279105 509 509 } 510 510 511 JSC_DEFINE_JIT_OPERATION(operationHasPrivateName , EncodedJSValue, (JSGlobalObject* globalObject, JSCell* base, EncodedJSValue key))511 JSC_DEFINE_JIT_OPERATION(operationHasPrivateNameOptimize, EncodedJSValue, (JSGlobalObject* globalObject, StructureStubInfo* stubInfo, EncodedJSValue encodedBase, EncodedJSValue encodedProperty)) 512 512 { 513 513 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)); 522 523 return encodedJSValue(); 523 524 } 524 525 JSValue propertyValue = JSValue::decode(key); 525 JSObject* baseObject = asObject(baseValue); 526 527 JSValue propertyValue = JSValue::decode(encodedProperty); 526 528 ASSERT(propertyValue.isSymbol()); 527 529 auto property = propertyValue.toPropertyKey(globalObject); 528 530 EXCEPTION_ASSERT(!scope.exception()); 529 531 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 544 JSC_DEFINE_JIT_OPERATION(operationHasPrivateNameGeneric, EncodedJSValue, (JSGlobalObject* globalObject, StructureStubInfo* stubInfo, EncodedJSValue encodedBase, EncodedJSValue encodedProperty)) 534 545 { 535 546 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)); 544 558 return encodedJSValue(); 545 559 } 546 560 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 569 JSC_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 597 JSC_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)))); 548 615 } 549 616 -
trunk/Source/JavaScriptCore/jit/JITOperations.h
r278445 r279105 179 179 JSC_DECLARE_JIT_OPERATION(operationInByValGeneric, EncodedJSValue, (JSGlobalObject*, StructureStubInfo*, ArrayProfile*, EncodedJSValue, EncodedJSValue)); 180 180 JSC_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)); 181 JSC_DECLARE_JIT_OPERATION(operationHasPrivateNameGeneric, EncodedJSValue, (JSGlobalObject*, StructureStubInfo*, EncodedJSValue, EncodedJSValue)); 182 JSC_DECLARE_JIT_OPERATION(operationHasPrivateNameOptimize, EncodedJSValue, (JSGlobalObject*, StructureStubInfo*, EncodedJSValue, EncodedJSValue)); 183 JSC_DECLARE_JIT_OPERATION(operationHasPrivateBrandGeneric, EncodedJSValue, (JSGlobalObject*, StructureStubInfo*, EncodedJSValue, EncodedJSValue)); 184 JSC_DECLARE_JIT_OPERATION(operationHasPrivateBrandOptimize, EncodedJSValue, (JSGlobalObject*, StructureStubInfo*, EncodedJSValue, EncodedJSValue)); 183 185 184 186 JSC_DECLARE_JIT_OPERATION(operationPutByIdStrict, void, (JSGlobalObject*, StructureStubInfo*, EncodedJSValue encodedValue, EncodedJSValue encodedBase, uintptr_t)); -
trunk/Source/JavaScriptCore/jit/JITPropertyAccess.cpp
r278656 r279105 1711 1711 1712 1712 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(), 1714 1714 JSValueRegs(regT0), JSValueRegs(regT1), JSValueRegs(regT0), regT2); 1715 1715 gen.generateFastPath(*this); … … 1771 1771 1772 1772 gen.reportSlowPathCall(coldPathBegin, call); 1773 } 1774 1775 void 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 1794 void 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 1835 void 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 1841 void 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 1849 void 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 1855 void 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); 1773 1861 } 1774 1862 -
trunk/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp
r278656 r279105 925 925 926 926 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(), 928 928 JSValueRegs::payloadOnly(regT0), JSValueRegs(regT3, regT2), JSValueRegs(regT1, regT0), InvalidGPRReg); 929 929 gen.generateFastPath(*this); … … 950 950 951 951 gen.reportSlowPathCall(coldPathBegin, call); 952 } 953 954 void 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 969 void 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 981 void 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 987 void 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 995 void 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 1001 void 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); 952 1007 } 953 1008 -
trunk/Source/JavaScriptCore/jit/Repatch.cpp
r278696 r279105 923 923 } 924 924 925 inline 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 938 inline 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 925 951 static InlineCacheAction tryCacheInBy( 926 952 JSGlobalObject* globalObject, CodeBlock* codeBlock, JSObject* base, CacheableIdentifier propertyName, … … 1017 1043 if (result.generatedSomeCode()) { 1018 1044 LOG_IC((ICEvent::InReplaceWithJump, structure->classInfo(), ident, slot.slotBase() == base)); 1019 1045 1020 1046 RELEASE_ASSERT(result.code()); 1021 1022 switch (kind) { 1023 case InByKind::ById: 1047 if (kind == InByKind::ById) 1024 1048 InlineAccess::rewireStubAsJumpInAccess(codeBlock, stubInfo, CodeLocationLabel<JITStubRoutinePtrTag>(result.code())); 1025 break; 1026 case InByKind::ByVal: 1049 else 1027 1050 InlineAccess::rewireStubAsJumpInAccessNotUsingInlineAccess(codeBlock, stubInfo, CodeLocationLabel<JITStubRoutinePtrTag>(result.code())); 1028 break;1029 }1030 1051 } 1031 1052 } … … 1043 1064 if (tryCacheInBy(globalObject, codeBlock, baseObject, propertyName, wasFound, slot, stubInfo, kind) == GiveUpOnCache) { 1044 1065 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 1070 static 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 1107 void 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); 1050 1113 } 1051 1114 … … 1729 1792 void resetInBy(CodeBlock* codeBlock, StructureStubInfo& stubInfo, InByKind kind) 1730 1793 { 1731 switch (kind) { 1732 case InByKind::ById: 1733 repatchSlowPathCall(codeBlock, stubInfo, operationInByIdOptimize); 1794 repatchSlowPathCall(codeBlock, stubInfo, appropriateOptimizingInByFunction(kind)); 1795 if (kind == InByKind::ById) 1734 1796 InlineAccess::resetStubAsJumpInAccess(codeBlock, stubInfo); 1735 break; 1736 case InByKind::ByVal: 1737 repatchSlowPathCall(codeBlock, stubInfo, operationInByValOptimize); 1797 else 1738 1798 InlineAccess::resetStubAsJumpInAccessNotUsingInlineAccess(codeBlock, stubInfo); 1739 break; 1740 } 1799 } 1800 1801 void resetHasPrivateBrand(CodeBlock* codeBlock, StructureStubInfo& stubInfo) 1802 { 1803 repatchSlowPathCall(codeBlock, stubInfo, operationHasPrivateBrandOptimize); 1804 InlineAccess::resetStubAsJumpInAccessNotUsingInlineAccess(codeBlock, stubInfo); 1741 1805 } 1742 1806 -
trunk/Source/JavaScriptCore/jit/Repatch.h
r278696 r279105 51 51 enum class InByKind { 52 52 ById, 53 ByVal 53 ByVal, 54 PrivateName 54 55 }; 55 56 … … 59 60 void repatchDeleteBy(JSGlobalObject*, CodeBlock*, DeletePropertySlot&, JSValue, Structure*, CacheableIdentifier, StructureStubInfo&, DelByKind, ECMAMode); 60 61 void repatchInBy(JSGlobalObject*, CodeBlock*, JSObject*, CacheableIdentifier, bool wasFound, const PropertySlot&, StructureStubInfo&, InByKind); 62 void repatchHasPrivateBrand(JSGlobalObject*, CodeBlock*, JSObject*, CacheableIdentifier, bool wasFound, StructureStubInfo&); 61 63 void repatchCheckPrivateBrand(JSGlobalObject*, CodeBlock*, JSObject*, CacheableIdentifier, StructureStubInfo&); 62 64 void repatchSetPrivateBrand(JSGlobalObject*, CodeBlock*, JSObject*, Structure*, CacheableIdentifier, StructureStubInfo&); … … 71 73 void resetDelBy(CodeBlock*, StructureStubInfo&, DelByKind); 72 74 void resetInBy(CodeBlock*, StructureStubInfo&, InByKind); 75 void resetHasPrivateBrand(CodeBlock*, StructureStubInfo&); 73 76 void resetInstanceOf(CodeBlock*, StructureStubInfo&); 74 77 void resetCheckPrivateBrand(CodeBlock*, StructureStubInfo&); -
trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
r278591 r279105 1433 1433 } 1434 1434 1435 LLINT_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 1452 LLINT_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 1435 1464 LLINT_SLOW_PATH_DECL(slow_path_put_getter_by_id) 1436 1465 { -
trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.h
r278445 r279105 74 74 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_in_by_id); 75 75 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_in_by_val); 76 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_has_private_name); 77 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_has_private_brand); 76 78 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_del_by_id); 77 79 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_get_by_val); -
trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm
r278591 r279105 2011 2011 end 2012 2012 2013 slowPathOp(has_private_name)2014 slowPathOp(has_private_brand)2015 2013 slowPathOp(is_callable) 2016 2014 slowPathOp(is_constructor) … … 2045 2043 llintSlowPathOp(in_by_id) 2046 2044 llintSlowPathOp(in_by_val) 2045 llintSlowPathOp(has_private_name) 2046 llintSlowPathOp(has_private_brand) 2047 2047 llintSlowPathOp(del_by_id) 2048 2048 llintSlowPathOp(del_by_val) -
trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp
r278445 r279105 831 831 } 832 832 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 862 833 template<OpcodeSize width> 863 834 ALWAYS_INLINE SlowPathReturnType iteratorOpenTryFastImpl(VM& vm, JSGlobalObject* globalObject, CodeBlock* codeBlock, CallFrame* callFrame, const Instruction* pc) -
trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.h
r278445 r279105 252 252 JSC_DECLARE_COMMON_SLOW_PATH(slow_path_is_callable); 253 253 JSC_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);256 254 JSC_DECLARE_COMMON_SLOW_PATH(slow_path_strcat); 257 255 JSC_DECLARE_COMMON_SLOW_PATH(slow_path_to_primitive); -
trunk/Source/JavaScriptCore/runtime/OptionsList.h
r279048 r279105 530 530 v(Bool, usePrivateClassFields, true, Normal, "If true, the parser will understand private data fields inside classes.") \ 531 531 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.") \ 533 533 v(Bool, useWebAssemblyStreaming, true, Normal, "Allow to run WebAssembly's Streaming API") \ 534 534 v(Bool, useWebAssemblyReferences, true, Normal, "Allow types from the wasm references spec.") \
Note:
See TracChangeset
for help on using the changeset viewer.