| Differences between
and this patch
- a/Source/JavaScriptCore/ChangeLog +119 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/Repatch.cpp:
109
        (JSC::tryCacheInBy): Renamed from tryCacheInByID.
110
        (JSC::repatchInBy): Renamed from repatchInByID.
111
        (JSC::resetInBy): Renamed from resetInByID.
112
        * jit/Repatch.h:
113
        * llint/LLIntSlowPaths.cpp:
114
        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
115
        * llint/LLIntSlowPaths.h:
116
        * llint/LowLevelInterpreter.asm:
117
        * runtime/CommonSlowPaths.cpp:
118
        * runtime/CommonSlowPaths.h:
119
1
2021-06-02  Robin Morisset  <rmorisset@apple.com>
120
2021-06-02  Robin Morisset  <rmorisset@apple.com>
2
121
3
        B3MoveConstants should filter directly on Values, and only create ValueKeys when useful
122
        B3MoveConstants should filter directly on Values, and only create ValueKeys when useful
- a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj -6 / +10 lines
Lines 1401-1407 a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec1
1401
		A1D792FF1B43864B004516F5 /* IntlNumberFormatConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = A1D792F91B43864B004516F5 /* IntlNumberFormatConstructor.h */; };
1401
		A1D792FF1B43864B004516F5 /* IntlNumberFormatConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = A1D792F91B43864B004516F5 /* IntlNumberFormatConstructor.h */; };
1402
		A1D793011B43864B004516F5 /* IntlNumberFormatPrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = A1D792FB1B43864B004516F5 /* IntlNumberFormatPrototype.h */; };
1402
		A1D793011B43864B004516F5 /* IntlNumberFormatPrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = A1D792FB1B43864B004516F5 /* IntlNumberFormatPrototype.h */; };
1403
		A321AA6D2626359B0023ADA2 /* IntlWorkaround.h in Headers */ = {isa = PBXBuildFile; fileRef = A321AA6C2626359B0023ADA2 /* IntlWorkaround.h */; };
1403
		A321AA6D2626359B0023ADA2 /* IntlWorkaround.h in Headers */ = {isa = PBXBuildFile; fileRef = A321AA6C2626359B0023ADA2 /* IntlWorkaround.h */; };
1404
		A382C5312667111D0042CD99 /* InByIdVariant.h in Headers */ = {isa = PBXBuildFile; fileRef = E3305FB120B0F78800CEB82B /* InByIdVariant.h */; settings = {ATTRIBUTES = (Private, ); }; };
1404
		A38D250E25800D440042BFDD /* JSArrayBufferPrototypeInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = A38D250D25800D430042BFDD /* JSArrayBufferPrototypeInlines.h */; };
1405
		A38D250E25800D440042BFDD /* JSArrayBufferPrototypeInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = A38D250D25800D430042BFDD /* JSArrayBufferPrototypeInlines.h */; };
1406
		A38D5BFC2666D3DA00A109A6 /* InByStatus.h in Headers */ = {isa = PBXBuildFile; fileRef = A38D5BFA2666D3DA00A109A6 /* InByStatus.h */; settings = {ATTRIBUTES = (Private, ); }; };
1405
		A3EE8543262514B000FC9B8D /* IntlWorkaround.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A37619402625127C00CBCBA9 /* IntlWorkaround.cpp */; };
1407
		A3EE8543262514B000FC9B8D /* IntlWorkaround.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A37619402625127C00CBCBA9 /* IntlWorkaround.cpp */; };
1406
		A3FF9BC72234749100B1A9AB /* YarrFlags.h in Headers */ = {isa = PBXBuildFile; fileRef = A3FF9BC52234746600B1A9AB /* YarrFlags.h */; settings = {ATTRIBUTES = (Private, ); }; };
1408
		A3FF9BC72234749100B1A9AB /* YarrFlags.h in Headers */ = {isa = PBXBuildFile; fileRef = A3FF9BC52234746600B1A9AB /* YarrFlags.h */; settings = {ATTRIBUTES = (Private, ); }; };
1407
		A503FA1A188E0FB000110F14 /* JavaScriptCallFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = A503FA14188E0FAF00110F14 /* JavaScriptCallFrame.h */; };
1409
		A503FA1A188E0FB000110F14 /* JavaScriptCallFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = A503FA14188E0FAF00110F14 /* JavaScriptCallFrame.h */; };
Lines 4430-4435 a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec2
4430
		A321AA6C2626359B0023ADA2 /* IntlWorkaround.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IntlWorkaround.h; sourceTree = "<group>"; };
4432
		A321AA6C2626359B0023ADA2 /* IntlWorkaround.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IntlWorkaround.h; sourceTree = "<group>"; };
4431
		A37619402625127C00CBCBA9 /* IntlWorkaround.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IntlWorkaround.cpp; sourceTree = "<group>"; };
4433
		A37619402625127C00CBCBA9 /* IntlWorkaround.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IntlWorkaround.cpp; sourceTree = "<group>"; };
4432
		A38D250D25800D430042BFDD /* JSArrayBufferPrototypeInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSArrayBufferPrototypeInlines.h; sourceTree = "<group>"; };
4434
		A38D250D25800D430042BFDD /* JSArrayBufferPrototypeInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSArrayBufferPrototypeInlines.h; sourceTree = "<group>"; };
4435
		A38D5BF92666D3DA00A109A6 /* InByStatus.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InByStatus.cpp; sourceTree = "<group>"; };
4436
		A38D5BFA2666D3DA00A109A6 /* InByStatus.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InByStatus.h; sourceTree = "<group>"; };
4433
		A3AFF92B245A3CF900C9BA3B /* IntlLocale.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IntlLocale.h; sourceTree = "<group>"; };
4437
		A3AFF92B245A3CF900C9BA3B /* IntlLocale.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IntlLocale.h; sourceTree = "<group>"; };
4434
		A3AFF92C245A3CFA00C9BA3B /* IntlLocaleConstructor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IntlLocaleConstructor.h; sourceTree = "<group>"; };
4438
		A3AFF92C245A3CFA00C9BA3B /* IntlLocaleConstructor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IntlLocaleConstructor.h; sourceTree = "<group>"; };
4435
		A3AFF92D245A3CFA00C9BA3B /* IntlLocale.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IntlLocale.cpp; sourceTree = "<group>"; };
4439
		A3AFF92D245A3CFA00C9BA3B /* IntlLocale.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IntlLocale.cpp; sourceTree = "<group>"; };
Lines 5058-5067 a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec3
5058
		E3282BB91FE930A300EDAF71 /* YarrErrorCode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = YarrErrorCode.cpp; path = yarr/YarrErrorCode.cpp; sourceTree = "<group>"; };
5062
		E3282BB91FE930A300EDAF71 /* YarrErrorCode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = YarrErrorCode.cpp; path = yarr/YarrErrorCode.cpp; sourceTree = "<group>"; };
5059
		E3282BBA1FE930A400EDAF71 /* YarrErrorCode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = YarrErrorCode.h; path = yarr/YarrErrorCode.h; sourceTree = "<group>"; };
5063
		E3282BBA1FE930A400EDAF71 /* YarrErrorCode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = YarrErrorCode.h; path = yarr/YarrErrorCode.h; sourceTree = "<group>"; };
5060
		E32C3C6823E94C1E00BC97C0 /* UnlinkedCodeBlockGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UnlinkedCodeBlockGenerator.h; sourceTree = "<group>"; };
5064
		E32C3C6823E94C1E00BC97C0 /* UnlinkedCodeBlockGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UnlinkedCodeBlockGenerator.h; sourceTree = "<group>"; };
5061
		E3305FAF20B0F78700CEB82B /* InByIdStatus.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InByIdStatus.h; sourceTree = "<group>"; };
5062
		E3305FB020B0F78700CEB82B /* InByIdVariant.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InByIdVariant.cpp; sourceTree = "<group>"; };
5065
		E3305FB020B0F78700CEB82B /* InByIdVariant.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InByIdVariant.cpp; sourceTree = "<group>"; };
5063
		E3305FB120B0F78800CEB82B /* InByIdVariant.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InByIdVariant.h; sourceTree = "<group>"; };
5066
		E3305FB120B0F78800CEB82B /* InByIdVariant.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InByIdVariant.h; sourceTree = "<group>"; };
5064
		E3305FB220B0F78800CEB82B /* InByIdStatus.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InByIdStatus.cpp; sourceTree = "<group>"; };
5065
		E33095DC23210A1400EB7856 /* JSInternalFieldObjectImpl.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JSInternalFieldObjectImpl.h; sourceTree = "<group>"; };
5067
		E33095DC23210A1400EB7856 /* JSInternalFieldObjectImpl.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JSInternalFieldObjectImpl.h; sourceTree = "<group>"; };
5066
		E334CBB221FD96A8000EB178 /* RegExpGlobalData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RegExpGlobalData.cpp; sourceTree = "<group>"; };
5068
		E334CBB221FD96A8000EB178 /* RegExpGlobalData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RegExpGlobalData.cpp; sourceTree = "<group>"; };
5067
		E334CBB321FD96A9000EB178 /* RegExpGlobalData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegExpGlobalData.h; sourceTree = "<group>"; };
5069
		E334CBB321FD96A9000EB178 /* RegExpGlobalData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegExpGlobalData.h; sourceTree = "<group>"; };
Lines 6282-6290 a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec4
6282
				FE3A06B91C1103D900390FDD /* JITRightShiftGenerator.h */,
6284
				FE3A06B91C1103D900390FDD /* JITRightShiftGenerator.h */,
6283
				72131BF326587EF2007114CF /* JITSafepoint.cpp */,
6285
				72131BF326587EF2007114CF /* JITSafepoint.cpp */,
6284
				72131BF526587EF2007114CF /* JITSafepoint.h */,
6286
				72131BF526587EF2007114CF /* JITSafepoint.h */,
6287
				72131BF426587EF2007114CF /* JITScannable.h */,
6285
				52B5100C265EFCD4008970E7 /* JITSizeStatistics.cpp */,
6288
				52B5100C265EFCD4008970E7 /* JITSizeStatistics.cpp */,
6286
				52B5100B265EFCD4008970E7 /* JITSizeStatistics.h */,
6289
				52B5100B265EFCD4008970E7 /* JITSizeStatistics.h */,
6287
				72131BF426587EF2007114CF /* JITScannable.h */,
6288
				0F766D2615A8CC1B008F363E /* JITStubRoutine.cpp */,
6290
				0F766D2615A8CC1B008F363E /* JITStubRoutine.cpp */,
6289
				0F766D1C15A5028D008F363E /* JITStubRoutine.h */,
6291
				0F766D1C15A5028D008F363E /* JITStubRoutine.h */,
6290
				FE42388F1BE18C1200514737 /* JITSubGenerator.cpp */,
6292
				FE42388F1BE18C1200514737 /* JITSubGenerator.cpp */,
Lines 8577-8586 a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec5
8577
				0F44A7AF20BF685F0022B171 /* ICStatusMap.h */,
8579
				0F44A7AF20BF685F0022B171 /* ICStatusMap.h */,
8578
				0F44A7B520C0BE3F0022B171 /* ICStatusUtils.cpp */,
8580
				0F44A7B520C0BE3F0022B171 /* ICStatusUtils.cpp */,
8579
				0FB399BD20AF6B380017E213 /* ICStatusUtils.h */,
8581
				0FB399BD20AF6B380017E213 /* ICStatusUtils.h */,
8580
				E3305FB220B0F78800CEB82B /* InByIdStatus.cpp */,
8581
				E3305FAF20B0F78700CEB82B /* InByIdStatus.h */,
8582
				E3305FB020B0F78700CEB82B /* InByIdVariant.cpp */,
8582
				E3305FB020B0F78700CEB82B /* InByIdVariant.cpp */,
8583
				E3305FB120B0F78800CEB82B /* InByIdVariant.h */,
8583
				E3305FB120B0F78800CEB82B /* InByIdVariant.h */,
8584
				A38D5BF92666D3DA00A109A6 /* InByStatus.cpp */,
8585
				A38D5BFA2666D3DA00A109A6 /* InByStatus.h */,
8584
				7905BB661D12050E0019FE57 /* InlineAccess.cpp */,
8586
				7905BB661D12050E0019FE57 /* InlineAccess.cpp */,
8585
				7905BB671D12050E0019FE57 /* InlineAccess.h */,
8587
				7905BB671D12050E0019FE57 /* InlineAccess.h */,
8586
				148A7BED1B82975A002D9157 /* InlineCallFrame.cpp */,
8588
				148A7BED1B82975A002D9157 /* InlineCallFrame.cpp */,
Lines 9617-9623 a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec6
9617
				0F2BDC21151E803B00CD8910 /* DFGInsertionSet.h in Headers */,
9619
				0F2BDC21151E803B00CD8910 /* DFGInsertionSet.h in Headers */,
9618
				0F300B7C18AB1B1400A6D72E /* DFGIntegerCheckCombiningPhase.h in Headers */,
9620
				0F300B7C18AB1B1400A6D72E /* DFGIntegerCheckCombiningPhase.h in Headers */,
9619
				0F898F321B27689F0083A33C /* DFGIntegerRangeOptimizationPhase.h in Headers */,
9621
				0F898F321B27689F0083A33C /* DFGIntegerRangeOptimizationPhase.h in Headers */,
9620
				52B5100D265EFCDB008970E7 /* JITSizeStatistics.h in Headers */,
9621
				0FC97F3E18202119002C9B26 /* DFGInvalidationPointInjectionPhase.h in Headers */,
9622
				0FC97F3E18202119002C9B26 /* DFGInvalidationPointInjectionPhase.h in Headers */,
9622
				0FEA0A34170D40BF00BB722C /* DFGJITCode.h in Headers */,
9623
				0FEA0A34170D40BF00BB722C /* DFGJITCode.h in Headers */,
9623
				86EC9DCC1328DF82002B2AD7 /* DFGJITCompiler.h in Headers */,
9624
				86EC9DCC1328DF82002B2AD7 /* DFGJITCompiler.h in Headers */,
Lines 9920-9925 a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec7
9920
				BC18C40F0E16F5CD00B34460 /* Identifier.h in Headers */,
9921
				BC18C40F0E16F5CD00B34460 /* Identifier.h in Headers */,
9921
				8606DDEA18DA44AB00A383D0 /* IdentifierInlines.h in Headers */,
9922
				8606DDEA18DA44AB00A383D0 /* IdentifierInlines.h in Headers */,
9922
				A5FD0076189B038C00633231 /* IdentifiersFactory.h in Headers */,
9923
				A5FD0076189B038C00633231 /* IdentifiersFactory.h in Headers */,
9924
				A382C5312667111D0042CD99 /* InByIdVariant.h in Headers */,
9925
				A38D5BFC2666D3DA00A109A6 /* InByStatus.h in Headers */,
9923
				C25F8BCE157544A900245B71 /* IncrementalSweeper.h in Headers */,
9926
				C25F8BCE157544A900245B71 /* IncrementalSweeper.h in Headers */,
9924
				0FB7F39915ED8E4600F167B2 /* IndexingHeader.h in Headers */,
9927
				0FB7F39915ED8E4600F167B2 /* IndexingHeader.h in Headers */,
9925
				0FB7F39A15ED8E4600F167B2 /* IndexingHeaderInlines.h in Headers */,
9928
				0FB7F39A15ED8E4600F167B2 /* IndexingHeaderInlines.h in Headers */,
Lines 10071-10076 a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec8
10071
				FE3A06C01C11041A00390FDD /* JITRightShiftGenerator.h in Headers */,
10074
				FE3A06C01C11041A00390FDD /* JITRightShiftGenerator.h in Headers */,
10072
				72131BF926587EF2007114CF /* JITSafepoint.h in Headers */,
10075
				72131BF926587EF2007114CF /* JITSafepoint.h in Headers */,
10073
				72131BF826587EF2007114CF /* JITScannable.h in Headers */,
10076
				72131BF826587EF2007114CF /* JITScannable.h in Headers */,
10077
				52B5100D265EFCDB008970E7 /* JITSizeStatistics.h in Headers */,
10074
				0F766D3115AA8112008F363E /* JITStubRoutine.h in Headers */,
10078
				0F766D3115AA8112008F363E /* JITStubRoutine.h in Headers */,
10075
				0F766D2C15A8CC3A008F363E /* JITStubRoutineSet.h in Headers */,
10079
				0F766D2C15A8CC3A008F363E /* JITStubRoutineSet.h in Headers */,
10076
				0F5EF91F16878F7D003E5C25 /* JITThunks.h in Headers */,
10080
				0F5EF91F16878F7D003E5C25 /* JITThunks.h in Headers */,
- a/Source/JavaScriptCore/Sources.txt -1 / +1 lines
Lines 239-245 bytecode/GetByIdVariant.cpp a/Source/JavaScriptCore/Sources.txt_sec1
239
bytecode/GetterSetterAccessCase.cpp
239
bytecode/GetterSetterAccessCase.cpp
240
bytecode/ICStatusMap.cpp
240
bytecode/ICStatusMap.cpp
241
bytecode/ICStatusUtils.cpp
241
bytecode/ICStatusUtils.cpp
242
bytecode/InByIdStatus.cpp
242
bytecode/InByStatus.cpp
243
bytecode/InByIdVariant.cpp
243
bytecode/InByIdVariant.cpp
244
bytecode/InlineAccess.cpp
244
bytecode/InlineAccess.cpp
245
bytecode/InlineCallFrame.cpp
245
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/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/InByIdStatus.cpp -49 / +70 lines
Lines 25-32 a/Source/JavaScriptCore/bytecode/InByIdStatus.cpp_sec1
25
 */
25
 */
26
26
27
#include "config.h"
27
#include "config.h"
28
#include "InByIdStatus.h"
28
#include "InByStatus.h"
29
29
30
#include "CacheableIdentifierInlines.h"
30
#include "CodeBlock.h"
31
#include "CodeBlock.h"
31
#include "ComplexGetStatus.h"
32
#include "ComplexGetStatus.h"
32
#include "ICStatusUtils.h"
33
#include "ICStatusUtils.h"
Lines 36-81 a/Source/JavaScriptCore/bytecode/InByIdStatus.cpp_sec2
36
37
37
namespace JSC {
38
namespace JSC {
38
39
39
bool InByIdStatus::appendVariant(const InByIdVariant& variant)
40
bool InByStatus::appendVariant(const InByIdVariant& variant)
40
{
41
{
41
    return appendICStatusVariant(m_variants, variant);
42
    return appendICStatusVariant(m_variants, variant);
42
}
43
}
43
44
44
void InByIdStatus::shrinkToFit()
45
void InByStatus::shrinkToFit()
45
{
46
{
46
    m_variants.shrinkToFit();
47
    m_variants.shrinkToFit();
47
}
48
}
48
49
49
#if ENABLE(JIT)
50
#if ENABLE(JIT)
50
InByIdStatus InByIdStatus::computeFor(CodeBlock* profiledBlock, ICStatusMap& map, BytecodeIndex bytecodeIndex, UniquedStringImpl* uid, ExitFlag didExit)
51
InByStatus InByStatus::computeFor(CodeBlock* profiledBlock, ICStatusMap& map, BytecodeIndex bytecodeIndex, ExitFlag didExit)
51
{
52
{
52
    ConcurrentJSLocker locker(profiledBlock->m_lock);
53
    ConcurrentJSLocker locker(profiledBlock->m_lock);
53
54
54
    InByIdStatus result;
55
    InByStatus result;
55
56
56
#if ENABLE(DFG_JIT)
57
#if ENABLE(DFG_JIT)
57
    result = computeForStubInfoWithoutExitSiteFeedback(locker, profiledBlock->vm(), map.get(CodeOrigin(bytecodeIndex)).stubInfo, uid);
58
    result = computeForStubInfoWithoutExitSiteFeedback(locker, profiledBlock->vm(), map.get(CodeOrigin(bytecodeIndex)).stubInfo);
58
59
59
    if (!result.takesSlowPath() && didExit)
60
    if (!result.takesSlowPath() && didExit)
60
        return InByIdStatus(TakesSlowPath);
61
        return InByStatus(TakesSlowPath);
61
#else
62
#else
62
    UNUSED_PARAM(map);
63
    UNUSED_PARAM(map);
63
    UNUSED_PARAM(bytecodeIndex);
64
    UNUSED_PARAM(bytecodeIndex);
64
    UNUSED_PARAM(uid);
65
    UNUSED_PARAM(didExit);
65
    UNUSED_PARAM(didExit);
66
#endif
66
#endif
67
67
68
    return result;
68
    return result;
69
}
69
}
70
70
71
InByIdStatus InByIdStatus::computeFor(CodeBlock* profiledBlock, ICStatusMap& map, BytecodeIndex bytecodeIndex, UniquedStringImpl* uid)
71
InByStatus InByStatus::computeFor(CodeBlock* profiledBlock, ICStatusMap& map, BytecodeIndex bytecodeIndex)
72
{
72
{
73
    return computeFor(profiledBlock, map, bytecodeIndex, uid, hasBadCacheExitSite(profiledBlock, bytecodeIndex));
73
    return computeFor(profiledBlock, map, bytecodeIndex, hasBadCacheExitSite(profiledBlock, bytecodeIndex));
74
}
74
}
75
75
76
InByIdStatus InByIdStatus::computeFor(
76
InByStatus InByStatus::computeFor(
77
    CodeBlock* profiledBlock, ICStatusMap& baselineMap,
77
    CodeBlock* profiledBlock, ICStatusMap& baselineMap,
78
    ICStatusContextStack& contextStack, CodeOrigin codeOrigin, UniquedStringImpl* uid)
78
    ICStatusContextStack& contextStack, CodeOrigin codeOrigin)
79
{
79
{
80
    BytecodeIndex bytecodeIndex = codeOrigin.bytecodeIndex();
80
    BytecodeIndex bytecodeIndex = codeOrigin.bytecodeIndex();
81
    ExitFlag didExit = hasBadCacheExitSite(profiledBlock, bytecodeIndex);
81
    ExitFlag didExit = hasBadCacheExitSite(profiledBlock, bytecodeIndex);
Lines 83-106 InByIdStatus InByIdStatus::computeFor( a/Source/JavaScriptCore/bytecode/InByIdStatus.cpp_sec3
83
    for (ICStatusContext* context : contextStack) {
83
    for (ICStatusContext* context : contextStack) {
84
        ICStatus status = context->get(codeOrigin);
84
        ICStatus status = context->get(codeOrigin);
85
        
85
        
86
        auto bless = [&] (const InByIdStatus& result) -> InByIdStatus {
86
        auto bless = [&] (const InByStatus& result) -> InByStatus {
87
            if (!context->isInlined(codeOrigin)) {
87
            if (!context->isInlined(codeOrigin)) {
88
                InByIdStatus baselineResult = computeFor(
88
                InByStatus baselineResult = computeFor(
89
                    profiledBlock, baselineMap, bytecodeIndex, uid, didExit);
89
                    profiledBlock, baselineMap, bytecodeIndex, didExit);
90
                baselineResult.merge(result);
90
                baselineResult.merge(result);
91
                return baselineResult;
91
                return baselineResult;
92
            }
92
            }
93
            if (didExit.isSet(ExitFromInlined))
93
            if (didExit.isSet(ExitFromInlined))
94
                return InByIdStatus(TakesSlowPath);
94
                return InByStatus(TakesSlowPath);
95
            return result;
95
            return result;
96
        };
96
        };
97
        
97
        
98
#if ENABLE(DFG_JIT)
98
#if ENABLE(DFG_JIT)
99
        if (status.stubInfo) {
99
        if (status.stubInfo) {
100
            InByIdStatus result;
100
            InByStatus result;
101
            {
101
            {
102
                ConcurrentJSLocker locker(context->optimizedCodeBlock->m_lock);
102
                ConcurrentJSLocker locker(context->optimizedCodeBlock->m_lock);
103
                result = computeForStubInfoWithoutExitSiteFeedback(locker, profiledBlock->vm(), status.stubInfo, uid);
103
                result = computeForStubInfoWithoutExitSiteFeedback(locker, profiledBlock->vm(), status.stubInfo);
104
            }
104
            }
105
            if (result.isSet())
105
            if (result.isSet())
106
                return bless(result);
106
                return bless(result);
Lines 111-154 InByIdStatus InByIdStatus::computeFor( a/Source/JavaScriptCore/bytecode/InByIdStatus.cpp_sec4
111
            return bless(*status.inStatus);
111
            return bless(*status.inStatus);
112
    }
112
    }
113
    
113
    
114
    return computeFor(profiledBlock, baselineMap, bytecodeIndex, uid, didExit);
114
    return computeFor(profiledBlock, baselineMap, bytecodeIndex, didExit);
115
}
115
}
116
#endif // ENABLE(JIT)
116
#endif // ENABLE(JIT)
117
117
118
#if ENABLE(DFG_JIT)
118
#if ENABLE(DFG_JIT)
119
InByIdStatus InByIdStatus::computeForStubInfo(const ConcurrentJSLocker& locker, CodeBlock* profiledBlock, StructureStubInfo* stubInfo, CodeOrigin codeOrigin, UniquedStringImpl* uid)
119
InByStatus InByStatus::computeForStubInfo(const ConcurrentJSLocker& locker, CodeBlock* profiledBlock, StructureStubInfo* stubInfo, CodeOrigin codeOrigin)
120
{
120
{
121
    InByIdStatus result = InByIdStatus::computeForStubInfoWithoutExitSiteFeedback(locker, profiledBlock->vm(), stubInfo, uid);
121
    InByStatus result = InByStatus::computeForStubInfoWithoutExitSiteFeedback(locker, profiledBlock->vm(), stubInfo);
122
122
123
    if (!result.takesSlowPath() && hasBadCacheExitSite(profiledBlock, codeOrigin.bytecodeIndex()))
123
    if (!result.takesSlowPath() && hasBadCacheExitSite(profiledBlock, codeOrigin.bytecodeIndex()))
124
        return InByIdStatus(TakesSlowPath);
124
        return InByStatus(TakesSlowPath);
125
    return result;
125
    return result;
126
}
126
}
127
127
128
InByIdStatus InByIdStatus::computeForStubInfoWithoutExitSiteFeedback(const ConcurrentJSLocker&, VM& vm, StructureStubInfo* stubInfo, UniquedStringImpl* uid)
128
InByStatus InByStatus::computeForStubInfoWithoutExitSiteFeedback(const ConcurrentJSLocker&, VM& vm, StructureStubInfo* stubInfo)
129
{
129
{
130
    StubInfoSummary summary = StructureStubInfo::summary(vm, stubInfo);
130
    StubInfoSummary summary = StructureStubInfo::summary(vm, stubInfo);
131
    if (!isInlineable(summary))
131
    if (!isInlineable(summary))
132
        return InByIdStatus(summary);
132
        return InByStatus(summary);
133
    
133
    
134
    // Finally figure out if we can derive an access strategy.
134
    // Finally figure out if we can derive an access strategy.
135
    InByIdStatus result;
135
    InByStatus result;
136
    result.m_state = Simple;
136
    result.m_state = Simple;
137
    switch (stubInfo->cacheType()) {
137
    switch (stubInfo->cacheType()) {
138
    case CacheType::Unset:
138
    case CacheType::Unset:
139
        return InByIdStatus(NoInformation);
139
        return InByStatus(NoInformation);
140
140
141
    case CacheType::InByIdSelf: {
141
    case CacheType::InByIdSelf: {
142
        Structure* structure = stubInfo->u.byIdSelf.baseObjectStructure.get();
142
        Structure* structure = stubInfo->u.byIdSelf.baseObjectStructure.get();
143
        if (structure->takesSlowPathInDFGForImpureProperty())
143
        if (structure->takesSlowPathInDFGForImpureProperty())
144
            return InByIdStatus(TakesSlowPath);
144
            return InByStatus(TakesSlowPath);
145
        CacheableIdentifier identifier = stubInfo->identifier();
146
        UniquedStringImpl* uid = identifier.uid();
147
        RELEASE_ASSERT(uid);
148
        InByIdVariant variant(WTFMove(identifier));
145
        unsigned attributes;
149
        unsigned attributes;
146
        InByIdVariant variant;
147
        variant.m_offset = structure->getConcurrently(uid, attributes);
150
        variant.m_offset = structure->getConcurrently(uid, attributes);
148
        if (!isValidOffset(variant.m_offset))
151
        if (!isValidOffset(variant.m_offset))
149
            return InByIdStatus(TakesSlowPath);
152
            return InByStatus(TakesSlowPath);
150
        if (attributes & PropertyAttribute::CustomAccessorOrValue)
153
        if (attributes & PropertyAttribute::CustomAccessorOrValue)
151
            return InByIdStatus(TakesSlowPath);
154
            return InByStatus(TakesSlowPath);
152
155
153
        variant.m_structureSet.add(structure);
156
        variant.m_structureSet.add(structure);
154
        bool didAppend = result.appendVariant(variant);
157
        bool didAppend = result.appendVariant(variant);
Lines 161-170 InByIdStatus InByIdStatus::computeForStubInfoWithoutExitSiteFeedback(const Concu a/Source/JavaScriptCore/bytecode/InByIdStatus.cpp_sec5
161
        for (unsigned listIndex = 0; listIndex < list->size(); ++listIndex) {
164
        for (unsigned listIndex = 0; listIndex < list->size(); ++listIndex) {
162
            const AccessCase& access = list->at(listIndex);
165
            const AccessCase& access = list->at(listIndex);
163
            if (access.viaProxy())
166
            if (access.viaProxy())
164
                return InByIdStatus(TakesSlowPath);
167
                return InByStatus(TakesSlowPath);
165
168
166
            if (access.usesPolyProto())
169
            if (access.usesPolyProto())
167
                return InByIdStatus(TakesSlowPath);
170
                return InByStatus(TakesSlowPath);
168
171
169
            Structure* structure = access.structure();
172
            Structure* structure = access.structure();
170
            if (!structure) {
173
            if (!structure) {
Lines 174-189 InByIdStatus InByIdStatus::computeForStubInfoWithoutExitSiteFeedback(const Concu a/Source/JavaScriptCore/bytecode/InByIdStatus.cpp_sec6
174
                // have to use value profiling to discover something that the AccessCase could have
177
                // 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
178
                // told us. But, it works well enough. So, our only concern here is to not
176
                // crash on null structure.
179
                // crash on null structure.
177
                return InByIdStatus(TakesSlowPath);
180
                return InByStatus(TakesSlowPath);
178
            }
181
            }
179
182
180
            ComplexGetStatus complexGetStatus = ComplexGetStatus::computeFor(structure, access.conditionSet(), uid);
183
            ComplexGetStatus complexGetStatus = ComplexGetStatus::computeFor(structure, access.conditionSet(), access.uid());
181
            switch (complexGetStatus.kind()) {
184
            switch (complexGetStatus.kind()) {
182
            case ComplexGetStatus::ShouldSkip:
185
            case ComplexGetStatus::ShouldSkip:
183
                continue;
186
                continue;
184
187
185
            case ComplexGetStatus::TakesSlowPath:
188
            case ComplexGetStatus::TakesSlowPath:
186
                return InByIdStatus(TakesSlowPath);
189
                return InByStatus(TakesSlowPath);
187
190
188
            case ComplexGetStatus::Inlineable: {
191
            case ComplexGetStatus::Inlineable: {
189
                switch (access.type()) {
192
                switch (access.type()) {
Lines 191-205 InByIdStatus InByIdStatus::computeForStubInfoWithoutExitSiteFeedback(const Concu a/Source/JavaScriptCore/bytecode/InByIdStatus.cpp_sec7
191
                case AccessCase::InMiss:
194
                case AccessCase::InMiss:
192
                    break;
195
                    break;
193
                default:
196
                default:
194
                    return InByIdStatus(TakesSlowPath);
197
                    return InByStatus(TakesSlowPath);
195
                }
198
                }
196
199
197
                InByIdVariant variant(
200
                InByIdVariant variant(
198
                    StructureSet(structure), complexGetStatus.offset(),
201
                    access.identifier(), StructureSet(structure), complexGetStatus.offset(),
199
                    complexGetStatus.conditionSet());
202
                    complexGetStatus.conditionSet());
200
203
201
                if (!result.appendVariant(variant))
204
                if (!result.appendVariant(variant))
202
                    return InByIdStatus(TakesSlowPath);
205
                    return InByStatus(TakesSlowPath);
203
                break;
206
                break;
204
            }
207
            }
205
            }
208
            }
Lines 210-224 InByIdStatus InByIdStatus::computeForStubInfoWithoutExitSiteFeedback(const Concu a/Source/JavaScriptCore/bytecode/InByIdStatus.cpp_sec8
210
    }
213
    }
211
214
212
    default:
215
    default:
213
        return InByIdStatus(TakesSlowPath);
216
        return InByStatus(TakesSlowPath);
214
    }
217
    }
215
218
216
    RELEASE_ASSERT_NOT_REACHED();
219
    RELEASE_ASSERT_NOT_REACHED();
217
    return InByIdStatus();
220
    return InByStatus();
218
}
221
}
219
#endif
222
#endif
220
223
221
void InByIdStatus::merge(const InByIdStatus& other)
224
void InByStatus::merge(const InByStatus& other)
222
{
225
{
223
    if (other.m_state == NoInformation)
226
    if (other.m_state == NoInformation)
224
        return;
227
        return;
Lines 230-241 void InByIdStatus::merge(const InByIdStatus& other) a/Source/JavaScriptCore/bytecode/InByIdStatus.cpp_sec9
230
        
233
        
231
    case Simple:
234
    case Simple:
232
        if (other.m_state != Simple) {
235
        if (other.m_state != Simple) {
233
            *this = InByIdStatus(TakesSlowPath);
236
            *this = InByStatus(TakesSlowPath);
234
            return;
237
            return;
235
        }
238
        }
236
        for (const InByIdVariant& otherVariant : other.m_variants) {
239
        for (const InByIdVariant& otherVariant : other.m_variants) {
237
            if (!appendVariant(otherVariant)) {
240
            if (!appendVariant(otherVariant)) {
238
                *this = InByIdStatus(TakesSlowPath);
241
                *this = InByStatus(TakesSlowPath);
239
                return;
242
                return;
240
            }
243
            }
241
        }
244
        }
Lines 249-255 void InByIdStatus::merge(const InByIdStatus& other) a/Source/JavaScriptCore/bytecode/InByIdStatus.cpp_sec10
249
    RELEASE_ASSERT_NOT_REACHED();
252
    RELEASE_ASSERT_NOT_REACHED();
250
}
253
}
251
254
252
void InByIdStatus::filter(const StructureSet& structureSet)
255
void InByStatus::filter(const StructureSet& structureSet)
253
{
256
{
254
    if (m_state != Simple)
257
    if (m_state != Simple)
255
        return;
258
        return;
Lines 259-274 void InByIdStatus::filter(const StructureSet& structureSet) a/Source/JavaScriptCore/bytecode/InByIdStatus.cpp_sec11
259
}
262
}
260
263
261
template<typename Visitor>
264
template<typename Visitor>
262
void InByIdStatus::markIfCheap(Visitor& visitor)
265
void InByStatus::markIfCheap(Visitor& visitor)
263
{
266
{
264
    for (InByIdVariant& variant : m_variants)
267
    for (InByIdVariant& variant : m_variants)
265
        variant.markIfCheap(visitor);
268
        variant.markIfCheap(visitor);
266
}
269
}
267
270
268
template void InByIdStatus::markIfCheap(AbstractSlotVisitor&);
271
template void InByStatus::markIfCheap(AbstractSlotVisitor&);
269
template void InByIdStatus::markIfCheap(SlotVisitor&);
272
template void InByStatus::markIfCheap(SlotVisitor&);
270
273
271
bool InByIdStatus::finalize(VM& vm)
274
bool InByStatus::finalize(VM& vm)
272
{
275
{
273
    for (InByIdVariant& variant : m_variants) {
276
    for (InByIdVariant& variant : m_variants) {
274
        if (!variant.finalize(vm))
277
        if (!variant.finalize(vm))
Lines 277-283 bool InByIdStatus::finalize(VM& vm) a/Source/JavaScriptCore/bytecode/InByIdStatus.cpp_sec12
277
    return true;
280
    return true;
278
}
281
}
279
282
280
void InByIdStatus::dump(PrintStream& out) const
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
281
{
302
{
282
    out.print("(");
303
    out.print("(");
283
    switch (m_state) {
304
    switch (m_state) {
- a/Source/JavaScriptCore/bytecode/InByIdStatus.h -13 / +13 lines
Lines 39-45 class AccessCase; a/Source/JavaScriptCore/bytecode/InByIdStatus.h_sec1
39
class CodeBlock;
39
class CodeBlock;
40
class StructureStubInfo;
40
class StructureStubInfo;
41
41
42
class InByIdStatus final {
42
class InByStatus final {
43
    WTF_MAKE_FAST_ALLOCATED;
43
    WTF_MAKE_FAST_ALLOCATED;
44
public:
44
public:
45
    enum State {
45
    enum State {
Lines 52-68 public: a/Source/JavaScriptCore/bytecode/InByIdStatus.h_sec2
52
        TakesSlowPath,
52
        TakesSlowPath,
53
    };
53
    };
54
54
55
    InByIdStatus() = default;
55
    InByStatus() = default;
56
56
57
    InByIdStatus(State state, const InByIdVariant& variant = InByIdVariant())
57
    InByStatus(State state)
58
        : m_state(state)
58
        : m_state(state)
59
    {
59
    {
60
        ASSERT((state == Simple) == variant.isSet());
60
        ASSERT(state != Simple);
61
        if (variant.isSet())
62
            m_variants.append(variant);
63
    }
61
    }
64
62
65
    explicit InByIdStatus(StubInfoSummary summary)
63
    explicit InByStatus(StubInfoSummary summary)
66
    {
64
    {
67
        switch (summary) {
65
        switch (summary) {
68
        case StubInfoSummary::NoInformation:
66
        case StubInfoSummary::NoInformation:
Lines 80-91 public: a/Source/JavaScriptCore/bytecode/InByIdStatus.h_sec3
80
        RELEASE_ASSERT_NOT_REACHED();
78
        RELEASE_ASSERT_NOT_REACHED();
81
    }
79
    }
82
    
80
    
83
    static InByIdStatus computeFor(CodeBlock*, ICStatusMap&, BytecodeIndex, UniquedStringImpl* uid);
81
    static InByStatus computeFor(CodeBlock*, ICStatusMap&, BytecodeIndex);
84
    static InByIdStatus computeFor(CodeBlock*, ICStatusMap&, BytecodeIndex, UniquedStringImpl* uid, ExitFlag);
82
    static InByStatus computeFor(CodeBlock*, ICStatusMap&, BytecodeIndex, ExitFlag);
85
    static InByIdStatus computeFor(CodeBlock* baselineBlock, ICStatusMap& baselineMap, ICStatusContextStack& contextStack, CodeOrigin, UniquedStringImpl* uid);
83
    static InByStatus computeFor(CodeBlock* baselineBlock, ICStatusMap& baselineMap, ICStatusContextStack&, CodeOrigin);
86
84
87
#if ENABLE(DFG_JIT)
85
#if ENABLE(DFG_JIT)
88
    static InByIdStatus computeForStubInfo(const ConcurrentJSLocker&, CodeBlock* baselineBlock, StructureStubInfo*, CodeOrigin, UniquedStringImpl* uid);
86
    static InByStatus computeForStubInfo(const ConcurrentJSLocker&, CodeBlock* baselineBlock, StructureStubInfo*, CodeOrigin);
89
#endif
87
#endif
90
88
91
    State state() const { return m_state; }
89
    State state() const { return m_state; }
Lines 101-107 public: a/Source/JavaScriptCore/bytecode/InByIdStatus.h_sec4
101
99
102
    bool takesSlowPath() const { return m_state == TakesSlowPath; }
100
    bool takesSlowPath() const { return m_state == TakesSlowPath; }
103
    
101
    
104
    void merge(const InByIdStatus&);
102
    void merge(const InByStatus&);
105
103
106
    // Attempts to reduce the set of variants to fit the given structure set. This may be approximate.
104
    // Attempts to reduce the set of variants to fit the given structure set. This may be approximate.
107
    void filter(const StructureSet&);
105
    void filter(const StructureSet&);
Lines 111-119 public: a/Source/JavaScriptCore/bytecode/InByIdStatus.h_sec5
111
109
112
    void dump(PrintStream&) const;
110
    void dump(PrintStream&) const;
113
111
112
    CacheableIdentifier singleIdentifier() const;
113
114
private:
114
private:
115
#if ENABLE(DFG_JIT)
115
#if ENABLE(DFG_JIT)
116
    static InByIdStatus computeForStubInfoWithoutExitSiteFeedback(const ConcurrentJSLocker&, VM&, StructureStubInfo*, UniquedStringImpl* uid);
116
    static InByStatus computeForStubInfoWithoutExitSiteFeedback(const ConcurrentJSLocker&, VM&, StructureStubInfo*);
117
#endif
117
#endif
118
    bool appendVariant(const InByIdVariant&);
118
    bool appendVariant(const InByIdVariant&);
119
    void shrinkToFit();
119
    void shrinkToFit();
- 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 255-260 void JITCompiler::link(LinkBuffer& linkBuffer) a/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp_sec1
255
    finalizeInlineCaches(m_delByIds, linkBuffer);
255
    finalizeInlineCaches(m_delByIds, linkBuffer);
256
    finalizeInlineCaches(m_delByVals, linkBuffer);
256
    finalizeInlineCaches(m_delByVals, linkBuffer);
257
    finalizeInlineCaches(m_inByIds, linkBuffer);
257
    finalizeInlineCaches(m_inByIds, linkBuffer);
258
    finalizeInlineCaches(m_inByVals, linkBuffer);
258
    finalizeInlineCaches(m_instanceOfs, linkBuffer);
259
    finalizeInlineCaches(m_instanceOfs, linkBuffer);
259
    finalizeInlineCaches(m_privateBrandAccesses, linkBuffer);
260
    finalizeInlineCaches(m_privateBrandAccesses, linkBuffer);
260
261
- 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 1286-1303 void SpeculativeJIT::compileInByVal(Node* node) a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp_sec1
1286
{
1286
{
1287
    SpeculateCellOperand base(this, node->child1());
1287
    SpeculateCellOperand base(this, node->child1());
1288
    JSValueOperand key(this, node->child2());
1288
    JSValueOperand key(this, node->child2());
1289
    JSValueRegsTemporary result(this, Reuse, key);
1289
1290
1290
    GPRReg baseGPR = base.gpr();
1291
    GPRReg baseGPR = base.gpr();
1291
    JSValueRegs regs = key.jsValueRegs();
1292
    JSValueRegs keyRegs = key.jsValueRegs();
1293
    JSValueRegs resultRegs = result.regs();
1292
1294
1293
    base.use();
1295
    base.use();
1294
    key.use();
1296
    key.use();
1295
1297
1296
    flushRegisters();
1298
    CodeOrigin codeOrigin = node->origin.semantic;
1297
    JSValueRegsFlushedCallResult result(this);
1299
    CallSiteIndex callSite = m_jit.recordCallSiteAndGenerateExceptionHandlingOSRExitIfNeeded(codeOrigin, m_stream->size());
1298
    JSValueRegs resultRegs = result.regs();
1300
    RegisterSet usedRegisters = this->usedRegisters();
1299
    callOperation(operationInByVal, resultRegs, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), baseGPR, regs);
1301
    JITInByValGenerator gen(
1300
    m_jit.exceptionCheck();
1302
        m_jit.codeBlock(), codeOrigin, callSite, usedRegisters,
1303
        JSValueRegs::payloadOnly(baseGPR), keyRegs, resultRegs);
1304
    gen.generateFastPath(m_jit);
1305
1306
    auto slowPath = slowPathCall(
1307
        gen.slowPathJump(), this, operationInByValOptimize,
1308
        NeedToSpill, ExceptionCheckRequirement::CheckNeeded,
1309
        resultRegs, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), gen.stubInfo(), nullptr, CCallHelpers::CellValue(baseGPR), keyRegs);
1310
1311
    m_jit.addInByVal(gen, slowPath.get());
1312
    addSlowPathGenerator(WTFMove(slowPath));
1313
1301
    blessedBooleanResult(resultRegs.payloadGPR(), node, UseChildrenCalledExplicitly);
1314
    blessedBooleanResult(resultRegs.payloadGPR(), node, UseChildrenCalledExplicitly);
1302
}
1315
}
1303
1316
- 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 198-204 private: a/Source/JavaScriptCore/dfg/DFGVarargsForwardingPhase.cpp_sec1
198
            case FilterGetByStatus:
198
            case FilterGetByStatus:
199
            case FilterPutByIdStatus:
199
            case FilterPutByIdStatus:
200
            case FilterCallLinkStatus:
200
            case FilterCallLinkStatus:
201
            case FilterInByIdStatus:
201
            case FilterInByStatus:
202
            case FilterDeleteByStatus:
202
            case FilterDeleteByStatus:
203
            case FilterCheckPrivateBrandStatus:
203
            case FilterCheckPrivateBrandStatus:
204
            case FilterSetPrivateBrandStatus:
204
            case FilterSetPrivateBrandStatus:
Lines 423-429 private: a/Source/JavaScriptCore/dfg/DFGVarargsForwardingPhase.cpp_sec2
423
            case FilterGetByStatus:
423
            case FilterGetByStatus:
424
            case FilterPutByIdStatus:
424
            case FilterPutByIdStatus:
425
            case FilterCallLinkStatus:
425
            case FilterCallLinkStatus:
426
            case FilterInByIdStatus:
426
            case FilterInByStatus:
427
            case FilterDeleteByStatus:
427
            case FilterDeleteByStatus:
428
            case FilterCheckPrivateBrandStatus:
428
            case FilterCheckPrivateBrandStatus:
429
            case FilterSetPrivateBrandStatus:
429
            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 285-291 void JIT::privateCompileMainPass() a/Source/JavaScriptCore/jit/JIT.cpp_sec1
285
        }
285
        }
286
286
287
        switch (opcodeID) {
287
        switch (opcodeID) {
288
        DEFINE_SLOW_OP(in_by_val)
289
        DEFINE_SLOW_OP(has_private_name)
288
        DEFINE_SLOW_OP(has_private_name)
290
        DEFINE_SLOW_OP(has_private_brand)
289
        DEFINE_SLOW_OP(has_private_brand)
291
        DEFINE_SLOW_OP(less)
290
        DEFINE_SLOW_OP(less)
Lines 361-366 void JIT::privateCompileMainPass() a/Source/JavaScriptCore/jit/JIT.cpp_sec2
361
        DEFINE_OP(op_beloweq)
360
        DEFINE_OP(op_beloweq)
362
        DEFINE_OP(op_try_get_by_id)
361
        DEFINE_OP(op_try_get_by_id)
363
        DEFINE_OP(op_in_by_id)
362
        DEFINE_OP(op_in_by_id)
363
        DEFINE_OP(op_in_by_val)
364
        DEFINE_OP(op_get_by_id)
364
        DEFINE_OP(op_get_by_id)
365
        DEFINE_OP(op_get_by_id_with_this)
365
        DEFINE_OP(op_get_by_id_with_this)
366
        DEFINE_OP(op_get_by_id_direct)
366
        DEFINE_OP(op_get_by_id_direct)
Lines 518-525 void JIT::privateCompileSlowCases() a/Source/JavaScriptCore/jit/JIT.cpp_sec3
518
    m_getByIdWithThisIndex = 0;
518
    m_getByIdWithThisIndex = 0;
519
    m_putByIdIndex = 0;
519
    m_putByIdIndex = 0;
520
    m_inByIdIndex = 0;
520
    m_inByIdIndex = 0;
521
    m_delByValIndex = 0;
521
    m_inByValIndex = 0;
522
    m_delByIdIndex = 0;
522
    m_delByIdIndex = 0;
523
    m_delByValIndex = 0;
523
    m_instanceOfIndex = 0;
524
    m_instanceOfIndex = 0;
524
    m_privateBrandAccessIndex = 0;
525
    m_privateBrandAccessIndex = 0;
525
    m_byValInstructionIndex = 0;
526
    m_byValInstructionIndex = 0;
Lines 570-575 void JIT::privateCompileSlowCases() a/Source/JavaScriptCore/jit/JIT.cpp_sec4
570
        DEFINE_SLOWCASE_OP(op_eq)
571
        DEFINE_SLOWCASE_OP(op_eq)
571
        DEFINE_SLOWCASE_OP(op_try_get_by_id)
572
        DEFINE_SLOWCASE_OP(op_try_get_by_id)
572
        DEFINE_SLOWCASE_OP(op_in_by_id)
573
        DEFINE_SLOWCASE_OP(op_in_by_id)
574
        DEFINE_SLOWCASE_OP(op_in_by_val)
573
        DEFINE_SLOWCASE_OP(op_get_by_id)
575
        DEFINE_SLOWCASE_OP(op_get_by_id)
574
        DEFINE_SLOWCASE_OP(op_get_by_id_with_this)
576
        DEFINE_SLOWCASE_OP(op_get_by_id_with_this)
575
        DEFINE_SLOWCASE_OP(op_get_by_id_direct)
577
        DEFINE_SLOWCASE_OP(op_get_by_id_direct)
Lines 919-924 void JIT::link() a/Source/JavaScriptCore/jit/JIT.cpp_sec5
919
    finalizeInlineCaches(m_delByIds, patchBuffer);
921
    finalizeInlineCaches(m_delByIds, patchBuffer);
920
    finalizeInlineCaches(m_delByVals, patchBuffer);
922
    finalizeInlineCaches(m_delByVals, patchBuffer);
921
    finalizeInlineCaches(m_inByIds, patchBuffer);
923
    finalizeInlineCaches(m_inByIds, patchBuffer);
924
    finalizeInlineCaches(m_inByVals, patchBuffer);
922
    finalizeInlineCaches(m_instanceOfs, patchBuffer);
925
    finalizeInlineCaches(m_instanceOfs, patchBuffer);
923
    finalizeInlineCaches(m_privateBrandAccesses, patchBuffer);
926
    finalizeInlineCaches(m_privateBrandAccesses, patchBuffer);
924
927
- a/Source/JavaScriptCore/jit/JIT.h +4 lines
Lines 565-570 namespace JSC { a/Source/JavaScriptCore/jit/JIT.h_sec1
565
        void emit_op_get_argument_by_val(const Instruction*);
565
        void emit_op_get_argument_by_val(const Instruction*);
566
        void emit_op_get_prototype_of(const Instruction*);
566
        void emit_op_get_prototype_of(const Instruction*);
567
        void emit_op_in_by_id(const Instruction*);
567
        void emit_op_in_by_id(const Instruction*);
568
        void emit_op_in_by_val(const Instruction*);
568
        void emit_op_init_lazy_reg(const Instruction*);
569
        void emit_op_init_lazy_reg(const Instruction*);
569
        void emit_op_overrides_has_instance(const Instruction*);
570
        void emit_op_overrides_has_instance(const Instruction*);
570
        void emit_op_instanceof(const Instruction*);
571
        void emit_op_instanceof(const Instruction*);
Lines 698-703 namespace JSC { a/Source/JavaScriptCore/jit/JIT.h_sec2
698
        void emitSlow_op_check_private_brand(const Instruction*, Vector<SlowCaseEntry>::iterator&);
699
        void emitSlow_op_check_private_brand(const Instruction*, Vector<SlowCaseEntry>::iterator&);
699
        void emitSlow_op_get_argument_by_val(const Instruction*, Vector<SlowCaseEntry>::iterator&);
700
        void emitSlow_op_get_argument_by_val(const Instruction*, Vector<SlowCaseEntry>::iterator&);
700
        void emitSlow_op_in_by_id(const Instruction*, Vector<SlowCaseEntry>::iterator&);
701
        void emitSlow_op_in_by_id(const Instruction*, Vector<SlowCaseEntry>::iterator&);
702
        void emitSlow_op_in_by_val(const Instruction*, Vector<SlowCaseEntry>::iterator&);
701
        void emitSlow_op_instanceof(const Instruction*, Vector<SlowCaseEntry>::iterator&);
703
        void emitSlow_op_instanceof(const Instruction*, Vector<SlowCaseEntry>::iterator&);
702
        void emitSlow_op_instanceof_custom(const Instruction*, Vector<SlowCaseEntry>::iterator&);
704
        void emitSlow_op_instanceof_custom(const Instruction*, Vector<SlowCaseEntry>::iterator&);
703
        void emitSlow_op_jless(const Instruction*, Vector<SlowCaseEntry>::iterator&);
705
        void emitSlow_op_jless(const Instruction*, Vector<SlowCaseEntry>::iterator&);
Lines 1037-1042 namespace JSC { a/Source/JavaScriptCore/jit/JIT.h_sec3
1037
        Vector<JITGetByIdWithThisGenerator> m_getByIdsWithThis;
1039
        Vector<JITGetByIdWithThisGenerator> m_getByIdsWithThis;
1038
        Vector<JITPutByIdGenerator> m_putByIds;
1040
        Vector<JITPutByIdGenerator> m_putByIds;
1039
        Vector<JITInByIdGenerator> m_inByIds;
1041
        Vector<JITInByIdGenerator> m_inByIds;
1042
        Vector<JITInByValGenerator> m_inByVals;
1040
        Vector<JITDelByIdGenerator> m_delByIds;
1043
        Vector<JITDelByIdGenerator> m_delByIds;
1041
        Vector<JITDelByValGenerator> m_delByVals;
1044
        Vector<JITDelByValGenerator> m_delByVals;
1042
        Vector<JITInstanceOfGenerator> m_instanceOfs;
1045
        Vector<JITInstanceOfGenerator> m_instanceOfs;
Lines 1063-1068 namespace JSC { a/Source/JavaScriptCore/jit/JIT.h_sec4
1063
        unsigned m_getByIdWithThisIndex { UINT_MAX };
1066
        unsigned m_getByIdWithThisIndex { UINT_MAX };
1064
        unsigned m_putByIdIndex { UINT_MAX };
1067
        unsigned m_putByIdIndex { UINT_MAX };
1065
        unsigned m_inByIdIndex { UINT_MAX };
1068
        unsigned m_inByIdIndex { UINT_MAX };
1069
        unsigned m_inByValIndex { UINT_MAX };
1066
        unsigned m_delByValIndex { UINT_MAX };
1070
        unsigned m_delByValIndex { UINT_MAX };
1067
        unsigned m_delByIdIndex { UINT_MAX };
1071
        unsigned m_delByIdIndex { UINT_MAX };
1068
        unsigned m_instanceOfIndex { UINT_MAX };
1072
        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 394-400 JSC_DEFINE_JIT_OPERATION(operationGetByIdWithThisOptimize, EncodedJSValue, (JSGl a/Source/JavaScriptCore/jit/JITOperations.cpp_sec1
394
    }));
394
    }));
395
}
395
}
396
396
397
JSC_DEFINE_JIT_OPERATION(operationInById, EncodedJSValue, (JSGlobalObject* globalObject, StructureStubInfo* stubInfo, EncodedJSValue base, uintptr_t rawCacheableIdentifier))
397
JSC_DEFINE_JIT_OPERATION(operationInByIdGeneric, EncodedJSValue, (JSGlobalObject* globalObject, StructureStubInfo* stubInfo, EncodedJSValue base, uintptr_t rawCacheableIdentifier))
398
{
398
{
399
    SuperSamplerScope superSamplerScope(false);
399
    SuperSamplerScope superSamplerScope(false);
400
400
Lines 415-421 JSC_DEFINE_JIT_OPERATION(operationInById, EncodedJSValue, (JSGlobalObject* globa a/Source/JavaScriptCore/jit/JITOperations.cpp_sec2
415
    }
415
    }
416
    JSObject* baseObject = asObject(baseValue);
416
    JSObject* baseObject = asObject(baseValue);
417
417
418
    LOG_IC((ICEvent::OperationInById, baseObject->classInfo(vm), ident));
418
    LOG_IC((ICEvent::OperationInByIdGeneric, baseObject->classInfo(vm), ident));
419
419
420
    scope.release();
420
    scope.release();
421
    PropertySlot slot(baseObject, PropertySlot::InternalMethodType::HasProperty);
421
    PropertySlot slot(baseObject, PropertySlot::InternalMethodType::HasProperty);
Lines 448-466 JSC_DEFINE_JIT_OPERATION(operationInByIdOptimize, EncodedJSValue, (JSGlobalObjec a/Source/JavaScriptCore/jit/JITOperations.cpp_sec3
448
    bool found = baseObject->getPropertySlot(globalObject, ident, slot);
448
    bool found = baseObject->getPropertySlot(globalObject, ident, slot);
449
    CodeBlock* codeBlock = callFrame->codeBlock();
449
    CodeBlock* codeBlock = callFrame->codeBlock();
450
    if (stubInfo->considerCachingBy(vm, codeBlock, baseObject->structure(vm), identifier))
450
    if (stubInfo->considerCachingBy(vm, codeBlock, baseObject->structure(vm), identifier))
451
        repatchInByID(globalObject, codeBlock, baseObject, identifier, found, slot, *stubInfo);
451
        repatchInBy(globalObject, codeBlock, baseObject, identifier, found, slot, *stubInfo, InByKind::Normal);
452
    return JSValue::encode(jsBoolean(found));
452
    return JSValue::encode(jsBoolean(found));
453
}
453
}
454
454
455
JSC_DEFINE_JIT_OPERATION(operationInByVal, EncodedJSValue, (JSGlobalObject* globalObject, JSCell* base, EncodedJSValue key))
455
JSC_DEFINE_JIT_OPERATION(operationInByValOptimize, EncodedJSValue, (JSGlobalObject* globalObject, StructureStubInfo* stubInfo, ArrayProfile* arrayProfile, EncodedJSValue encodedBase, EncodedJSValue encodedKey))
456
{
456
{
457
    SuperSamplerScope superSamplerScope(false);
457
    SuperSamplerScope superSamplerScope(false);
458
    
458
459
    VM& vm = globalObject->vm();
460
    CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
461
    JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
462
    auto scope = DECLARE_THROW_SCOPE(vm);
463
464
    JSValue baseValue = JSValue::decode(encodedBase);
465
    if (!baseValue.isObject()) {
466
        throwException(globalObject, scope, createInvalidInParameterError(globalObject, baseValue));
467
        return encodedJSValue();
468
    }
469
    JSObject* baseObject = asObject(baseValue);
470
    if (arrayProfile)
471
        arrayProfile->observeStructure(baseObject->structure(vm));
472
473
    JSValue key = JSValue::decode(encodedKey);
474
    uint32_t i;
475
    if (key.getUInt32(i)) {
476
        if (arrayProfile)
477
            arrayProfile->observeIndexedRead(vm, baseObject, i);
478
        RELEASE_AND_RETURN(scope, JSValue::encode(jsBoolean(baseObject->hasProperty(globalObject, i))));
479
    }
480
481
    const Identifier propertyName = key.toPropertyKey(globalObject);
482
    RETURN_IF_EXCEPTION(scope, encodedJSValue());
483
    PropertySlot slot(baseObject, PropertySlot::InternalMethodType::HasProperty);
484
    bool found = baseObject->getPropertySlot(globalObject, propertyName, slot);
485
    RETURN_IF_EXCEPTION(scope, encodedJSValue());
486
487
    if (CacheableIdentifier::isCacheableIdentifierCell(key) && (key.isSymbol() || !parseIndex(propertyName))) {
488
        CodeBlock* codeBlock = callFrame->codeBlock();
489
        CacheableIdentifier identifier = CacheableIdentifier::createFromCell(key.asCell());
490
        if (stubInfo->considerCachingBy(vm, codeBlock, baseObject->structure(vm), identifier))
491
            repatchInBy(globalObject, codeBlock, baseObject, identifier, found, slot, *stubInfo, InByKind::NormalByVal);
492
    }
493
494
    return JSValue::encode(jsBoolean(found));
495
}
496
497
JSC_DEFINE_JIT_OPERATION(operationInByValGeneric, EncodedJSValue, (JSGlobalObject* globalObject, StructureStubInfo* stubInfo, ArrayProfile* arrayProfile, EncodedJSValue base, EncodedJSValue key))
498
{
499
    SuperSamplerScope superSamplerScope(false);
500
459
    VM& vm = globalObject->vm();
501
    VM& vm = globalObject->vm();
460
    CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
502
    CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
461
    JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
503
    JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
462
504
463
    return JSValue::encode(jsBoolean(CommonSlowPaths::opInByVal(globalObject, base, JSValue::decode(key))));
505
    stubInfo->tookSlowPath = true;
506
    return JSValue::encode(jsBoolean(CommonSlowPaths::opInByVal(globalObject, JSValue::decode(base), JSValue::decode(key), arrayProfile)));
464
}
507
}
465
508
466
JSC_DEFINE_JIT_OPERATION(operationHasPrivateName, EncodedJSValue, (JSGlobalObject* globalObject, JSCell* base, EncodedJSValue key))
509
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 = callOperation(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 = callOperation(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/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 1424-1429 LLINT_SLOW_PATH_DECL(slow_path_in_by_id) a/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp_sec1
1424
    LLINT_RETURN(jsBoolean(asObject(baseValue)->hasProperty(globalObject, codeBlock->identifier(bytecode.m_property))));
1424
    LLINT_RETURN(jsBoolean(asObject(baseValue)->hasProperty(globalObject, codeBlock->identifier(bytecode.m_property))));
1425
}
1425
}
1426
1426
1427
LLINT_SLOW_PATH_DECL(slow_path_in_by_val)
1428
{
1429
    LLINT_BEGIN();
1430
    auto bytecode = pc->as<OpInByVal>();
1431
    auto& metadata = bytecode.metadata(codeBlock);
1432
    LLINT_RETURN(jsBoolean(CommonSlowPaths::opInByVal(globalObject, getOperand(callFrame, bytecode.m_base), getOperand(callFrame, bytecode.m_property), &metadata.m_arrayProfile)));
1433
}
1434
1427
LLINT_SLOW_PATH_DECL(slow_path_put_getter_by_id)
1435
LLINT_SLOW_PATH_DECL(slow_path_put_getter_by_id)
1428
{
1436
{
1429
    LLINT_BEGIN();
1437
    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-28  Robin Morisset  <rmorisset@apple.com>
12
2021-05-28  Robin Morisset  <rmorisset@apple.com>
2
13
3
        Fix LikelyDenseUnsignedIntegerSet::clear()
14
        Fix LikelyDenseUnsignedIntegerSet::clear()
- 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