| Differences between
and this patch
- a/Source/JavaScriptCore/ChangeLog +121 lines
Lines 1-3 a/Source/JavaScriptCore/ChangeLog_sec1
1
2021-06-02  Ross Kirsling  <ross.kirsling@sony.com>
2
3
        [JSC] Implement JIT ICs for InByVal
4
        https://bugs.webkit.org/show_bug.cgi?id=226563
5
6
        Reviewed by NOBODY (OOPS!).
7
8
        Until now, InByVal has had few optimizations implemented:
9
        DFG would attempt to convert string index lookups to InById and int32 lookups to HasIndexedProperty,
10
        but there has been no inline caching nor any special handling for symbol lookups.
11
12
        This has become a more urgent problem now, as `#x in obj` (i.e. HasPrivateName / HasPrivateBrand)
13
        will need to mimic InByVal's inline caching strategy in order to be deemed performant enough to ship.
14
15
        This patch thus implements inline caching for InByVal at all JIT tiers.
16
        The result is a night-and-day difference for symbols, a nice boost for string indices, and no change for int32s: 
17
18
        in-by-val-symbol                  203.5572+-2.7647     ^     19.1035+-0.7498        ^ definitely 10.6555x faster
19
        in-by-val-string-index             87.0368+-44.7766          45.9971+-32.0007         might be 1.8922x faster
20
        in-by-val-int32                   110.9904+-1.7109     ?    111.3431+-1.7558        ?
21
22
        * JavaScriptCore.xcodeproj/project.pbxproj:
23
        * Sources.txt:
24
        * bytecode/ICStatusMap.h:
25
        * bytecode/InByIdVariant.cpp:
26
        (JSC::InByIdVariant::InByIdVariant):
27
        (JSC::InByIdVariant::attemptToMerge):
28
        (JSC::InByIdVariant::dumpInContext const):
29
        * bytecode/InByIdVariant.h:
30
        (JSC::InByIdVariant::identifier const):
31
        (JSC::InByIdVariant::overlaps):
32
        * bytecode/InByStatus.cpp: Renamed from Source/JavaScriptCore/bytecode/InByIdStatus.cpp.
33
        * bytecode/InByStatus.h: Renamed from Source/JavaScriptCore/bytecode/InByIdStatus.h.
34
        * bytecode/RecordedStatuses.cpp:
35
        (JSC::RecordedStatuses::addInByStatus): Renamed from addInByIdStatus.
36
        * bytecode/RecordedStatuses.h:
37
        * bytecode/StructureStubInfo.cpp:
38
        (JSC::StructureStubInfo::reset):
39
        * bytecode/StructureStubInfo.h:
40
        * dfg/DFGAbstractInterpreterInlines.h:
41
        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
42
        (JSC::DFG::AbstractInterpreter<AbstractStateType>::filterICStatus):
43
        * dfg/DFGArgumentsEliminationPhase.cpp:
44
        * dfg/DFGByteCodeParser.cpp:
45
        (JSC::DFG::ByteCodeParser::handleInById):
46
        (JSC::DFG::ByteCodeParser::parseBlock):
47
        * dfg/DFGClobberize.h:
48
        (JSC::DFG::clobberize):
49
        * dfg/DFGClobbersExitState.cpp:
50
        (JSC::DFG::clobbersExitState):
51
        * dfg/DFGDoesGC.cpp:
52
        (JSC::DFG::doesGC):
53
        * dfg/DFGFixupPhase.cpp:
54
        (JSC::DFG::FixupPhase::fixupNode):
55
        * dfg/DFGGraph.cpp:
56
        (JSC::DFG::Graph::dump):
57
        * dfg/DFGJITCompiler.cpp:
58
        (JSC::DFG::JITCompiler::link):
59
        * dfg/DFGJITCompiler.h:
60
        (JSC::DFG::JITCompiler::addInByVal):
61
        * dfg/DFGMayExit.cpp:
62
        * dfg/DFGNode.h:
63
        (JSC::DFG::Node::hasInByStatus): Renamed from hasInByIdStatus.
64
        (JSC::DFG::Node::inByStatus): Renamed from inByIdStatus.
65
        * dfg/DFGNodeType.h:
66
        * dfg/DFGObjectAllocationSinkingPhase.cpp:
67
        * dfg/DFGPredictionPropagationPhase.cpp:
68
        * dfg/DFGSafeToExecute.h:
69
        (JSC::DFG::safeToExecute):
70
        * dfg/DFGSpeculativeJIT.cpp:
71
        (JSC::DFG::SpeculativeJIT::compileInByVal):
72
        * dfg/DFGSpeculativeJIT32_64.cpp:
73
        (JSC::DFG::SpeculativeJIT::compile):
74
        * dfg/DFGSpeculativeJIT64.cpp:
75
        (JSC::DFG::SpeculativeJIT::compile):
76
        * dfg/DFGVarargsForwardingPhase.cpp:
77
        * ftl/FTLCapabilities.cpp:
78
        (JSC::FTL::canCompile):
79
        * ftl/FTLLowerDFGToB3.cpp:
80
        (JSC::FTL::DFG::LowerDFGToB3::compileNode):
81
        (JSC::FTL::DFG::LowerDFGToB3::compileInBy):
82
        (JSC::FTL::DFG::LowerDFGToB3::compileInById):
83
        (JSC::FTL::DFG::LowerDFGToB3::compileInByVal):
84
        * jit/ICStats.h:
85
        * jit/JIT.cpp:
86
        (JSC::JIT::privateCompileMainPass):
87
        (JSC::JIT::privateCompileSlowCases):
88
        (JSC::JIT::link):
89
        * jit/JIT.h:
90
        * jit/JITInlineCacheGenerator.cpp:
91
        (JSC::JITInByValGenerator::JITInByValGenerator):
92
        (JSC::JITInByValGenerator::generateFastPath):
93
        (JSC::JITInByValGenerator::finalize):
94
        (JSC::JITInByIdGenerator::JITInByIdGenerator):
95
        * jit/JITInlineCacheGenerator.h:
96
        (JSC::JITDelByIdGenerator::slowPathJump const):
97
        (JSC::JITInByValGenerator::JITInByValGenerator):
98
        (JSC::JITInByValGenerator::slowPathJump const):
99
        * jit/JITOperations.cpp:
100
        (JSC::JSC_DEFINE_JIT_OPERATION):
101
        * jit/JITOperations.h:
102
        * jit/JITPropertyAccess.cpp:
103
        (JSC::JIT::emit_op_in_by_val):
104
        (JSC::JIT::emitSlow_op_in_by_val):
105
        * jit/JITPropertyAccess32_64.cpp:
106
        (JSC::JIT::emit_op_in_by_val):
107
        (JSC::JIT::emitSlow_op_in_by_val):
108
        * jit/JITThunks.cpp:
109
        (JSC::JITThunks::preinitializeCTIThunks):
110
        * jit/Repatch.cpp:
111
        (JSC::tryCacheInBy): Renamed from tryCacheInByID.
112
        (JSC::repatchInBy): Renamed from repatchInByID.
113
        (JSC::resetInBy): Renamed from resetInByID.
114
        * jit/Repatch.h:
115
        * llint/LLIntSlowPaths.cpp:
116
        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
117
        * llint/LLIntSlowPaths.h:
118
        * llint/LowLevelInterpreter.asm:
119
        * runtime/CommonSlowPaths.cpp:
120
        * runtime/CommonSlowPaths.h:
121
1
2021-05-24  Keith Miller  <keith_miller@apple.com>
122
2021-05-24  Keith Miller  <keith_miller@apple.com>
2
123
3
        Unreviewed, revert r276610 because it causes a 1% PLT regression.
124
        Unreviewed, revert r276610 because it causes a 1% PLT regression.
- a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj -11 / +15 lines
Lines 1402-1408 a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec1
1402
		A1D792FF1B43864B004516F5 /* IntlNumberFormatConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = A1D792F91B43864B004516F5 /* IntlNumberFormatConstructor.h */; };
1402
		A1D792FF1B43864B004516F5 /* IntlNumberFormatConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = A1D792F91B43864B004516F5 /* IntlNumberFormatConstructor.h */; };
1403
		A1D793011B43864B004516F5 /* IntlNumberFormatPrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = A1D792FB1B43864B004516F5 /* IntlNumberFormatPrototype.h */; };
1403
		A1D793011B43864B004516F5 /* IntlNumberFormatPrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = A1D792FB1B43864B004516F5 /* IntlNumberFormatPrototype.h */; };
1404
		A321AA6D2626359B0023ADA2 /* IntlWorkaround.h in Headers */ = {isa = PBXBuildFile; fileRef = A321AA6C2626359B0023ADA2 /* IntlWorkaround.h */; };
1404
		A321AA6D2626359B0023ADA2 /* IntlWorkaround.h in Headers */ = {isa = PBXBuildFile; fileRef = A321AA6C2626359B0023ADA2 /* IntlWorkaround.h */; };
1405
		A382C5312667111D0042CD99 /* InByIdVariant.h in Headers */ = {isa = PBXBuildFile; fileRef = E3305FB120B0F78800CEB82B /* InByIdVariant.h */; settings = {ATTRIBUTES = (Private, ); }; };
1405
		A38D250E25800D440042BFDD /* JSArrayBufferPrototypeInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = A38D250D25800D430042BFDD /* JSArrayBufferPrototypeInlines.h */; };
1406
		A38D250E25800D440042BFDD /* JSArrayBufferPrototypeInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = A38D250D25800D430042BFDD /* JSArrayBufferPrototypeInlines.h */; };
1407
		A38D5BFC2666D3DA00A109A6 /* InByStatus.h in Headers */ = {isa = PBXBuildFile; fileRef = A38D5BFA2666D3DA00A109A6 /* InByStatus.h */; settings = {ATTRIBUTES = (Private, ); }; };
1406
		A3EE8543262514B000FC9B8D /* IntlWorkaround.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A37619402625127C00CBCBA9 /* IntlWorkaround.cpp */; };
1408
		A3EE8543262514B000FC9B8D /* IntlWorkaround.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A37619402625127C00CBCBA9 /* IntlWorkaround.cpp */; };
1407
		A3FF9BC72234749100B1A9AB /* YarrFlags.h in Headers */ = {isa = PBXBuildFile; fileRef = A3FF9BC52234746600B1A9AB /* YarrFlags.h */; settings = {ATTRIBUTES = (Private, ); }; };
1409
		A3FF9BC72234749100B1A9AB /* YarrFlags.h in Headers */ = {isa = PBXBuildFile; fileRef = A3FF9BC52234746600B1A9AB /* YarrFlags.h */; settings = {ATTRIBUTES = (Private, ); }; };
1408
		A503FA1A188E0FB000110F14 /* JavaScriptCallFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = A503FA14188E0FAF00110F14 /* JavaScriptCallFrame.h */; };
1410
		A503FA1A188E0FB000110F14 /* JavaScriptCallFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = A503FA14188E0FAF00110F14 /* JavaScriptCallFrame.h */; };
Lines 4432-4437 a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec2
4432
		A321AA6C2626359B0023ADA2 /* IntlWorkaround.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IntlWorkaround.h; sourceTree = "<group>"; };
4434
		A321AA6C2626359B0023ADA2 /* IntlWorkaround.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IntlWorkaround.h; sourceTree = "<group>"; };
4433
		A37619402625127C00CBCBA9 /* IntlWorkaround.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IntlWorkaround.cpp; sourceTree = "<group>"; };
4435
		A37619402625127C00CBCBA9 /* IntlWorkaround.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IntlWorkaround.cpp; sourceTree = "<group>"; };
4434
		A38D250D25800D430042BFDD /* JSArrayBufferPrototypeInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSArrayBufferPrototypeInlines.h; sourceTree = "<group>"; };
4436
		A38D250D25800D430042BFDD /* JSArrayBufferPrototypeInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSArrayBufferPrototypeInlines.h; sourceTree = "<group>"; };
4437
		A38D5BF92666D3DA00A109A6 /* InByStatus.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InByStatus.cpp; sourceTree = "<group>"; };
4438
		A38D5BFA2666D3DA00A109A6 /* InByStatus.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InByStatus.h; sourceTree = "<group>"; };
4435
		A3AFF92B245A3CF900C9BA3B /* IntlLocale.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IntlLocale.h; sourceTree = "<group>"; };
4439
		A3AFF92B245A3CF900C9BA3B /* IntlLocale.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IntlLocale.h; sourceTree = "<group>"; };
4436
		A3AFF92C245A3CFA00C9BA3B /* IntlLocaleConstructor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IntlLocaleConstructor.h; sourceTree = "<group>"; };
4440
		A3AFF92C245A3CFA00C9BA3B /* IntlLocaleConstructor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IntlLocaleConstructor.h; sourceTree = "<group>"; };
4437
		A3AFF92D245A3CFA00C9BA3B /* IntlLocale.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IntlLocale.cpp; sourceTree = "<group>"; };
4441
		A3AFF92D245A3CFA00C9BA3B /* IntlLocale.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IntlLocale.cpp; sourceTree = "<group>"; };
Lines 5060-5069 a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec3
5060
		E3282BB91FE930A300EDAF71 /* YarrErrorCode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = YarrErrorCode.cpp; path = yarr/YarrErrorCode.cpp; sourceTree = "<group>"; };
5064
		E3282BB91FE930A300EDAF71 /* YarrErrorCode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = YarrErrorCode.cpp; path = yarr/YarrErrorCode.cpp; sourceTree = "<group>"; };
5061
		E3282BBA1FE930A400EDAF71 /* YarrErrorCode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = YarrErrorCode.h; path = yarr/YarrErrorCode.h; sourceTree = "<group>"; };
5065
		E3282BBA1FE930A400EDAF71 /* YarrErrorCode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = YarrErrorCode.h; path = yarr/YarrErrorCode.h; sourceTree = "<group>"; };
5062
		E32C3C6823E94C1E00BC97C0 /* UnlinkedCodeBlockGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UnlinkedCodeBlockGenerator.h; sourceTree = "<group>"; };
5066
		E32C3C6823E94C1E00BC97C0 /* UnlinkedCodeBlockGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UnlinkedCodeBlockGenerator.h; sourceTree = "<group>"; };
5063
		E3305FAF20B0F78700CEB82B /* InByIdStatus.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InByIdStatus.h; sourceTree = "<group>"; };
5064
		E3305FB020B0F78700CEB82B /* InByIdVariant.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InByIdVariant.cpp; sourceTree = "<group>"; };
5067
		E3305FB020B0F78700CEB82B /* InByIdVariant.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InByIdVariant.cpp; sourceTree = "<group>"; };
5065
		E3305FB120B0F78800CEB82B /* InByIdVariant.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InByIdVariant.h; sourceTree = "<group>"; };
5068
		E3305FB120B0F78800CEB82B /* InByIdVariant.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InByIdVariant.h; sourceTree = "<group>"; };
5066
		E3305FB220B0F78800CEB82B /* InByIdStatus.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InByIdStatus.cpp; sourceTree = "<group>"; };
5067
		E33095DC23210A1400EB7856 /* JSInternalFieldObjectImpl.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JSInternalFieldObjectImpl.h; sourceTree = "<group>"; };
5069
		E33095DC23210A1400EB7856 /* JSInternalFieldObjectImpl.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JSInternalFieldObjectImpl.h; sourceTree = "<group>"; };
5068
		E334CBB221FD96A8000EB178 /* RegExpGlobalData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RegExpGlobalData.cpp; sourceTree = "<group>"; };
5070
		E334CBB221FD96A8000EB178 /* RegExpGlobalData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RegExpGlobalData.cpp; sourceTree = "<group>"; };
5069
		E334CBB321FD96A9000EB178 /* RegExpGlobalData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegExpGlobalData.h; sourceTree = "<group>"; };
5071
		E334CBB321FD96A9000EB178 /* RegExpGlobalData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegExpGlobalData.h; sourceTree = "<group>"; };
Lines 8580-8589 a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec4
8580
				0F44A7AF20BF685F0022B171 /* ICStatusMap.h */,
8582
				0F44A7AF20BF685F0022B171 /* ICStatusMap.h */,
8581
				0F44A7B520C0BE3F0022B171 /* ICStatusUtils.cpp */,
8583
				0F44A7B520C0BE3F0022B171 /* ICStatusUtils.cpp */,
8582
				0FB399BD20AF6B380017E213 /* ICStatusUtils.h */,
8584
				0FB399BD20AF6B380017E213 /* ICStatusUtils.h */,
8583
				E3305FB220B0F78800CEB82B /* InByIdStatus.cpp */,
8584
				E3305FAF20B0F78700CEB82B /* InByIdStatus.h */,
8585
				E3305FB020B0F78700CEB82B /* InByIdVariant.cpp */,
8585
				E3305FB020B0F78700CEB82B /* InByIdVariant.cpp */,
8586
				E3305FB120B0F78800CEB82B /* InByIdVariant.h */,
8586
				E3305FB120B0F78800CEB82B /* InByIdVariant.h */,
8587
				A38D5BF92666D3DA00A109A6 /* InByStatus.cpp */,
8588
				A38D5BFA2666D3DA00A109A6 /* InByStatus.h */,
8587
				7905BB661D12050E0019FE57 /* InlineAccess.cpp */,
8589
				7905BB661D12050E0019FE57 /* InlineAccess.cpp */,
8588
				7905BB671D12050E0019FE57 /* InlineAccess.h */,
8590
				7905BB671D12050E0019FE57 /* InlineAccess.h */,
8589
				148A7BED1B82975A002D9157 /* InlineCallFrame.cpp */,
8591
				148A7BED1B82975A002D9157 /* InlineCallFrame.cpp */,
Lines 9458-9464 a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec5
9458
				BC18C45E0E16F5CD00B34460 /* CLoopStack.h in Headers */,
9460
				BC18C45E0E16F5CD00B34460 /* CLoopStack.h in Headers */,
9459
				A7C1EAF017987AB600299DB2 /* CLoopStackInlines.h in Headers */,
9461
				A7C1EAF017987AB600299DB2 /* CLoopStackInlines.h in Headers */,
9460
				969A07970ED1D3AE00F1F681 /* CodeBlock.h in Headers */,
9462
				969A07970ED1D3AE00F1F681 /* CodeBlock.h in Headers */,
9461
				FEF5B4292628B5240016E776 /* JSSetInlines.h in Headers */,
9462
				0F8F94411667633200D61971 /* CodeBlockHash.h in Headers */,
9463
				0F8F94411667633200D61971 /* CodeBlockHash.h in Headers */,
9463
				0FC97F34182020D7002C9B26 /* CodeBlockJettisoningWatchpoint.h in Headers */,
9464
				0FC97F34182020D7002C9B26 /* CodeBlockJettisoningWatchpoint.h in Headers */,
9464
				0FD8A31417D4326C00CA2C40 /* CodeBlockSet.h in Headers */,
9465
				0FD8A31417D4326C00CA2C40 /* CodeBlockSet.h in Headers */,
Lines 9657-9663 a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec6
9657
				0FD82E57141DAF1000179C94 /* DFGOSREntry.h in Headers */,
9658
				0FD82E57141DAF1000179C94 /* DFGOSREntry.h in Headers */,
9658
				0FD8A32617D51F5700CA2C40 /* DFGOSREntrypointCreationPhase.h in Headers */,
9659
				0FD8A32617D51F5700CA2C40 /* DFGOSREntrypointCreationPhase.h in Headers */,
9659
				0FC0976A1468A6F700CF2442 /* DFGOSRExit.h in Headers */,
9660
				0FC0976A1468A6F700CF2442 /* DFGOSRExit.h in Headers */,
9660
				FEF5B4272628ABD90016E776 /* JSWeakMapInlines.h in Headers */,
9661
				0F235BEC17178E7300690C7F /* DFGOSRExitBase.h in Headers */,
9661
				0F235BEC17178E7300690C7F /* DFGOSRExitBase.h in Headers */,
9662
				0FFB921C16D02F110055A5DB /* DFGOSRExitCompilationInfo.h in Headers */,
9662
				0FFB921C16D02F110055A5DB /* DFGOSRExitCompilationInfo.h in Headers */,
9663
				0F7025AA1714B0FC00382C0E /* DFGOSRExitCompilerCommon.h in Headers */,
9663
				0F7025AA1714B0FC00382C0E /* DFGOSRExitCompilerCommon.h in Headers */,
Lines 9752-9757 a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec7
9752
				147341D21DC02E2E00AA29BA /* EvalExecutable.h in Headers */,
9752
				147341D21DC02E2E00AA29BA /* EvalExecutable.h in Headers */,
9753
				FE1C0FFD1B193E9800B53FCA /* Exception.h in Headers */,
9753
				FE1C0FFD1B193E9800B53FCA /* Exception.h in Headers */,
9754
				FE6029D91D6E1E4F0030204D /* ExceptionEventLocation.h in Headers */,
9754
				FE6029D91D6E1E4F0030204D /* ExceptionEventLocation.h in Headers */,
9755
				FEF5B430262A338B0016E776 /* ExceptionExpectation.h in Headers */,
9755
				0F12DE101979D5FD0006FF4E /* ExceptionFuzz.h in Headers */,
9756
				0F12DE101979D5FD0006FF4E /* ExceptionFuzz.h in Headers */,
9756
				BC18C4000E16F5CD00B34460 /* ExceptionHelpers.h in Headers */,
9757
				BC18C4000E16F5CD00B34460 /* ExceptionHelpers.h in Headers */,
9757
				FE6491371D78F01D00A694D4 /* ExceptionScope.h in Headers */,
9758
				FE6491371D78F01D00A694D4 /* ExceptionScope.h in Headers */,
Lines 9788-9794 a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec8
9788
				0FEA0A0C170513DB00BB722C /* FTLCompile.h in Headers */,
9789
				0FEA0A0C170513DB00BB722C /* FTLCompile.h in Headers */,
9789
				0F9D4C0D1C3E1C11006CD984 /* FTLExceptionTarget.h in Headers */,
9790
				0F9D4C0D1C3E1C11006CD984 /* FTLExceptionTarget.h in Headers */,
9790
				0F235BD417178E1C00690C7F /* FTLExitArgument.h in Headers */,
9791
				0F235BD417178E1C00690C7F /* FTLExitArgument.h in Headers */,
9791
				FEF5B4232628A0EE0016E776 /* HashMapImplInlines.h in Headers */,
9792
				0F235BD617178E1C00690C7F /* FTLExitArgumentForOperand.h in Headers */,
9792
				0F235BD617178E1C00690C7F /* FTLExitArgumentForOperand.h in Headers */,
9793
				0F2B9CF519D0BAC100B1D1B5 /* FTLExitPropertyValue.h in Headers */,
9793
				0F2B9CF519D0BAC100B1D1B5 /* FTLExitPropertyValue.h in Headers */,
9794
				0F2B9CF719D0BAC100B1D1B5 /* FTLExitTimeObjectMaterialization.h in Headers */,
9794
				0F2B9CF719D0BAC100B1D1B5 /* FTLExitTimeObjectMaterialization.h in Headers */,
Lines 9832-9838 a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec9
9832
				2A83638A18D7D0FE0000EBCC /* FullGCActivityCallback.h in Headers */,
9832
				2A83638A18D7D0FE0000EBCC /* FullGCActivityCallback.h in Headers */,
9833
				52EED7942492B870008F4C93 /* FunctionAllowlist.h in Headers */,
9833
				52EED7942492B870008F4C93 /* FunctionAllowlist.h in Headers */,
9834
				14AD910D1DCA92940014F9FE /* FunctionCodeBlock.h in Headers */,
9834
				14AD910D1DCA92940014F9FE /* FunctionCodeBlock.h in Headers */,
9835
				FEF5B42C2628CBC80016E776 /* VMTrapsInlines.h in Headers */,
9836
				BC18C4040E16F5CD00B34460 /* FunctionConstructor.h in Headers */,
9835
				BC18C4040E16F5CD00B34460 /* FunctionConstructor.h in Headers */,
9837
				147341D81DC02F9900AA29BA /* FunctionExecutable.h in Headers */,
9836
				147341D81DC02F9900AA29BA /* FunctionExecutable.h in Headers */,
9838
				0FF0F1A016B72A1A005DF95B /* FunctionExecutableDump.h in Headers */,
9837
				0FF0F1A016B72A1A005DF95B /* FunctionExecutableDump.h in Headers */,
Lines 9911-9916 a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec10
9911
				142E3136134FF0A600AFADB5 /* HandleSet.h in Headers */,
9910
				142E3136134FF0A600AFADB5 /* HandleSet.h in Headers */,
9912
				1478297B1379E8A800A7C2A3 /* HandleTypes.h in Headers */,
9911
				1478297B1379E8A800A7C2A3 /* HandleTypes.h in Headers */,
9913
				79A090801D768465008B889B /* HashMapImpl.h in Headers */,
9912
				79A090801D768465008B889B /* HashMapImpl.h in Headers */,
9913
				FEF5B4232628A0EE0016E776 /* HashMapImplInlines.h in Headers */,
9914
				79DFCBDB1D88C59600527D03 /* HasOwnPropertyCache.h in Headers */,
9914
				79DFCBDB1D88C59600527D03 /* HasOwnPropertyCache.h in Headers */,
9915
				14BA7A9813AADFF8005B7C2C /* Heap.h in Headers */,
9915
				14BA7A9813AADFF8005B7C2C /* Heap.h in Headers */,
9916
				9177A1DC22F958D500B34CA2 /* HeapAnalyzer.h in Headers */,
9916
				9177A1DC22F958D500B34CA2 /* HeapAnalyzer.h in Headers */,
Lines 9933-9938 a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec11
9933
				BC18C40F0E16F5CD00B34460 /* Identifier.h in Headers */,
9933
				BC18C40F0E16F5CD00B34460 /* Identifier.h in Headers */,
9934
				8606DDEA18DA44AB00A383D0 /* IdentifierInlines.h in Headers */,
9934
				8606DDEA18DA44AB00A383D0 /* IdentifierInlines.h in Headers */,
9935
				A5FD0076189B038C00633231 /* IdentifiersFactory.h in Headers */,
9935
				A5FD0076189B038C00633231 /* IdentifiersFactory.h in Headers */,
9936
				A382C5312667111D0042CD99 /* InByIdVariant.h in Headers */,
9937
				A38D5BFC2666D3DA00A109A6 /* InByStatus.h in Headers */,
9936
				C25F8BCE157544A900245B71 /* IncrementalSweeper.h in Headers */,
9938
				C25F8BCE157544A900245B71 /* IncrementalSweeper.h in Headers */,
9937
				0FB7F39915ED8E4600F167B2 /* IndexingHeader.h in Headers */,
9939
				0FB7F39915ED8E4600F167B2 /* IndexingHeader.h in Headers */,
9938
				0FB7F39A15ED8E4600F167B2 /* IndexingHeaderInlines.h in Headers */,
9940
				0FB7F39A15ED8E4600F167B2 /* IndexingHeaderInlines.h in Headers */,
Lines 10184-10189 a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec12
10184
				C25D709C16DE99F400FCA6BC /* JSManagedValue.h in Headers */,
10186
				C25D709C16DE99F400FCA6BC /* JSManagedValue.h in Headers */,
10185
				2A4BB7F318A41179008A0FCD /* JSManagedValueInternal.h in Headers */,
10187
				2A4BB7F318A41179008A0FCD /* JSManagedValueInternal.h in Headers */,
10186
				A700874217CBE8EB00C3E643 /* JSMap.h in Headers */,
10188
				A700874217CBE8EB00C3E643 /* JSMap.h in Headers */,
10189
				FEF5B4252628A8500016E776 /* JSMapInlines.h in Headers */,
10187
				A74DEF96182D991400522C22 /* JSMapIterator.h in Headers */,
10190
				A74DEF96182D991400522C22 /* JSMapIterator.h in Headers */,
10188
				0F0B286D1EB8E6D5000EB5D2 /* JSMarkingConstraintPrivate.h in Headers */,
10191
				0F0B286D1EB8E6D5000EB5D2 /* JSMarkingConstraintPrivate.h in Headers */,
10189
				7013CA8C1B491A9400CAE613 /* JSMicrotask.h in Headers */,
10192
				7013CA8C1B491A9400CAE613 /* JSMicrotask.h in Headers */,
Lines 10219-10224 a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec13
10219
				14D01A7721FB351F00BC54E9 /* JSScriptSourceProvider.h in Headers */,
10222
				14D01A7721FB351F00BC54E9 /* JSScriptSourceProvider.h in Headers */,
10220
				0F919D11157F332C004A4E7D /* JSSegmentedVariableObject.h in Headers */,
10223
				0F919D11157F332C004A4E7D /* JSSegmentedVariableObject.h in Headers */,
10221
				A7299D9E17D12837005F5FF9 /* JSSet.h in Headers */,
10224
				A7299D9E17D12837005F5FF9 /* JSSet.h in Headers */,
10225
				FEF5B4292628B5240016E776 /* JSSetInlines.h in Headers */,
10222
				A790DD70182F499700588807 /* JSSetIterator.h in Headers */,
10226
				A790DD70182F499700588807 /* JSSetIterator.h in Headers */,
10223
				BDFCB2BBE90F41349E1B0BED /* JSSourceCode.h in Headers */,
10227
				BDFCB2BBE90F41349E1B0BED /* JSSourceCode.h in Headers */,
10224
				BC18C4270E16F5CD00B34460 /* JSString.h in Headers */,
10228
				BC18C4270E16F5CD00B34460 /* JSString.h in Headers */,
Lines 10247-10258 a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec14
10247
				86E3C612167BABD7006D760A /* JSValue.h in Headers */,
10251
				86E3C612167BABD7006D760A /* JSValue.h in Headers */,
10248
				86E3C61B167BABEE006D760A /* JSValueInternal.h in Headers */,
10252
				86E3C61B167BABEE006D760A /* JSValueInternal.h in Headers */,
10249
				53E1F8F82154715A0001DDBC /* JSValuePrivate.h in Headers */,
10253
				53E1F8F82154715A0001DDBC /* JSValuePrivate.h in Headers */,
10250
				FE8C0312264A6911001A44AD /* SlowPathFunction.h in Headers */,
10251
				BC18C42C0E16F5CD00B34460 /* JSValueRef.h in Headers */,
10254
				BC18C42C0E16F5CD00B34460 /* JSValueRef.h in Headers */,
10252
				86E3C615167BABD7006D760A /* JSVirtualMachine.h in Headers */,
10255
				86E3C615167BABD7006D760A /* JSVirtualMachine.h in Headers */,
10253
				86E3C61D167BABEE006D760A /* JSVirtualMachineInternal.h in Headers */,
10256
				86E3C61D167BABEE006D760A /* JSVirtualMachineInternal.h in Headers */,
10254
				795AC61820A2355E0052C76C /* JSVirtualMachinePrivate.h in Headers */,
10257
				795AC61820A2355E0052C76C /* JSVirtualMachinePrivate.h in Headers */,
10255
				A7CA3AE817DA41AE006538AF /* JSWeakMap.h in Headers */,
10258
				A7CA3AE817DA41AE006538AF /* JSWeakMap.h in Headers */,
10259
				FEF5B4272628ABD90016E776 /* JSWeakMapInlines.h in Headers */,
10256
				A7482E93116A7CAD003B0712 /* JSWeakObjectMapRefInternal.h in Headers */,
10260
				A7482E93116A7CAD003B0712 /* JSWeakObjectMapRefInternal.h in Headers */,
10257
				A7482B9311671147003B0712 /* JSWeakObjectMapRefPrivate.h in Headers */,
10261
				A7482B9311671147003B0712 /* JSWeakObjectMapRefPrivate.h in Headers */,
10258
				539BFBB022AD3CDC0023F4C0 /* JSWeakObjectRef.h in Headers */,
10262
				539BFBB022AD3CDC0023F4C0 /* JSWeakObjectRef.h in Headers */,
Lines 10531-10536 a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec15
10531
				C2160FE715F7E95E00942DFC /* SlotVisitorInlines.h in Headers */,
10535
				C2160FE715F7E95E00942DFC /* SlotVisitorInlines.h in Headers */,
10532
				FE041553252EC0730091EB5D /* SlotVisitorMacros.h in Headers */,
10536
				FE041553252EC0730091EB5D /* SlotVisitorMacros.h in Headers */,
10533
				A709F2F017A0AC0400512E98 /* SlowPathCall.h in Headers */,
10537
				A709F2F017A0AC0400512E98 /* SlowPathCall.h in Headers */,
10538
				FE8C0312264A6911001A44AD /* SlowPathFunction.h in Headers */,
10534
				0F5B4A331C84F0D600F1B17E /* SlowPathReturnType.h in Headers */,
10539
				0F5B4A331C84F0D600F1B17E /* SlowPathReturnType.h in Headers */,
10535
				933040040E6A749400786E6A /* SmallStrings.h in Headers */,
10540
				933040040E6A749400786E6A /* SmallStrings.h in Headers */,
10536
				E3F23A821ECF13FE00978D99 /* Snippet.h in Headers */,
10541
				E3F23A821ECF13FE00978D99 /* Snippet.h in Headers */,
Lines 10568-10574 a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec16
10568
				BCDE3AB80E6C82F5001453A7 /* Structure.h in Headers */,
10573
				BCDE3AB80E6C82F5001453A7 /* Structure.h in Headers */,
10569
				7986943B1F8C0ACC009232AE /* StructureCache.h in Headers */,
10574
				7986943B1F8C0ACC009232AE /* StructureCache.h in Headers */,
10570
				7E4EE7090EBB7963005934AA /* StructureChain.h in Headers */,
10575
				7E4EE7090EBB7963005934AA /* StructureChain.h in Headers */,
10571
				FEF5B4252628A8500016E776 /* JSMapInlines.h in Headers */,
10572
				2AAAA31218BD49D100394CC8 /* StructureIDBlob.h in Headers */,
10576
				2AAAA31218BD49D100394CC8 /* StructureIDBlob.h in Headers */,
10573
				2AF7382D18BBBF92008A5A37 /* StructureIDTable.h in Headers */,
10577
				2AF7382D18BBBF92008A5A37 /* StructureIDTable.h in Headers */,
10574
				0FD2C92416D01EE900C7803F /* StructureInlines.h in Headers */,
10578
				0FD2C92416D01EE900C7803F /* StructureInlines.h in Headers */,
Lines 10661-10666 a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec17
10661
				FE3022D71E42857300BAC493 /* VMInspector.h in Headers */,
10665
				FE3022D71E42857300BAC493 /* VMInspector.h in Headers */,
10662
				FEC5797323105B5100BCA83F /* VMInspectorInlines.h in Headers */,
10666
				FEC5797323105B5100BCA83F /* VMInspectorInlines.h in Headers */,
10663
				FE6F56DE1E64EAD600D17801 /* VMTraps.h in Headers */,
10667
				FE6F56DE1E64EAD600D17801 /* VMTraps.h in Headers */,
10668
				FEF5B42C2628CBC80016E776 /* VMTrapsInlines.h in Headers */,
10664
				52847ADC21FFB8690061A9DB /* WasmAirIRGenerator.h in Headers */,
10669
				52847ADC21FFB8690061A9DB /* WasmAirIRGenerator.h in Headers */,
10665
				53F40E931D5A4AB30099A1B6 /* WasmB3IRGenerator.h in Headers */,
10670
				53F40E931D5A4AB30099A1B6 /* WasmB3IRGenerator.h in Headers */,
10666
				53CA730A1EA533D80076049D /* WasmBBQPlan.h in Headers */,
10671
				53CA730A1EA533D80076049D /* WasmBBQPlan.h in Headers */,
Lines 10753-10759 a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec18
10753
				ADE8029A1E08F1DE0058DE78 /* WebAssemblyLinkErrorConstructor.h in Headers */,
10758
				ADE8029A1E08F1DE0058DE78 /* WebAssemblyLinkErrorConstructor.h in Headers */,
10754
				ADE8029C1E08F1DE0058DE78 /* WebAssemblyLinkErrorPrototype.h in Headers */,
10759
				ADE8029C1E08F1DE0058DE78 /* WebAssemblyLinkErrorPrototype.h in Headers */,
10755
				AD2FCBF51DB58DAD00B3E736 /* WebAssemblyMemoryConstructor.h in Headers */,
10760
				AD2FCBF51DB58DAD00B3E736 /* WebAssemblyMemoryConstructor.h in Headers */,
10756
				FEF5B430262A338B0016E776 /* ExceptionExpectation.h in Headers */,
10757
				AD2FCC1A1DB59CB200B3E736 /* WebAssemblyMemoryConstructor.lut.h in Headers */,
10761
				AD2FCC1A1DB59CB200B3E736 /* WebAssemblyMemoryConstructor.lut.h in Headers */,
10758
				AD2FCBF71DB58DAD00B3E736 /* WebAssemblyMemoryPrototype.h in Headers */,
10762
				AD2FCBF71DB58DAD00B3E736 /* WebAssemblyMemoryPrototype.h in Headers */,
10759
				AD2FCC1B1DB59CB200B3E736 /* WebAssemblyMemoryPrototype.lut.h in Headers */,
10763
				AD2FCC1B1DB59CB200B3E736 /* WebAssemblyMemoryPrototype.lut.h in Headers */,
- a/Source/JavaScriptCore/Sources.txt -1 / +1 lines
Lines 240-246 bytecode/GetByIdVariant.cpp a/Source/JavaScriptCore/Sources.txt_sec1
240
bytecode/GetterSetterAccessCase.cpp
240
bytecode/GetterSetterAccessCase.cpp
241
bytecode/ICStatusMap.cpp
241
bytecode/ICStatusMap.cpp
242
bytecode/ICStatusUtils.cpp
242
bytecode/ICStatusUtils.cpp
243
bytecode/InByIdStatus.cpp
243
bytecode/InByStatus.cpp
244
bytecode/InByIdVariant.cpp
244
bytecode/InByIdVariant.cpp
245
bytecode/InlineAccess.cpp
245
bytecode/InlineAccess.cpp
246
bytecode/InlineCallFrame.cpp
246
bytecode/InlineCallFrame.cpp
- a/Source/JavaScriptCore/bytecode/ICStatusMap.h -2 / +2 lines
Lines 35-41 class CallLinkInfo; a/Source/JavaScriptCore/bytecode/ICStatusMap.h_sec1
35
class CallLinkStatus;
35
class CallLinkStatus;
36
class CodeBlock;
36
class CodeBlock;
37
class GetByStatus;
37
class GetByStatus;
38
class InByIdStatus;
38
class InByStatus;
39
class PutByIdStatus;
39
class PutByIdStatus;
40
class DeleteByStatus;
40
class DeleteByStatus;
41
class StructureStubInfo;
41
class StructureStubInfo;
Lines 47-53 struct ICStatus { a/Source/JavaScriptCore/bytecode/ICStatusMap.h_sec2
47
    ByValInfo* byValInfo { nullptr };
47
    ByValInfo* byValInfo { nullptr };
48
    CallLinkStatus* callStatus { nullptr };
48
    CallLinkStatus* callStatus { nullptr };
49
    GetByStatus* getStatus { nullptr };
49
    GetByStatus* getStatus { nullptr };
50
    InByIdStatus* inStatus { nullptr };
50
    InByStatus* inStatus { nullptr };
51
    PutByIdStatus* putStatus { nullptr };
51
    PutByIdStatus* putStatus { nullptr };
52
    DeleteByStatus* deleteStatus { nullptr };
52
    DeleteByStatus* deleteStatus { nullptr };
53
};
53
};
- a/Source/JavaScriptCore/bytecode/InByIdStatus.cpp -298 lines
Lines 1-298 a/Source/JavaScriptCore/bytecode/InByIdStatus.cpp_sec1
1
/*
2
 * Copyright (C) 2018 Yusuke Suzuki <utatane.tea@gmail.com>.
3
 * Copyright (C) 2018-2021 Apple Inc. All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
7
 * are met:
8
 * 1. Redistributions of source code must retain the above copyright
9
 *    notice, this list of conditions and the following disclaimer.
10
 * 2. Redistributions in binary form must reproduce the above copyright
11
 *    notice, this list of conditions and the following disclaimer in the
12
 *    documentation and/or other materials provided with the distribution.
13
 *
14
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
15
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
18
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
 */
26
27
#include "config.h"
28
#include "InByIdStatus.h"
29
30
#include "CodeBlock.h"
31
#include "ComplexGetStatus.h"
32
#include "ICStatusUtils.h"
33
#include "PolymorphicAccess.h"
34
#include "StructureStubInfo.h"
35
#include <wtf/ListDump.h>
36
37
namespace JSC {
38
39
bool InByIdStatus::appendVariant(const InByIdVariant& variant)
40
{
41
    return appendICStatusVariant(m_variants, variant);
42
}
43
44
void InByIdStatus::shrinkToFit()
45
{
46
    m_variants.shrinkToFit();
47
}
48
49
#if ENABLE(JIT)
50
InByIdStatus InByIdStatus::computeFor(CodeBlock* profiledBlock, ICStatusMap& map, BytecodeIndex bytecodeIndex, UniquedStringImpl* uid, ExitFlag didExit)
51
{
52
    ConcurrentJSLocker locker(profiledBlock->m_lock);
53
54
    InByIdStatus result;
55
56
#if ENABLE(DFG_JIT)
57
    result = computeForStubInfoWithoutExitSiteFeedback(locker, profiledBlock->vm(), map.get(CodeOrigin(bytecodeIndex)).stubInfo, uid);
58
59
    if (!result.takesSlowPath() && didExit)
60
        return InByIdStatus(TakesSlowPath);
61
#else
62
    UNUSED_PARAM(map);
63
    UNUSED_PARAM(bytecodeIndex);
64
    UNUSED_PARAM(uid);
65
    UNUSED_PARAM(didExit);
66
#endif
67
68
    return result;
69
}
70
71
InByIdStatus InByIdStatus::computeFor(CodeBlock* profiledBlock, ICStatusMap& map, BytecodeIndex bytecodeIndex, UniquedStringImpl* uid)
72
{
73
    return computeFor(profiledBlock, map, bytecodeIndex, uid, hasBadCacheExitSite(profiledBlock, bytecodeIndex));
74
}
75
76
InByIdStatus InByIdStatus::computeFor(
77
    CodeBlock* profiledBlock, ICStatusMap& baselineMap,
78
    ICStatusContextStack& contextStack, CodeOrigin codeOrigin, UniquedStringImpl* uid)
79
{
80
    BytecodeIndex bytecodeIndex = codeOrigin.bytecodeIndex();
81
    ExitFlag didExit = hasBadCacheExitSite(profiledBlock, bytecodeIndex);
82
    
83
    for (ICStatusContext* context : contextStack) {
84
        ICStatus status = context->get(codeOrigin);
85
        
86
        auto bless = [&] (const InByIdStatus& result) -> InByIdStatus {
87
            if (!context->isInlined(codeOrigin)) {
88
                InByIdStatus baselineResult = computeFor(
89
                    profiledBlock, baselineMap, bytecodeIndex, uid, didExit);
90
                baselineResult.merge(result);
91
                return baselineResult;
92
            }
93
            if (didExit.isSet(ExitFromInlined))
94
                return InByIdStatus(TakesSlowPath);
95
            return result;
96
        };
97
        
98
#if ENABLE(DFG_JIT)
99
        if (status.stubInfo) {
100
            InByIdStatus result;
101
            {
102
                ConcurrentJSLocker locker(context->optimizedCodeBlock->m_lock);
103
                result = computeForStubInfoWithoutExitSiteFeedback(locker, profiledBlock->vm(), status.stubInfo, uid);
104
            }
105
            if (result.isSet())
106
                return bless(result);
107
        }
108
#endif
109
        
110
        if (status.inStatus)
111
            return bless(*status.inStatus);
112
    }
113
    
114
    return computeFor(profiledBlock, baselineMap, bytecodeIndex, uid, didExit);
115
}
116
#endif // ENABLE(JIT)
117
118
#if ENABLE(DFG_JIT)
119
InByIdStatus InByIdStatus::computeForStubInfo(const ConcurrentJSLocker& locker, CodeBlock* profiledBlock, StructureStubInfo* stubInfo, CodeOrigin codeOrigin, UniquedStringImpl* uid)
120
{
121
    InByIdStatus result = InByIdStatus::computeForStubInfoWithoutExitSiteFeedback(locker, profiledBlock->vm(), stubInfo, uid);
122
123
    if (!result.takesSlowPath() && hasBadCacheExitSite(profiledBlock, codeOrigin.bytecodeIndex()))
124
        return InByIdStatus(TakesSlowPath);
125
    return result;
126
}
127
128
InByIdStatus InByIdStatus::computeForStubInfoWithoutExitSiteFeedback(const ConcurrentJSLocker&, VM& vm, StructureStubInfo* stubInfo, UniquedStringImpl* uid)
129
{
130
    StubInfoSummary summary = StructureStubInfo::summary(vm, stubInfo);
131
    if (!isInlineable(summary))
132
        return InByIdStatus(summary);
133
    
134
    // Finally figure out if we can derive an access strategy.
135
    InByIdStatus result;
136
    result.m_state = Simple;
137
    switch (stubInfo->cacheType()) {
138
    case CacheType::Unset:
139
        return InByIdStatus(NoInformation);
140
141
    case CacheType::InByIdSelf: {
142
        Structure* structure = stubInfo->u.byIdSelf.baseObjectStructure.get();
143
        if (structure->takesSlowPathInDFGForImpureProperty())
144
            return InByIdStatus(TakesSlowPath);
145
        unsigned attributes;
146
        InByIdVariant variant;
147
        variant.m_offset = structure->getConcurrently(uid, attributes);
148
        if (!isValidOffset(variant.m_offset))
149
            return InByIdStatus(TakesSlowPath);
150
        if (attributes & PropertyAttribute::CustomAccessorOrValue)
151
            return InByIdStatus(TakesSlowPath);
152
153
        variant.m_structureSet.add(structure);
154
        bool didAppend = result.appendVariant(variant);
155
        ASSERT_UNUSED(didAppend, didAppend);
156
        return result;
157
    }
158
159
    case CacheType::Stub: {
160
        PolymorphicAccess* list = stubInfo->u.stub;
161
        for (unsigned listIndex = 0; listIndex < list->size(); ++listIndex) {
162
            const AccessCase& access = list->at(listIndex);
163
            if (access.viaProxy())
164
                return InByIdStatus(TakesSlowPath);
165
166
            if (access.usesPolyProto())
167
                return InByIdStatus(TakesSlowPath);
168
169
            Structure* structure = access.structure();
170
            if (!structure) {
171
                // The null structure cases arise due to array.length. We have no way of creating a
172
                // InByIdVariant for those, and we don't really have to since the DFG handles those
173
                // cases in FixupPhase using value profiling. That's a bit awkward - we shouldn't
174
                // have to use value profiling to discover something that the AccessCase could have
175
                // told us. But, it works well enough. So, our only concern here is to not
176
                // crash on null structure.
177
                return InByIdStatus(TakesSlowPath);
178
            }
179
180
            ComplexGetStatus complexGetStatus = ComplexGetStatus::computeFor(structure, access.conditionSet(), uid);
181
            switch (complexGetStatus.kind()) {
182
            case ComplexGetStatus::ShouldSkip:
183
                continue;
184
185
            case ComplexGetStatus::TakesSlowPath:
186
                return InByIdStatus(TakesSlowPath);
187
188
            case ComplexGetStatus::Inlineable: {
189
                switch (access.type()) {
190
                case AccessCase::InHit:
191
                case AccessCase::InMiss:
192
                    break;
193
                default:
194
                    return InByIdStatus(TakesSlowPath);
195
                }
196
197
                InByIdVariant variant(
198
                    StructureSet(structure), complexGetStatus.offset(),
199
                    complexGetStatus.conditionSet());
200
201
                if (!result.appendVariant(variant))
202
                    return InByIdStatus(TakesSlowPath);
203
                break;
204
            }
205
            }
206
        }
207
208
        result.shrinkToFit();
209
        return result;
210
    }
211
212
    default:
213
        return InByIdStatus(TakesSlowPath);
214
    }
215
216
    RELEASE_ASSERT_NOT_REACHED();
217
    return InByIdStatus();
218
}
219
#endif
220
221
void InByIdStatus::merge(const InByIdStatus& other)
222
{
223
    if (other.m_state == NoInformation)
224
        return;
225
    
226
    switch (m_state) {
227
    case NoInformation:
228
        *this = other;
229
        return;
230
        
231
    case Simple:
232
        if (other.m_state != Simple) {
233
            *this = InByIdStatus(TakesSlowPath);
234
            return;
235
        }
236
        for (const InByIdVariant& otherVariant : other.m_variants) {
237
            if (!appendVariant(otherVariant)) {
238
                *this = InByIdStatus(TakesSlowPath);
239
                return;
240
            }
241
        }
242
        shrinkToFit();
243
        return;
244
        
245
    case TakesSlowPath:
246
        return;
247
    }
248
    
249
    RELEASE_ASSERT_NOT_REACHED();
250
}
251
252
void InByIdStatus::filter(const StructureSet& structureSet)
253
{
254
    if (m_state != Simple)
255
        return;
256
    filterICStatusVariants(m_variants, structureSet);
257
    if (m_variants.isEmpty())
258
        m_state = NoInformation;
259
}
260
261
template<typename Visitor>
262
void InByIdStatus::markIfCheap(Visitor& visitor)
263
{
264
    for (InByIdVariant& variant : m_variants)
265
        variant.markIfCheap(visitor);
266
}
267
268
template void InByIdStatus::markIfCheap(AbstractSlotVisitor&);
269
template void InByIdStatus::markIfCheap(SlotVisitor&);
270
271
bool InByIdStatus::finalize(VM& vm)
272
{
273
    for (InByIdVariant& variant : m_variants) {
274
        if (!variant.finalize(vm))
275
            return false;
276
    }
277
    return true;
278
}
279
280
void InByIdStatus::dump(PrintStream& out) const
281
{
282
    out.print("(");
283
    switch (m_state) {
284
    case NoInformation:
285
        out.print("NoInformation");
286
        break;
287
    case Simple:
288
        out.print("Simple");
289
        break;
290
    case TakesSlowPath:
291
        out.print("TakesSlowPath");
292
        break;
293
    }
294
    out.print(", ", listDump(m_variants), ")");
295
}
296
297
} // namespace JSC
298
- a/Source/JavaScriptCore/bytecode/InByIdStatus.h -125 lines
Lines 1-125 a/Source/JavaScriptCore/bytecode/InByIdStatus.h_sec1
1
/*
2
 * Copyright (C) 2018 Yusuke Suzuki <utatane.tea@gmail.com>.
3
 * Copyright (C) 2018-2021 Apple Inc. All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
7
 * are met:
8
 * 1. Redistributions of source code must retain the above copyright
9
 *    notice, this list of conditions and the following disclaimer.
10
 * 2. Redistributions in binary form must reproduce the above copyright
11
 *    notice, this list of conditions and the following disclaimer in the
12
 *    documentation and/or other materials provided with the distribution.
13
 *
14
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
15
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
18
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
 */
26
27
#pragma once
28
29
#include "CallLinkStatus.h"
30
#include "CodeOrigin.h"
31
#include "ConcurrentJSLock.h"
32
#include "ICStatusMap.h"
33
#include "InByIdVariant.h"
34
#include "StubInfoSummary.h"
35
36
namespace JSC {
37
38
class AccessCase;
39
class CodeBlock;
40
class StructureStubInfo;
41
42
class InByIdStatus final {
43
    WTF_MAKE_FAST_ALLOCATED;
44
public:
45
    enum State {
46
        // It's uncached so we have no information.
47
        NoInformation,
48
        // It's cached for a simple access to a known object property with
49
        // a possible structure chain and a possible specific value.
50
        Simple,
51
        // It's known to often take slow path.
52
        TakesSlowPath,
53
    };
54
55
    InByIdStatus() = default;
56
57
    InByIdStatus(State state, const InByIdVariant& variant = InByIdVariant())
58
        : m_state(state)
59
    {
60
        ASSERT((state == Simple) == variant.isSet());
61
        if (variant.isSet())
62
            m_variants.append(variant);
63
    }
64
65
    explicit InByIdStatus(StubInfoSummary summary)
66
    {
67
        switch (summary) {
68
        case StubInfoSummary::NoInformation:
69
            m_state = NoInformation;
70
            return;
71
        case StubInfoSummary::Simple:
72
        case StubInfoSummary::MakesCalls:
73
            RELEASE_ASSERT_NOT_REACHED();
74
            return;
75
        case StubInfoSummary::TakesSlowPath:
76
        case StubInfoSummary::TakesSlowPathAndMakesCalls:
77
            m_state = TakesSlowPath;
78
            return;
79
        }
80
        RELEASE_ASSERT_NOT_REACHED();
81
    }
82
    
83
    static InByIdStatus computeFor(CodeBlock*, ICStatusMap&, BytecodeIndex, UniquedStringImpl* uid);
84
    static InByIdStatus computeFor(CodeBlock*, ICStatusMap&, BytecodeIndex, UniquedStringImpl* uid, ExitFlag);
85
    static InByIdStatus computeFor(CodeBlock* baselineBlock, ICStatusMap& baselineMap, ICStatusContextStack& contextStack, CodeOrigin, UniquedStringImpl* uid);
86
87
#if ENABLE(DFG_JIT)
88
    static InByIdStatus computeForStubInfo(const ConcurrentJSLocker&, CodeBlock* baselineBlock, StructureStubInfo*, CodeOrigin, UniquedStringImpl* uid);
89
#endif
90
91
    State state() const { return m_state; }
92
93
    bool isSet() const { return m_state != NoInformation; }
94
    explicit operator bool() const { return isSet(); }
95
    bool isSimple() const { return m_state == Simple; }
96
97
    size_t numVariants() const { return m_variants.size(); }
98
    const Vector<InByIdVariant, 1>& variants() const { return m_variants; }
99
    const InByIdVariant& at(size_t index) const { return m_variants[index]; }
100
    const InByIdVariant& operator[](size_t index) const { return at(index); }
101
102
    bool takesSlowPath() const { return m_state == TakesSlowPath; }
103
    
104
    void merge(const InByIdStatus&);
105
106
    // Attempts to reduce the set of variants to fit the given structure set. This may be approximate.
107
    void filter(const StructureSet&);
108
    
109
    template<typename Visitor> void markIfCheap(Visitor&);
110
    bool finalize(VM&);
111
112
    void dump(PrintStream&) const;
113
114
private:
115
#if ENABLE(DFG_JIT)
116
    static InByIdStatus computeForStubInfoWithoutExitSiteFeedback(const ConcurrentJSLocker&, VM&, StructureStubInfo*, UniquedStringImpl* uid);
117
#endif
118
    bool appendVariant(const InByIdVariant&);
119
    void shrinkToFit();
120
121
    State m_state { NoInformation };
122
    Vector<InByIdVariant, 1> m_variants;
123
};
124
125
} // namespace JSC
- a/Source/JavaScriptCore/bytecode/InByIdVariant.cpp -4 / +13 lines
Lines 27-38 a/Source/JavaScriptCore/bytecode/InByIdVariant.cpp_sec1
27
#include "config.h"
27
#include "config.h"
28
#include "InByIdVariant.h"
28
#include "InByIdVariant.h"
29
29
30
#include "CacheableIdentifierInlines.h"
31
30
namespace JSC {
32
namespace JSC {
31
33
32
InByIdVariant::InByIdVariant(const StructureSet& structureSet, PropertyOffset offset, const ObjectPropertyConditionSet& conditionSet)
34
InByIdVariant::InByIdVariant(CacheableIdentifier identifier, const StructureSet& structureSet, PropertyOffset offset, const ObjectPropertyConditionSet& conditionSet)
33
    : m_structureSet(structureSet)
35
    : m_structureSet(structureSet)
34
    , m_conditionSet(conditionSet)
36
    , m_conditionSet(conditionSet)
35
    , m_offset(offset)
37
    , m_offset(offset)
38
    , m_identifier(WTFMove(identifier))
36
{
39
{
37
    if (!structureSet.size()) {
40
    if (!structureSet.size()) {
38
        ASSERT(offset == invalidOffset);
41
        ASSERT(offset == invalidOffset);
Lines 42-47 InByIdVariant::InByIdVariant(const StructureSet& structureSet, PropertyOffset of a/Source/JavaScriptCore/bytecode/InByIdVariant.cpp_sec2
42
45
43
bool InByIdVariant::attemptToMerge(const InByIdVariant& other)
46
bool InByIdVariant::attemptToMerge(const InByIdVariant& other)
44
{
47
{
48
    if (!!m_identifier != !!other.m_identifier)
49
        return false;
50
51
    if (m_identifier && (m_identifier != other.m_identifier))
52
        return false;
53
45
    if (m_offset != other.m_offset)
54
    if (m_offset != other.m_offset)
46
        return false;
55
        return false;
47
56
Lines 89-101 void InByIdVariant::dump(PrintStream& out) const a/Source/JavaScriptCore/bytecode/InByIdVariant.cpp_sec3
89
98
90
void InByIdVariant::dumpInContext(PrintStream& out, DumpContext* context) const
99
void InByIdVariant::dumpInContext(PrintStream& out, DumpContext* context) const
91
{
100
{
101
    out.print("<id='", m_identifier, "', ");
92
    if (!isSet()) {
102
    if (!isSet()) {
93
        out.print("<empty>");
103
        out.print("empty>");
94
        return;
104
        return;
95
    }
105
    }
96
106
97
    out.print(
107
    out.print(inContext(structureSet(), context), ", ", inContext(m_conditionSet, context));
98
        "<", inContext(structureSet(), context), ", ", inContext(m_conditionSet, context));
99
    out.print(", offset = ", offset());
108
    out.print(", offset = ", offset());
100
    out.print(">");
109
    out.print(">");
101
}
110
}
- a/Source/JavaScriptCore/bytecode/InByIdVariant.h -3 / +13 lines
Lines 26-31 a/Source/JavaScriptCore/bytecode/InByIdVariant.h_sec1
26
26
27
#pragma once
27
#pragma once
28
28
29
#include "CacheableIdentifier.h"
29
#include "ObjectPropertyConditionSet.h"
30
#include "ObjectPropertyConditionSet.h"
30
#include "PropertyOffset.h"
31
#include "PropertyOffset.h"
31
#include "StructureSet.h"
32
#include "StructureSet.h"
Lines 35-47 namespace DOMJIT { a/Source/JavaScriptCore/bytecode/InByIdVariant.h_sec2
35
class GetterSetter;
36
class GetterSetter;
36
}
37
}
37
38
38
class InByIdStatus;
39
class InByStatus;
39
struct DumpContext;
40
struct DumpContext;
40
41
41
class InByIdVariant {
42
class InByIdVariant {
42
    WTF_MAKE_FAST_ALLOCATED;
43
    WTF_MAKE_FAST_ALLOCATED;
43
public:
44
public:
44
    InByIdVariant(const StructureSet& = StructureSet(), PropertyOffset = invalidOffset, const ObjectPropertyConditionSet& = ObjectPropertyConditionSet());
45
    InByIdVariant(CacheableIdentifier, const StructureSet& = StructureSet(), PropertyOffset = invalidOffset, const ObjectPropertyConditionSet& = ObjectPropertyConditionSet());
45
46
46
    bool isSet() const { return !!m_structureSet.size(); }
47
    bool isSet() const { return !!m_structureSet.size(); }
47
    explicit operator bool() const { return isSet(); }
48
    explicit operator bool() const { return isSet(); }
Lines 63-79 public: a/Source/JavaScriptCore/bytecode/InByIdVariant.h_sec3
63
    void dump(PrintStream&) const;
64
    void dump(PrintStream&) const;
64
    void dumpInContext(PrintStream&, DumpContext*) const;
65
    void dumpInContext(PrintStream&, DumpContext*) const;
65
66
67
    CacheableIdentifier identifier() const { return m_identifier; }
68
66
    bool overlaps(const InByIdVariant& other)
69
    bool overlaps(const InByIdVariant& other)
67
    {
70
    {
71
        if (!!m_identifier != !!other.m_identifier)
72
            return true;
73
        if (m_identifier) {
74
            if (m_identifier != other.m_identifier)
75
                return false;
76
        }
68
        return structureSet().overlaps(other.structureSet());
77
        return structureSet().overlaps(other.structureSet());
69
    }
78
    }
70
79
71
private:
80
private:
72
    friend class InByIdStatus;
81
    friend class InByStatus;
73
82
74
    StructureSet m_structureSet;
83
    StructureSet m_structureSet;
75
    ObjectPropertyConditionSet m_conditionSet;
84
    ObjectPropertyConditionSet m_conditionSet;
76
    PropertyOffset m_offset;
85
    PropertyOffset m_offset;
86
    CacheableIdentifier m_identifier;
77
};
87
};
78
88
79
} // namespace JSC
89
} // namespace JSC
- a/Source/JavaScriptCore/bytecode/InByStatus.cpp +319 lines
Line 0 a/Source/JavaScriptCore/bytecode/InByStatus.cpp_sec1
1
/*
2
 * Copyright (C) 2018 Yusuke Suzuki <utatane.tea@gmail.com>.
3
 * Copyright (C) 2018-2021 Apple Inc. All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
7
 * are met:
8
 * 1. Redistributions of source code must retain the above copyright
9
 *    notice, this list of conditions and the following disclaimer.
10
 * 2. Redistributions in binary form must reproduce the above copyright
11
 *    notice, this list of conditions and the following disclaimer in the
12
 *    documentation and/or other materials provided with the distribution.
13
 *
14
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
15
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
18
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
 */
26
27
#include "config.h"
28
#include "InByStatus.h"
29
30
#include "CacheableIdentifierInlines.h"
31
#include "CodeBlock.h"
32
#include "ComplexGetStatus.h"
33
#include "ICStatusUtils.h"
34
#include "PolymorphicAccess.h"
35
#include "StructureStubInfo.h"
36
#include <wtf/ListDump.h>
37
38
namespace JSC {
39
40
bool InByStatus::appendVariant(const InByIdVariant& variant)
41
{
42
    return appendICStatusVariant(m_variants, variant);
43
}
44
45
void InByStatus::shrinkToFit()
46
{
47
    m_variants.shrinkToFit();
48
}
49
50
#if ENABLE(JIT)
51
InByStatus InByStatus::computeFor(CodeBlock* profiledBlock, ICStatusMap& map, BytecodeIndex bytecodeIndex, ExitFlag didExit)
52
{
53
    ConcurrentJSLocker locker(profiledBlock->m_lock);
54
55
    InByStatus result;
56
57
#if ENABLE(DFG_JIT)
58
    result = computeForStubInfoWithoutExitSiteFeedback(locker, profiledBlock->vm(), map.get(CodeOrigin(bytecodeIndex)).stubInfo);
59
60
    if (!result.takesSlowPath() && didExit)
61
        return InByStatus(TakesSlowPath);
62
#else
63
    UNUSED_PARAM(map);
64
    UNUSED_PARAM(bytecodeIndex);
65
    UNUSED_PARAM(didExit);
66
#endif
67
68
    return result;
69
}
70
71
InByStatus InByStatus::computeFor(CodeBlock* profiledBlock, ICStatusMap& map, BytecodeIndex bytecodeIndex)
72
{
73
    return computeFor(profiledBlock, map, bytecodeIndex, hasBadCacheExitSite(profiledBlock, bytecodeIndex));
74
}
75
76
InByStatus InByStatus::computeFor(
77
    CodeBlock* profiledBlock, ICStatusMap& baselineMap,
78
    ICStatusContextStack& contextStack, CodeOrigin codeOrigin)
79
{
80
    BytecodeIndex bytecodeIndex = codeOrigin.bytecodeIndex();
81
    ExitFlag didExit = hasBadCacheExitSite(profiledBlock, bytecodeIndex);
82
    
83
    for (ICStatusContext* context : contextStack) {
84
        ICStatus status = context->get(codeOrigin);
85
        
86
        auto bless = [&] (const InByStatus& result) -> InByStatus {
87
            if (!context->isInlined(codeOrigin)) {
88
                InByStatus baselineResult = computeFor(
89
                    profiledBlock, baselineMap, bytecodeIndex, didExit);
90
                baselineResult.merge(result);
91
                return baselineResult;
92
            }
93
            if (didExit.isSet(ExitFromInlined))
94
                return InByStatus(TakesSlowPath);
95
            return result;
96
        };
97
        
98
#if ENABLE(DFG_JIT)
99
        if (status.stubInfo) {
100
            InByStatus result;
101
            {
102
                ConcurrentJSLocker locker(context->optimizedCodeBlock->m_lock);
103
                result = computeForStubInfoWithoutExitSiteFeedback(locker, profiledBlock->vm(), status.stubInfo);
104
            }
105
            if (result.isSet())
106
                return bless(result);
107
        }
108
#endif
109
        
110
        if (status.inStatus)
111
            return bless(*status.inStatus);
112
    }
113
    
114
    return computeFor(profiledBlock, baselineMap, bytecodeIndex, didExit);
115
}
116
#endif // ENABLE(JIT)
117
118
#if ENABLE(DFG_JIT)
119
InByStatus InByStatus::computeForStubInfo(const ConcurrentJSLocker& locker, CodeBlock* profiledBlock, StructureStubInfo* stubInfo, CodeOrigin codeOrigin)
120
{
121
    InByStatus result = InByStatus::computeForStubInfoWithoutExitSiteFeedback(locker, profiledBlock->vm(), stubInfo);
122
123
    if (!result.takesSlowPath() && hasBadCacheExitSite(profiledBlock, codeOrigin.bytecodeIndex()))
124
        return InByStatus(TakesSlowPath);
125
    return result;
126
}
127
128
InByStatus InByStatus::computeForStubInfoWithoutExitSiteFeedback(const ConcurrentJSLocker&, VM& vm, StructureStubInfo* stubInfo)
129
{
130
    StubInfoSummary summary = StructureStubInfo::summary(vm, stubInfo);
131
    if (!isInlineable(summary))
132
        return InByStatus(summary);
133
    
134
    // Finally figure out if we can derive an access strategy.
135
    InByStatus result;
136
    result.m_state = Simple;
137
    switch (stubInfo->cacheType()) {
138
    case CacheType::Unset:
139
        return InByStatus(NoInformation);
140
141
    case CacheType::InByIdSelf: {
142
        Structure* structure = stubInfo->u.byIdSelf.baseObjectStructure.get();
143
        if (structure->takesSlowPathInDFGForImpureProperty())
144
            return InByStatus(TakesSlowPath);
145
        CacheableIdentifier identifier = stubInfo->identifier();
146
        UniquedStringImpl* uid = identifier.uid();
147
        RELEASE_ASSERT(uid);
148
        InByIdVariant variant(WTFMove(identifier));
149
        unsigned attributes;
150
        variant.m_offset = structure->getConcurrently(uid, attributes);
151
        if (!isValidOffset(variant.m_offset))
152
            return InByStatus(TakesSlowPath);
153
        if (attributes & PropertyAttribute::CustomAccessorOrValue)
154
            return InByStatus(TakesSlowPath);
155
156
        variant.m_structureSet.add(structure);
157
        bool didAppend = result.appendVariant(variant);
158
        ASSERT_UNUSED(didAppend, didAppend);
159
        return result;
160
    }
161
162
    case CacheType::Stub: {
163
        PolymorphicAccess* list = stubInfo->u.stub;
164
        for (unsigned listIndex = 0; listIndex < list->size(); ++listIndex) {
165
            const AccessCase& access = list->at(listIndex);
166
            if (access.viaProxy())
167
                return InByStatus(TakesSlowPath);
168
169
            if (access.usesPolyProto())
170
                return InByStatus(TakesSlowPath);
171
172
            Structure* structure = access.structure();
173
            if (!structure) {
174
                // The null structure cases arise due to array.length. We have no way of creating a
175
                // InByIdVariant for those, and we don't really have to since the DFG handles those
176
                // cases in FixupPhase using value profiling. That's a bit awkward - we shouldn't
177
                // have to use value profiling to discover something that the AccessCase could have
178
                // told us. But, it works well enough. So, our only concern here is to not
179
                // crash on null structure.
180
                return InByStatus(TakesSlowPath);
181
            }
182
183
            ComplexGetStatus complexGetStatus = ComplexGetStatus::computeFor(structure, access.conditionSet(), access.uid());
184
            switch (complexGetStatus.kind()) {
185
            case ComplexGetStatus::ShouldSkip:
186
                continue;
187
188
            case ComplexGetStatus::TakesSlowPath:
189
                return InByStatus(TakesSlowPath);
190
191
            case ComplexGetStatus::Inlineable: {
192
                switch (access.type()) {
193
                case AccessCase::InHit:
194
                case AccessCase::InMiss:
195
                    break;
196
                default:
197
                    return InByStatus(TakesSlowPath);
198
                }
199
200
                InByIdVariant variant(
201
                    access.identifier(), StructureSet(structure), complexGetStatus.offset(),
202
                    complexGetStatus.conditionSet());
203
204
                if (!result.appendVariant(variant))
205
                    return InByStatus(TakesSlowPath);
206
                break;
207
            }
208
            }
209
        }
210
211
        result.shrinkToFit();
212
        return result;
213
    }
214
215
    default:
216
        return InByStatus(TakesSlowPath);
217
    }
218
219
    RELEASE_ASSERT_NOT_REACHED();
220
    return InByStatus();
221
}
222
#endif
223
224
void InByStatus::merge(const InByStatus& other)
225
{
226
    if (other.m_state == NoInformation)
227
        return;
228
    
229
    switch (m_state) {
230
    case NoInformation:
231
        *this = other;
232
        return;
233
        
234
    case Simple:
235
        if (other.m_state != Simple) {
236
            *this = InByStatus(TakesSlowPath);
237
            return;
238
        }
239
        for (const InByIdVariant& otherVariant : other.m_variants) {
240
            if (!appendVariant(otherVariant)) {
241
                *this = InByStatus(TakesSlowPath);
242
                return;
243
            }
244
        }
245
        shrinkToFit();
246
        return;
247
        
248
    case TakesSlowPath:
249
        return;
250
    }
251
    
252
    RELEASE_ASSERT_NOT_REACHED();
253
}
254
255
void InByStatus::filter(const StructureSet& structureSet)
256
{
257
    if (m_state != Simple)
258
        return;
259
    filterICStatusVariants(m_variants, structureSet);
260
    if (m_variants.isEmpty())
261
        m_state = NoInformation;
262
}
263
264
template<typename Visitor>
265
void InByStatus::markIfCheap(Visitor& visitor)
266
{
267
    for (InByIdVariant& variant : m_variants)
268
        variant.markIfCheap(visitor);
269
}
270
271
template void InByStatus::markIfCheap(AbstractSlotVisitor&);
272
template void InByStatus::markIfCheap(SlotVisitor&);
273
274
bool InByStatus::finalize(VM& vm)
275
{
276
    for (InByIdVariant& variant : m_variants) {
277
        if (!variant.finalize(vm))
278
            return false;
279
    }
280
    return true;
281
}
282
283
CacheableIdentifier InByStatus::singleIdentifier() const
284
{
285
    if (m_variants.isEmpty())
286
        return nullptr;
287
288
    CacheableIdentifier result = m_variants.first().identifier();
289
    if (!result)
290
        return nullptr;
291
    for (size_t i = 1; i < m_variants.size(); ++i) {
292
        CacheableIdentifier identifier = m_variants[i].identifier();
293
        if (!identifier)
294
            return nullptr;
295
        if (identifier != result)
296
            return nullptr;
297
    }
298
    return result;
299
}
300
301
void InByStatus::dump(PrintStream& out) const
302
{
303
    out.print("(");
304
    switch (m_state) {
305
    case NoInformation:
306
        out.print("NoInformation");
307
        break;
308
    case Simple:
309
        out.print("Simple");
310
        break;
311
    case TakesSlowPath:
312
        out.print("TakesSlowPath");
313
        break;
314
    }
315
    out.print(", ", listDump(m_variants), ")");
316
}
317
318
} // namespace JSC
319
- a/Source/JavaScriptCore/bytecode/InByStatus.h +125 lines
Line 0 a/Source/JavaScriptCore/bytecode/InByStatus.h_sec1
1
/*
2
 * Copyright (C) 2018 Yusuke Suzuki <utatane.tea@gmail.com>.
3
 * Copyright (C) 2018-2021 Apple Inc. All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
7
 * are met:
8
 * 1. Redistributions of source code must retain the above copyright
9
 *    notice, this list of conditions and the following disclaimer.
10
 * 2. Redistributions in binary form must reproduce the above copyright
11
 *    notice, this list of conditions and the following disclaimer in the
12
 *    documentation and/or other materials provided with the distribution.
13
 *
14
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
15
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
18
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
 */
26
27
#pragma once
28
29
#include "CallLinkStatus.h"
30
#include "CodeOrigin.h"
31
#include "ConcurrentJSLock.h"
32
#include "ICStatusMap.h"
33
#include "InByIdVariant.h"
34
#include "StubInfoSummary.h"
35
36
namespace JSC {
37
38
class AccessCase;
39
class CodeBlock;
40
class StructureStubInfo;
41
42
class InByStatus final {
43
    WTF_MAKE_FAST_ALLOCATED;
44
public:
45
    enum State {
46
        // It's uncached so we have no information.
47
        NoInformation,
48
        // It's cached for a simple access to a known object property with
49
        // a possible structure chain and a possible specific value.
50
        Simple,
51
        // It's known to often take slow path.
52
        TakesSlowPath,
53
    };
54
55
    InByStatus() = default;
56
57
    InByStatus(State state)
58
        : m_state(state)
59
    {
60
        ASSERT(state != Simple);
61
    }
62
63
    explicit InByStatus(StubInfoSummary summary)
64
    {
65
        switch (summary) {
66
        case StubInfoSummary::NoInformation:
67
            m_state = NoInformation;
68
            return;
69
        case StubInfoSummary::Simple:
70
        case StubInfoSummary::MakesCalls:
71
            RELEASE_ASSERT_NOT_REACHED();
72
            return;
73
        case StubInfoSummary::TakesSlowPath:
74
        case StubInfoSummary::TakesSlowPathAndMakesCalls:
75
            m_state = TakesSlowPath;
76
            return;
77
        }
78
        RELEASE_ASSERT_NOT_REACHED();
79
    }
80
    
81
    static InByStatus computeFor(CodeBlock*, ICStatusMap&, BytecodeIndex);
82
    static InByStatus computeFor(CodeBlock*, ICStatusMap&, BytecodeIndex, ExitFlag);
83
    static InByStatus computeFor(CodeBlock* baselineBlock, ICStatusMap& baselineMap, ICStatusContextStack&, CodeOrigin);
84
85
#if ENABLE(DFG_JIT)
86
    static InByStatus computeForStubInfo(const ConcurrentJSLocker&, CodeBlock* baselineBlock, StructureStubInfo*, CodeOrigin);
87
#endif
88
89
    State state() const { return m_state; }
90
91
    bool isSet() const { return m_state != NoInformation; }
92
    explicit operator bool() const { return isSet(); }
93
    bool isSimple() const { return m_state == Simple; }
94
95
    size_t numVariants() const { return m_variants.size(); }
96
    const Vector<InByIdVariant, 1>& variants() const { return m_variants; }
97
    const InByIdVariant& at(size_t index) const { return m_variants[index]; }
98
    const InByIdVariant& operator[](size_t index) const { return at(index); }
99
100
    bool takesSlowPath() const { return m_state == TakesSlowPath; }
101
    
102
    void merge(const InByStatus&);
103
104
    // Attempts to reduce the set of variants to fit the given structure set. This may be approximate.
105
    void filter(const StructureSet&);
106
    
107
    template<typename Visitor> void markIfCheap(Visitor&);
108
    bool finalize(VM&);
109
110
    void dump(PrintStream&) const;
111
112
    CacheableIdentifier singleIdentifier() const;
113
114
private:
115
#if ENABLE(DFG_JIT)
116
    static InByStatus computeForStubInfoWithoutExitSiteFeedback(const ConcurrentJSLocker&, VM&, StructureStubInfo*);
117
#endif
118
    bool appendVariant(const InByIdVariant&);
119
    void shrinkToFit();
120
121
    State m_state { NoInformation };
122
    Vector<InByIdVariant, 1> m_variants;
123
};
124
125
} // namespace JSC
- a/Source/JavaScriptCore/bytecode/RecordedStatuses.cpp -3 / +3 lines
Lines 70-79 PutByIdStatus* RecordedStatuses::addPutByIdStatus(const CodeOrigin& codeOrigin, a/Source/JavaScriptCore/bytecode/RecordedStatuses.cpp_sec1
70
    return result;
70
    return result;
71
}
71
}
72
72
73
InByIdStatus* RecordedStatuses::addInByIdStatus(const CodeOrigin& codeOrigin, const InByIdStatus& status)
73
InByStatus* RecordedStatuses::addInByStatus(const CodeOrigin& codeOrigin, const InByStatus& status)
74
{
74
{
75
    auto statusPtr = makeUnique<InByIdStatus>(status);
75
    auto statusPtr = makeUnique<InByStatus>(status);
76
    InByIdStatus* result = statusPtr.get();
76
    InByStatus* result = statusPtr.get();
77
    ins.append(std::make_pair(codeOrigin, WTFMove(statusPtr)));
77
    ins.append(std::make_pair(codeOrigin, WTFMove(statusPtr)));
78
    return result;
78
    return result;
79
}
79
}
- a/Source/JavaScriptCore/bytecode/RecordedStatuses.h -3 / +3 lines
Lines 29-35 a/Source/JavaScriptCore/bytecode/RecordedStatuses.h_sec1
29
#include "CheckPrivateBrandStatus.h"
29
#include "CheckPrivateBrandStatus.h"
30
#include "DeleteByStatus.h"
30
#include "DeleteByStatus.h"
31
#include "GetByStatus.h"
31
#include "GetByStatus.h"
32
#include "InByIdStatus.h"
32
#include "InByStatus.h"
33
#include "PutByIdStatus.h"
33
#include "PutByIdStatus.h"
34
#include "SetPrivateBrandStatus.h"
34
#include "SetPrivateBrandStatus.h"
35
35
Lines 49-55 struct RecordedStatuses { a/Source/JavaScriptCore/bytecode/RecordedStatuses.h_sec2
49
    CallLinkStatus* addCallLinkStatus(const CodeOrigin&, const CallLinkStatus&);
49
    CallLinkStatus* addCallLinkStatus(const CodeOrigin&, const CallLinkStatus&);
50
    GetByStatus* addGetByStatus(const CodeOrigin&, const GetByStatus&);
50
    GetByStatus* addGetByStatus(const CodeOrigin&, const GetByStatus&);
51
    PutByIdStatus* addPutByIdStatus(const CodeOrigin&, const PutByIdStatus&);
51
    PutByIdStatus* addPutByIdStatus(const CodeOrigin&, const PutByIdStatus&);
52
    InByIdStatus* addInByIdStatus(const CodeOrigin&, const InByIdStatus&);
52
    InByStatus* addInByStatus(const CodeOrigin&, const InByStatus&);
53
    DeleteByStatus* addDeleteByStatus(const CodeOrigin&, const DeleteByStatus&);
53
    DeleteByStatus* addDeleteByStatus(const CodeOrigin&, const DeleteByStatus&);
54
    CheckPrivateBrandStatus* addCheckPrivateBrandStatus(const CodeOrigin&, const CheckPrivateBrandStatus&);
54
    CheckPrivateBrandStatus* addCheckPrivateBrandStatus(const CodeOrigin&, const CheckPrivateBrandStatus&);
55
    SetPrivateBrandStatus* addSetPrivateBrandStatus(const CodeOrigin&, const SetPrivateBrandStatus&);
55
    SetPrivateBrandStatus* addSetPrivateBrandStatus(const CodeOrigin&, const SetPrivateBrandStatus&);
Lines 77-83 struct RecordedStatuses { a/Source/JavaScriptCore/bytecode/RecordedStatuses.h_sec3
77
    Vector<std::pair<CodeOrigin, std::unique_ptr<CallLinkStatus>>> calls;
77
    Vector<std::pair<CodeOrigin, std::unique_ptr<CallLinkStatus>>> calls;
78
    Vector<std::pair<CodeOrigin, std::unique_ptr<GetByStatus>>> gets;
78
    Vector<std::pair<CodeOrigin, std::unique_ptr<GetByStatus>>> gets;
79
    Vector<std::pair<CodeOrigin, std::unique_ptr<PutByIdStatus>>> puts;
79
    Vector<std::pair<CodeOrigin, std::unique_ptr<PutByIdStatus>>> puts;
80
    Vector<std::pair<CodeOrigin, std::unique_ptr<InByIdStatus>>> ins;
80
    Vector<std::pair<CodeOrigin, std::unique_ptr<InByStatus>>> ins;
81
    Vector<std::pair<CodeOrigin, std::unique_ptr<DeleteByStatus>>> deletes;
81
    Vector<std::pair<CodeOrigin, std::unique_ptr<DeleteByStatus>>> deletes;
82
    Vector<std::pair<CodeOrigin, std::unique_ptr<CheckPrivateBrandStatus>>> checkPrivateBrands;
82
    Vector<std::pair<CodeOrigin, std::unique_ptr<CheckPrivateBrandStatus>>> checkPrivateBrands;
83
    Vector<std::pair<CodeOrigin, std::unique_ptr<SetPrivateBrandStatus>>> setPrivateBrands;
83
    Vector<std::pair<CodeOrigin, std::unique_ptr<SetPrivateBrandStatus>>> setPrivateBrands;
- a/Source/JavaScriptCore/bytecode/StructureStubInfo.cpp -2 / +5 lines
Lines 272-279 void StructureStubInfo::reset(const ConcurrentJSLockerBase& locker, CodeBlock* c a/Source/JavaScriptCore/bytecode/StructureStubInfo.cpp_sec1
272
    case AccessType::Put:
272
    case AccessType::Put:
273
        resetPutByID(codeBlock, *this);
273
        resetPutByID(codeBlock, *this);
274
        break;
274
        break;
275
    case AccessType::In:
275
    case AccessType::InById:
276
        resetInByID(codeBlock, *this);
276
        resetInBy(codeBlock, *this, InByKind::Normal);
277
        break;
278
    case AccessType::InByVal:
279
        resetInBy(codeBlock, *this, InByKind::NormalByVal);
277
        break;
280
        break;
278
    case AccessType::InstanceOf:
281
    case AccessType::InstanceOf:
279
        resetInstanceOf(*this);
282
        resetInstanceOf(*this);
- a/Source/JavaScriptCore/bytecode/StructureStubInfo.h -1 / +2 lines
Lines 55-61 enum class AccessType : int8_t { a/Source/JavaScriptCore/bytecode/StructureStubInfo.h_sec1
55
    TryGetById,
55
    TryGetById,
56
    GetByVal,
56
    GetByVal,
57
    Put,
57
    Put,
58
    In,
58
    InById,
59
    InByVal,
59
    InstanceOf,
60
    InstanceOf,
60
    DeleteByID,
61
    DeleteByID,
61
    DeleteByVal,
62
    DeleteByVal,
- a/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h -3 / +3 lines
Lines 4439-4445 bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi a/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h_sec1
4439
    case FilterCallLinkStatus:
4439
    case FilterCallLinkStatus:
4440
    case FilterGetByStatus:
4440
    case FilterGetByStatus:
4441
    case FilterPutByIdStatus:
4441
    case FilterPutByIdStatus:
4442
    case FilterInByIdStatus:
4442
    case FilterInByStatus:
4443
    case FilterDeleteByStatus:
4443
    case FilterDeleteByStatus:
4444
    case FilterCheckPrivateBrandStatus:
4444
    case FilterCheckPrivateBrandStatus:
4445
    case FilterSetPrivateBrandStatus:
4445
    case FilterSetPrivateBrandStatus:
Lines 4610-4619 void AbstractInterpreter<AbstractStateType>::filterICStatus(Node* node) a/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h_sec2
4610
        break;
4610
        break;
4611
    }
4611
    }
4612
        
4612
        
4613
    case FilterInByIdStatus: {
4613
    case FilterInByStatus: {
4614
        AbstractValue& value = forNode(node->child1());
4614
        AbstractValue& value = forNode(node->child1());
4615
        if (value.m_structure.isFinite())
4615
        if (value.m_structure.isFinite())
4616
            node->inByIdStatus()->filter(value.m_structure.toStructureSet());
4616
            node->inByStatus()->filter(value.m_structure.toStructureSet());
4617
        break;
4617
        break;
4618
    }
4618
    }
4619
        
4619
        
- a/Source/JavaScriptCore/dfg/DFGArgumentsEliminationPhase.cpp -2 / +2 lines
Lines 404-410 private: a/Source/JavaScriptCore/dfg/DFGArgumentsEliminationPhase.cpp_sec1
404
                case FilterGetByStatus:
404
                case FilterGetByStatus:
405
                case FilterPutByIdStatus:
405
                case FilterPutByIdStatus:
406
                case FilterCallLinkStatus:
406
                case FilterCallLinkStatus:
407
                case FilterInByIdStatus:
407
                case FilterInByStatus:
408
                case FilterDeleteByStatus:
408
                case FilterDeleteByStatus:
409
                case FilterCheckPrivateBrandStatus:
409
                case FilterCheckPrivateBrandStatus:
410
                case FilterSetPrivateBrandStatus:
410
                case FilterSetPrivateBrandStatus:
Lines 1267-1273 private: a/Source/JavaScriptCore/dfg/DFGArgumentsEliminationPhase.cpp_sec2
1267
                case FilterGetByStatus:
1267
                case FilterGetByStatus:
1268
                case FilterPutByIdStatus:
1268
                case FilterPutByIdStatus:
1269
                case FilterCallLinkStatus:
1269
                case FilterCallLinkStatus:
1270
                case FilterInByIdStatus:
1270
                case FilterInByStatus:
1271
                case FilterDeleteByStatus:
1271
                case FilterDeleteByStatus:
1272
                case FilterCheckPrivateBrandStatus:
1272
                case FilterCheckPrivateBrandStatus:
1273
                case FilterSetPrivateBrandStatus: {
1273
                case FilterSetPrivateBrandStatus: {
- a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp -35 / +70 lines
Lines 55-61 a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp_sec1
55
#include "GetByStatus.h"
55
#include "GetByStatus.h"
56
#include "GetterSetter.h"
56
#include "GetterSetter.h"
57
#include "Heap.h"
57
#include "Heap.h"
58
#include "InByIdStatus.h"
58
#include "InByStatus.h"
59
#include "InstanceOfStatus.h"
59
#include "InstanceOfStatus.h"
60
#include "JSArrayIterator.h"
60
#include "JSArrayIterator.h"
61
#include "JSCInlines.h"
61
#include "JSCInlines.h"
Lines 263-269 private: a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp_sec2
263
263
264
    void handleDeleteById(
264
    void handleDeleteById(
265
        VirtualRegister destination, Node* base, CacheableIdentifier, unsigned identifierNumber, DeleteByStatus, ECMAMode);
265
        VirtualRegister destination, Node* base, CacheableIdentifier, unsigned identifierNumber, DeleteByStatus, ECMAMode);
266
    
266
267
    void handleInById(VirtualRegister destination, Node* base, CacheableIdentifier, InByStatus);
268
267
    // Either register a watchpoint or emit a check for this condition. Returns false if the
269
    // Either register a watchpoint or emit a check for this condition. Returns false if the
268
    // condition no longer holds, and therefore no reasonable check can be emitted.
270
    // condition no longer holds, and therefore no reasonable check can be emitted.
269
    bool check(const ObjectPropertyCondition&);
271
    bool check(const ObjectPropertyCondition&);
Lines 4928-4933 void ByteCodeParser::handleDeleteById( a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp_sec3
4928
    return;
4930
    return;
4929
}
4931
}
4930
4932
4933
void ByteCodeParser::handleInById(VirtualRegister destination, Node* base, CacheableIdentifier identifier, InByStatus status)
4934
{
4935
    if (status.isSimple() && Options::useAccessInlining()) {
4936
        bool allOK = true;
4937
        MatchStructureData* data = m_graph.m_matchStructureData.add();
4938
        for (const InByIdVariant& variant : status.variants()) {
4939
            if (!check(variant.conditionSet())) {
4940
                allOK = false;
4941
                break;
4942
            }
4943
            for (Structure* structure : variant.structureSet()) {
4944
                MatchStructureVariant matchVariant;
4945
                matchVariant.structure = m_graph.registerStructure(structure);
4946
                matchVariant.result = variant.isHit();
4947
4948
                data->variants.append(WTFMove(matchVariant));
4949
            }
4950
        }
4951
4952
        if (allOK) {
4953
            addToGraph(FilterInByStatus, OpInfo(m_graph.m_plan.recordedStatuses().addInByStatus(currentCodeOrigin(), status)), base);
4954
            set(destination, addToGraph(MatchStructure, OpInfo(data), base));
4955
            return;
4956
        }
4957
    }
4958
4959
    set(destination, addToGraph(InById, OpInfo(identifier), base));
4960
}
4961
4931
void ByteCodeParser::emitPutById(
4962
void ByteCodeParser::emitPutById(
4932
    Node* base, CacheableIdentifier identifier, Node* value, const PutByIdStatus& putByIdStatus, bool isDirect, ECMAMode ecmaMode)
4963
    Node* base, CacheableIdentifier identifier, Node* value, const PutByIdStatus& putByIdStatus, bool isDirect, ECMAMode ecmaMode)
4933
{
4964
{
Lines 8212-8260 void ByteCodeParser::parseBlock(unsigned limit) a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp_sec4
8212
8243
8213
        case op_in_by_val: {
8244
        case op_in_by_val: {
8214
            auto bytecode = currentInstruction->as<OpInByVal>();
8245
            auto bytecode = currentInstruction->as<OpInByVal>();
8215
            ArrayMode arrayMode = getArrayMode(bytecode.metadata(codeBlock).m_arrayProfile, Array::Read);
8216
            set(bytecode.m_dst, addToGraph(InByVal, OpInfo(arrayMode.asWord()), get(bytecode.m_base), get(bytecode.m_property)));
8217
            NEXT_OPCODE(op_in_by_val);
8218
        }
8219
8220
        case op_in_by_id: {
8221
            auto bytecode = currentInstruction->as<OpInById>();
8222
            Node* base = get(bytecode.m_base);
8246
            Node* base = get(bytecode.m_base);
8223
            unsigned identifierNumber = m_inlineStackTop->m_identifierRemap[bytecode.m_property];
8247
            Node* property = get(bytecode.m_property);
8224
            UniquedStringImpl* uid = m_graph.identifiers()[identifierNumber];
8248
            bool compiledAsInById = false;
8225
8249
8226
            InByIdStatus status = InByIdStatus::computeFor(
8250
            InByStatus status = InByStatus::computeFor(
8227
                m_inlineStackTop->m_profiledBlock,
8251
                m_inlineStackTop->m_profiledBlock,
8228
                m_inlineStackTop->m_baselineMap, m_icContextStack,
8252
                m_inlineStackTop->m_baselineMap, m_icContextStack,
8229
                currentCodeOrigin(), uid);
8253
                currentCodeOrigin());
8230
8231
            if (status.isSimple() && Options::useAccessInlining()) {
8232
                bool allOK = true;
8233
                MatchStructureData* data = m_graph.m_matchStructureData.add();
8234
                for (const InByIdVariant& variant : status.variants()) {
8235
                    if (!check(variant.conditionSet())) {
8236
                        allOK = false;
8237
                        break;
8238
                    }
8239
                    for (Structure* structure : variant.structureSet()) {
8240
                        MatchStructureVariant matchVariant;
8241
                        matchVariant.structure = m_graph.registerStructure(structure);
8242
                        matchVariant.result = variant.isHit();
8243
8254
8244
                        data->variants.append(WTFMove(matchVariant));
8255
            if (!m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadIdent)
8245
                    }
8256
                && !m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadType)
8246
                }
8257
                && !m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadConstantValue)) {
8247
8258
8248
                if (allOK) {
8259
                if (CacheableIdentifier identifier = status.singleIdentifier()) {
8249
                    addToGraph(FilterInByIdStatus, OpInfo(m_graph.m_plan.recordedStatuses().addInByIdStatus(currentCodeOrigin(), status)), base);
8260
                    UniquedStringImpl* uid = identifier.uid();
8261
                    m_graph.identifiers().ensure(uid);
8262
                    if (identifier.isCell()) {
8263
                        FrozenValue* frozen = m_graph.freezeStrong(identifier.cell());
8264
                        if (identifier.isSymbolCell())
8265
                            addToGraph(CheckIsConstant, OpInfo(frozen), property);
8266
                        else
8267
                            addToGraph(CheckIdent, OpInfo(uid), property);
8268
                    } else
8269
                        addToGraph(CheckIdent, OpInfo(uid), property);
8250
8270
8251
                    Node* match = addToGraph(MatchStructure, OpInfo(data), base);
8271
                    handleInById(bytecode.m_dst, base, identifier, status);
8252
                    set(bytecode.m_dst, match);
8272
                    compiledAsInById = true;
8253
                    NEXT_OPCODE(op_in_by_id);
8254
                }
8273
                }
8255
            }
8274
            }
8256
8275
8257
            set(bytecode.m_dst, addToGraph(InById, OpInfo(CacheableIdentifier::createFromIdentifierOwnedByCodeBlock(m_inlineStackTop->m_profiledBlock, uid)), base));
8276
            if (!compiledAsInById) {
8277
                ArrayMode arrayMode = getArrayMode(bytecode.metadata(codeBlock).m_arrayProfile, Array::Read);
8278
                set(bytecode.m_dst, addToGraph(InByVal, OpInfo(arrayMode.asWord()), base, property));
8279
            }
8280
            NEXT_OPCODE(op_in_by_val);
8281
        }
8282
8283
        case op_in_by_id: {
8284
            auto bytecode = currentInstruction->as<OpInById>();
8285
            Node* base = get(bytecode.m_base);
8286
            unsigned identifierNumber = m_inlineStackTop->m_identifierRemap[bytecode.m_property];
8287
            UniquedStringImpl* uid = m_graph.identifiers()[identifierNumber];
8288
            InByStatus status = InByStatus::computeFor(
8289
                m_inlineStackTop->m_profiledBlock,
8290
                m_inlineStackTop->m_baselineMap, m_icContextStack,
8291
                currentCodeOrigin());
8292
            handleInById(bytecode.m_dst, base, CacheableIdentifier::createFromIdentifierOwnedByCodeBlock(m_inlineStackTop->m_profiledBlock, uid), status);
8258
            NEXT_OPCODE(op_in_by_id);
8293
            NEXT_OPCODE(op_in_by_id);
8259
        }
8294
        }
8260
        
8295
        
- a/Source/JavaScriptCore/dfg/DFGClobberize.h -1 / +1 lines
Lines 504-510 void clobberize(Graph& graph, Node* node, const ReadFunctor& read, const WriteFu a/Source/JavaScriptCore/dfg/DFGClobberize.h_sec1
504
    case FilterCallLinkStatus:
504
    case FilterCallLinkStatus:
505
    case FilterGetByStatus:
505
    case FilterGetByStatus:
506
    case FilterPutByIdStatus:
506
    case FilterPutByIdStatus:
507
    case FilterInByIdStatus:
507
    case FilterInByStatus:
508
    case FilterDeleteByStatus:
508
    case FilterDeleteByStatus:
509
    case FilterCheckPrivateBrandStatus:
509
    case FilterCheckPrivateBrandStatus:
510
    case FilterSetPrivateBrandStatus:
510
    case FilterSetPrivateBrandStatus:
- a/Source/JavaScriptCore/dfg/DFGClobbersExitState.cpp -1 / +1 lines
Lines 82-88 bool clobbersExitState(Graph& graph, Node* node) a/Source/JavaScriptCore/dfg/DFGClobbersExitState.cpp_sec1
82
    case FilterCallLinkStatus:
82
    case FilterCallLinkStatus:
83
    case FilterGetByStatus:
83
    case FilterGetByStatus:
84
    case FilterPutByIdStatus:
84
    case FilterPutByIdStatus:
85
    case FilterInByIdStatus:
85
    case FilterInByStatus:
86
    case FilterDeleteByStatus:
86
    case FilterDeleteByStatus:
87
    case FilterCheckPrivateBrandStatus:
87
    case FilterCheckPrivateBrandStatus:
88
    case FilterSetPrivateBrandStatus:
88
    case FilterSetPrivateBrandStatus:
- a/Source/JavaScriptCore/dfg/DFGDoesGC.cpp -1 / +1 lines
Lines 249-255 bool doesGC(Graph& graph, Node* node) a/Source/JavaScriptCore/dfg/DFGDoesGC.cpp_sec1
249
    case FilterCallLinkStatus:
249
    case FilterCallLinkStatus:
250
    case FilterGetByStatus:
250
    case FilterGetByStatus:
251
    case FilterPutByIdStatus:
251
    case FilterPutByIdStatus:
252
    case FilterInByIdStatus:
252
    case FilterInByStatus:
253
    case FilterDeleteByStatus:
253
    case FilterDeleteByStatus:
254
    case FilterCheckPrivateBrandStatus:
254
    case FilterCheckPrivateBrandStatus:
255
    case FilterSetPrivateBrandStatus:
255
    case FilterSetPrivateBrandStatus:
- a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp -1 / +1 lines
Lines 2882-2888 private: a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp_sec1
2882
        case FilterCallLinkStatus:
2882
        case FilterCallLinkStatus:
2883
        case FilterGetByStatus:
2883
        case FilterGetByStatus:
2884
        case FilterPutByIdStatus:
2884
        case FilterPutByIdStatus:
2885
        case FilterInByIdStatus:
2885
        case FilterInByStatus:
2886
        case FilterDeleteByStatus:
2886
        case FilterDeleteByStatus:
2887
        case FilterCheckPrivateBrandStatus:
2887
        case FilterCheckPrivateBrandStatus:
2888
        case FilterSetPrivateBrandStatus:
2888
        case FilterSetPrivateBrandStatus:
- a/Source/JavaScriptCore/dfg/DFGGraph.cpp -2 / +2 lines
Lines 383-390 void Graph::dump(PrintStream& out, const char* prefixStr, Node* node, DumpContex a/Source/JavaScriptCore/dfg/DFGGraph.cpp_sec1
383
        out.print(comma, *node->callLinkStatus());
383
        out.print(comma, *node->callLinkStatus());
384
    if (node->hasGetByStatus())
384
    if (node->hasGetByStatus())
385
        out.print(comma, *node->getByStatus());
385
        out.print(comma, *node->getByStatus());
386
    if (node->hasInByIdStatus())
386
    if (node->hasInByStatus())
387
        out.print(comma, *node->inByIdStatus());
387
        out.print(comma, *node->inByStatus());
388
    if (node->hasPutByIdStatus())
388
    if (node->hasPutByIdStatus())
389
        out.print(comma, *node->putByIdStatus());
389
        out.print(comma, *node->putByIdStatus());
390
    if (node->isJump())
390
    if (node->isJump())
- a/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp +1 lines
Lines 254-259 void JITCompiler::link(LinkBuffer& linkBuffer) a/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp_sec1
254
    finalizeInlineCaches(m_delByIds, linkBuffer);
254
    finalizeInlineCaches(m_delByIds, linkBuffer);
255
    finalizeInlineCaches(m_delByVals, linkBuffer);
255
    finalizeInlineCaches(m_delByVals, linkBuffer);
256
    finalizeInlineCaches(m_inByIds, linkBuffer);
256
    finalizeInlineCaches(m_inByIds, linkBuffer);
257
    finalizeInlineCaches(m_inByVals, linkBuffer);
257
    finalizeInlineCaches(m_instanceOfs, linkBuffer);
258
    finalizeInlineCaches(m_instanceOfs, linkBuffer);
258
    finalizeInlineCaches(m_privateBrandAccesses, linkBuffer);
259
    finalizeInlineCaches(m_privateBrandAccesses, linkBuffer);
259
260
- a/Source/JavaScriptCore/dfg/DFGJITCompiler.h +6 lines
Lines 214-219 public: a/Source/JavaScriptCore/dfg/DFGJITCompiler.h_sec1
214
        m_inByIds.append(InlineCacheWrapper<JITInByIdGenerator>(gen, slowPath));
214
        m_inByIds.append(InlineCacheWrapper<JITInByIdGenerator>(gen, slowPath));
215
    }
215
    }
216
216
217
    void addInByVal(const JITInByValGenerator& gen, SlowPathGenerator* slowPath)
218
    {
219
        m_inByVals.append(InlineCacheWrapper<JITInByValGenerator>(gen, slowPath));
220
    }
221
217
    void addPrivateBrandAccess(const JITPrivateBrandAccessGenerator& gen, SlowPathGenerator* slowPath)
222
    void addPrivateBrandAccess(const JITPrivateBrandAccessGenerator& gen, SlowPathGenerator* slowPath)
218
    {
223
    {
219
        m_privateBrandAccesses.append(InlineCacheWrapper<JITPrivateBrandAccessGenerator>(gen, slowPath));
224
        m_privateBrandAccesses.append(InlineCacheWrapper<JITPrivateBrandAccessGenerator>(gen, slowPath));
Lines 353-358 private: a/Source/JavaScriptCore/dfg/DFGJITCompiler.h_sec2
353
    Vector<InlineCacheWrapper<JITDelByIdGenerator>, 4> m_delByIds;
358
    Vector<InlineCacheWrapper<JITDelByIdGenerator>, 4> m_delByIds;
354
    Vector<InlineCacheWrapper<JITDelByValGenerator>, 4> m_delByVals;
359
    Vector<InlineCacheWrapper<JITDelByValGenerator>, 4> m_delByVals;
355
    Vector<InlineCacheWrapper<JITInByIdGenerator>, 4> m_inByIds;
360
    Vector<InlineCacheWrapper<JITInByIdGenerator>, 4> m_inByIds;
361
    Vector<InlineCacheWrapper<JITInByValGenerator>, 4> m_inByVals;
356
    Vector<InlineCacheWrapper<JITInstanceOfGenerator>, 4> m_instanceOfs;
362
    Vector<InlineCacheWrapper<JITInstanceOfGenerator>, 4> m_instanceOfs;
357
    Vector<InlineCacheWrapper<JITPrivateBrandAccessGenerator>, 4> m_privateBrandAccesses;
363
    Vector<InlineCacheWrapper<JITPrivateBrandAccessGenerator>, 4> m_privateBrandAccesses;
358
    Vector<JSCallRecord, 4> m_jsCalls;
364
    Vector<JSCallRecord, 4> m_jsCalls;
- a/Source/JavaScriptCore/dfg/DFGMayExit.cpp -1 / +1 lines
Lines 107-113 ExitMode mayExitImpl(Graph& graph, Node* node, StateType& state) a/Source/JavaScriptCore/dfg/DFGMayExit.cpp_sec1
107
    case FilterCallLinkStatus:
107
    case FilterCallLinkStatus:
108
    case FilterGetByStatus:
108
    case FilterGetByStatus:
109
    case FilterPutByIdStatus:
109
    case FilterPutByIdStatus:
110
    case FilterInByIdStatus:
110
    case FilterInByStatus:
111
    case FilterDeleteByStatus:
111
    case FilterDeleteByStatus:
112
    case FilterCheckPrivateBrandStatus:
112
    case FilterCheckPrivateBrandStatus:
113
    case FilterSetPrivateBrandStatus:
113
    case FilterSetPrivateBrandStatus:
- a/Source/JavaScriptCore/dfg/DFGNode.h -5 / +5 lines
Lines 3109-3123 public: a/Source/JavaScriptCore/dfg/DFGNode.h_sec1
3109
        return m_opInfo.as<GetByStatus*>();
3109
        return m_opInfo.as<GetByStatus*>();
3110
    }
3110
    }
3111
    
3111
    
3112
    bool hasInByIdStatus()
3112
    bool hasInByStatus()
3113
    {
3113
    {
3114
        return op() == FilterInByIdStatus;
3114
        return op() == FilterInByStatus;
3115
    }
3115
    }
3116
    
3116
    
3117
    InByIdStatus* inByIdStatus()
3117
    InByStatus* inByStatus()
3118
    {
3118
    {
3119
        ASSERT(hasInByIdStatus());
3119
        ASSERT(hasInByStatus());
3120
        return m_opInfo.as<InByIdStatus*>();
3120
        return m_opInfo.as<InByStatus*>();
3121
    }
3121
    }
3122
    
3122
    
3123
    bool hasPutByIdStatus()
3123
    bool hasPutByIdStatus()
- a/Source/JavaScriptCore/dfg/DFGNodeType.h -1 / +1 lines
Lines 546-552 namespace JSC { namespace DFG { a/Source/JavaScriptCore/dfg/DFGNodeType.h_sec1
546
    /* Used to provide feedback to the IC profiler. */ \
546
    /* Used to provide feedback to the IC profiler. */ \
547
    macro(FilterCallLinkStatus, NodeMustGenerate) \
547
    macro(FilterCallLinkStatus, NodeMustGenerate) \
548
    macro(FilterGetByStatus, NodeMustGenerate) \
548
    macro(FilterGetByStatus, NodeMustGenerate) \
549
    macro(FilterInByIdStatus, NodeMustGenerate) \
549
    macro(FilterInByStatus, NodeMustGenerate) \
550
    macro(FilterPutByIdStatus, NodeMustGenerate) \
550
    macro(FilterPutByIdStatus, NodeMustGenerate) \
551
    macro(FilterDeleteByStatus, NodeMustGenerate) \
551
    macro(FilterDeleteByStatus, NodeMustGenerate) \
552
    macro(FilterCheckPrivateBrandStatus, NodeMustGenerate) \
552
    macro(FilterCheckPrivateBrandStatus, NodeMustGenerate) \
- a/Source/JavaScriptCore/dfg/DFGObjectAllocationSinkingPhase.cpp -2 / +2 lines
Lines 1259-1265 private: a/Source/JavaScriptCore/dfg/DFGObjectAllocationSinkingPhase.cpp_sec1
1259
        case FilterCallLinkStatus:
1259
        case FilterCallLinkStatus:
1260
        case FilterGetByStatus:
1260
        case FilterGetByStatus:
1261
        case FilterPutByIdStatus:
1261
        case FilterPutByIdStatus:
1262
        case FilterInByIdStatus:
1262
        case FilterInByStatus:
1263
        case FilterDeleteByStatus:
1263
        case FilterDeleteByStatus:
1264
        case FilterCheckPrivateBrandStatus:
1264
        case FilterCheckPrivateBrandStatus:
1265
        case FilterSetPrivateBrandStatus:
1265
        case FilterSetPrivateBrandStatus:
Lines 2616-2622 private: a/Source/JavaScriptCore/dfg/DFGObjectAllocationSinkingPhase.cpp_sec2
2616
                case FilterCallLinkStatus:
2616
                case FilterCallLinkStatus:
2617
                case FilterGetByStatus:
2617
                case FilterGetByStatus:
2618
                case FilterPutByIdStatus:
2618
                case FilterPutByIdStatus:
2619
                case FilterInByIdStatus:
2619
                case FilterInByStatus:
2620
                case FilterDeleteByStatus:
2620
                case FilterDeleteByStatus:
2621
                case FilterCheckPrivateBrandStatus:
2621
                case FilterCheckPrivateBrandStatus:
2622
                case FilterSetPrivateBrandStatus:
2622
                case FilterSetPrivateBrandStatus:
- a/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp -1 / +1 lines
Lines 1451-1457 private: a/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp_sec1
1451
        case FilterCallLinkStatus:
1451
        case FilterCallLinkStatus:
1452
        case FilterGetByStatus:
1452
        case FilterGetByStatus:
1453
        case FilterPutByIdStatus:
1453
        case FilterPutByIdStatus:
1454
        case FilterInByIdStatus:
1454
        case FilterInByStatus:
1455
        case FilterDeleteByStatus:
1455
        case FilterDeleteByStatus:
1456
        case FilterCheckPrivateBrandStatus:
1456
        case FilterCheckPrivateBrandStatus:
1457
        case FilterSetPrivateBrandStatus:
1457
        case FilterSetPrivateBrandStatus:
- a/Source/JavaScriptCore/dfg/DFGSafeToExecute.h -1 / +1 lines
Lines 361-367 bool safeToExecute(AbstractStateType& state, Graph& graph, Node* node, bool igno a/Source/JavaScriptCore/dfg/DFGSafeToExecute.h_sec1
361
    case FilterCallLinkStatus:
361
    case FilterCallLinkStatus:
362
    case FilterGetByStatus:
362
    case FilterGetByStatus:
363
    case FilterPutByIdStatus:
363
    case FilterPutByIdStatus:
364
    case FilterInByIdStatus:
364
    case FilterInByStatus:
365
    case FilterDeleteByStatus:
365
    case FilterDeleteByStatus:
366
    case FilterCheckPrivateBrandStatus:
366
    case FilterCheckPrivateBrandStatus:
367
    case FilterSetPrivateBrandStatus:
367
    case FilterSetPrivateBrandStatus:
- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp -6 / +19 lines
Lines 1267-1284 void SpeculativeJIT::compileInByVal(Node* node) a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp_sec1
1267
{
1267
{
1268
    SpeculateCellOperand base(this, node->child1());
1268
    SpeculateCellOperand base(this, node->child1());
1269
    JSValueOperand key(this, node->child2());
1269
    JSValueOperand key(this, node->child2());
1270
    JSValueRegsTemporary result(this, Reuse, key);
1270
1271
1271
    GPRReg baseGPR = base.gpr();
1272
    GPRReg baseGPR = base.gpr();
1272
    JSValueRegs regs = key.jsValueRegs();
1273
    JSValueRegs keyRegs = key.jsValueRegs();
1274
    JSValueRegs resultRegs = result.regs();
1273
1275
1274
    base.use();
1276
    base.use();
1275
    key.use();
1277
    key.use();
1276
1278
1277
    flushRegisters();
1279
    CodeOrigin codeOrigin = node->origin.semantic;
1278
    JSValueRegsFlushedCallResult result(this);
1280
    CallSiteIndex callSite = m_jit.recordCallSiteAndGenerateExceptionHandlingOSRExitIfNeeded(codeOrigin, m_stream->size());
1279
    JSValueRegs resultRegs = result.regs();
1281
    RegisterSet usedRegisters = this->usedRegisters();
1280
    callOperation(operationInByVal, resultRegs, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), baseGPR, regs);
1282
    JITInByValGenerator gen(
1281
    m_jit.exceptionCheck();
1283
        m_jit.codeBlock(), codeOrigin, callSite, usedRegisters,
1284
        JSValueRegs::payloadOnly(baseGPR), keyRegs, resultRegs);
1285
    gen.generateFastPath(m_jit);
1286
1287
    auto slowPath = slowPathCall(
1288
        gen.slowPathJump(), this, operationInByValOptimize,
1289
        NeedToSpill, ExceptionCheckRequirement::CheckNeeded,
1290
        resultRegs, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), gen.stubInfo(), nullptr, CCallHelpers::CellValue(baseGPR), keyRegs);
1291
1292
    m_jit.addInByVal(gen, slowPath.get());
1293
    addSlowPathGenerator(WTFMove(slowPath));
1294
1282
    blessedBooleanResult(resultRegs.payloadGPR(), node, UseChildrenCalledExplicitly);
1295
    blessedBooleanResult(resultRegs.payloadGPR(), node, UseChildrenCalledExplicitly);
1283
}
1296
}
1284
1297
- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp -1 / +1 lines
Lines 4271-4277 void SpeculativeJIT::compile(Node* node) a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp_sec1
4271
    case FilterCallLinkStatus:
4271
    case FilterCallLinkStatus:
4272
    case FilterGetByStatus:
4272
    case FilterGetByStatus:
4273
    case FilterPutByIdStatus:
4273
    case FilterPutByIdStatus:
4274
    case FilterInByIdStatus:
4274
    case FilterInByStatus:
4275
    case FilterDeleteByStatus:
4275
    case FilterDeleteByStatus:
4276
    case FilterCheckPrivateBrandStatus:
4276
    case FilterCheckPrivateBrandStatus:
4277
    case FilterSetPrivateBrandStatus:
4277
    case FilterSetPrivateBrandStatus:
- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp -1 / +1 lines
Lines 5705-5711 void SpeculativeJIT::compile(Node* node) a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp_sec1
5705
    case FilterCallLinkStatus:
5705
    case FilterCallLinkStatus:
5706
    case FilterGetByStatus:
5706
    case FilterGetByStatus:
5707
    case FilterPutByIdStatus:
5707
    case FilterPutByIdStatus:
5708
    case FilterInByIdStatus:
5708
    case FilterInByStatus:
5709
    case FilterDeleteByStatus:
5709
    case FilterDeleteByStatus:
5710
    case FilterCheckPrivateBrandStatus:
5710
    case FilterCheckPrivateBrandStatus:
5711
    case FilterSetPrivateBrandStatus:
5711
    case FilterSetPrivateBrandStatus:
- a/Source/JavaScriptCore/dfg/DFGVarargsForwardingPhase.cpp -2 / +2 lines
Lines 197-203 private: a/Source/JavaScriptCore/dfg/DFGVarargsForwardingPhase.cpp_sec1
197
            case FilterGetByStatus:
197
            case FilterGetByStatus:
198
            case FilterPutByIdStatus:
198
            case FilterPutByIdStatus:
199
            case FilterCallLinkStatus:
199
            case FilterCallLinkStatus:
200
            case FilterInByIdStatus:
200
            case FilterInByStatus:
201
            case FilterDeleteByStatus:
201
            case FilterDeleteByStatus:
202
            case FilterCheckPrivateBrandStatus:
202
            case FilterCheckPrivateBrandStatus:
203
            case FilterSetPrivateBrandStatus:
203
            case FilterSetPrivateBrandStatus:
Lines 401-407 private: a/Source/JavaScriptCore/dfg/DFGVarargsForwardingPhase.cpp_sec2
401
            case FilterGetByStatus:
401
            case FilterGetByStatus:
402
            case FilterPutByIdStatus:
402
            case FilterPutByIdStatus:
403
            case FilterCallLinkStatus:
403
            case FilterCallLinkStatus:
404
            case FilterInByIdStatus:
404
            case FilterInByStatus:
405
            case FilterDeleteByStatus:
405
            case FilterDeleteByStatus:
406
            case FilterCheckPrivateBrandStatus:
406
            case FilterCheckPrivateBrandStatus:
407
            case FilterSetPrivateBrandStatus:
407
            case FilterSetPrivateBrandStatus:
- a/Source/JavaScriptCore/ftl/FTLCapabilities.cpp -1 / +1 lines
Lines 409-415 inline CapabilityLevel canCompile(Node* node) a/Source/JavaScriptCore/ftl/FTLCapabilities.cpp_sec1
409
    case FilterCallLinkStatus:
409
    case FilterCallLinkStatus:
410
    case FilterGetByStatus:
410
    case FilterGetByStatus:
411
    case FilterPutByIdStatus:
411
    case FilterPutByIdStatus:
412
    case FilterInByIdStatus:
412
    case FilterInByStatus:
413
    case FilterDeleteByStatus:
413
    case FilterDeleteByStatus:
414
    case FilterCheckPrivateBrandStatus:
414
    case FilterCheckPrivateBrandStatus:
415
    case FilterSetPrivateBrandStatus:
415
    case FilterSetPrivateBrandStatus:
- a/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp -30 / +59 lines
Lines 1652-1658 private: a/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp_sec1
1652
        case FilterCallLinkStatus:
1652
        case FilterCallLinkStatus:
1653
        case FilterGetByStatus:
1653
        case FilterGetByStatus:
1654
        case FilterPutByIdStatus:
1654
        case FilterPutByIdStatus:
1655
        case FilterInByIdStatus:
1655
        case FilterInByStatus:
1656
        case FilterDeleteByStatus:
1656
        case FilterDeleteByStatus:
1657
        case FilterCheckPrivateBrandStatus:
1657
        case FilterCheckPrivateBrandStatus:
1658
        case FilterSetPrivateBrandStatus:
1658
        case FilterSetPrivateBrandStatus:
Lines 12213-12225 private: a/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp_sec2
12213
        m_out.appendTo(continuation, lastNext);
12213
        m_out.appendTo(continuation, lastNext);
12214
        setJSValue(m_out.phi(Int64, results));
12214
        setJSValue(m_out.phi(Int64, results));
12215
    }
12215
    }
12216
    
12216
12217
    void compileInByVal()
12218
    {
12219
        JSGlobalObject* globalObject = m_graph.globalObjectFor(m_origin.semantic);
12220
        setJSValue(vmCall(Int64, operationInByVal, weakPointer(globalObject), lowCell(m_node->child1()), lowJSValue(m_node->child2())));
12221
    }
12222
    
12223
    void compileHasPrivateName()
12217
    void compileHasPrivateName()
12224
    {
12218
    {
12225
        JSGlobalObject* globalObject = m_graph.globalObjectFor(m_origin.semantic);
12219
        JSGlobalObject* globalObject = m_graph.globalObjectFor(m_origin.semantic);
Lines 12232-12269 private: a/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp_sec3
12232
        setJSValue(vmCall(Int64, operationHasPrivateBrand, weakPointer(globalObject), lowCell(m_node->child1()), lowSymbol(m_node->child2())));
12226
        setJSValue(vmCall(Int64, operationHasPrivateBrand, weakPointer(globalObject), lowCell(m_node->child1()), lowSymbol(m_node->child2())));
12233
    }
12227
    }
12234
12228
12235
    void compileInById()
12229
    template<InByKind kind, typename SubscriptKind>
12230
    void compileInBy(LValue base, SubscriptKind subscriptValue)
12236
    {
12231
    {
12237
        Node* node = m_node;
12238
        CacheableIdentifier identifier = node->cacheableIdentifier();
12239
        LValue base = lowCell(m_node->child1());
12240
12241
        PatchpointValue* patchpoint = m_out.patchpoint(Int64);
12232
        PatchpointValue* patchpoint = m_out.patchpoint(Int64);
12242
        patchpoint->appendSomeRegister(base);
12233
        patchpoint->appendSomeRegister(base);
12234
        if constexpr (kind != InByKind::Normal)
12235
            patchpoint->appendSomeRegister(subscriptValue);
12243
        patchpoint->append(m_notCellMask, ValueRep::lateReg(GPRInfo::notCellMaskRegister));
12236
        patchpoint->append(m_notCellMask, ValueRep::lateReg(GPRInfo::notCellMaskRegister));
12244
        patchpoint->append(m_numberTag, ValueRep::lateReg(GPRInfo::numberTagRegister));
12237
        patchpoint->append(m_numberTag, ValueRep::lateReg(GPRInfo::numberTagRegister));
12245
12246
        patchpoint->clobber(RegisterSet::macroScratchRegisters());
12238
        patchpoint->clobber(RegisterSet::macroScratchRegisters());
12247
12239
12248
        RefPtr<PatchpointExceptionHandle> exceptionHandle =
12240
        RefPtr<PatchpointExceptionHandle> exceptionHandle = preparePatchpointForExceptions(patchpoint);
12249
            preparePatchpointForExceptions(patchpoint);
12250
12241
12251
        State* state = &m_ftlState;
12242
        State* state = &m_ftlState;
12243
        Node* node = m_node;
12252
        patchpoint->setGenerator(
12244
        patchpoint->setGenerator(
12253
            [=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
12245
            [=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
12254
                AllowMacroScratchRegisterUsage allowScratch(jit);
12246
                AllowMacroScratchRegisterUsage allowScratch(jit);
12255
12247
12256
                CallSiteIndex callSiteIndex =
12248
                CallSiteIndex callSiteIndex = state->jitCode->common.codeOrigins->addUniqueCallSiteIndex(node->origin.semantic);
12257
                    state->jitCode->common.codeOrigins->addUniqueCallSiteIndex(node->origin.semantic);
12258
12249
12259
                // This is the direct exit target for operation calls.
12250
                // This is the direct exit target for operation calls.
12260
                Box<CCallHelpers::JumpList> exceptions =
12251
                Box<CCallHelpers::JumpList> exceptions = exceptionHandle->scheduleExitCreation(params)->jumps(jit);
12261
                    exceptionHandle->scheduleExitCreation(params)->jumps(jit);
12262
12252
12263
                auto generator = Box<JITInByIdGenerator>::create(
12253
                auto returnGPR = params[0].gpr();
12264
                    jit.codeBlock(), node->origin.semantic, callSiteIndex,
12254
                auto base = JSValueRegs(params[1].gpr());
12265
                    params.unavailableRegisters(), identifier, JSValueRegs(params[1].gpr()),
12255
12266
                    JSValueRegs(params[0].gpr()));
12256
                const auto subscript = [&] {
12257
                    if constexpr (kind == InByKind::Normal)
12258
                        return CCallHelpers::TrustedImmPtr(subscriptValue.rawBits());
12259
                    else
12260
                        return JSValueRegs(params[2].gpr());
12261
                }();
12262
12263
                const auto generator = [&] {
12264
                    if constexpr (kind == InByKind::Normal) {
12265
                        return Box<JITInByIdGenerator>::create(
12266
                            jit.codeBlock(), node->origin.semantic, callSiteIndex,
12267
                            params.unavailableRegisters(), subscriptValue, base,
12268
                            JSValueRegs(returnGPR));
12269
                    } else {
12270
                        return Box<JITInByValGenerator>::create(
12271
                            jit.codeBlock(), node->origin.semantic, callSiteIndex,
12272
                            params.unavailableRegisters(), base, subscript,
12273
                            JSValueRegs(returnGPR));
12274
                    }
12275
                }();
12267
12276
12268
                generator->generateFastPath(jit);
12277
                generator->generateFastPath(jit);
12269
                CCallHelpers::Label done = jit.label();
12278
                CCallHelpers::Label done = jit.label();
Lines 12274-12285 private: a/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp_sec4
12274
12283
12275
                        generator->slowPathJump().link(&jit);
12284
                        generator->slowPathJump().link(&jit);
12276
                        CCallHelpers::Label slowPathBegin = jit.label();
12285
                        CCallHelpers::Label slowPathBegin = jit.label();
12277
                        CCallHelpers::Call slowPathCall = callOperation(
12286
                        CCallHelpers::Call slowPathCall;
12278
                            *state, params.unavailableRegisters(), jit, node->origin.semantic,
12287
                        if constexpr (kind == InByKind::Normal) {
12279
                            exceptions.get(), operationInByIdOptimize, params[0].gpr(),
12288
                            slowPathCall = callOperation(
12280
                            jit.codeBlock()->globalObjectFor(node->origin.semantic),
12289
                                *state, params.unavailableRegisters(), jit, node->origin.semantic,
12281
                            CCallHelpers::TrustedImmPtr(generator->stubInfo()), params[1].gpr(),
12290
                                exceptions.get(), operationInByIdOptimize, returnGPR,
12282
                            identifier.rawBits()).call();
12291
                                jit.codeBlock()->globalObjectFor(node->origin.semantic),
12292
                                CCallHelpers::TrustedImmPtr(generator->stubInfo()),
12293
                                base, subscript).call();
12294
                        } else {
12295
                            slowPathCall = callOperation(
12296
                                *state, params.unavailableRegisters(), jit, node->origin.semantic,
12297
                                exceptions.get(), operationInByValOptimize, returnGPR,
12298
                                jit.codeBlock()->globalObjectFor(node->origin.semantic),
12299
                                CCallHelpers::TrustedImmPtr(generator->stubInfo()),
12300
                                CCallHelpers::TrustedImmPtr(nullptr), base, subscript).call();
12301
                        }
12283
                        jit.jump().linkTo(done, &jit);
12302
                        jit.jump().linkTo(done, &jit);
12284
12303
12285
                        generator->reportSlowPathCall(slowPathBegin, slowPathCall);
12304
                        generator->reportSlowPathCall(slowPathBegin, slowPathCall);
Lines 12294-12299 private: a/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp_sec5
12294
        setJSValue(patchpoint);
12313
        setJSValue(patchpoint);
12295
    }
12314
    }
12296
12315
12316
    void compileInById()
12317
    {
12318
        compileInBy<InByKind::Normal>(lowCell(m_node->child1()), m_node->cacheableIdentifier());
12319
    }
12320
12321
    void compileInByVal()
12322
    {
12323
        compileInBy<InByKind::NormalByVal>(lowCell(m_node->child1()), lowJSValue(m_node->child2()));
12324
    }
12325
12297
    void compileHasOwnProperty()
12326
    void compileHasOwnProperty()
12298
    {
12327
    {
12299
        JSGlobalObject* globalObject = m_graph.globalObjectFor(m_origin.semantic);
12328
        JSGlobalObject* globalObject = m_graph.globalObjectFor(m_origin.semantic);
- a/Source/JavaScriptCore/jit/ICStats.h -1 / +2 lines
Lines 43-48 namespace JSC { a/Source/JavaScriptCore/jit/ICStats.h_sec1
43
    macro(GetBySelfPatch) \
43
    macro(GetBySelfPatch) \
44
    macro(InAddAccessCase) \
44
    macro(InAddAccessCase) \
45
    macro(InReplaceWithJump) \
45
    macro(InReplaceWithJump) \
46
    macro(InReplaceWithGeneric) \
46
    macro(InstanceOfAddAccessCase) \
47
    macro(InstanceOfAddAccessCase) \
47
    macro(InstanceOfReplaceWithJump) \
48
    macro(InstanceOfReplaceWithJump) \
48
    macro(OperationGetById) \
49
    macro(OperationGetById) \
Lines 52-58 namespace JSC { a/Source/JavaScriptCore/jit/ICStats.h_sec2
52
    macro(OperationGetByValOptimize) \
53
    macro(OperationGetByValOptimize) \
53
    macro(OperationGetByIdWithThisOptimize) \
54
    macro(OperationGetByIdWithThisOptimize) \
54
    macro(OperationGenericIn) \
55
    macro(OperationGenericIn) \
55
    macro(OperationInById) \
56
    macro(OperationInByIdGeneric) \
56
    macro(OperationInByIdOptimize) \
57
    macro(OperationInByIdOptimize) \
57
    macro(OperationPutByIdStrict) \
58
    macro(OperationPutByIdStrict) \
58
    macro(OperationPutByIdNonStrict) \
59
    macro(OperationPutByIdNonStrict) \
- a/Source/JavaScriptCore/jit/JIT.cpp -2 / +5 lines
Lines 278-284 void JIT::privateCompileMainPass() a/Source/JavaScriptCore/jit/JIT.cpp_sec1
278
        }
278
        }
279
279
280
        switch (opcodeID) {
280
        switch (opcodeID) {
281
        DEFINE_SLOW_OP(in_by_val)
282
        DEFINE_SLOW_OP(has_private_name)
281
        DEFINE_SLOW_OP(has_private_name)
283
        DEFINE_SLOW_OP(has_private_brand)
282
        DEFINE_SLOW_OP(has_private_brand)
284
        DEFINE_SLOW_OP(less)
283
        DEFINE_SLOW_OP(less)
Lines 354-359 void JIT::privateCompileMainPass() a/Source/JavaScriptCore/jit/JIT.cpp_sec2
354
        DEFINE_OP(op_beloweq)
353
        DEFINE_OP(op_beloweq)
355
        DEFINE_OP(op_try_get_by_id)
354
        DEFINE_OP(op_try_get_by_id)
356
        DEFINE_OP(op_in_by_id)
355
        DEFINE_OP(op_in_by_id)
356
        DEFINE_OP(op_in_by_val)
357
        DEFINE_OP(op_get_by_id)
357
        DEFINE_OP(op_get_by_id)
358
        DEFINE_OP(op_get_by_id_with_this)
358
        DEFINE_OP(op_get_by_id_with_this)
359
        DEFINE_OP(op_get_by_id_direct)
359
        DEFINE_OP(op_get_by_id_direct)
Lines 508-515 void JIT::privateCompileSlowCases() a/Source/JavaScriptCore/jit/JIT.cpp_sec3
508
    m_getByIdWithThisIndex = 0;
508
    m_getByIdWithThisIndex = 0;
509
    m_putByIdIndex = 0;
509
    m_putByIdIndex = 0;
510
    m_inByIdIndex = 0;
510
    m_inByIdIndex = 0;
511
    m_delByValIndex = 0;
511
    m_inByValIndex = 0;
512
    m_delByIdIndex = 0;
512
    m_delByIdIndex = 0;
513
    m_delByValIndex = 0;
513
    m_instanceOfIndex = 0;
514
    m_instanceOfIndex = 0;
514
    m_privateBrandAccessIndex = 0;
515
    m_privateBrandAccessIndex = 0;
515
    m_byValInstructionIndex = 0;
516
    m_byValInstructionIndex = 0;
Lines 553-558 void JIT::privateCompileSlowCases() a/Source/JavaScriptCore/jit/JIT.cpp_sec4
553
        DEFINE_SLOWCASE_OP(op_eq)
554
        DEFINE_SLOWCASE_OP(op_eq)
554
        DEFINE_SLOWCASE_OP(op_try_get_by_id)
555
        DEFINE_SLOWCASE_OP(op_try_get_by_id)
555
        DEFINE_SLOWCASE_OP(op_in_by_id)
556
        DEFINE_SLOWCASE_OP(op_in_by_id)
557
        DEFINE_SLOWCASE_OP(op_in_by_val)
556
        DEFINE_SLOWCASE_OP(op_get_by_id)
558
        DEFINE_SLOWCASE_OP(op_get_by_id)
557
        DEFINE_SLOWCASE_OP(op_get_by_id_with_this)
559
        DEFINE_SLOWCASE_OP(op_get_by_id_with_this)
558
        DEFINE_SLOWCASE_OP(op_get_by_id_direct)
560
        DEFINE_SLOWCASE_OP(op_get_by_id_direct)
Lines 904-909 void JIT::link() a/Source/JavaScriptCore/jit/JIT.cpp_sec5
904
    finalizeInlineCaches(m_delByIds, patchBuffer);
906
    finalizeInlineCaches(m_delByIds, patchBuffer);
905
    finalizeInlineCaches(m_delByVals, patchBuffer);
907
    finalizeInlineCaches(m_delByVals, patchBuffer);
906
    finalizeInlineCaches(m_inByIds, patchBuffer);
908
    finalizeInlineCaches(m_inByIds, patchBuffer);
909
    finalizeInlineCaches(m_inByVals, patchBuffer);
907
    finalizeInlineCaches(m_instanceOfs, patchBuffer);
910
    finalizeInlineCaches(m_instanceOfs, patchBuffer);
908
    finalizeInlineCaches(m_privateBrandAccesses, patchBuffer);
911
    finalizeInlineCaches(m_privateBrandAccesses, patchBuffer);
909
912
- a/Source/JavaScriptCore/jit/JIT.h +4 lines
Lines 564-569 namespace JSC { a/Source/JavaScriptCore/jit/JIT.h_sec1
564
        void emit_op_get_argument_by_val(const Instruction*);
564
        void emit_op_get_argument_by_val(const Instruction*);
565
        void emit_op_get_prototype_of(const Instruction*);
565
        void emit_op_get_prototype_of(const Instruction*);
566
        void emit_op_in_by_id(const Instruction*);
566
        void emit_op_in_by_id(const Instruction*);
567
        void emit_op_in_by_val(const Instruction*);
567
        void emit_op_init_lazy_reg(const Instruction*);
568
        void emit_op_init_lazy_reg(const Instruction*);
568
        void emit_op_overrides_has_instance(const Instruction*);
569
        void emit_op_overrides_has_instance(const Instruction*);
569
        void emit_op_instanceof(const Instruction*);
570
        void emit_op_instanceof(const Instruction*);
Lines 697-702 namespace JSC { a/Source/JavaScriptCore/jit/JIT.h_sec2
697
        void emitSlow_op_check_private_brand(const Instruction*, Vector<SlowCaseEntry>::iterator&);
698
        void emitSlow_op_check_private_brand(const Instruction*, Vector<SlowCaseEntry>::iterator&);
698
        void emitSlow_op_get_argument_by_val(const Instruction*, Vector<SlowCaseEntry>::iterator&);
699
        void emitSlow_op_get_argument_by_val(const Instruction*, Vector<SlowCaseEntry>::iterator&);
699
        void emitSlow_op_in_by_id(const Instruction*, Vector<SlowCaseEntry>::iterator&);
700
        void emitSlow_op_in_by_id(const Instruction*, Vector<SlowCaseEntry>::iterator&);
701
        void emitSlow_op_in_by_val(const Instruction*, Vector<SlowCaseEntry>::iterator&);
700
        void emitSlow_op_instanceof(const Instruction*, Vector<SlowCaseEntry>::iterator&);
702
        void emitSlow_op_instanceof(const Instruction*, Vector<SlowCaseEntry>::iterator&);
701
        void emitSlow_op_instanceof_custom(const Instruction*, Vector<SlowCaseEntry>::iterator&);
703
        void emitSlow_op_instanceof_custom(const Instruction*, Vector<SlowCaseEntry>::iterator&);
702
        void emitSlow_op_jless(const Instruction*, Vector<SlowCaseEntry>::iterator&);
704
        void emitSlow_op_jless(const Instruction*, Vector<SlowCaseEntry>::iterator&);
Lines 1001-1006 namespace JSC { a/Source/JavaScriptCore/jit/JIT.h_sec3
1001
        Vector<JITGetByIdWithThisGenerator> m_getByIdsWithThis;
1003
        Vector<JITGetByIdWithThisGenerator> m_getByIdsWithThis;
1002
        Vector<JITPutByIdGenerator> m_putByIds;
1004
        Vector<JITPutByIdGenerator> m_putByIds;
1003
        Vector<JITInByIdGenerator> m_inByIds;
1005
        Vector<JITInByIdGenerator> m_inByIds;
1006
        Vector<JITInByValGenerator> m_inByVals;
1004
        Vector<JITDelByIdGenerator> m_delByIds;
1007
        Vector<JITDelByIdGenerator> m_delByIds;
1005
        Vector<JITDelByValGenerator> m_delByVals;
1008
        Vector<JITDelByValGenerator> m_delByVals;
1006
        Vector<JITInstanceOfGenerator> m_instanceOfs;
1009
        Vector<JITInstanceOfGenerator> m_instanceOfs;
Lines 1027-1032 namespace JSC { a/Source/JavaScriptCore/jit/JIT.h_sec4
1027
        unsigned m_getByIdWithThisIndex { UINT_MAX };
1030
        unsigned m_getByIdWithThisIndex { UINT_MAX };
1028
        unsigned m_putByIdIndex { UINT_MAX };
1031
        unsigned m_putByIdIndex { UINT_MAX };
1029
        unsigned m_inByIdIndex { UINT_MAX };
1032
        unsigned m_inByIdIndex { UINT_MAX };
1033
        unsigned m_inByValIndex { UINT_MAX };
1030
        unsigned m_delByValIndex { UINT_MAX };
1034
        unsigned m_delByValIndex { UINT_MAX };
1031
        unsigned m_delByIdIndex { UINT_MAX };
1035
        unsigned m_delByIdIndex { UINT_MAX };
1032
        unsigned m_instanceOfIndex { UINT_MAX };
1036
        unsigned m_instanceOfIndex { UINT_MAX };
- a/Source/JavaScriptCore/jit/JITInlineCacheGenerator.cpp -4 / +32 lines
Lines 235-244 void JITDelByIdGenerator::finalize( a/Source/JavaScriptCore/jit/JITInlineCacheGenerator.cpp_sec1
235
        fastPath, slowPath, fastPath.locationOf<JITStubRoutinePtrTag>(m_start));
235
        fastPath, slowPath, fastPath.locationOf<JITStubRoutinePtrTag>(m_start));
236
}
236
}
237
237
238
JITInByIdGenerator::JITInByIdGenerator(
238
JITInByValGenerator::JITInByValGenerator(CodeBlock* codeBlock, CodeOrigin codeOrigin, CallSiteIndex callSiteIndex, const RegisterSet& usedRegisters, JSValueRegs base, JSValueRegs property, JSValueRegs result)
239
    CodeBlock* codeBlock, CodeOrigin codeOrigin, CallSiteIndex callSite, const RegisterSet& usedRegisters,
239
    : Base(codeBlock, codeOrigin, callSiteIndex, AccessType::InByVal, usedRegisters)
240
    CacheableIdentifier propertyName, JSValueRegs base, JSValueRegs value)
240
{
241
    : JITByIdGenerator(codeBlock, codeOrigin, callSite, AccessType::In, usedRegisters, base, value)
241
    m_stubInfo->hasConstantIdentifier = false;
242
243
    m_stubInfo->baseGPR = base.payloadGPR();
244
    m_stubInfo->regs.propertyGPR = property.payloadGPR();
245
    m_stubInfo->valueGPR = result.payloadGPR();
246
#if USE(JSVALUE32_64)
247
    m_stubInfo->baseTagGPR = base.tagGPR();
248
    m_stubInfo->valueTagGPR = result.tagGPR();
249
    m_stubInfo->v.propertyTagGPR = property.tagGPR();
250
#endif
251
}
252
253
void JITInByValGenerator::generateFastPath(MacroAssembler& jit)
254
{
255
    m_start = jit.label();
256
    m_slowPathJump = jit.patchableJump();
257
    m_done = jit.label();
258
}
259
260
void JITInByValGenerator::finalize(
261
    LinkBuffer& fastPath, LinkBuffer& slowPath)
262
{
263
    ASSERT(m_start.isSet());
264
    Base::finalize(
265
        fastPath, slowPath, fastPath.locationOf<JITStubRoutinePtrTag>(m_start));
266
}
267
268
JITInByIdGenerator::JITInByIdGenerator(CodeBlock* codeBlock, CodeOrigin codeOrigin, CallSiteIndex callSite, const RegisterSet& usedRegisters, CacheableIdentifier propertyName, JSValueRegs base, JSValueRegs value)
269
    : JITByIdGenerator(codeBlock, codeOrigin, callSite, AccessType::InById, usedRegisters, base, value)
242
{
270
{
243
    // FIXME: We are not supporting fast path for "length" property.
271
    // FIXME: We are not supporting fast path for "length" property.
244
    UNUSED_PARAM(propertyName);
272
    UNUSED_PARAM(propertyName);
- a/Source/JavaScriptCore/jit/JITInlineCacheGenerator.h +25 lines
Lines 195-200 private: a/Source/JavaScriptCore/jit/JITInlineCacheGenerator.h_sec1
195
    MacroAssembler::PatchableJump m_slowPathJump;
195
    MacroAssembler::PatchableJump m_slowPathJump;
196
};
196
};
197
197
198
class JITInByValGenerator : public JITInlineCacheGenerator {
199
    using Base = JITInlineCacheGenerator;
200
public:
201
    JITInByValGenerator() { }
202
203
    JITInByValGenerator(
204
        CodeBlock*, CodeOrigin, CallSiteIndex, const RegisterSet& usedRegisters,
205
        JSValueRegs base, JSValueRegs property, JSValueRegs result);
206
207
    MacroAssembler::Jump slowPathJump() const
208
    {
209
        ASSERT(m_slowPathJump.m_jump.isSet());
210
        return m_slowPathJump.m_jump;
211
    }
212
213
    void finalize(
214
        LinkBuffer& fastPathLinkBuffer, LinkBuffer& slowPathLinkBuffer);
215
216
    void generateFastPath(MacroAssembler&);
217
218
private:
219
    MacroAssembler::Label m_start;
220
    MacroAssembler::PatchableJump m_slowPathJump;
221
};
222
198
class JITInByIdGenerator : public JITByIdGenerator {
223
class JITInByIdGenerator : public JITByIdGenerator {
199
public:
224
public:
200
    JITInByIdGenerator() { }
225
    JITInByIdGenerator() { }
- a/Source/JavaScriptCore/jit/JITOperations.cpp -6 / +49 lines
Lines 395-401 JSC_DEFINE_JIT_OPERATION(operationGetByIdWithThisOptimize, EncodedJSValue, (JSGl a/Source/JavaScriptCore/jit/JITOperations.cpp_sec1
395
    }));
395
    }));
396
}
396
}
397
397
398
JSC_DEFINE_JIT_OPERATION(operationInById, EncodedJSValue, (JSGlobalObject* globalObject, StructureStubInfo* stubInfo, EncodedJSValue base, uintptr_t rawCacheableIdentifier))
398
JSC_DEFINE_JIT_OPERATION(operationInByIdGeneric, EncodedJSValue, (JSGlobalObject* globalObject, StructureStubInfo* stubInfo, EncodedJSValue base, uintptr_t rawCacheableIdentifier))
399
{
399
{
400
    SuperSamplerScope superSamplerScope(false);
400
    SuperSamplerScope superSamplerScope(false);
401
401
Lines 416-422 JSC_DEFINE_JIT_OPERATION(operationInById, EncodedJSValue, (JSGlobalObject* globa a/Source/JavaScriptCore/jit/JITOperations.cpp_sec2
416
    }
416
    }
417
    JSObject* baseObject = asObject(baseValue);
417
    JSObject* baseObject = asObject(baseValue);
418
418
419
    LOG_IC((ICEvent::OperationInById, baseObject->classInfo(vm), ident));
419
    LOG_IC((ICEvent::OperationInByIdGeneric, baseObject->classInfo(vm), ident));
420
420
421
    scope.release();
421
    scope.release();
422
    PropertySlot slot(baseObject, PropertySlot::InternalMethodType::HasProperty);
422
    PropertySlot slot(baseObject, PropertySlot::InternalMethodType::HasProperty);
Lines 449-467 JSC_DEFINE_JIT_OPERATION(operationInByIdOptimize, EncodedJSValue, (JSGlobalObjec a/Source/JavaScriptCore/jit/JITOperations.cpp_sec3
449
    bool found = baseObject->getPropertySlot(globalObject, ident, slot);
449
    bool found = baseObject->getPropertySlot(globalObject, ident, slot);
450
    CodeBlock* codeBlock = callFrame->codeBlock();
450
    CodeBlock* codeBlock = callFrame->codeBlock();
451
    if (stubInfo->considerCachingBy(vm, codeBlock, baseObject->structure(vm), identifier))
451
    if (stubInfo->considerCachingBy(vm, codeBlock, baseObject->structure(vm), identifier))
452
        repatchInByID(globalObject, codeBlock, baseObject, identifier, found, slot, *stubInfo);
452
        repatchInBy(globalObject, codeBlock, baseObject, identifier, found, slot, *stubInfo, InByKind::Normal);
453
    return JSValue::encode(jsBoolean(found));
453
    return JSValue::encode(jsBoolean(found));
454
}
454
}
455
455
456
JSC_DEFINE_JIT_OPERATION(operationInByVal, EncodedJSValue, (JSGlobalObject* globalObject, JSCell* base, EncodedJSValue key))
456
JSC_DEFINE_JIT_OPERATION(operationInByValOptimize, EncodedJSValue, (JSGlobalObject* globalObject, StructureStubInfo* stubInfo, ArrayProfile* arrayProfile, EncodedJSValue encodedBase, EncodedJSValue encodedKey))
457
{
457
{
458
    SuperSamplerScope superSamplerScope(false);
458
    SuperSamplerScope superSamplerScope(false);
459
    
459
460
    VM& vm = globalObject->vm();
461
    CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
462
    JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
463
    auto scope = DECLARE_THROW_SCOPE(vm);
464
465
    JSValue baseValue = JSValue::decode(encodedBase);
466
    if (!baseValue.isObject()) {
467
        throwException(globalObject, scope, createInvalidInParameterError(globalObject, baseValue));
468
        return encodedJSValue();
469
    }
470
    JSObject* baseObject = asObject(baseValue);
471
    if (arrayProfile)
472
        arrayProfile->observeStructure(baseObject->structure(vm));
473
474
    JSValue key = JSValue::decode(encodedKey);
475
    uint32_t i;
476
    if (key.getUInt32(i)) {
477
        if (arrayProfile)
478
            arrayProfile->observeIndexedRead(vm, baseObject, i);
479
        RELEASE_AND_RETURN(scope, JSValue::encode(jsBoolean(baseObject->hasProperty(globalObject, i))));
480
    }
481
482
    const Identifier propertyName = key.toPropertyKey(globalObject);
483
    RETURN_IF_EXCEPTION(scope, encodedJSValue());
484
    PropertySlot slot(baseObject, PropertySlot::InternalMethodType::HasProperty);
485
    bool found = baseObject->getPropertySlot(globalObject, propertyName, slot);
486
    RETURN_IF_EXCEPTION(scope, encodedJSValue());
487
488
    if (CacheableIdentifier::isCacheableIdentifierCell(key) && (key.isSymbol() || !parseIndex(propertyName))) {
489
        CodeBlock* codeBlock = callFrame->codeBlock();
490
        CacheableIdentifier identifier = CacheableIdentifier::createFromCell(key.asCell());
491
        if (stubInfo->considerCachingBy(vm, codeBlock, baseObject->structure(vm), identifier))
492
            repatchInBy(globalObject, codeBlock, baseObject, identifier, found, slot, *stubInfo, InByKind::NormalByVal);
493
    }
494
495
    return JSValue::encode(jsBoolean(found));
496
}
497
498
JSC_DEFINE_JIT_OPERATION(operationInByValGeneric, EncodedJSValue, (JSGlobalObject* globalObject, StructureStubInfo* stubInfo, ArrayProfile* arrayProfile, EncodedJSValue base, EncodedJSValue key))
499
{
500
    SuperSamplerScope superSamplerScope(false);
501
460
    VM& vm = globalObject->vm();
502
    VM& vm = globalObject->vm();
461
    CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
503
    CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
462
    JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
504
    JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
463
505
464
    return JSValue::encode(jsBoolean(CommonSlowPaths::opInByVal(globalObject, base, JSValue::decode(key))));
506
    stubInfo->tookSlowPath = true;
507
    return JSValue::encode(jsBoolean(CommonSlowPaths::opInByVal(globalObject, JSValue::decode(base), JSValue::decode(key), arrayProfile)));
465
}
508
}
466
509
467
JSC_DEFINE_JIT_OPERATION(operationHasPrivateName, EncodedJSValue, (JSGlobalObject* globalObject, JSCell* base, EncodedJSValue key))
510
JSC_DEFINE_JIT_OPERATION(operationHasPrivateName, EncodedJSValue, (JSGlobalObject* globalObject, JSCell* base, EncodedJSValue key))
- a/Source/JavaScriptCore/jit/JITOperations.h -3 / +3 lines
Lines 174-183 JSC_DECLARE_JIT_OPERATION(operationGetByIdDirect, EncodedJSValue, (JSGlobalObjec a/Source/JavaScriptCore/jit/JITOperations.h_sec1
174
JSC_DECLARE_JIT_OPERATION(operationGetByIdDirectGeneric, EncodedJSValue, (JSGlobalObject*, EncodedJSValue, uintptr_t));
174
JSC_DECLARE_JIT_OPERATION(operationGetByIdDirectGeneric, EncodedJSValue, (JSGlobalObject*, EncodedJSValue, uintptr_t));
175
JSC_DECLARE_JIT_OPERATION(operationGetByIdDirectOptimize, EncodedJSValue, (JSGlobalObject*, StructureStubInfo*, EncodedJSValue, uintptr_t));
175
JSC_DECLARE_JIT_OPERATION(operationGetByIdDirectOptimize, EncodedJSValue, (JSGlobalObject*, StructureStubInfo*, EncodedJSValue, uintptr_t));
176
176
177
JSC_DECLARE_JIT_OPERATION(operationInById, EncodedJSValue, (JSGlobalObject*, StructureStubInfo*, EncodedJSValue, uintptr_t));
177
JSC_DECLARE_JIT_OPERATION(operationInByIdGeneric, EncodedJSValue, (JSGlobalObject*, StructureStubInfo*, EncodedJSValue, uintptr_t));
178
JSC_DECLARE_JIT_OPERATION(operationInByIdOptimize, EncodedJSValue, (JSGlobalObject*, StructureStubInfo*, EncodedJSValue, uintptr_t));
178
JSC_DECLARE_JIT_OPERATION(operationInByIdOptimize, EncodedJSValue, (JSGlobalObject*, StructureStubInfo*, EncodedJSValue, uintptr_t));
179
179
JSC_DECLARE_JIT_OPERATION(operationInByValGeneric, EncodedJSValue, (JSGlobalObject*, StructureStubInfo*, ArrayProfile*, EncodedJSValue, EncodedJSValue));
180
JSC_DECLARE_JIT_OPERATION(operationInByVal, EncodedJSValue, (JSGlobalObject*, JSCell*, EncodedJSValue));
180
JSC_DECLARE_JIT_OPERATION(operationInByValOptimize, EncodedJSValue, (JSGlobalObject*, StructureStubInfo*, ArrayProfile*, EncodedJSValue, EncodedJSValue));
181
JSC_DECLARE_JIT_OPERATION(operationHasPrivateName, EncodedJSValue, (JSGlobalObject*, JSCell*, EncodedJSValue));
181
JSC_DECLARE_JIT_OPERATION(operationHasPrivateName, EncodedJSValue, (JSGlobalObject*, JSCell*, EncodedJSValue));
182
JSC_DECLARE_JIT_OPERATION(operationHasPrivateBrand, EncodedJSValue, (JSGlobalObject*, JSCell*, EncodedJSValue));
182
JSC_DECLARE_JIT_OPERATION(operationHasPrivateBrand, EncodedJSValue, (JSGlobalObject*, JSCell*, EncodedJSValue));
183
183
- a/Source/JavaScriptCore/jit/JITPropertyAccess.cpp +70 lines
Lines 1573-1578 void JIT::emitSlow_op_in_by_id(const Instruction* currentInstruction, Vector<Slo a/Source/JavaScriptCore/jit/JITPropertyAccess.cpp_sec1
1573
    gen.reportSlowPathCall(coldPathBegin, call);
1573
    gen.reportSlowPathCall(coldPathBegin, call);
1574
}
1574
}
1575
1575
1576
void JIT::emit_op_in_by_val(const Instruction* currentInstruction)
1577
{
1578
    auto bytecode = currentInstruction->as<OpInByVal>();
1579
    VirtualRegister dst = bytecode.m_dst;
1580
    VirtualRegister base = bytecode.m_base;
1581
    VirtualRegister property = bytecode.m_property;
1582
    auto& metadata = bytecode.metadata(m_codeBlock);
1583
    ArrayProfile* profile = &metadata.m_arrayProfile;
1584
1585
    emitGetVirtualRegister(base, regT0);
1586
    emitJumpSlowCaseIfNotJSCell(regT0, base);
1587
    emitGetVirtualRegister(property, regT1);
1588
    emitArrayProfilingSiteWithCell(regT0, regT2, profile);
1589
1590
    JITInByValGenerator gen(
1591
        m_codeBlock, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), RegisterSet::stubUnavailableRegisters(),
1592
        JSValueRegs(regT0), JSValueRegs(regT1), JSValueRegs(regT0));
1593
    gen.generateFastPath(*this);
1594
    addSlowCase(gen.slowPathJump());
1595
    m_inByVals.append(gen);
1596
1597
    emitPutVirtualRegister(dst);
1598
}
1599
1600
void JIT::emitSlow_op_in_by_val(const Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
1601
{
1602
    linkAllSlowCases(iter);
1603
1604
    auto bytecode = currentInstruction->as<OpInByVal>();
1605
    VirtualRegister dst = bytecode.m_dst;
1606
    auto& metadata = bytecode.metadata(m_codeBlock);
1607
    ArrayProfile* profile = &metadata.m_arrayProfile;
1608
1609
    JITInByValGenerator& gen = m_inByVals[m_inByValIndex++];
1610
1611
    Label coldPathBegin = label();
1612
1613
#if !ENABLE(EXTRA_CTI_THUNKS)
1614
    Call call = callOperationWithProfile(metadata, operationInByValOptimize, dst, TrustedImmPtr(m_codeBlock->globalObject()), gen.stubInfo(), profile, regT0, regT1);
1615
#else
1616
    VM& vm = this->vm();
1617
    uint32_t bytecodeOffset = m_bytecodeIndex.offset();
1618
    ASSERT(BytecodeIndex(bytecodeOffset) == m_bytecodeIndex);
1619
1620
    constexpr GPRReg bytecodeOffsetGPR = argumentGPR4;
1621
    move(TrustedImm32(bytecodeOffset), bytecodeOffsetGPR);
1622
1623
    constexpr GPRReg stubInfoGPR = argumentGPR3;
1624
    constexpr GPRReg profileGPR = argumentGPR2;
1625
    constexpr GPRReg baseGPR = regT0;
1626
    constexpr GPRReg propertyGPR = regT1;
1627
    static_assert(baseGPR == argumentGPR0 || !isARM64());
1628
    static_assert(propertyGPR == argumentGPR1);
1629
1630
    move(TrustedImmPtr(gen.stubInfo()), stubInfoGPR);
1631
    move(TrustedImmPtr(profile), profileGPR);
1632
    // slow_op_get_by_val_prepareCallGenerator will do exactly what we need.
1633
    // So, there's no point in creating a duplicate thunk just to give it a different name.
1634
    static_assert(std::is_same<decltype(operationInByValOptimize), decltype(operationGetByValOptimize)>::value);
1635
    emitNakedNearCall(vm.getCTIStub(slow_op_get_by_val_prepareCallGenerator).retaggedCode<NoPtrTag>());
1636
1637
    Call call = appendCall(operationInByValOptimize);
1638
    emitNakedNearCall(vm.getCTIStub(checkExceptionGenerator).retaggedCode<NoPtrTag>());
1639
1640
    emitPutVirtualRegister(dst, returnValueGPR);
1641
#endif // ENABLE(EXTRA_CTI_THUNKS)
1642
1643
    gen.reportSlowPathCall(coldPathBegin, call);
1644
}
1645
1576
void JIT::emitVarInjectionCheck(bool needsVarInjectionChecks)
1646
void JIT::emitVarInjectionCheck(bool needsVarInjectionChecks)
1577
{
1647
{
1578
    if (!needsVarInjectionChecks)
1648
    if (!needsVarInjectionChecks)
- a/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp +41 lines
Lines 908-913 void JIT::emitSlow_op_in_by_id(const Instruction* currentInstruction, Vector<Slo a/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp_sec1
908
    gen.reportSlowPathCall(coldPathBegin, call);
908
    gen.reportSlowPathCall(coldPathBegin, call);
909
}
909
}
910
910
911
void JIT::emit_op_in_by_val(const Instruction* currentInstruction)
912
{
913
    auto bytecode = currentInstruction->as<OpInByVal>();
914
    VirtualRegister dst = bytecode.m_dst;
915
    VirtualRegister base = bytecode.m_base;
916
    VirtualRegister property = bytecode.m_property;
917
    auto& metadata = bytecode.metadata(m_codeBlock);
918
    ArrayProfile* profile = &metadata.m_arrayProfile;
919
920
    emitLoad2(base, regT1, regT0, property, regT3, regT2);
921
    emitJumpSlowCaseIfNotJSCell(base, regT1);
922
    emitArrayProfilingSiteWithCell(regT0, regT4, profile);
923
924
    JITInByValGenerator gen(
925
        m_codeBlock, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), RegisterSet::stubUnavailableRegisters(),
926
        JSValueRegs::payloadOnly(regT0), JSValueRegs(regT3, regT2), JSValueRegs(regT1, regT0));
927
    gen.generateFastPath(*this);
928
    addSlowCase(gen.slowPathJump());
929
    m_inByVals.append(gen);
930
931
    emitStore(dst, regT1, regT0);
932
}
933
934
void JIT::emitSlow_op_in_by_val(const Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
935
{
936
    linkAllSlowCases(iter);
937
938
    auto bytecode = currentInstruction->as<OpInByVal>();
939
    VirtualRegister dst = bytecode.m_dst;
940
    auto& metadata = bytecode.metadata(m_codeBlock);
941
    ArrayProfile* profile = &metadata.m_arrayProfile;
942
943
    JITInByValGenerator& gen = m_inByVals[m_inByValIndex++];
944
945
    Label coldPathBegin = label();
946
947
    Call call = callOperationWithProfile(metadata, operationInByValOptimize, dst, TrustedImmPtr(m_codeBlock->globalObject()), gen.stubInfo(), profile, JSValueRegs(regT1, regT0), JSValueRegs(regT3, regT2));
948
949
    gen.reportSlowPathCall(coldPathBegin, call);
950
}
951
911
void JIT::emitVarInjectionCheck(bool needsVarInjectionChecks)
952
void JIT::emitVarInjectionCheck(bool needsVarInjectionChecks)
912
{
953
{
913
    if (!needsVarInjectionChecks)
954
    if (!needsVarInjectionChecks)
- a/Source/JavaScriptCore/jit/JITThunks.cpp -1 lines
Lines 278-284 void JITThunks::preinitializeCTIThunks(VM& vm) a/Source/JavaScriptCore/jit/JITThunks.cpp_sec1
278
#define INIT_BASELINE_SLOW_PATH_CALL_ROUTINE(name) ctiSlowPathFunctionStub(vm, slow_path_##name)
278
#define INIT_BASELINE_SLOW_PATH_CALL_ROUTINE(name) ctiSlowPathFunctionStub(vm, slow_path_##name)
279
279
280
    // From the BaselineJIT DEFINE_SLOW_OP list:
280
    // From the BaselineJIT DEFINE_SLOW_OP list:
281
    INIT_BASELINE_SLOW_PATH_CALL_ROUTINE(in_by_val);
282
    INIT_BASELINE_SLOW_PATH_CALL_ROUTINE(has_private_name);
281
    INIT_BASELINE_SLOW_PATH_CALL_ROUTINE(has_private_name);
283
    INIT_BASELINE_SLOW_PATH_CALL_ROUTINE(has_private_brand);
282
    INIT_BASELINE_SLOW_PATH_CALL_ROUTINE(has_private_brand);
284
    INIT_BASELINE_SLOW_PATH_CALL_ROUTINE(less);
283
    INIT_BASELINE_SLOW_PATH_CALL_ROUTINE(less);
- a/Source/JavaScriptCore/jit/Repatch.cpp -12 / +21 lines
Lines 897-903 void repatchDeleteBy(JSGlobalObject* globalObject, CodeBlock* codeBlock, DeleteP a/Source/JavaScriptCore/jit/Repatch.cpp_sec1
897
    }
897
    }
898
}
898
}
899
899
900
static InlineCacheAction tryCacheInByID(
900
static InlineCacheAction tryCacheInBy(
901
    JSGlobalObject* globalObject, CodeBlock* codeBlock, JSObject* base, CacheableIdentifier propertyName,
901
    JSGlobalObject* globalObject, CodeBlock* codeBlock, JSObject* base, CacheableIdentifier propertyName,
902
    bool wasFound, const PropertySlot& slot, StructureStubInfo& stubInfo)
902
    bool wasFound, const PropertySlot& slot, StructureStubInfo& stubInfo)
903
{
903
{
Lines 909-925 static InlineCacheAction tryCacheInByID( a/Source/JavaScriptCore/jit/Repatch.cpp_sec2
909
        GCSafeConcurrentJSLocker locker(codeBlock->m_lock, vm.heap);
909
        GCSafeConcurrentJSLocker locker(codeBlock->m_lock, vm.heap);
910
        if (forceICFailure(globalObject))
910
        if (forceICFailure(globalObject))
911
            return GiveUpOnCache;
911
            return GiveUpOnCache;
912
        
912
913
        if (!base->structure(vm)->propertyAccessesAreCacheable() || (!wasFound && !base->structure(vm)->propertyAccessesAreCacheableForAbsence()))
913
        if (!base->structure(vm)->propertyAccessesAreCacheable() || (!wasFound && !base->structure(vm)->propertyAccessesAreCacheableForAbsence()))
914
            return GiveUpOnCache;
914
            return GiveUpOnCache;
915
        
915
916
        if (wasFound) {
916
        if (wasFound) {
917
            if (!slot.isCacheable())
917
            if (!slot.isCacheable())
918
                return GiveUpOnCache;
918
                return GiveUpOnCache;
919
        }
919
        }
920
        
920
921
        Structure* structure = base->structure(vm);
921
        Structure* structure = base->structure(vm);
922
        
922
923
        RefPtr<PolyProtoAccessChain> prototypeAccessChain;
923
        RefPtr<PolyProtoAccessChain> prototypeAccessChain;
924
        ObjectPropertyConditionSet conditionSet;
924
        ObjectPropertyConditionSet conditionSet;
925
        if (wasFound) {
925
        if (wasFound) {
Lines 991-1013 static InlineCacheAction tryCacheInByID( a/Source/JavaScriptCore/jit/Repatch.cpp_sec3
991
991
992
        if (result.generatedSomeCode()) {
992
        if (result.generatedSomeCode()) {
993
            LOG_IC((ICEvent::InReplaceWithJump, structure->classInfo(), ident, slot.slotBase() == base));
993
            LOG_IC((ICEvent::InReplaceWithJump, structure->classInfo(), ident, slot.slotBase() == base));
994
            
994
995
            RELEASE_ASSERT(result.code());
995
            RELEASE_ASSERT(result.code());
996
            InlineAccess::rewireStubAsJump(stubInfo, CodeLocationLabel<JITStubRoutinePtrTag>(result.code()));
996
            InlineAccess::rewireStubAsJump(stubInfo, CodeLocationLabel<JITStubRoutinePtrTag>(result.code()));
997
        }
997
        }
998
    }
998
    }
999
999
1000
    fireWatchpointsAndClearStubIfNeeded(vm, stubInfo, codeBlock, result);
1000
    fireWatchpointsAndClearStubIfNeeded(vm, stubInfo, codeBlock, result);
1001
    
1001
1002
    return result.shouldGiveUpNow() ? GiveUpOnCache : RetryCacheLater;
1002
    return result.shouldGiveUpNow() ? GiveUpOnCache : RetryCacheLater;
1003
}
1003
}
1004
1004
1005
void repatchInByID(JSGlobalObject* globalObject, CodeBlock* codeBlock, JSObject* baseObject, CacheableIdentifier propertyName, bool wasFound, const PropertySlot& slot, StructureStubInfo& stubInfo)
1005
void repatchInBy(JSGlobalObject* globalObject, CodeBlock* codeBlock, JSObject* baseObject, CacheableIdentifier propertyName, bool wasFound, const PropertySlot& slot, StructureStubInfo& stubInfo, InByKind kind)
1006
{
1006
{
1007
    SuperSamplerScope superSamplerScope(false);
1007
    SuperSamplerScope superSamplerScope(false);
1008
    VM& vm = globalObject->vm();
1008
1009
1009
    if (tryCacheInByID(globalObject, codeBlock, baseObject, propertyName, wasFound, slot, stubInfo) == GiveUpOnCache)
1010
    if (tryCacheInBy(globalObject, codeBlock, baseObject, propertyName, wasFound, slot, stubInfo) == GiveUpOnCache) {
1010
        ftlThunkAwareRepatchCall(codeBlock, stubInfo.slowPathCallLocation, operationInById);
1011
        LOG_IC((ICEvent::InReplaceWithGeneric, baseObject->classInfo(globalObject->vm()), Identifier::fromUid(vm, propertyName.uid())));
1012
        if (kind == InByKind::Normal)
1013
            ftlThunkAwareRepatchCall(codeBlock, stubInfo.slowPathCallLocation, operationInByIdGeneric);
1014
        else
1015
            ftlThunkAwareRepatchCall(codeBlock, stubInfo.slowPathCallLocation, operationInByValGeneric);
1016
    }
1011
}
1017
}
1012
1018
1013
static InlineCacheAction tryCacheCheckPrivateBrand(
1019
static InlineCacheAction tryCacheCheckPrivateBrand(
Lines 1683-1691 static void resetPatchableJump(StructureStubInfo& stubInfo) a/Source/JavaScriptCore/jit/Repatch.cpp_sec4
1683
    MacroAssembler::repatchJump(stubInfo.patchableJump(), stubInfo.slowPathStartLocation);
1689
    MacroAssembler::repatchJump(stubInfo.patchableJump(), stubInfo.slowPathStartLocation);
1684
}
1690
}
1685
1691
1686
void resetInByID(CodeBlock* codeBlock, StructureStubInfo& stubInfo)
1692
void resetInBy(CodeBlock* codeBlock, StructureStubInfo& stubInfo, InByKind kind)
1687
{
1693
{
1688
    ftlThunkAwareRepatchCall(codeBlock, stubInfo.slowPathCallLocation, operationInByIdOptimize);
1694
    if (kind == InByKind::Normal)
1695
        ftlThunkAwareRepatchCall(codeBlock, stubInfo.slowPathCallLocation, operationInByIdOptimize);
1696
    else
1697
        ftlThunkAwareRepatchCall(codeBlock, stubInfo.slowPathCallLocation, operationInByValOptimize);
1689
    InlineAccess::rewireStubAsJump(stubInfo, stubInfo.slowPathStartLocation);
1698
    InlineAccess::rewireStubAsJump(stubInfo, stubInfo.slowPathStartLocation);
1690
}
1699
}
1691
1700
- a/Source/JavaScriptCore/jit/Repatch.h -2 / +7 lines
Lines 48-58 enum class DelByKind { a/Source/JavaScriptCore/jit/Repatch.h_sec1
48
    NormalByVal
48
    NormalByVal
49
};
49
};
50
50
51
enum class InByKind {
52
    Normal,
53
    NormalByVal
54
};
55
51
void repatchArrayGetByVal(JSGlobalObject*, CodeBlock*, JSValue base, JSValue index, StructureStubInfo&);
56
void repatchArrayGetByVal(JSGlobalObject*, CodeBlock*, JSValue base, JSValue index, StructureStubInfo&);
52
void repatchGetBy(JSGlobalObject*, CodeBlock*, JSValue, CacheableIdentifier, const PropertySlot&, StructureStubInfo&, GetByKind);
57
void repatchGetBy(JSGlobalObject*, CodeBlock*, JSValue, CacheableIdentifier, const PropertySlot&, StructureStubInfo&, GetByKind);
53
void repatchPutByID(JSGlobalObject*, CodeBlock*, JSValue, Structure*, CacheableIdentifier, const PutPropertySlot&, StructureStubInfo&, PutKind);
58
void repatchPutByID(JSGlobalObject*, CodeBlock*, JSValue, Structure*, CacheableIdentifier, const PutPropertySlot&, StructureStubInfo&, PutKind);
54
void repatchDeleteBy(JSGlobalObject*, CodeBlock*, DeletePropertySlot&, JSValue, Structure*, CacheableIdentifier, StructureStubInfo&, DelByKind, ECMAMode);
59
void repatchDeleteBy(JSGlobalObject*, CodeBlock*, DeletePropertySlot&, JSValue, Structure*, CacheableIdentifier, StructureStubInfo&, DelByKind, ECMAMode);
55
void repatchInByID(JSGlobalObject*, CodeBlock*, JSObject*, CacheableIdentifier, bool wasFound, const PropertySlot&, StructureStubInfo&);
60
void repatchInBy(JSGlobalObject*, CodeBlock*, JSObject*, CacheableIdentifier, bool wasFound, const PropertySlot&, StructureStubInfo&, InByKind);
56
void repatchCheckPrivateBrand(JSGlobalObject*, CodeBlock*, JSObject*, CacheableIdentifier, StructureStubInfo&);
61
void repatchCheckPrivateBrand(JSGlobalObject*, CodeBlock*, JSObject*, CacheableIdentifier, StructureStubInfo&);
57
void repatchSetPrivateBrand(JSGlobalObject*, CodeBlock*, JSObject*, Structure*, CacheableIdentifier, StructureStubInfo&);
62
void repatchSetPrivateBrand(JSGlobalObject*, CodeBlock*, JSObject*, Structure*, CacheableIdentifier, StructureStubInfo&);
58
void repatchInstanceOf(JSGlobalObject*, CodeBlock*, JSValue value, JSValue prototype, StructureStubInfo&, bool wasFound);
63
void repatchInstanceOf(JSGlobalObject*, CodeBlock*, JSValue value, JSValue prototype, StructureStubInfo&, bool wasFound);
Lines 64-70 void linkPolymorphicCall(JSGlobalObject*, CallFrame*, CallLinkInfo&, CallVariant a/Source/JavaScriptCore/jit/Repatch.h_sec2
64
void resetGetBy(CodeBlock*, StructureStubInfo&, GetByKind);
69
void resetGetBy(CodeBlock*, StructureStubInfo&, GetByKind);
65
void resetPutByID(CodeBlock*, StructureStubInfo&);
70
void resetPutByID(CodeBlock*, StructureStubInfo&);
66
void resetDelBy(CodeBlock*, StructureStubInfo&, DelByKind);
71
void resetDelBy(CodeBlock*, StructureStubInfo&, DelByKind);
67
void resetInByID(CodeBlock*, StructureStubInfo&);
72
void resetInBy(CodeBlock*, StructureStubInfo&, InByKind);
68
void resetInstanceOf(StructureStubInfo&);
73
void resetInstanceOf(StructureStubInfo&);
69
void resetCheckPrivateBrand(CodeBlock*, StructureStubInfo&);
74
void resetCheckPrivateBrand(CodeBlock*, StructureStubInfo&);
70
void resetSetPrivateBrand(CodeBlock*, StructureStubInfo&);
75
void resetSetPrivateBrand(CodeBlock*, StructureStubInfo&);
- a/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp +8 lines
Lines 1425-1430 LLINT_SLOW_PATH_DECL(slow_path_in_by_id) a/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp_sec1
1425
    LLINT_RETURN(jsBoolean(asObject(baseValue)->hasProperty(globalObject, codeBlock->identifier(bytecode.m_property))));
1425
    LLINT_RETURN(jsBoolean(asObject(baseValue)->hasProperty(globalObject, codeBlock->identifier(bytecode.m_property))));
1426
}
1426
}
1427
1427
1428
LLINT_SLOW_PATH_DECL(slow_path_in_by_val)
1429
{
1430
    LLINT_BEGIN();
1431
    auto bytecode = pc->as<OpInByVal>();
1432
    auto& metadata = bytecode.metadata(codeBlock);
1433
    LLINT_RETURN(jsBoolean(CommonSlowPaths::opInByVal(globalObject, getOperand(callFrame, bytecode.m_base), getOperand(callFrame, bytecode.m_property), &metadata.m_arrayProfile)));
1434
}
1435
1428
LLINT_SLOW_PATH_DECL(slow_path_put_getter_by_id)
1436
LLINT_SLOW_PATH_DECL(slow_path_put_getter_by_id)
1429
{
1437
{
1430
    LLINT_BEGIN();
1438
    LLINT_BEGIN();
- a/Source/JavaScriptCore/llint/LLIntSlowPaths.h +1 lines
Lines 72-77 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_get_by_id); a/Source/JavaScriptCore/llint/LLIntSlowPaths.h_sec1
72
LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_get_by_id_with_this);
72
LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_get_by_id_with_this);
73
LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_put_by_id);
73
LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_put_by_id);
74
LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_in_by_id);
74
LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_in_by_id);
75
LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_in_by_val);
75
LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_del_by_id);
76
LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_del_by_id);
76
LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_get_by_val);
77
LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_get_by_val);
77
LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_get_private_name);
78
LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_get_private_name);
- a/Source/JavaScriptCore/llint/LowLevelInterpreter.asm -1 / +1 lines
Lines 2010-2016 if not JSVALUE64 a/Source/JavaScriptCore/llint/LowLevelInterpreter.asm_sec1
2010
    slowPathOp(get_prototype_of)
2010
    slowPathOp(get_prototype_of)
2011
end
2011
end
2012
2012
2013
slowPathOp(in_by_val)
2014
slowPathOp(has_private_name)
2013
slowPathOp(has_private_name)
2015
slowPathOp(has_private_brand)
2014
slowPathOp(has_private_brand)
2016
slowPathOp(is_callable)
2015
slowPathOp(is_callable)
Lines 2044-2049 macro llintSlowPathOp(opcodeName) a/Source/JavaScriptCore/llint/LowLevelInterpreter.asm_sec2
2044
end
2043
end
2045
2044
2046
llintSlowPathOp(in_by_id)
2045
llintSlowPathOp(in_by_id)
2046
llintSlowPathOp(in_by_val)
2047
llintSlowPathOp(del_by_id)
2047
llintSlowPathOp(del_by_id)
2048
llintSlowPathOp(del_by_val)
2048
llintSlowPathOp(del_by_val)
2049
llintSlowPathOp(instanceof)
2049
llintSlowPathOp(instanceof)
- a/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp -8 lines
Lines 830-843 JSC_DEFINE_COMMON_SLOW_PATH(slow_path_is_constructor) a/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp_sec1
830
    RETURN(jsBoolean(GET_C(bytecode.m_operand).jsValue().isConstructor(vm)));
830
    RETURN(jsBoolean(GET_C(bytecode.m_operand).jsValue().isConstructor(vm)));
831
}
831
}
832
832
833
JSC_DEFINE_COMMON_SLOW_PATH(slow_path_in_by_val)
834
{
835
    BEGIN();
836
    auto bytecode = pc->as<OpInByVal>();
837
    auto& metadata = bytecode.metadata(codeBlock);
838
    RETURN(jsBoolean(CommonSlowPaths::opInByVal(globalObject, GET_C(bytecode.m_base).jsValue(), GET_C(bytecode.m_property).jsValue(), &metadata.m_arrayProfile)));
839
}
840
841
JSC_DEFINE_COMMON_SLOW_PATH(slow_path_has_private_name)
833
JSC_DEFINE_COMMON_SLOW_PATH(slow_path_has_private_name)
842
{
834
{
843
    BEGIN();
835
    BEGIN();
- a/Source/JavaScriptCore/runtime/CommonSlowPaths.h -1 lines
Lines 251-257 JSC_DECLARE_COMMON_SLOW_PATH(slow_path_typeof_is_object); a/Source/JavaScriptCore/runtime/CommonSlowPaths.h_sec1
251
JSC_DECLARE_COMMON_SLOW_PATH(slow_path_typeof_is_function);
251
JSC_DECLARE_COMMON_SLOW_PATH(slow_path_typeof_is_function);
252
JSC_DECLARE_COMMON_SLOW_PATH(slow_path_is_callable);
252
JSC_DECLARE_COMMON_SLOW_PATH(slow_path_is_callable);
253
JSC_DECLARE_COMMON_SLOW_PATH(slow_path_is_constructor);
253
JSC_DECLARE_COMMON_SLOW_PATH(slow_path_is_constructor);
254
JSC_DECLARE_COMMON_SLOW_PATH(slow_path_in_by_val);
255
JSC_DECLARE_COMMON_SLOW_PATH(slow_path_has_private_name);
254
JSC_DECLARE_COMMON_SLOW_PATH(slow_path_has_private_name);
256
JSC_DECLARE_COMMON_SLOW_PATH(slow_path_has_private_brand);
255
JSC_DECLARE_COMMON_SLOW_PATH(slow_path_has_private_brand);
257
JSC_DECLARE_COMMON_SLOW_PATH(slow_path_strcat);
256
JSC_DECLARE_COMMON_SLOW_PATH(slow_path_strcat);
- a/JSTests/ChangeLog +11 lines
Lines 1-3 a/JSTests/ChangeLog_sec1
1
2021-06-02  Ross Kirsling  <ross.kirsling@sony.com>
2
3
        [JSC] Implement JIT ICs for InByVal
4
        https://bugs.webkit.org/show_bug.cgi?id=226563
5
6
        Reviewed by NOBODY (OOPS!).
7
8
        * microbenchmarks/in-by-val-int32.js: Added.
9
        * microbenchmarks/in-by-val-string-index.js: Added.
10
        * microbenchmarks/in-by-val-symbol.js: Added.
11
1
2021-05-22  Ross Kirsling  <ross.kirsling@sony.com>
12
2021-05-22  Ross Kirsling  <ross.kirsling@sony.com>
2
13
3
        Support Ergonomic Brand Checks proposal (`#x in obj`)
14
        Support Ergonomic Brand Checks proposal (`#x in obj`)
- a/JSTests/microbenchmarks/in-by-val-int32.js +16 lines
Line 0 a/JSTests/microbenchmarks/in-by-val-int32.js_sec1
1
//@ skip if $model == "Apple Watch Series 3" # added by mark-jsc-stress-test.py
2
function test(object)
3
{
4
    if (1 in object)
5
        return object[1];
6
    return 0;
7
}
8
noInline(test);
9
10
var o1 = [42];
11
var o2 = [42, 41];
12
13
for (var i = 0; i < 1e6; ++i) {
14
    test(o1);
15
    test(o2);
16
}
- a/JSTests/microbenchmarks/in-by-val-string-index.js +16 lines
Line 0 a/JSTests/microbenchmarks/in-by-val-string-index.js_sec1
1
//@ skip if $model == "Apple Watch Series 3" # added by mark-jsc-stress-test.py
2
function test(object)
3
{
4
    if ('1' in object)
5
        return object[1];
6
    return 0;
7
}
8
noInline(test);
9
10
var o1 = [42];
11
var o2 = [42, 41];
12
13
for (var i = 0; i < 1e6; ++i) {
14
    test(o1);
15
    test(o2);
16
}
- a/JSTests/microbenchmarks/in-by-val-symbol.js +23 lines
Line 0 a/JSTests/microbenchmarks/in-by-val-symbol.js_sec1
1
//@ skip if $model == "Apple Watch Series 3" # added by mark-jsc-stress-test.py
2
const cocoaSymbol = Symbol('cocoa');
3
const cappuccinoSymbol = Symbol('cappuccino');
4
5
function test(object)
6
{
7
    if (cocoaSymbol in object)
8
        return object[cocoaSymbol];
9
    return 0;
10
}
11
noInline(test);
12
13
var o1 = {
14
    [cocoaSymbol]: 42
15
};
16
var o2 = {
17
    [cappuccinoSymbol]: 41
18
};
19
20
for (var i = 0; i < 1e6; ++i) {
21
    test(o1);
22
    test(o2);
23
}

Return to Bug 226563