Changeset 278656 in webkit
- Timestamp:
- Jun 9, 2021, 4:17:36 AM (5 years ago)
- Location:
- trunk
- Files:
-
- 66 edited
-
Source/JavaScriptCore/ChangeLog (modified) (1 diff)
-
Source/JavaScriptCore/assembler/MacroAssemblerARM64E.h (modified) (1 diff)
-
Source/JavaScriptCore/bytecode/AccessCase.cpp (modified) (22 diffs)
-
Source/JavaScriptCore/bytecode/AccessCase.h (modified) (6 diffs)
-
Source/JavaScriptCore/bytecode/ByValInfo.h (modified) (2 diffs)
-
Source/JavaScriptCore/bytecode/CallLinkInfo.cpp (modified) (2 diffs)
-
Source/JavaScriptCore/bytecode/CodeBlock.h (modified) (1 diff)
-
Source/JavaScriptCore/bytecode/GetterSetterAccessCase.cpp (modified) (6 diffs)
-
Source/JavaScriptCore/bytecode/GetterSetterAccessCase.h (modified) (1 diff)
-
Source/JavaScriptCore/bytecode/InlineAccess.cpp (modified) (2 diffs)
-
Source/JavaScriptCore/bytecode/InlineAccess.h (modified) (1 diff)
-
Source/JavaScriptCore/bytecode/InstanceOfAccessCase.cpp (modified) (2 diffs)
-
Source/JavaScriptCore/bytecode/InstanceOfAccessCase.h (modified) (2 diffs)
-
Source/JavaScriptCore/bytecode/IntrinsicGetterAccessCase.cpp (modified) (2 diffs)
-
Source/JavaScriptCore/bytecode/IntrinsicGetterAccessCase.h (modified) (1 diff)
-
Source/JavaScriptCore/bytecode/ModuleNamespaceAccessCase.cpp (modified) (2 diffs)
-
Source/JavaScriptCore/bytecode/ModuleNamespaceAccessCase.h (modified) (1 diff)
-
Source/JavaScriptCore/bytecode/ObjectPropertyConditionSet.h (modified) (2 diffs)
-
Source/JavaScriptCore/bytecode/PolymorphicAccess.cpp (modified) (18 diffs)
-
Source/JavaScriptCore/bytecode/PolymorphicAccess.h (modified) (6 diffs)
-
Source/JavaScriptCore/bytecode/ProxyableAccessCase.cpp (modified) (2 diffs)
-
Source/JavaScriptCore/bytecode/ProxyableAccessCase.h (modified) (1 diff)
-
Source/JavaScriptCore/bytecode/StructureStubInfo.cpp (modified) (5 diffs)
-
Source/JavaScriptCore/bytecode/StructureStubInfo.h (modified) (4 diffs)
-
Source/JavaScriptCore/dfg/DFGJITCompiler.h (modified) (1 diff)
-
Source/JavaScriptCore/dfg/DFGSlowPathGenerator.h (modified) (1 diff)
-
Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp (modified) (44 diffs)
-
Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h (modified) (5 diffs)
-
Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp (modified) (6 diffs)
-
Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp (modified) (12 diffs)
-
Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp (modified) (31 diffs)
-
Source/JavaScriptCore/ftl/FTLSlowPathCall.cpp (modified) (4 diffs)
-
Source/JavaScriptCore/ftl/FTLSlowPathCall.h (modified) (4 diffs)
-
Source/JavaScriptCore/ftl/FTLSlowPathCallKey.cpp (modified) (1 diff)
-
Source/JavaScriptCore/ftl/FTLSlowPathCallKey.h (modified) (6 diffs)
-
Source/JavaScriptCore/ftl/FTLThunks.cpp (modified) (3 diffs)
-
Source/JavaScriptCore/jit/AssemblyHelpers.cpp (modified) (2 diffs)
-
Source/JavaScriptCore/jit/CCallHelpers.cpp (modified) (1 diff)
-
Source/JavaScriptCore/jit/CCallHelpers.h (modified) (25 diffs)
-
Source/JavaScriptCore/jit/GCAwareJITStubRoutine.cpp (modified) (6 diffs)
-
Source/JavaScriptCore/jit/GCAwareJITStubRoutine.h (modified) (8 diffs)
-
Source/JavaScriptCore/jit/GPRInfo.h (modified) (2 diffs)
-
Source/JavaScriptCore/jit/JIT.cpp (modified) (3 diffs)
-
Source/JavaScriptCore/jit/JIT.h (modified) (9 diffs)
-
Source/JavaScriptCore/jit/JITCall.cpp (modified) (7 diffs)
-
Source/JavaScriptCore/jit/JITCall32_64.cpp (modified) (6 diffs)
-
Source/JavaScriptCore/jit/JITCode.h (modified) (2 diffs)
-
Source/JavaScriptCore/jit/JITInlineCacheGenerator.cpp (modified) (22 diffs)
-
Source/JavaScriptCore/jit/JITInlineCacheGenerator.h (modified) (13 diffs)
-
Source/JavaScriptCore/jit/JITInlines.h (modified) (4 diffs)
-
Source/JavaScriptCore/jit/JITOpcodes.cpp (modified) (6 diffs)
-
Source/JavaScriptCore/jit/JITOpcodes32_64.cpp (modified) (4 diffs)
-
Source/JavaScriptCore/jit/JITOperations.cpp (modified) (4 diffs)
-
Source/JavaScriptCore/jit/JITPropertyAccess.cpp (modified) (78 diffs)
-
Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp (modified) (18 diffs)
-
Source/JavaScriptCore/jit/JITStubRoutine.h (modified) (2 diffs)
-
Source/JavaScriptCore/jit/PolymorphicCallStubRoutine.cpp (modified) (3 diffs)
-
Source/JavaScriptCore/jit/Repatch.cpp (modified) (37 diffs)
-
Source/JavaScriptCore/jit/Repatch.h (modified) (1 diff)
-
Source/JavaScriptCore/runtime/Options.cpp (modified) (1 diff)
-
Source/JavaScriptCore/runtime/OptionsList.h (modified) (1 diff)
-
Source/JavaScriptCore/runtime/StructureIDTable.h (modified) (2 diffs)
-
Source/JavaScriptCore/runtime/VM.cpp (modified) (3 diffs)
-
Source/JavaScriptCore/runtime/VM.h (modified) (3 diffs)
-
Tools/ChangeLog (modified) (1 diff)
-
Tools/Scripts/run-jsc-stress-tests (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r278642 r278656 1 2021-06-08 Yusuke Suzuki <ysuzuki@apple.com> 2 3 [JSC] Use DataIC for AccessCase 4 https://bugs.webkit.org/show_bug.cgi?id=226072 5 6 Reviewed by Saam Barati and Filip Pizlo. 7 8 This patch adds non-repatching IC for Baseline JIT in ARM64. 9 This does not work in non-ARM64 architectures (including X64) due to the use of link-register. 10 11 1. We add non-repatching IC, which is enabled only in Baseline due to performance reason. We are using the 12 existing IC in DFG and FTL. Non-repatching includes fast-path, and slow-path's operation function. 13 2. We still keep InlineAccess in all tiers. Removing that causes 0.3 ~ 1.0% regression in Speedometer2. This 14 means that we still need some repatching when we first introduce stubs. 15 3. We add a mechanism to share generated code stubs in non-repatching IC. Currently, getter / setter / custom 16 accessors are excluded since their code relies on JSGlobalObject, CodeBlock etc. which are not included in 17 AccessCase's data structure. 18 4. This patch still relies on that CodeBlock will be destroyed synchronously since we need to ensure that sharing-hash-table 19 does not include already-dead JIT code stubs. We can fix it (e.g. annotating epoch to these stubs, bump them in 20 finalizeUnconditionally), but we avoid doing that to prevent from further enlarging this patch. This patch is already 21 significant in its size. 22 5. Added callOperation(Address) support in CCallHelpers, which can save the target in nonArgGPR0, and call it so that we can use 23 Address including GPR which is also used for arguments. 24 25 Performance is neutral in JetStream2 and Speedometer2. But it offers the way to remove some code generation in Baseline. 26 27 * assembler/MacroAssemblerARM64E.h: 28 (JSC::MacroAssemblerARM64E::call): 29 * bytecode/AccessCase.cpp: 30 (JSC::AccessCase::create): 31 (JSC::AccessCase::createTransition): 32 (JSC::AccessCase::createDelete): 33 (JSC::AccessCase::createCheckPrivateBrand): 34 (JSC::AccessCase::createSetPrivateBrand): 35 (JSC::AccessCase::fromStructureStubInfo): 36 (JSC::AccessCase::clone const): 37 (JSC::AccessCase::generateWithGuard): 38 (JSC::AccessCase::generateImpl): 39 (JSC::AccessCase::canBeShared): 40 * bytecode/AccessCase.h: 41 (JSC::AccessCase::hash const): 42 (JSC::AccessCase::AccessCase): 43 (JSC::SharedJITStubSet::Hash::Key::Key): 44 (JSC::SharedJITStubSet::Hash::Key::isHashTableDeletedValue const): 45 (JSC::SharedJITStubSet::Hash::Key::operator==): 46 (JSC::SharedJITStubSet::Hash::hash): 47 (JSC::SharedJITStubSet::Hash::equal): 48 (JSC::SharedJITStubSet::Searcher::Translator::hash): 49 (JSC::SharedJITStubSet::Searcher::Translator::equal): 50 (JSC::SharedJITStubSet::PointerTranslator::hash): 51 (JSC::SharedJITStubSet::PointerTranslator::equal): 52 (JSC::SharedJITStubSet::add): 53 (JSC::SharedJITStubSet::remove): 54 (JSC::SharedJITStubSet::find): 55 * bytecode/ByValInfo.h: 56 (JSC::ByValInfo::setUp): 57 (JSC::ByValInfo::offsetOfSlowOperation): 58 (JSC::ByValInfo::offsetOfNotIndexJumpTarget): 59 (JSC::ByValInfo::offsetOfBadTypeJumpTarget): 60 * bytecode/CallLinkInfo.cpp: 61 (JSC::CallLinkInfo::initializeDirectCall): 62 (JSC::CallLinkInfo::setDirectCallTarget): 63 * bytecode/CodeBlock.h: 64 (JSC::CodeBlock::useDataIC const): 65 * bytecode/GetterSetterAccessCase.cpp: 66 (JSC::GetterSetterAccessCase::create): 67 (JSC::GetterSetterAccessCase::clone const): 68 (JSC::GetterSetterAccessCase::emitDOMJITGetter): 69 * bytecode/GetterSetterAccessCase.h: 70 * bytecode/InlineAccess.cpp: 71 (JSC::getScratchRegister): 72 (JSC::InlineAccess::rewireStubAsJumpInAccessNotUsingInlineAccess): 73 (JSC::InlineAccess::rewireStubAsJumpInAccess): 74 (JSC::InlineAccess::resetStubAsJumpInAccess): 75 (JSC::InlineAccess::resetStubAsJumpInAccessNotUsingInlineAccess): 76 (JSC::InlineAccess::rewireStubAsJump): Deleted. 77 * bytecode/InlineAccess.h: 78 * bytecode/InstanceOfAccessCase.cpp: 79 (JSC::InstanceOfAccessCase::create): 80 (JSC::InstanceOfAccessCase::clone const): 81 * bytecode/InstanceOfAccessCase.h: 82 * bytecode/IntrinsicGetterAccessCase.cpp: 83 (JSC::IntrinsicGetterAccessCase::create): 84 (JSC::IntrinsicGetterAccessCase::clone const): 85 * bytecode/IntrinsicGetterAccessCase.h: 86 * bytecode/ModuleNamespaceAccessCase.cpp: 87 (JSC::ModuleNamespaceAccessCase::create): 88 (JSC::ModuleNamespaceAccessCase::clone const): 89 * bytecode/ModuleNamespaceAccessCase.h: 90 * bytecode/ObjectPropertyConditionSet.h: 91 (JSC::ObjectPropertyConditionSet::hash const): 92 (JSC::ObjectPropertyConditionSet::operator==): 93 (JSC::ObjectPropertyConditionSet::operator!=): 94 * bytecode/PolymorphicAccess.cpp: 95 (JSC::AccessGenerationState::installWatchpoint): 96 (JSC::AccessGenerationState::succeed): 97 (JSC::AccessGenerationState::preserveLiveRegistersToStackForCallWithoutExceptions): 98 (JSC::PolymorphicAccess::addCases): 99 (JSC::PolymorphicAccess::addCase): 100 (JSC::PolymorphicAccess::visitWeak const): 101 (JSC::PolymorphicAccess::regenerate): 102 * bytecode/PolymorphicAccess.h: 103 (JSC::AccessGenerationState::AccessGenerationState): 104 (JSC::AccessGenerationState::preserveLiveRegistersToStackForCallWithoutExceptions): 105 * bytecode/ProxyableAccessCase.cpp: 106 (JSC::ProxyableAccessCase::create): 107 (JSC::ProxyableAccessCase::clone const): 108 * bytecode/ProxyableAccessCase.h: 109 * bytecode/StructureStubInfo.cpp: 110 (JSC::StructureStubInfo::StructureStubInfo): 111 (JSC::StructureStubInfo::addAccessCase): 112 (JSC::StructureStubInfo::reset): 113 * bytecode/StructureStubInfo.h: 114 (JSC::StructureStubInfo::offsetOfCodePtr): 115 (JSC::StructureStubInfo::offsetOfSlowPathStartLocation): 116 (JSC::StructureStubInfo::offsetOfSlowOperation): 117 (JSC::StructureStubInfo::patchableJump): Deleted. 118 * dfg/DFGJITCompiler.h: 119 (JSC::DFG::JITCompiler::appendCall): 120 * dfg/DFGSlowPathGenerator.h: 121 (JSC::DFG::slowPathICCall): 122 * dfg/DFGSpeculativeJIT.cpp: 123 (JSC::DFG::SpeculativeJIT::compileGetById): 124 (JSC::DFG::SpeculativeJIT::compileGetByIdFlush): 125 (JSC::DFG::SpeculativeJIT::compileDeleteById): 126 (JSC::DFG::SpeculativeJIT::compileDeleteByVal): 127 (JSC::DFG::SpeculativeJIT::compileInById): 128 (JSC::DFG::SpeculativeJIT::compileInByVal): 129 (JSC::DFG::SpeculativeJIT::compileGetPrivateNameByVal): 130 (JSC::DFG::SpeculativeJIT::compileGetPrivateNameById): 131 (JSC::DFG::SpeculativeJIT::compilePutPrivateNameById): 132 (JSC::DFG::SpeculativeJIT::compileCheckPrivateBrand): 133 (JSC::DFG::SpeculativeJIT::compileSetPrivateBrand): 134 (JSC::DFG::SpeculativeJIT::compileInstanceOfForCells): 135 (JSC::DFG::SpeculativeJIT::compileInstanceOf): 136 (JSC::DFG::SpeculativeJIT::compilePutByIdFlush): 137 (JSC::DFG::SpeculativeJIT::compilePutById): 138 (JSC::DFG::SpeculativeJIT::compilePutByIdDirect): 139 (JSC::DFG::SpeculativeJIT::cachedPutById): 140 * dfg/DFGSpeculativeJIT.h: 141 (JSC::DFG::SpeculativeJIT::callOperation): 142 (JSC::DFG::SpeculativeJIT::appendCall): 143 (JSC::DFG::SpeculativeJIT::appendCallSetResult): 144 * dfg/DFGSpeculativeJIT32_64.cpp: 145 (JSC::DFG::SpeculativeJIT::cachedGetById): 146 (JSC::DFG::SpeculativeJIT::cachedGetByIdWithThis): 147 (JSC::DFG::SpeculativeJIT::compile): 148 * dfg/DFGSpeculativeJIT64.cpp: 149 (JSC::DFG::SpeculativeJIT::cachedGetById): 150 (JSC::DFG::SpeculativeJIT::cachedGetByIdWithThis): 151 (JSC::DFG::SpeculativeJIT::compile): 152 * ftl/FTLLowerDFGToB3.cpp: 153 (JSC::FTL::DFG::LowerDFGToB3::getPrivateName): 154 (JSC::FTL::DFG::LowerDFGToB3::compilePrivateBrandAccess): 155 (JSC::FTL::DFG::LowerDFGToB3::cachedPutById): 156 (JSC::FTL::DFG::LowerDFGToB3::compileGetByVal): 157 (JSC::FTL::DFG::LowerDFGToB3::compileDelBy): 158 (JSC::FTL::DFG::LowerDFGToB3::compileCompareStrictEq): 159 * ftl/FTLSlowPathCall.cpp: 160 (JSC::FTL::SlowPathCallContext::SlowPathCallContext): 161 (JSC::FTL::SlowPathCallContext::keyWithTarget const): 162 (JSC::FTL::SlowPathCallContext::makeCall): 163 * ftl/FTLSlowPathCall.h: 164 (JSC::FTL::callOperation): 165 * ftl/FTLSlowPathCallKey.cpp: 166 (JSC::FTL::SlowPathCallKey::dump const): 167 * ftl/FTLSlowPathCallKey.h: 168 (JSC::FTL::SlowPathCallKey::SlowPathCallKey): 169 (JSC::FTL::SlowPathCallKey::indirectOffset const): 170 (JSC::FTL::SlowPathCallKey::withCallTarget): 171 (JSC::FTL::SlowPathCallKey::operator== const): 172 (JSC::FTL::SlowPathCallKey::hash const): 173 * ftl/FTLThunks.cpp: 174 (JSC::FTL::genericGenerationThunkGenerator): 175 (JSC::FTL::slowPathCallThunkGenerator): 176 * jit/AssemblyHelpers.cpp: 177 (JSC::AssemblyHelpers::emitVirtualCall): 178 * jit/CCallHelpers.cpp: 179 (JSC::CCallHelpers::emitJITCodeOver): 180 * jit/CCallHelpers.h: 181 (JSC::CCallHelpers::ArgCollection::ArgCollection): 182 (JSC::CCallHelpers::ArgCollection::pushRegArg): 183 (JSC::CCallHelpers::ArgCollection::pushExtraRegArg): 184 (JSC::CCallHelpers::ArgCollection::pushNonArg): 185 (JSC::CCallHelpers::ArgCollection::addGPRArg): 186 (JSC::CCallHelpers::ArgCollection::addGPRExtraArg): 187 (JSC::CCallHelpers::ArgCollection::addStackArg): 188 (JSC::CCallHelpers::ArgCollection::addPoke): 189 (JSC::CCallHelpers::calculatePokeOffset): 190 (JSC::CCallHelpers::pokeForArgument): 191 (JSC::CCallHelpers::stackAligned): 192 (JSC::CCallHelpers::marshallArgumentRegister): 193 (JSC::CCallHelpers::setupArgumentsImpl): 194 (JSC::CCallHelpers::pokeArgumentsAligned): 195 (JSC::CCallHelpers::std::is_integral<CURRENT_ARGUMENT_TYPE>::value): 196 (JSC::CCallHelpers::std::is_pointer<CURRENT_ARGUMENT_TYPE>::value): 197 (JSC::CCallHelpers::setupArgumentsEntryImpl): 198 (JSC::CCallHelpers::setupArguments): 199 (JSC::CCallHelpers::setupArgumentsForIndirectCall): 200 * jit/GCAwareJITStubRoutine.cpp: 201 (JSC::GCAwareJITStubRoutine::GCAwareJITStubRoutine): 202 (JSC::GCAwareJITStubRoutine::makeGCAware): 203 (JSC::GCAwareJITStubRoutine::observeZeroRefCount): 204 (JSC::PolymorphicAccessJITStubRoutine::PolymorphicAccessJITStubRoutine): 205 (JSC::PolymorphicAccessJITStubRoutine::observeZeroRefCount): 206 (JSC::PolymorphicAccessJITStubRoutine::computeHash): 207 (JSC::MarkingGCAwareJITStubRoutine::MarkingGCAwareJITStubRoutine): 208 (JSC::GCAwareJITStubRoutineWithExceptionHandler::GCAwareJITStubRoutineWithExceptionHandler): 209 (JSC::createICJITStubRoutine): 210 (JSC::createJITStubRoutine): Deleted. 211 * jit/GCAwareJITStubRoutine.h: 212 (JSC::GCAwareJITStubRoutine::create): 213 (JSC::PolymorphicAccessJITStubRoutine::cases const): 214 (JSC::PolymorphicAccessJITStubRoutine::weakStructures const): 215 (JSC::PolymorphicAccessJITStubRoutine::hash const): 216 * jit/GPRInfo.h: 217 * jit/JIT.cpp: 218 (JSC::JIT::link): 219 * jit/JIT.h: 220 * jit/JITCall.cpp: 221 (JSC::JIT::emit_op_iterator_open): 222 (JSC::JIT::emitSlow_op_iterator_open): 223 (JSC::JIT::emit_op_iterator_next): 224 (JSC::JIT::emitSlow_op_iterator_next): 225 * jit/JITCall32_64.cpp: 226 (JSC::JIT::emit_op_iterator_open): 227 (JSC::JIT::emit_op_iterator_next): 228 * jit/JITCode.h: 229 (JSC::JITCode::useDataIC): 230 * jit/JITInlineCacheGenerator.cpp: 231 (JSC::JITInlineCacheGenerator::JITInlineCacheGenerator): 232 (JSC::JITInlineCacheGenerator::finalize): 233 (JSC::JITByIdGenerator::JITByIdGenerator): 234 (JSC::JITByIdGenerator::finalize): 235 (JSC::JITByIdGenerator::generateFastCommon): 236 (JSC::JITGetByIdGenerator::JITGetByIdGenerator): 237 (JSC::JITGetByIdWithThisGenerator::JITGetByIdWithThisGenerator): 238 (JSC::JITPutByIdGenerator::JITPutByIdGenerator): 239 (JSC::JITDelByValGenerator::JITDelByValGenerator): 240 (JSC::JITDelByValGenerator::generateFastPath): 241 (JSC::JITDelByValGenerator::finalize): 242 (JSC::JITDelByIdGenerator::JITDelByIdGenerator): 243 (JSC::JITDelByIdGenerator::generateFastPath): 244 (JSC::JITDelByIdGenerator::finalize): 245 (JSC::JITInByValGenerator::JITInByValGenerator): 246 (JSC::JITInByValGenerator::generateFastPath): 247 (JSC::JITInByValGenerator::finalize): 248 (JSC::JITInByIdGenerator::JITInByIdGenerator): 249 (JSC::JITInstanceOfGenerator::JITInstanceOfGenerator): 250 (JSC::JITInstanceOfGenerator::generateFastPath): 251 (JSC::JITInstanceOfGenerator::finalize): 252 (JSC::JITGetByValGenerator::JITGetByValGenerator): 253 (JSC::JITGetByValGenerator::generateFastPath): 254 (JSC::JITGetByValGenerator::finalize): 255 (JSC::JITPrivateBrandAccessGenerator::JITPrivateBrandAccessGenerator): 256 (JSC::JITPrivateBrandAccessGenerator::generateFastPath): 257 (JSC::JITPrivateBrandAccessGenerator::finalize): 258 * jit/JITInlineCacheGenerator.h: 259 (JSC::JITGetByIdGenerator::JITGetByIdGenerator): Deleted. 260 (JSC::JITGetByIdWithThisGenerator::JITGetByIdWithThisGenerator): Deleted. 261 (JSC::JITPutByIdGenerator::JITPutByIdGenerator): Deleted. 262 (JSC::JITDelByValGenerator::JITDelByValGenerator): Deleted. 263 (JSC::JITDelByValGenerator::slowPathJump const): Deleted. 264 (JSC::JITDelByIdGenerator::JITDelByIdGenerator): Deleted. 265 (JSC::JITDelByIdGenerator::slowPathJump const): Deleted. 266 (JSC::JITInByIdGenerator::JITInByIdGenerator): Deleted. 267 (JSC::JITInstanceOfGenerator::JITInstanceOfGenerator): Deleted. 268 (JSC::JITGetByValGenerator::JITGetByValGenerator): Deleted. 269 (JSC::JITGetByValGenerator::slowPathJump const): Deleted. 270 (JSC::JITPrivateBrandAccessGenerator::JITPrivateBrandAccessGenerator): Deleted. 271 (JSC::JITPrivateBrandAccessGenerator::slowPathJump const): Deleted. 272 * jit/JITInlines.h: 273 (JSC::JIT::emitLoadForArrayMode): 274 (JSC::JIT::appendCallWithExceptionCheck): 275 (JSC::JIT::appendCallWithExceptionCheckSetJSValueResult): 276 (JSC::JIT::appendCallWithExceptionCheckSetJSValueResultWithProfile): 277 * jit/JITOpcodes.cpp: 278 (JSC::JIT::emit_op_instanceof): 279 (JSC::JIT::emitSlow_op_instanceof): 280 (JSC::JIT::privateCompileHasIndexedProperty): 281 (JSC::JIT::emit_op_has_enumerable_indexed_property): 282 (JSC::JIT::emitSlow_op_has_enumerable_indexed_property): 283 * jit/JITOpcodes32_64.cpp: 284 (JSC::JIT::emit_op_instanceof): 285 (JSC::JIT::privateCompileHasIndexedProperty): 286 (JSC::JIT::emit_op_has_enumerable_indexed_property): 287 * jit/JITOperations.cpp: 288 (JSC::JSC_DEFINE_JIT_OPERATION): 289 * jit/JITPropertyAccess.cpp: 290 (JSC::JIT::emit_op_get_by_val): 291 (JSC::JIT::emitSlow_op_get_by_val): 292 (JSC::JIT::slow_op_get_by_val_prepareCallGenerator): 293 (JSC::JIT::emit_op_get_private_name): 294 (JSC::JIT::emitSlow_op_get_private_name): 295 (JSC::JIT::slow_op_get_private_name_prepareCallGenerator): 296 (JSC::JIT::emit_op_set_private_brand): 297 (JSC::JIT::emitSlow_op_set_private_brand): 298 (JSC::JIT::emit_op_check_private_brand): 299 (JSC::JIT::emitSlow_op_check_private_brand): 300 (JSC::JIT::emit_op_put_by_val): 301 (JSC::JIT::emitGenericContiguousPutByVal): 302 (JSC::JIT::emitArrayStoragePutByVal): 303 (JSC::JIT::emitPutByValWithCachedId): 304 (JSC::JIT::emitSlow_op_put_by_val): 305 (JSC::JIT::slow_op_put_by_val_prepareCallGenerator): 306 (JSC::JIT::emit_op_put_private_name): 307 (JSC::JIT::emitSlow_op_put_private_name): 308 (JSC::JIT::slow_op_put_private_name_prepareCallGenerator): 309 (JSC::JIT::emit_op_del_by_id): 310 (JSC::JIT::emitSlow_op_del_by_id): 311 (JSC::JIT::slow_op_del_by_id_prepareCallGenerator): 312 (JSC::JIT::emit_op_del_by_val): 313 (JSC::JIT::emitSlow_op_del_by_val): 314 (JSC::JIT::slow_op_del_by_val_prepareCallGenerator): 315 (JSC::JIT::emit_op_try_get_by_id): 316 (JSC::JIT::emitSlow_op_try_get_by_id): 317 (JSC::JIT::emit_op_get_by_id_direct): 318 (JSC::JIT::emitSlow_op_get_by_id_direct): 319 (JSC::JIT::emit_op_get_by_id): 320 (JSC::JIT::emit_op_get_by_id_with_this): 321 (JSC::JIT::emitSlow_op_get_by_id): 322 (JSC::JIT::slow_op_get_by_id_prepareCallGenerator): 323 (JSC::JIT::emitSlow_op_get_by_id_with_this): 324 (JSC::JIT::slow_op_get_by_id_with_this_prepareCallGenerator): 325 (JSC::JIT::emit_op_put_by_id): 326 (JSC::JIT::emitSlow_op_put_by_id): 327 (JSC::JIT::slow_op_put_by_id_prepareCallGenerator): 328 (JSC::JIT::emit_op_in_by_id): 329 (JSC::JIT::emitSlow_op_in_by_id): 330 (JSC::JIT::emit_op_in_by_val): 331 (JSC::JIT::emitSlow_op_in_by_val): 332 (JSC::JIT::privateCompilePutByVal): 333 (JSC::JIT::privateCompilePutPrivateNameWithCachedId): 334 (JSC::JIT::privateCompilePutByValWithCachedId): 335 (JSC::JIT::emitDoubleLoad): 336 (JSC::JIT::emitContiguousLoad): 337 (JSC::JIT::emitArrayStorageLoad): 338 (JSC::JIT::emitIntTypedArrayPutByVal): 339 (JSC::JIT::emitFloatTypedArrayPutByVal): 340 * jit/JITPropertyAccess32_64.cpp: 341 (JSC::JIT::emit_op_del_by_id): 342 (JSC::JIT::emit_op_del_by_val): 343 (JSC::JIT::emit_op_get_by_val): 344 (JSC::JIT::emit_op_get_private_name): 345 (JSC::JIT::emit_op_set_private_brand): 346 (JSC::JIT::emit_op_check_private_brand): 347 (JSC::JIT::emit_op_put_by_val): 348 (JSC::JIT::emitGenericContiguousPutByVal): 349 (JSC::JIT::emitArrayStoragePutByVal): 350 (JSC::JIT::emit_op_try_get_by_id): 351 (JSC::JIT::emit_op_get_by_id_direct): 352 (JSC::JIT::emit_op_get_by_id): 353 (JSC::JIT::emit_op_get_by_id_with_this): 354 (JSC::JIT::emit_op_put_by_id): 355 (JSC::JIT::emit_op_in_by_id): 356 (JSC::JIT::emit_op_in_by_val): 357 * jit/JITStubRoutine.h: 358 * jit/PolymorphicCallStubRoutine.cpp: 359 (JSC::PolymorphicCallStubRoutine::PolymorphicCallStubRoutine): 360 * jit/Repatch.cpp: 361 (JSC::readPutICCallTarget): 362 (JSC::repatchSlowPathCall): 363 (JSC::tryCacheGetBy): 364 (JSC::repatchGetBy): 365 (JSC::tryCacheArrayGetByVal): 366 (JSC::repatchArrayGetByVal): 367 (JSC::tryCachePutByID): 368 (JSC::repatchPutByID): 369 (JSC::tryCacheDeleteBy): 370 (JSC::repatchDeleteBy): 371 (JSC::tryCacheInBy): 372 (JSC::repatchInBy): 373 (JSC::tryCacheCheckPrivateBrand): 374 (JSC::repatchCheckPrivateBrand): 375 (JSC::tryCacheSetPrivateBrand): 376 (JSC::repatchSetPrivateBrand): 377 (JSC::tryCacheInstanceOf): 378 (JSC::repatchInstanceOf): 379 (JSC::linkSlowFor): 380 (JSC::linkVirtualFor): 381 (JSC::resetGetBy): 382 (JSC::resetPutByID): 383 (JSC::resetDelBy): 384 (JSC::resetInBy): 385 (JSC::resetInstanceOf): 386 (JSC::resetCheckPrivateBrand): 387 (JSC::resetSetPrivateBrand): 388 (JSC::resetPatchableJump): Deleted. 389 * jit/Repatch.h: 390 * runtime/Options.cpp: 391 (JSC::Options::recomputeDependentOptions): 392 * runtime/OptionsList.h: 393 * runtime/StructureIDTable.h: 394 * runtime/VM.cpp: 395 (JSC::VM::VM): 396 (JSC::VM::~VM): 397 * runtime/VM.h: 398 1 399 2021-06-08 Robin Morisset <rmorisset@apple.com> 2 400 -
trunk/Source/JavaScriptCore/assembler/MacroAssemblerARM64E.h
r278576 r278656 226 226 } 227 227 228 ALWAYS_INLINE Callcall(Address address, PtrTag tag)228 ALWAYS_INLINE void call(Address address, PtrTag tag) 229 229 { 230 230 ASSERT(tag != CFunctionPtrTag && tag != NoPtrTag); 231 231 ASSERT(!Options::useJITCage() || callerType(tag) == PtrTagCallerType::JIT); 232 232 load64(address, getCachedDataTempRegisterIDAndInvalidate()); 233 returncall(dataTempRegister, tag);234 } 235 236 ALWAYS_INLINE Callcall(Address address, RegisterID tag)233 call(dataTempRegister, tag); 234 } 235 236 ALWAYS_INLINE void call(Address address, RegisterID tag) 237 237 { 238 238 ASSERT(tag != dataTempRegister); 239 239 load64(address, getCachedDataTempRegisterIDAndInvalidate()); 240 returncall(dataTempRegister, tag);240 call(dataTempRegister, tag); 241 241 } 242 242 -
trunk/Source/JavaScriptCore/bytecode/AccessCase.cpp
r278253 r278656 69 69 } 70 70 71 std::unique_ptr<AccessCase> AccessCase::create(VM& vm, JSCell* owner, AccessType type, CacheableIdentifier identifier, PropertyOffset offset, Structure* structure, const ObjectPropertyConditionSet& conditionSet, RefPtr<PolyProtoAccessChain>&& prototypeAccessChain)71 Ref<AccessCase> AccessCase::create(VM& vm, JSCell* owner, AccessType type, CacheableIdentifier identifier, PropertyOffset offset, Structure* structure, const ObjectPropertyConditionSet& conditionSet, RefPtr<PolyProtoAccessChain>&& prototypeAccessChain) 72 72 { 73 73 switch (type) { … … 106 106 }; 107 107 108 return std::unique_ptr<AccessCase>(new AccessCase(vm, owner, type, identifier, offset, structure, conditionSet, WTFMove(prototypeAccessChain)));109 } 110 111 std::unique_ptr<AccessCase> AccessCase::createTransition(108 return adoptRef(*new AccessCase(vm, owner, type, identifier, offset, structure, conditionSet, WTFMove(prototypeAccessChain))); 109 } 110 111 RefPtr<AccessCase> AccessCase::createTransition( 112 112 VM& vm, JSCell* owner, CacheableIdentifier identifier, PropertyOffset offset, Structure* oldStructure, Structure* newStructure, 113 113 const ObjectPropertyConditionSet& conditionSet, RefPtr<PolyProtoAccessChain>&& prototypeAccessChain) … … 123 123 } 124 124 125 return std::unique_ptr<AccessCase>(new AccessCase(vm, owner, Transition, identifier, offset, newStructure, conditionSet, WTFMove(prototypeAccessChain)));126 } 127 128 std::unique_ptr<AccessCase> AccessCase::createDelete(125 return adoptRef(*new AccessCase(vm, owner, Transition, identifier, offset, newStructure, conditionSet, WTFMove(prototypeAccessChain))); 126 } 127 128 Ref<AccessCase> AccessCase::createDelete( 129 129 VM& vm, JSCell* owner, CacheableIdentifier identifier, PropertyOffset offset, Structure* oldStructure, Structure* newStructure) 130 130 { 131 131 RELEASE_ASSERT(oldStructure == newStructure->previousID()); 132 132 ASSERT(!newStructure->outOfLineCapacity() || oldStructure->outOfLineCapacity()); 133 return std::unique_ptr<AccessCase>(new AccessCase(vm, owner, Delete, identifier, offset, newStructure, { }, { }));134 } 135 136 std::unique_ptr<AccessCase> AccessCase::createCheckPrivateBrand(VM& vm, JSCell* owner, CacheableIdentifier identifier, Structure* structure)137 { 138 return std::unique_ptr<AccessCase>(new AccessCase(vm, owner, CheckPrivateBrand, identifier, invalidOffset, structure, { }, { }));139 } 140 141 std::unique_ptr<AccessCase> AccessCase::createSetPrivateBrand(133 return adoptRef(*new AccessCase(vm, owner, Delete, identifier, offset, newStructure, { }, { })); 134 } 135 136 Ref<AccessCase> AccessCase::createCheckPrivateBrand(VM& vm, JSCell* owner, CacheableIdentifier identifier, Structure* structure) 137 { 138 return adoptRef(*new AccessCase(vm, owner, CheckPrivateBrand, identifier, invalidOffset, structure, { }, { })); 139 } 140 141 Ref<AccessCase> AccessCase::createSetPrivateBrand( 142 142 VM& vm, JSCell* owner, CacheableIdentifier identifier, Structure* oldStructure, Structure* newStructure) 143 143 { 144 144 RELEASE_ASSERT(oldStructure == newStructure->previousID()); 145 return std::unique_ptr<AccessCase>(new AccessCase(vm, owner, SetPrivateBrand, identifier, invalidOffset, newStructure, { }, { }));145 return adoptRef(*new AccessCase(vm, owner, SetPrivateBrand, identifier, invalidOffset, newStructure, { }, { })); 146 146 } 147 147 … … 150 150 } 151 151 152 std::unique_ptr<AccessCase> AccessCase::fromStructureStubInfo(152 RefPtr<AccessCase> AccessCase::fromStructureStubInfo( 153 153 VM& vm, JSCell* owner, CacheableIdentifier identifier, StructureStubInfo& stubInfo) 154 154 { … … 189 189 } 190 190 191 std::unique_ptr<AccessCase> AccessCase::clone() const192 { 193 std::unique_ptr<AccessCase> result(new AccessCase(*this));191 Ref<AccessCase> AccessCase::clone() const 192 { 193 auto result = adoptRef(*new AccessCase(*this)); 194 194 result->resetState(); 195 195 return result; … … 808 808 m_state = Generated; 809 809 810 JSGlobalObject* globalObject = state.m_globalObject; 810 811 CCallHelpers& jit = *state.jit; 811 812 StructureStubInfo& stubInfo = *state.stubInfo; … … 854 855 } else { 855 856 if (structure->hasMonoProto()) { 856 JSValue prototype = structure->prototypeForLookup( state.m_globalObject);857 JSValue prototype = structure->prototypeForLookup(globalObject); 857 858 RELEASE_ASSERT(prototype.isObject()); 858 859 jit.move(CCallHelpers::TrustedImmPtr(asObject(prototype)), baseForAccessGPR); … … 965 966 allocator.lock(valueRegs); 966 967 allocator.lock(stubInfo.propertyRegs()); 968 if (stubInfo.m_stubInfoGPR != InvalidGPRReg) 969 allocator.lock(stubInfo.m_stubInfoGPR); 967 970 allocator.lock(scratchGPR); 968 971 … … 1062 1065 allocator.lock(valueRegs); 1063 1066 allocator.lock(stubInfo.propertyRegs()); 1067 if (stubInfo.m_stubInfoGPR != InvalidGPRReg) 1068 allocator.lock(stubInfo.m_stubInfoGPR); 1064 1069 allocator.lock(scratchGPR); 1065 1070 GPRReg scratch2GPR = allocator.allocateScratchGPR(); … … 1145 1150 allocator.lock(valueRegs); 1146 1151 allocator.lock(stubInfo.propertyRegs()); 1152 if (stubInfo.m_stubInfoGPR != InvalidGPRReg) 1153 allocator.lock(stubInfo.m_stubInfoGPR); 1147 1154 allocator.lock(scratchGPR); 1148 1155 GPRReg scratch2GPR = allocator.allocateScratchGPR(); … … 1206 1213 allocator.lock(valueRegs); 1207 1214 allocator.lock(stubInfo.propertyRegs()); 1215 if (stubInfo.m_stubInfoGPR != InvalidGPRReg) 1216 allocator.lock(stubInfo.m_stubInfoGPR); 1208 1217 allocator.lock(scratchGPR); 1209 1218 GPRReg scratch2GPR = allocator.allocateScratchGPR(); … … 1318 1327 allocator.lock(valueRegs); 1319 1328 allocator.lock(stubInfo.propertyRegs()); 1329 if (stubInfo.m_stubInfoGPR != InvalidGPRReg) 1330 allocator.lock(stubInfo.m_stubInfoGPR); 1320 1331 allocator.lock(scratchGPR); 1321 1332 … … 1418 1429 1419 1430 if (condition.isWatchableAssumingImpurePropertyWatchpoint(PropertyCondition::WatchabilityEffort::EnsureWatchability)) { 1420 state.installWatchpoint(co ndition);1431 state.installWatchpoint(codeBlock, condition); 1421 1432 continue; 1422 1433 } … … 1436 1447 // We will emit code that has a weak reference that isn't otherwise listed anywhere. 1437 1448 Structure* structure = condition.object()->structure(vm); 1438 state.weak References.append(WriteBarrier<JSCell>(vm, codeBlock, structure));1449 state.weakStructures.append(structure->id()); 1439 1450 1440 1451 jit.move(CCallHelpers::TrustedImmPtr(condition.object()), scratchGPR); … … 1583 1594 // This also does the necessary calculations of whether or not we're an 1584 1595 // exception handling call site. 1585 AccessGenerationState::SpillState spillState = state.preserveLiveRegistersToStackForCall(); 1596 RegisterSet extraRegistersToPreserve; 1597 #if CPU(ARM64) 1598 if (codeBlock->useDataIC()) 1599 extraRegistersToPreserve.set(ARM64Registers::lr); 1600 #endif 1601 AccessGenerationState::SpillState spillState = state.preserveLiveRegistersToStackForCall(extraRegistersToPreserve); 1586 1602 1587 1603 auto restoreLiveRegistersFromStackForCall = [&](AccessGenerationState::SpillState& spillState, bool callHasReturnValue) { … … 1713 1729 jit.move(CCallHelpers::TrustedImmPtr(globalObject), GPRInfo::regT3); 1714 1730 access.callLinkInfo()->emitSlowPath(vm, jit); 1731 1715 1732 if (m_type == Getter) 1716 1733 jit.setupResults(valueRegs); … … 1724 1741 done.link(&jit); 1725 1742 1726 jit.addPtr(CCallHelpers::TrustedImm32((codeBlock->stackPointerOffset() * sizeof(Register)) - state.preservedReusedRegisterState.numberOfBytesPreserved - spillState.numberOfStackBytesUsedForRegisterPreservation),1727 GPRInfo::callFrameRegister, CCallHelpers::stackPointerRegister);1743 int stackPointerOffset = (codeBlock->stackPointerOffset() * sizeof(Register)) - state.preservedReusedRegisterState.numberOfBytesPreserved - spillState.numberOfStackBytesUsedForRegisterPreservation; 1744 jit.addPtr(CCallHelpers::TrustedImm32(stackPointerOffset), GPRInfo::callFrameRegister, CCallHelpers::stackPointerRegister); 1728 1745 bool callHasReturnValue = isGetter(); 1729 1746 restoreLiveRegistersFromStackForCall(spillState, callHasReturnValue); … … 1846 1863 1847 1864 jit.loadPtr(CCallHelpers::Address(baseGPR, JSProxy::targetOffset()), scratchGPR); 1848 auto spillState = state.preserveLiveRegistersToStackForCallWithoutExceptions(); 1865 1866 RegisterSet extraRegistersToPreserve; 1867 #if CPU(ARM64) 1868 if (codeBlock->useDataIC()) 1869 extraRegistersToPreserve.set(ARM64Registers::lr); 1870 #endif 1871 auto spillState = state.preserveLiveRegistersToStackForCallWithoutExceptions(extraRegistersToPreserve); 1872 1849 1873 jit.setupArguments<decltype(operationWriteBarrierSlowPath)>(CCallHelpers::TrustedImmPtr(&vm), scratchGPR); 1850 1874 jit.prepareCallOperation(vm); … … 1876 1900 allocator.lock(stubInfo.baseRegs()); 1877 1901 allocator.lock(valueRegs); 1902 if (stubInfo.m_stubInfoGPR != InvalidGPRReg) 1903 allocator.lock(stubInfo.m_stubInfoGPR); 1878 1904 allocator.lock(scratchGPR); 1879 1905 … … 1934 1960 extraRegistersToPreserve.set(baseGPR); 1935 1961 extraRegistersToPreserve.set(valueRegs); 1962 #if CPU(ARM64) 1963 if (codeBlock->useDataIC()) 1964 extraRegistersToPreserve.set(ARM64Registers::lr); 1965 #endif 1936 1966 AccessGenerationState::SpillState spillState = state.preserveLiveRegistersToStackForCall(extraRegistersToPreserve); 1937 1967 … … 2032 2062 allocator.lock(valueRegs); 2033 2063 allocator.lock(baseGPR); 2064 if (stubInfo.m_stubInfoGPR != InvalidGPRReg) 2065 allocator.lock(stubInfo.m_stubInfoGPR); 2034 2066 allocator.lock(scratchGPR); 2035 2067 ASSERT(structure()->transitionWatchpointSetHasBeenInvalidated()); … … 2204 2236 #endif // ASSERT_ENABLED 2205 2237 2238 bool AccessCase::canBeShared(const AccessCase& lhs, const AccessCase& rhs) 2239 { 2240 // We do not care m_state. 2241 // And we say "false" if either of them have m_polyProtoAccessChain. 2242 if (lhs.m_polyProtoAccessChain || rhs.m_polyProtoAccessChain) 2243 return false; 2244 if (lhs.additionalSet() || rhs.additionalSet()) 2245 return false; 2246 2247 if (lhs.m_type != rhs.m_type) 2248 return false; 2249 if (lhs.m_offset != rhs.m_offset) 2250 return false; 2251 if (lhs.m_viaProxy != rhs.m_viaProxy) 2252 return false; 2253 if (lhs.m_structure.get() != rhs.m_structure.get()) 2254 return false; 2255 if (lhs.m_identifier != rhs.m_identifier) 2256 return false; 2257 if (lhs.m_conditionSet != rhs.m_conditionSet) 2258 return false; 2259 2260 switch (lhs.m_type) { 2261 case Load: 2262 case Transition: 2263 case Delete: 2264 case DeleteNonConfigurable: 2265 case DeleteMiss: 2266 case Replace: 2267 case Miss: 2268 case GetGetter: 2269 case InHit: 2270 case InMiss: 2271 case ArrayLength: 2272 case StringLength: 2273 case DirectArgumentsLength: 2274 case ScopedArgumentsLength: 2275 case CheckPrivateBrand: 2276 case SetPrivateBrand: 2277 case IndexedInt32Load: 2278 case IndexedDoubleLoad: 2279 case IndexedContiguousLoad: 2280 case IndexedArrayStorageLoad: 2281 case IndexedScopedArgumentsLoad: 2282 case IndexedDirectArgumentsLoad: 2283 case IndexedTypedArrayInt8Load: 2284 case IndexedTypedArrayUint8Load: 2285 case IndexedTypedArrayUint8ClampedLoad: 2286 case IndexedTypedArrayInt16Load: 2287 case IndexedTypedArrayUint16Load: 2288 case IndexedTypedArrayInt32Load: 2289 case IndexedTypedArrayUint32Load: 2290 case IndexedTypedArrayFloat32Load: 2291 case IndexedTypedArrayFloat64Load: 2292 case IndexedStringLoad: 2293 case InstanceOfGeneric: 2294 return true; 2295 2296 case Getter: 2297 case Setter: { 2298 // Getter and Setter relies on CodeBlock, which makes sharing impossible. 2299 return false; 2300 } 2301 2302 case CustomValueGetter: 2303 case CustomAccessorGetter: 2304 case CustomValueSetter: 2305 case CustomAccessorSetter: { 2306 // They are embedding JSGlobalObject that are not tied to sharing JITStubRoutine. 2307 return false; 2308 } 2309 2310 case IntrinsicGetter: { 2311 auto& lhsd = lhs.as<IntrinsicGetterAccessCase>(); 2312 auto& rhsd = rhs.as<IntrinsicGetterAccessCase>(); 2313 return lhsd.m_intrinsicFunction == rhsd.m_intrinsicFunction; 2314 } 2315 2316 case ModuleNamespaceLoad: { 2317 auto& lhsd = lhs.as<ModuleNamespaceAccessCase>(); 2318 auto& rhsd = rhs.as<ModuleNamespaceAccessCase>(); 2319 return lhsd.m_moduleNamespaceObject == rhsd.m_moduleNamespaceObject 2320 && lhsd.m_moduleEnvironment == rhsd.m_moduleEnvironment 2321 && lhsd.m_scopeOffset == rhsd.m_scopeOffset; 2322 } 2323 2324 case InstanceOfHit: 2325 case InstanceOfMiss: { 2326 auto& lhsd = lhs.as<InstanceOfAccessCase>(); 2327 auto& rhsd = rhs.as<InstanceOfAccessCase>(); 2328 return lhsd.m_prototype == rhsd.m_prototype; 2329 } 2330 } 2331 2332 return true; 2333 } 2334 2206 2335 } // namespace JSC 2207 2336 -
trunk/Source/JavaScriptCore/bytecode/AccessCase.h
r275490 r278656 29 29 30 30 #include "CacheableIdentifier.h" 31 #include "GCAwareJITStubRoutine.h" 32 #include "JITStubRoutine.h" 31 33 #include "JSFunctionInlines.h" 32 34 #include "ObjectPropertyConditionSet.h" 33 35 #include "PolyProtoAccessChain.h" 34 36 #include <wtf/CommaPrinter.h> 37 #include <wtf/VectorHash.h> 35 38 36 39 namespace JSC { … … 80 83 // code. This allows us to only regenerate once we've accumulated (hopefully) more than one new 81 84 // AccessCase. 82 class AccessCase {85 class AccessCase : public ThreadSafeRefCounted<AccessCase> { 83 86 WTF_MAKE_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER(AccessCase); 84 87 public: … … 148 151 } 149 152 150 static std::unique_ptr<AccessCase> create(VM&, JSCell* owner, AccessType, CacheableIdentifier, PropertyOffset = invalidOffset,153 static Ref<AccessCase> create(VM&, JSCell* owner, AccessType, CacheableIdentifier, PropertyOffset = invalidOffset, 151 154 Structure* = nullptr, const ObjectPropertyConditionSet& = ObjectPropertyConditionSet(), RefPtr<PolyProtoAccessChain>&& = nullptr); 152 155 153 static std::unique_ptr<AccessCase> createTransition(VM&, JSCell* owner, CacheableIdentifier, PropertyOffset, Structure* oldStructure,156 static RefPtr<AccessCase> createTransition(VM&, JSCell* owner, CacheableIdentifier, PropertyOffset, Structure* oldStructure, 154 157 Structure* newStructure, const ObjectPropertyConditionSet&, RefPtr<PolyProtoAccessChain>&&); 155 158 156 static std::unique_ptr<AccessCase> createDelete(VM&, JSCell* owner, CacheableIdentifier, PropertyOffset, Structure* oldStructure,159 static Ref<AccessCase> createDelete(VM&, JSCell* owner, CacheableIdentifier, PropertyOffset, Structure* oldStructure, 157 160 Structure* newStructure); 158 161 159 static std::unique_ptr<AccessCase> createCheckPrivateBrand(VM&, JSCell* owner, CacheableIdentifier, Structure*);160 static std::unique_ptr<AccessCase> createSetPrivateBrand(VM&, JSCell* owner, CacheableIdentifier, Structure* oldStructure, Structure* newStructure);162 static Ref<AccessCase> createCheckPrivateBrand(VM&, JSCell* owner, CacheableIdentifier, Structure*); 163 static Ref<AccessCase> createSetPrivateBrand(VM&, JSCell* owner, CacheableIdentifier, Structure* oldStructure, Structure* newStructure); 161 164 162 static std::unique_ptr<AccessCase> fromStructureStubInfo(VM&, JSCell* owner, CacheableIdentifier, StructureStubInfo&);165 static RefPtr<AccessCase> fromStructureStubInfo(VM&, JSCell* owner, CacheableIdentifier, StructureStubInfo&); 163 166 164 167 AccessType type() const { return m_type; } … … 254 257 ALWAYS_INLINE void checkConsistency(StructureStubInfo&) { } 255 258 #endif 256 259 260 unsigned hash() const 261 { 262 return computeHash(m_conditionSet.hash(), static_cast<unsigned>(m_type), m_viaProxy, m_structure.unvalidatedGet(), m_offset); 263 } 264 265 static bool canBeShared(const AccessCase&, const AccessCase&); 266 257 267 protected: 258 268 AccessCase(VM&, JSCell* owner, AccessType, CacheableIdentifier, PropertyOffset, Structure*, const ObjectPropertyConditionSet&, RefPtr<PolyProtoAccessChain>&&); 259 AccessCase(AccessCase&&) = default; 260 AccessCase(const AccessCase& other) = default; 269 AccessCase(AccessCase&& other) 270 : m_type(WTFMove(other.m_type)) 271 , m_state(WTFMove(other.m_state)) 272 , m_viaProxy(WTFMove(other.m_viaProxy)) 273 , m_offset(WTFMove(other.m_offset)) 274 , m_structure(WTFMove(other.m_structure)) 275 , m_conditionSet(WTFMove(other.m_conditionSet)) 276 , m_polyProtoAccessChain(WTFMove(other.m_polyProtoAccessChain)) 277 , m_identifier(WTFMove(other.m_identifier)) 278 { } 279 280 AccessCase(const AccessCase& other) 281 : m_type(other.m_type) 282 , m_state(other.m_state) 283 , m_viaProxy(other.m_viaProxy) 284 , m_offset(other.m_offset) 285 , m_structure(other.m_structure) 286 , m_conditionSet(other.m_conditionSet) 287 , m_polyProtoAccessChain(other.m_polyProtoAccessChain) 288 , m_identifier(other.m_identifier) 289 { } 261 290 262 291 AccessCase& operator=(const AccessCase&) = delete; … … 276 305 // FIXME: This only exists because of how AccessCase puts post-generation things into itself. 277 306 // https://bugs.webkit.org/show_bug.cgi?id=156456 278 virtual std::unique_ptr<AccessCase> clone() const;307 virtual Ref<AccessCase> clone() const; 279 308 280 309 // Perform any action that must be performed before the end of the epoch in which the case … … 316 345 }; 317 346 347 class SharedJITStubSet { 348 WTF_MAKE_FAST_ALLOCATED(SharedJITStubSet); 349 public: 350 SharedJITStubSet() = default; 351 352 struct Hash { 353 struct Key { 354 Key() = default; 355 356 Key(GPRReg baseGPR, GPRReg valueGPR, GPRReg extraGPR, GPRReg stubInfoGPR, RegisterSet usedRegisters, PolymorphicAccessJITStubRoutine* wrapped) 357 : m_wrapped(wrapped) 358 , m_baseGPR(baseGPR) 359 , m_valueGPR(valueGPR) 360 , m_extraGPR(extraGPR) 361 , m_stubInfoGPR(stubInfoGPR) 362 , m_usedRegisters(usedRegisters) 363 { } 364 365 Key(WTF::HashTableDeletedValueType) 366 : m_wrapped(bitwise_cast<PolymorphicAccessJITStubRoutine*>(static_cast<uintptr_t>(1))) 367 { } 368 369 bool isHashTableDeletedValue() const { return m_wrapped == bitwise_cast<PolymorphicAccessJITStubRoutine*>(static_cast<uintptr_t>(1)); } 370 371 friend bool operator==(const Key& a, const Key& b) 372 { 373 return a.m_wrapped == b.m_wrapped 374 && a.m_baseGPR == b.m_baseGPR 375 && a.m_valueGPR == b.m_valueGPR 376 && a.m_extraGPR == b.m_extraGPR 377 && a.m_stubInfoGPR == b.m_stubInfoGPR 378 && a.m_usedRegisters == b.m_usedRegisters; 379 } 380 381 PolymorphicAccessJITStubRoutine* m_wrapped { nullptr }; 382 GPRReg m_baseGPR; 383 GPRReg m_valueGPR; 384 GPRReg m_extraGPR; 385 GPRReg m_stubInfoGPR; 386 RegisterSet m_usedRegisters; 387 }; 388 389 using KeyTraits = SimpleClassHashTraits<Key>; 390 391 static unsigned hash(const Key& p) 392 { 393 if (!p.m_wrapped) 394 return 1; 395 return p.m_wrapped->hash(); 396 } 397 398 static bool equal(const Key& a, const Key& b) 399 { 400 return a == b; 401 } 402 403 static constexpr bool safeToCompareToEmptyOrDeleted = false; 404 }; 405 406 struct Searcher { 407 struct Translator { 408 static unsigned hash(const Searcher& searcher) 409 { 410 return PolymorphicAccessJITStubRoutine::computeHash(searcher.m_cases, searcher.m_weakStructures); 411 } 412 413 static bool equal(const Hash::Key a, const Searcher& b) 414 { 415 if (a.m_baseGPR == b.m_baseGPR 416 && a.m_valueGPR == b.m_valueGPR 417 && a.m_extraGPR == b.m_extraGPR 418 && a.m_stubInfoGPR == b.m_stubInfoGPR 419 && a.m_usedRegisters == b.m_usedRegisters) { 420 // FIXME: The ordering of cases does not matter for sharing capabilities. 421 // We can potentially increase success rate by making this comparison / hashing non ordering sensitive. 422 const auto& aCases = a.m_wrapped->cases(); 423 const auto& bCases = b.m_cases; 424 if (aCases.size() != bCases.size()) 425 return false; 426 for (unsigned index = 0; index < bCases.size(); ++index) { 427 if (!AccessCase::canBeShared(*aCases[index], *bCases[index])) 428 return false; 429 } 430 const auto& aWeak = a.m_wrapped->weakStructures(); 431 const auto& bWeak = b.m_weakStructures; 432 if (aWeak.size() != bWeak.size()) 433 return false; 434 for (unsigned i = 0, size = aWeak.size(); i < size; ++i) { 435 if (aWeak[i] != bWeak[i]) 436 return false; 437 } 438 return true; 439 } 440 return false; 441 } 442 }; 443 444 GPRReg m_baseGPR; 445 GPRReg m_valueGPR; 446 GPRReg m_extraGPR; 447 GPRReg m_stubInfoGPR; 448 RegisterSet m_usedRegisters; 449 const FixedVector<RefPtr<AccessCase>>& m_cases; 450 const FixedVector<StructureID>& m_weakStructures; 451 }; 452 453 struct PointerTranslator { 454 static unsigned hash(PolymorphicAccessJITStubRoutine* stub) 455 { 456 return stub->hash(); 457 } 458 459 static bool equal(const Hash::Key& key, PolymorphicAccessJITStubRoutine* stub) 460 { 461 return key.m_wrapped == stub; 462 } 463 }; 464 465 void add(Hash::Key&& key) 466 { 467 m_stubs.add(WTFMove(key)); 468 } 469 470 void remove(PolymorphicAccessJITStubRoutine* stub) 471 { 472 auto iter = m_stubs.find<PointerTranslator>(stub); 473 if (iter != m_stubs.end()) 474 m_stubs.remove(iter); 475 } 476 477 PolymorphicAccessJITStubRoutine* find(const Searcher& searcher) 478 { 479 auto entry = m_stubs.find<SharedJITStubSet::Searcher::Translator>(searcher); 480 if (entry != m_stubs.end()) 481 return entry->m_wrapped; 482 return nullptr; 483 } 484 485 private: 486 HashSet<Hash::Key, Hash, Hash::KeyTraits> m_stubs; 487 }; 488 318 489 } // namespace JSC 319 490 -
trunk/Source/JavaScriptCore/bytecode/ByValInfo.h
r273138 r278656 245 245 } 246 246 247 void setUp(CodeLocation Jump<JSInternalPtrTag> notIndexJump, CodeLocationJump<JSInternalPtrTag> badTypeJump, CodeLocationLabel<ExceptionHandlerPtrTag> exceptionHandler, JITArrayMode arrayMode, ArrayProfile* arrayProfile, CodeLocationLabel<JSInternalPtrTag> doneTarget, CodeLocationLabel<JSInternalPtrTag> badTypeNextHotPathTarget, CodeLocationLabel<JSInternalPtrTag> slowPathTarget)247 void setUp(CodeLocationLabel<ExceptionHandlerPtrTag> exceptionHandler, JITArrayMode arrayMode, ArrayProfile* arrayProfile, CodeLocationLabel<JSInternalPtrTag> doneTarget, CodeLocationLabel<JSInternalPtrTag> badTypeNextHotPathTarget, CodeLocationLabel<JSInternalPtrTag> slowPathTarget) 248 248 { 249 this->notIndexJump = notIndexJump;250 this->badTypeJump = badTypeJump;251 249 this->exceptionHandler = exceptionHandler; 252 250 this->doneTarget = doneTarget; … … 263 261 DECLARE_VISIT_AGGREGATE; 264 262 265 CodeLocationJump<JSInternalPtrTag> notIndexJump; 266 CodeLocationJump<JSInternalPtrTag> badTypeJump; 263 static ptrdiff_t offsetOfSlowOperation() { return OBJECT_OFFSETOF(ByValInfo, m_slowOperation); } 264 static ptrdiff_t offsetOfNotIndexJumpTarget() { return OBJECT_OFFSETOF(ByValInfo, m_notIndexJumpTarget); } 265 static ptrdiff_t offsetOfBadTypeJumpTarget() { return OBJECT_OFFSETOF(ByValInfo, m_badTypeJumpTarget); } 266 267 FunctionPtr<OperationPtrTag> m_slowOperation; 268 269 union { 270 CodeLocationLabel<JITStubRoutinePtrTag> m_notIndexJumpTarget; 271 CodeLocationJump<JSInternalPtrTag> m_notIndexJump; 272 }; 273 union { 274 CodeLocationLabel<JITStubRoutinePtrTag> m_badTypeJumpTarget; 275 CodeLocationJump<JSInternalPtrTag> m_badTypeJump; 276 }; 277 267 278 CodeLocationLabel<ExceptionHandlerPtrTag> exceptionHandler; 268 279 CodeLocationLabel<JSInternalPtrTag> doneTarget; -
trunk/Source/JavaScriptCore/bytecode/CallLinkInfo.cpp
r277838 r278656 421 421 if (isTailCall()) { 422 422 RELEASE_ASSERT(fastPathStart()); 423 CCallHelpers::emitJITCodeOver(fastPathStart(), [&](CCallHelpers& jit) {423 CCallHelpers::emitJITCodeOver(fastPathStart(), scopedLambda<void(CCallHelpers&)>([&](CCallHelpers& jit) { 424 424 auto jump = jit.jump(); 425 425 jit.addLinkTask([=] (LinkBuffer& linkBuffer) { 426 426 linkBuffer.link(jump, slowPathStart()); 427 427 }); 428 } , "initialize direct call");428 }), "initialize direct call"); 429 429 } else 430 430 MacroAssembler::repatchNearCall(u.codeIC.m_callLocation, slowPathStart()); … … 437 437 if (isTailCall()) { 438 438 RELEASE_ASSERT(fastPathStart()); 439 CCallHelpers::emitJITCodeOver(fastPathStart(), [&](CCallHelpers& jit) {439 CCallHelpers::emitJITCodeOver(fastPathStart(), scopedLambda<void(CCallHelpers&)>([&](CCallHelpers& jit) { 440 440 // We reserved this many bytes for the jump at fastPathStart(). Make that 441 441 // code nops now so we fall through to the jump to the fast path. 442 jit.emitNops(CCallHelpers::patchableJumpSize()); 443 } , "Setting direct call target");442 jit.emitNops(CCallHelpers::patchableJumpSize()); 443 }), "Setting direct call target"); 444 444 } 445 445 -
trunk/Source/JavaScriptCore/bytecode/CodeBlock.h
r278576 r278656 424 424 return jitType() == JITType::BaselineJIT; 425 425 } 426 427 bool useDataIC() const 428 { 429 return JITCode::useDataIC(jitType()); 430 } 426 431 427 432 #if ENABLE(JIT) -
trunk/Source/JavaScriptCore/bytecode/GetterSetterAccessCase.cpp
r278253 r278656 48 48 } 49 49 50 std::unique_ptr<AccessCase> GetterSetterAccessCase::create(50 Ref<AccessCase> GetterSetterAccessCase::create( 51 51 VM& vm, JSCell* owner, AccessType type, CacheableIdentifier identifier, PropertyOffset offset, Structure* structure, const ObjectPropertyConditionSet& conditionSet, 52 52 bool viaProxy, WatchpointSet* additionalSet, FunctionPtr<CustomAccessorPtrTag> customGetter, JSObject* customSlotBase, … … 62 62 }; 63 63 64 std::unique_ptr<GetterSetterAccessCase> result(new GetterSetterAccessCase(vm, owner, type, identifier, offset, structure, conditionSet, viaProxy, additionalSet, customSlotBase, WTFMove(prototypeAccessChain)));64 auto result = adoptRef(*new GetterSetterAccessCase(vm, owner, type, identifier, offset, structure, conditionSet, viaProxy, additionalSet, customSlotBase, WTFMove(prototypeAccessChain))); 65 65 result->m_domAttribute = domAttribute; 66 66 result->m_customAccessor = customGetter ? FunctionPtr<CustomAccessorPtrTag>(customGetter) : nullptr; … … 68 68 } 69 69 70 std::unique_ptr<AccessCase> GetterSetterAccessCase::create(VM& vm, JSCell* owner, AccessType type, Structure* structure, CacheableIdentifier identifier, PropertyOffset offset,70 Ref<AccessCase> GetterSetterAccessCase::create(VM& vm, JSCell* owner, AccessType type, Structure* structure, CacheableIdentifier identifier, PropertyOffset offset, 71 71 const ObjectPropertyConditionSet& conditionSet, RefPtr<PolyProtoAccessChain>&& prototypeAccessChain, bool viaProxy, 72 72 FunctionPtr<CustomAccessorPtrTag> customSetter, JSObject* customSlotBase) 73 73 { 74 74 ASSERT(type == Setter || type == CustomValueSetter || type == CustomAccessorSetter); 75 std::unique_ptr<GetterSetterAccessCase> result(new GetterSetterAccessCase(vm, owner, type, identifier, offset, structure, conditionSet, viaProxy, nullptr, customSlotBase, WTFMove(prototypeAccessChain)));75 auto result = adoptRef(*new GetterSetterAccessCase(vm, owner, type, identifier, offset, structure, conditionSet, viaProxy, nullptr, customSlotBase, WTFMove(prototypeAccessChain))); 76 76 result->m_customAccessor = customSetter ? FunctionPtr<CustomAccessorPtrTag>(customSetter) : nullptr; 77 77 return result; … … 92 92 } 93 93 94 std::unique_ptr<AccessCase> GetterSetterAccessCase::clone() const95 { 96 std::unique_ptr<GetterSetterAccessCase> result(new GetterSetterAccessCase(*this));94 Ref<AccessCase> GetterSetterAccessCase::clone() const 95 { 96 auto result = adoptRef(*new GetterSetterAccessCase(*this)); 97 97 result->resetState(); 98 98 return result; … … 140 140 allocator.lock(stubInfo.baseRegs()); 141 141 allocator.lock(valueRegs); 142 if (stubInfo.m_stubInfoGPR != InvalidGPRReg) 143 allocator.lock(stubInfo.m_stubInfoGPR); 142 144 allocator.lock(scratchGPR); 143 145 … … 224 226 registersToSpillForCCall.set(reg); 225 227 registersToSpillForCCall.exclude(RegisterSet::registersToNotSaveForCCall()); 228 #if CPU(ARM64) 229 CodeBlock* codeBlock = jit.codeBlock(); 230 if (codeBlock->useDataIC()) 231 registersToSpillForCCall.set(ARM64Registers::lr); 232 #endif 226 233 227 234 AccessCaseSnippetParams params(state.m_vm, WTFMove(regs), WTFMove(gpScratch), WTFMove(fpScratch)); -
trunk/Source/JavaScriptCore/bytecode/GetterSetterAccessCase.h
r278253 r278656 54 54 void emitDOMJITGetter(AccessGenerationState&, const DOMJIT::GetterSetter*, GPRReg baseForGetGPR); 55 55 56 static std::unique_ptr<AccessCase> create(56 static Ref<AccessCase> create( 57 57 VM&, JSCell* owner, AccessType, CacheableIdentifier, PropertyOffset, Structure*, 58 58 const ObjectPropertyConditionSet&, bool viaProxy, WatchpointSet* additionalSet, FunctionPtr<CustomAccessorPtrTag> customGetter, 59 59 JSObject* customSlotBase, std::optional<DOMAttributeAnnotation>, RefPtr<PolyProtoAccessChain>&&); 60 60 61 static std::unique_ptr<AccessCase> create(VM&, JSCell* owner, AccessType, Structure*, CacheableIdentifier, PropertyOffset,61 static Ref<AccessCase> create(VM&, JSCell* owner, AccessType, Structure*, CacheableIdentifier, PropertyOffset, 62 62 const ObjectPropertyConditionSet&, RefPtr<PolyProtoAccessChain>&&, bool viaProxy = false, 63 63 FunctionPtr<CustomAccessorPtrTag> customSetter = nullptr, JSObject* customSlotBase = nullptr); 64 64 65 65 void dumpImpl(PrintStream&, CommaPrinter&) const final; 66 std::unique_ptr<AccessCase> clone() const final;66 Ref<AccessCase> clone() const final; 67 67 68 68 ~GetterSetterAccessCase() final; -
trunk/Source/JavaScriptCore/bytecode/InlineAccess.cpp
r277305 r278656 217 217 allocator.lock(stubInfo.valueTagGPR); 218 218 #endif 219 if (stubInfo.m_stubInfoGPR != InvalidGPRReg) 220 allocator.lock(stubInfo.m_stubInfoGPR); 219 221 GPRReg scratch = allocator.allocateScratchGPR(); 220 222 if (allocator.didReuseRegisters()) … … 380 382 } 381 383 382 void InlineAccess::rewireStubAsJump(StructureStubInfo& stubInfo, CodeLocationLabel<JITStubRoutinePtrTag> target) 383 { 384 CCallHelpers jit; 385 386 auto jump = jit.jump(); 387 388 // We don't need a nop sled here because nobody should be jumping into the middle of an IC. 389 bool needsBranchCompaction = false; 390 LinkBuffer linkBuffer(jit, stubInfo.start, jit.m_assembler.buffer().codeSize(), LinkBuffer::Profile::InlineCache, JITCompilationMustSucceed, needsBranchCompaction); 391 RELEASE_ASSERT(linkBuffer.isValid()); 392 linkBuffer.link(jump, target); 393 394 FINALIZE_CODE(linkBuffer, NoPtrTag, "InlineAccess: linking constant jump"); 384 void InlineAccess::rewireStubAsJumpInAccessNotUsingInlineAccess(CodeBlock* codeBlock, StructureStubInfo& stubInfo, CodeLocationLabel<JITStubRoutinePtrTag> target) 385 { 386 if (codeBlock->useDataIC()) { 387 stubInfo.m_codePtr = target; 388 return; 389 } 390 391 CCallHelpers::emitJITCodeOver(stubInfo.start.retagged<JSInternalPtrTag>(), scopedLambda<void(CCallHelpers&)>([&](CCallHelpers& jit) { 392 // We don't need a nop sled here because nobody should be jumping into the middle of an IC. 393 auto jump = jit.jump(); 394 jit.addLinkTask([=] (LinkBuffer& linkBuffer) { 395 linkBuffer.link(jump, target); 396 }); 397 }), "InlineAccess: linking constant jump"); 398 } 399 400 void InlineAccess::rewireStubAsJumpInAccess(CodeBlock* codeBlock, StructureStubInfo& stubInfo, CodeLocationLabel<JITStubRoutinePtrTag> target) 401 { 402 if (codeBlock->useDataIC()) { 403 // If it is not GetById-like-thing, we do not emit nop sled (e.g. GetByVal). 404 // The code is already an indirect jump, and only thing we should do is replacing m_codePtr. 405 if (stubInfo.hasConstantIdentifier) { 406 // If m_codePtr is pointing to stubInfo.slowPathStartLocation, this means that InlineAccess code is not a stub one. 407 // We rewrite this with the stub-based dispatching code once, and continue using it until we reset the code. 408 if (stubInfo.m_codePtr.executableAddress() == stubInfo.slowPathStartLocation.executableAddress()) { 409 CCallHelpers::emitJITCodeOver(stubInfo.start.retagged<JSInternalPtrTag>(), scopedLambda<void(CCallHelpers&)>([&](CCallHelpers& jit) { 410 jit.move(CCallHelpers::TrustedImmPtr(&stubInfo), stubInfo.m_stubInfoGPR); 411 jit.call(CCallHelpers::Address(stubInfo.m_stubInfoGPR, StructureStubInfo::offsetOfCodePtr()), JITStubRoutinePtrTag); 412 auto jump = jit.jump(); 413 auto doneLocation = stubInfo.doneLocation; 414 jit.addLinkTask([=](LinkBuffer& linkBuffer) { 415 linkBuffer.link(jump, doneLocation); 416 }); 417 }), "InlineAccess: linking stub call"); 418 } 419 } 420 stubInfo.m_codePtr = target; 421 return; 422 } 423 424 CCallHelpers::emitJITCodeOver(stubInfo.start.retagged<JSInternalPtrTag>(), scopedLambda<void(CCallHelpers&)>([&](CCallHelpers& jit) { 425 // We don't need a nop sled here because nobody should be jumping into the middle of an IC. 426 auto jump = jit.jump(); 427 jit.addLinkTask([=] (LinkBuffer& linkBuffer) { 428 linkBuffer.link(jump, target); 429 }); 430 }), "InlineAccess: linking constant jump"); 431 } 432 433 void InlineAccess::resetStubAsJumpInAccess(CodeBlock*, StructureStubInfo& stubInfo) 434 { 435 CCallHelpers::emitJITCodeOver(stubInfo.start.retagged<JSInternalPtrTag>(), scopedLambda<void(CCallHelpers&)>([&](CCallHelpers& jit) { 436 // We don't need a nop sled here because nobody should be jumping into the middle of an IC. 437 auto jump = jit.jump(); 438 auto slowPathStartLocation = stubInfo.slowPathStartLocation; 439 jit.addLinkTask([=] (LinkBuffer& linkBuffer) { 440 linkBuffer.link(jump, slowPathStartLocation); 441 }); 442 }), "InlineAccess: linking constant jump"); 443 } 444 445 void InlineAccess::resetStubAsJumpInAccessNotUsingInlineAccess(CodeBlock* codeBlock, StructureStubInfo& stubInfo) 446 { 447 rewireStubAsJumpInAccessNotUsingInlineAccess(codeBlock, stubInfo, stubInfo.slowPathStartLocation); 395 448 } 396 449 -
trunk/Source/JavaScriptCore/bytecode/InlineAccess.h
r242252 r278656 105 105 static bool isCacheableStringLength(StructureStubInfo&); 106 106 static bool generateArrayLength(StructureStubInfo&, JSArray*); 107 static void rewireStubAsJump(StructureStubInfo&, CodeLocationLabel<JITStubRoutinePtrTag>);108 107 static bool generateSelfInAccess(StructureStubInfo&, Structure*); 109 108 static bool generateStringLength(StructureStubInfo&); 109 110 static void rewireStubAsJumpInAccessNotUsingInlineAccess(CodeBlock*, StructureStubInfo&, CodeLocationLabel<JITStubRoutinePtrTag>); 111 static void rewireStubAsJumpInAccess(CodeBlock*, StructureStubInfo&, CodeLocationLabel<JITStubRoutinePtrTag>); 112 static void resetStubAsJumpInAccessNotUsingInlineAccess(CodeBlock*, StructureStubInfo&); 113 static void resetStubAsJumpInAccess(CodeBlock*, StructureStubInfo&); 110 114 111 115 // This is helpful when determining the size of an IC on -
trunk/Source/JavaScriptCore/bytecode/InstanceOfAccessCase.cpp
r261755 r278656 33 33 namespace JSC { 34 34 35 std::unique_ptr<AccessCase> InstanceOfAccessCase::create(35 Ref<AccessCase> InstanceOfAccessCase::create( 36 36 VM& vm, JSCell* owner, AccessType accessType, Structure* structure, 37 37 const ObjectPropertyConditionSet& conditionSet, JSObject* prototype) 38 38 { 39 return std::unique_ptr<AccessCase>(new InstanceOfAccessCase(vm, owner, accessType, structure, conditionSet, prototype));39 return adoptRef(*new InstanceOfAccessCase(vm, owner, accessType, structure, conditionSet, prototype)); 40 40 } 41 41 … … 46 46 } 47 47 48 std::unique_ptr<AccessCase> InstanceOfAccessCase::clone() const48 Ref<AccessCase> InstanceOfAccessCase::clone() const 49 49 { 50 std::unique_ptr<InstanceOfAccessCase> result(new InstanceOfAccessCase(*this));50 auto result = adoptRef(*new InstanceOfAccessCase(*this)); 51 51 result->resetState(); 52 52 return result; -
trunk/Source/JavaScriptCore/bytecode/InstanceOfAccessCase.h
r261567 r278656 35 35 public: 36 36 using Base = AccessCase; 37 friend class AccessCase; 37 38 38 static std::unique_ptr<AccessCase> create(39 static Ref<AccessCase> create( 39 40 VM&, JSCell*, AccessType, Structure*, const ObjectPropertyConditionSet&, 40 41 JSObject* prototype); … … 43 44 44 45 void dumpImpl(PrintStream&, CommaPrinter&) const final; 45 std::unique_ptr<AccessCase> clone() const final;46 Ref<AccessCase> clone() const final; 46 47 47 48 ~InstanceOfAccessCase() final; -
trunk/Source/JavaScriptCore/bytecode/IntrinsicGetterAccessCase.cpp
r275490 r278656 40 40 } 41 41 42 std::unique_ptr<AccessCase> IntrinsicGetterAccessCase::create(VM& vm, JSCell* owner, CacheableIdentifier identifier, PropertyOffset offset, Structure* structure, const ObjectPropertyConditionSet& conditionSet, JSFunction* intrinsicFunction, RefPtr<PolyProtoAccessChain>&& prototypeAccessChain)42 Ref<AccessCase> IntrinsicGetterAccessCase::create(VM& vm, JSCell* owner, CacheableIdentifier identifier, PropertyOffset offset, Structure* structure, const ObjectPropertyConditionSet& conditionSet, JSFunction* intrinsicFunction, RefPtr<PolyProtoAccessChain>&& prototypeAccessChain) 43 43 { 44 return std::unique_ptr<AccessCase>(new IntrinsicGetterAccessCase(vm, owner, identifier, offset, structure, conditionSet, intrinsicFunction, WTFMove(prototypeAccessChain)));44 return adoptRef(*new IntrinsicGetterAccessCase(vm, owner, identifier, offset, structure, conditionSet, intrinsicFunction, WTFMove(prototypeAccessChain))); 45 45 } 46 46 … … 49 49 } 50 50 51 std::unique_ptr<AccessCase> IntrinsicGetterAccessCase::clone() const51 Ref<AccessCase> IntrinsicGetterAccessCase::clone() const 52 52 { 53 std::unique_ptr<IntrinsicGetterAccessCase> result(new IntrinsicGetterAccessCase(*this));53 auto result = adoptRef(*new IntrinsicGetterAccessCase(*this)); 54 54 result->resetState(); 55 55 return result; -
trunk/Source/JavaScriptCore/bytecode/IntrinsicGetterAccessCase.h
r275490 r278656 43 43 void emitIntrinsicGetter(AccessGenerationState&); 44 44 45 static std::unique_ptr<AccessCase> create(VM&, JSCell*, CacheableIdentifier, PropertyOffset, Structure*, const ObjectPropertyConditionSet&, JSFunction* intrinsicFunction, RefPtr<PolyProtoAccessChain>&&);45 static Ref<AccessCase> create(VM&, JSCell*, CacheableIdentifier, PropertyOffset, Structure*, const ObjectPropertyConditionSet&, JSFunction* intrinsicFunction, RefPtr<PolyProtoAccessChain>&&); 46 46 47 std::unique_ptr<AccessCase> clone() const final;47 Ref<AccessCase> clone() const final; 48 48 49 49 ~IntrinsicGetterAccessCase() final; -
trunk/Source/JavaScriptCore/bytecode/ModuleNamespaceAccessCase.cpp
r261755 r278656 46 46 } 47 47 48 std::unique_ptr<AccessCase> ModuleNamespaceAccessCase::create(VM& vm, JSCell* owner, CacheableIdentifier identifier, JSModuleNamespaceObject* moduleNamespaceObject, JSModuleEnvironment* moduleEnvironment, ScopeOffset scopeOffset)48 Ref<AccessCase> ModuleNamespaceAccessCase::create(VM& vm, JSCell* owner, CacheableIdentifier identifier, JSModuleNamespaceObject* moduleNamespaceObject, JSModuleEnvironment* moduleEnvironment, ScopeOffset scopeOffset) 49 49 { 50 return std::unique_ptr<AccessCase>(new ModuleNamespaceAccessCase(vm, owner, identifier, moduleNamespaceObject, moduleEnvironment, scopeOffset));50 return adoptRef(*new ModuleNamespaceAccessCase(vm, owner, identifier, moduleNamespaceObject, moduleEnvironment, scopeOffset)); 51 51 } 52 52 … … 55 55 } 56 56 57 std::unique_ptr<AccessCase> ModuleNamespaceAccessCase::clone() const57 Ref<AccessCase> ModuleNamespaceAccessCase::clone() const 58 58 { 59 std::unique_ptr<ModuleNamespaceAccessCase> result(new ModuleNamespaceAccessCase(*this));59 auto result = adoptRef(*new ModuleNamespaceAccessCase(*this)); 60 60 result->resetState(); 61 61 return result; -
trunk/Source/JavaScriptCore/bytecode/ModuleNamespaceAccessCase.h
r261567 r278656 45 45 ScopeOffset scopeOffset() const { return m_scopeOffset; } 46 46 47 static std::unique_ptr<AccessCase> create(VM&, JSCell* owner, CacheableIdentifier, JSModuleNamespaceObject*, JSModuleEnvironment*, ScopeOffset);47 static Ref<AccessCase> create(VM&, JSCell* owner, CacheableIdentifier, JSModuleNamespaceObject*, JSModuleEnvironment*, ScopeOffset); 48 48 49 std::unique_ptr<AccessCase> clone() const final;49 Ref<AccessCase> clone() const final; 50 50 51 51 void emit(AccessGenerationState&, MacroAssembler::JumpList& fallThrough); -
trunk/Source/JavaScriptCore/bytecode/ObjectPropertyConditionSet.h
r278253 r278656 29 29 #include <wtf/FastMalloc.h> 30 30 #include <wtf/FixedVector.h> 31 #include <wtf/Hasher.h> 31 32 #include <wtf/Vector.h> 32 33 … … 89 90 return nullptr; 90 91 return m_data->m_vector.end(); 92 } 93 94 unsigned hash() const 95 { 96 Hasher hasher; 97 for (auto& condition : *this) 98 add(hasher, condition.hash()); 99 return hasher.hash(); 100 } 101 102 friend bool operator==(const ObjectPropertyConditionSet& lhs, const ObjectPropertyConditionSet& rhs) 103 { 104 if (lhs.size() != rhs.size()) 105 return false; 106 auto liter = lhs.begin(); 107 auto riter = rhs.begin(); 108 for (; liter != lhs.end(); ++liter, ++riter) { 109 if (!(*liter == *riter)) 110 return false; 111 } 112 return true; 113 } 114 115 friend bool operator!=(const ObjectPropertyConditionSet& lhs, const ObjectPropertyConditionSet& rhs) 116 { 117 return !(lhs == rhs); 91 118 } 92 119 -
trunk/Source/JavaScriptCore/bytecode/PolymorphicAccess.cpp
r277669 r278656 60 60 } 61 61 62 void AccessGenerationState::installWatchpoint(const ObjectPropertyCondition& condition) 63 { 64 WatchpointsOnStructureStubInfo::ensureReferenceAndInstallWatchpoint( 65 watchpoints, jit->codeBlock(), stubInfo, condition); 62 void AccessGenerationState::installWatchpoint(CodeBlock* codeBlock, const ObjectPropertyCondition& condition) 63 { 64 WatchpointsOnStructureStubInfo::ensureReferenceAndInstallWatchpoint(watchpoints, codeBlock, stubInfo, condition); 66 65 } 67 66 … … 74 73 { 75 74 restoreScratch(); 76 success.append(jit->jump()); 75 if (jit->codeBlock()->useDataIC()) 76 jit->ret(); 77 else 78 success.append(jit->jump()); 77 79 } 78 80 … … 127 129 } 128 130 129 auto AccessGenerationState::preserveLiveRegistersToStackForCallWithoutExceptions( ) -> SpillState131 auto AccessGenerationState::preserveLiveRegistersToStackForCallWithoutExceptions(const RegisterSet& extra) -> SpillState 130 132 { 131 133 RegisterSet liveRegisters = allocator->usedRegisters(); 132 134 liveRegisters.exclude(calleeSaveRegisters()); 135 liveRegisters.merge(extra); 133 136 134 137 constexpr unsigned extraStackPadding = 0; … … 253 256 AccessGenerationResult PolymorphicAccess::addCases( 254 257 const GCSafeConcurrentJSLocker& locker, VM& vm, CodeBlock* codeBlock, StructureStubInfo& stubInfo, 255 Vector< std::unique_ptr<AccessCase>, 2> originalCasesToAdd)258 Vector<RefPtr<AccessCase>, 2> originalCasesToAdd) 256 259 { 257 260 SuperSamplerScope superSamplerScope(false); … … 269 272 270 273 // First ensure that the originalCasesToAdd doesn't contain duplicates. 271 Vector< std::unique_ptr<AccessCase>> casesToAdd;274 Vector<RefPtr<AccessCase>> casesToAdd; 272 275 for (unsigned i = 0; i < originalCasesToAdd.size(); ++i) { 273 std::unique_ptr<AccessCase> myCase = WTFMove(originalCasesToAdd[i]);276 RefPtr<AccessCase> myCase = WTFMove(originalCasesToAdd[i]); 274 277 275 278 // Add it only if it is not replaced by the subsequent cases in the list. … … 288 291 } 289 292 290 if (PolymorphicAccessInternal::verbose) 291 dataLog("casesToAdd: ", listDump(casesToAdd), "\n"); 293 dataLogLnIf(PolymorphicAccessInternal::verbose, "casesToAdd: ", listDump(casesToAdd)); 292 294 293 295 // If there aren't any cases to add, then fail on the grounds that there's no point to generating a … … 340 342 } 341 343 342 if (PolymorphicAccessInternal::verbose) 343 dataLog("After addCases: m_list: ", listDump(m_list), "\n"); 344 dataLogLnIf(PolymorphicAccessInternal::verbose, "After addCases: m_list: ", listDump(m_list)); 344 345 345 346 return AccessGenerationResult::Buffered; … … 347 348 348 349 AccessGenerationResult PolymorphicAccess::addCase( 349 const GCSafeConcurrentJSLocker& locker, VM& vm, CodeBlock* codeBlock, StructureStubInfo& stubInfo, std::unique_ptr<AccessCase> newAccess)350 { 351 Vector< std::unique_ptr<AccessCase>, 2> newAccesses;350 const GCSafeConcurrentJSLocker& locker, VM& vm, CodeBlock* codeBlock, StructureStubInfo& stubInfo, Ref<AccessCase> newAccess) 351 { 352 Vector<RefPtr<AccessCase>, 2> newAccesses; 352 353 newAccesses.append(WTFMove(newAccess)); 353 354 return addCases(locker, vm, codeBlock, stubInfo, WTFMove(newAccesses)); … … 360 361 return false; 361 362 } 362 for (const WriteBarrier<JSCell>& weakReference : m_weakReferences) { 363 if (!vm.heap.isMarked(weakReference.get())) 364 return false; 363 if (m_stubRoutine) { 364 for (StructureID weakReference : m_stubRoutine->weakStructures()) { 365 Structure* structure = vm.getStructure(weakReference); 366 if (!vm.heap.isMarked(structure)) 367 return false; 368 } 365 369 } 366 370 return true; … … 420 424 SuperSamplerScope superSamplerScope(false); 421 425 422 if (PolymorphicAccessInternal::verbose) 423 dataLog("Regenerate with m_list: ", listDump(m_list), "\n"); 426 dataLogLnIf(PolymorphicAccessInternal::verbose, "Regenerate with m_list: ", listDump(m_list)); 424 427 425 428 AccessGenerationState state(vm, globalObject, ecmaMode); … … 441 444 unsigned dstIndex = 0; 442 445 while (srcIndex < m_list.size()) { 443 std::unique_ptr<AccessCase> someCase = WTFMove(m_list[srcIndex++]);446 RefPtr<AccessCase> someCase = WTFMove(m_list[srcIndex++]); 444 447 445 448 // If the case had been generated, then we have to keep the original in m_list in case we … … 492 495 allocator.lock(stubInfo.v.thisTagGPR); 493 496 #endif 497 if (stubInfo.m_stubInfoGPR != InvalidGPRReg) 498 allocator.lock(stubInfo.m_stubInfoGPR); 494 499 495 500 state.scratchGPR = allocator.allocateScratchGPR(); … … 501 506 } 502 507 } 503 504 CCallHelpers jit(codeBlock);505 state.jit = &jit;506 507 state.preservedReusedRegisterState =508 allocator.preserveReusedRegistersByPushing(jit, ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);509 508 510 509 bool generatedFinalCode = false; … … 520 519 } 521 520 522 if (PolymorphicAccessInternal::verbose) 523 dataLog("Optimized cases: ", listDump(cases), "\n"); 524 521 dataLogLnIf(PolymorphicAccessInternal::verbose, "Optimized cases: ", listDump(cases)); 522 523 bool doesCalls = false; 524 bool doesJSGetterSetterCalls = false; 525 bool canBeShared = true; 526 Vector<JSCell*> cellsToMark; 527 FixedVector<RefPtr<AccessCase>> keys(cases.size()); 528 unsigned index = 0; 529 for (auto& entry : cases) { 530 doesCalls |= entry->doesCalls(vm, &cellsToMark); 531 switch (entry->type()) { 532 case AccessCase::Getter: 533 case AccessCase::Setter: 534 // Getter / Setter relies on stack-pointer adjustment, which is tied to the linked CodeBlock, which makes this code unshareable. 535 canBeShared = false; 536 doesJSGetterSetterCalls = true; 537 break; 538 case AccessCase::CustomValueGetter: 539 case AccessCase::CustomAccessorGetter: 540 case AccessCase::CustomValueSetter: 541 case AccessCase::CustomAccessorSetter: 542 // Custom getter / setter emits JSGlobalObject pointer, which is tied to the linked CodeBlock. 543 canBeShared = false; 544 break; 545 default: 546 break; 547 } 548 keys[index] = entry; 549 ++index; 550 } 551 state.m_doesCalls = doesCalls; 552 state.m_doesJSGetterSetterCalls = doesJSGetterSetterCalls; 553 525 554 // At this point we're convinced that 'cases' contains the cases that we want to JIT now and we 526 555 // won't change that set anymore. 527 556 528 557 bool allGuardedByStructureCheck = true; 529 bool hasJSGetterSetterCall = false;530 558 bool needsInt32PropertyCheck = false; 531 559 bool needsStringPropertyCheck = false; … … 543 571 commit(locker, vm, state.watchpoints, codeBlock, stubInfo, *newCase); 544 572 allGuardedByStructureCheck &= newCase->guardedByStructureCheck(stubInfo); 545 if (newCase->type() == AccessCase::Getter || newCase->type() == AccessCase::Setter) 546 hasJSGetterSetterCall = true; 547 } 548 573 if (newCase->usesPolyProto()) 574 canBeShared = false; 575 } 576 if (needsSymbolPropertyCheck || needsStringPropertyCheck || needsInt32PropertyCheck) 577 canBeShared = false; 578 579 auto finishCodeGeneration = [&](RefPtr<PolymorphicAccessJITStubRoutine>&& stub) { 580 m_stubRoutine = WTFMove(stub); 581 m_watchpoints = WTFMove(state.watchpoints); 582 dataLogLnIf(PolymorphicAccessInternal::verbose, "Returning: ", m_stubRoutine->code()); 583 584 m_list = WTFMove(cases); 585 m_list.shrinkToFit(); 586 587 AccessGenerationResult::Kind resultKind; 588 if (m_list.size() >= Options::maxAccessVariantListSize() || generatedFinalCode) 589 resultKind = AccessGenerationResult::GeneratedFinalCode; 590 else 591 resultKind = AccessGenerationResult::GeneratedNewCode; 592 593 return AccessGenerationResult(resultKind, m_stubRoutine->code().code()); 594 }; 595 596 CCallHelpers jit(codeBlock); 597 state.jit = &jit; 598 599 if (codeBlock->useDataIC()) { 600 if (state.m_doesJSGetterSetterCalls) { 601 // We have no guarantee that stack-pointer is the expected one. This is not a problem if we do not have JS getter / setter calls since stack-pointer is 602 // a callee-save register in the C calling convension. However, our JS executable call does not save stack-pointer. So we are adjusting stack-pointer after 603 // JS getter / setter calls. But this could be different from the initial stack-pointer, and makes PAC tagging broken. 604 // To ensure PAC-tagging work, we first adjust stack-pointer to the appropriate one. 605 jit.addPtr(CCallHelpers::TrustedImm32(codeBlock->stackPointerOffset() * sizeof(Register)), GPRInfo::callFrameRegister, CCallHelpers::stackPointerRegister); 606 jit.tagReturnAddress(); 607 } else 608 jit.tagReturnAddress(); 609 } 610 611 state.preservedReusedRegisterState = 612 allocator.preserveReusedRegistersByPushing(jit, ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace); 613 549 614 if (cases.isEmpty()) { 550 615 // This is super unlikely, but we make it legal anyway. … … 691 756 CodeBlock* codeBlockThatOwnsExceptionHandlers = nullptr; 692 757 DisposableCallSiteIndex callSiteIndexForExceptionHandling; 693 if (state.needsToRestoreRegistersIfException() && hasJSGetterSetterCall) {758 if (state.needsToRestoreRegistersIfException() && doesJSGetterSetterCalls) { 694 759 // Emit the exception handler. 695 760 // Note that this code is only reachable when doing genericUnwind from a pure JS getter/setter . … … 731 796 } 732 797 798 if (codeBlock->useDataIC()) { 799 failure.link(&jit); 800 // In ARM64, we do not push anything on stack specially. 801 // So we can just jump to the slow-path even though this thunk is called (not jumped). 802 // FIXME: We should tail call to the thunk which calls the slow path function. 803 // And we should eliminate IC slow-path generation in BaselineJIT. 804 jit.farJump(CCallHelpers::Address(stubInfo.m_stubInfoGPR, StructureStubInfo::offsetOfSlowPathStartLocation()), JITStubRoutinePtrTag); 805 } 806 807 RefPtr<PolymorphicAccessJITStubRoutine> stub; 808 FixedVector<StructureID> weakStructures(WTFMove(state.weakStructures)); 809 if (codeBlock->useDataIC() && canBeShared) { 810 SharedJITStubSet::Searcher searcher { 811 stubInfo.baseGPR, 812 stubInfo.valueGPR, 813 stubInfo.regs.thisGPR, 814 stubInfo.m_stubInfoGPR, 815 stubInfo.usedRegisters, 816 keys, 817 weakStructures, 818 }; 819 stub = vm.m_sharedJITStubs->find(searcher); 820 if (stub) { 821 dataLogLnIf(PolymorphicAccessInternal::verbose, "Found existing code stub ", stub->code()); 822 return finishCodeGeneration(WTFMove(stub)); 823 } 824 } 825 733 826 LinkBuffer linkBuffer(jit, codeBlock, LinkBuffer::Profile::InlineCache, JITCompilationCanFail); 734 827 if (linkBuffer.didFailToAllocate()) { 735 if (PolymorphicAccessInternal::verbose) 736 dataLog("Did fail to allocate.\n"); 828 dataLogLnIf(PolymorphicAccessInternal::verbose, "Did fail to allocate."); 737 829 return AccessGenerationResult::GaveUp; 738 830 } … … 740 832 CodeLocationLabel<JSInternalPtrTag> successLabel = stubInfo.doneLocation; 741 833 742 linkBuffer.link(state.success, successLabel); 743 744 linkBuffer.link(failure, stubInfo.slowPathStartLocation); 834 if (codeBlock->useDataIC()) 835 ASSERT(state.success.empty()); 836 else { 837 linkBuffer.link(state.success, successLabel); 838 linkBuffer.link(failure, stubInfo.slowPathStartLocation); 839 } 745 840 746 if (PolymorphicAccessInternal::verbose) 747 dataLog(FullCodeOrigin(codeBlock, stubInfo.codeOrigin), ": Generating polymorphic access stub for ", listDump(cases), "\n"); 841 dataLogLnIf(PolymorphicAccessInternal::verbose, FullCodeOrigin(codeBlock, stubInfo.codeOrigin), ": Generating polymorphic access stub for ", listDump(cases)); 748 842 749 843 MacroAssemblerCodeRef<JITStubRoutinePtrTag> code = FINALIZE_CODE_FOR( 750 844 codeBlock, linkBuffer, JITStubRoutinePtrTag, 751 845 "%s", toCString("Access stub for ", *codeBlock, " ", stubInfo.codeOrigin, " with return point ", successLabel, ": ", listDump(cases)).data()); 752 753 bool doesCalls = false;754 Vector<JSCell*> cellsToMark;755 for (auto& entry : cases)756 doesCalls |= entry->doesCalls(vm, &cellsToMark);757 846 758 m_stubRoutine = createJITStubRoutine(code, vm, codeBlock, doesCalls, cellsToMark, WTFMove(state.m_callLinkInfos), codeBlockThatOwnsExceptionHandlers, callSiteIndexForExceptionHandling); 759 m_watchpoints = WTFMove(state.watchpoints); 760 if (!state.weakReferences.isEmpty()) 761 m_weakReferences = FixedVector<WriteBarrier<JSCell>>(WTFMove(state.weakReferences)); 762 if (PolymorphicAccessInternal::verbose) 763 dataLog("Returning: ", code.code(), "\n"); 764 765 m_list = WTFMove(cases); 766 m_list.shrinkToFit(); 767 768 AccessGenerationResult::Kind resultKind; 769 if (m_list.size() >= Options::maxAccessVariantListSize() || generatedFinalCode) 770 resultKind = AccessGenerationResult::GeneratedFinalCode; 771 else 772 resultKind = AccessGenerationResult::GeneratedNewCode; 773 774 return AccessGenerationResult(resultKind, code.code()); 847 stub = createICJITStubRoutine(code, WTFMove(keys), WTFMove(weakStructures), vm, codeBlock, doesCalls, cellsToMark, WTFMove(state.m_callLinkInfos), codeBlockThatOwnsExceptionHandlers, callSiteIndexForExceptionHandling); 848 849 if (codeBlock->useDataIC()) { 850 if (canBeShared) 851 vm.m_sharedJITStubs->add(SharedJITStubSet::Hash::Key(stubInfo.baseGPR, stubInfo.valueGPR, stubInfo.regs.thisGPR, stubInfo.m_stubInfoGPR, stubInfo.usedRegisters, stub.get())); 852 } 853 854 return finishCodeGeneration(WTFMove(stub)); 775 855 } 776 856 -
trunk/Source/JavaScriptCore/bytecode/PolymorphicAccess.h
r277669 r278656 142 142 // to call this method again for that PolymorphicAccess instance. 143 143 AccessGenerationResult addCases( 144 const GCSafeConcurrentJSLocker&, VM&, CodeBlock*, StructureStubInfo&, Vector< std::unique_ptr<AccessCase>, 2>);144 const GCSafeConcurrentJSLocker&, VM&, CodeBlock*, StructureStubInfo&, Vector<RefPtr<AccessCase>, 2>); 145 145 146 146 AccessGenerationResult addCase( 147 const GCSafeConcurrentJSLocker&, VM&, CodeBlock*, StructureStubInfo&, std::unique_ptr<AccessCase>);147 const GCSafeConcurrentJSLocker&, VM&, CodeBlock*, StructureStubInfo&, Ref<AccessCase>); 148 148 149 149 AccessGenerationResult regenerate(const GCSafeConcurrentJSLocker&, VM&, JSGlobalObject*, CodeBlock*, ECMAMode, StructureStubInfo&); … … 180 180 friend struct AccessGenerationState; 181 181 182 typedef Vector< std::unique_ptr<AccessCase>, 2> ListType;182 typedef Vector<RefPtr<AccessCase>, 2> ListType; 183 183 184 184 void commit( … … 187 187 188 188 ListType m_list; 189 RefPtr< JITStubRoutine> m_stubRoutine;189 RefPtr<PolymorphicAccessJITStubRoutine> m_stubRoutine; 190 190 std::unique_ptr<WatchpointsOnStructureStubInfo> m_watchpoints; 191 FixedVector<WriteBarrier<JSCell>> m_weakReferences;192 191 }; 193 192 … … 197 196 , m_globalObject(globalObject) 198 197 , m_ecmaMode(ecmaMode) 198 , m_doesJSGetterSetterCalls(false) 199 , m_doesCalls(false) 199 200 , m_calculatedRegistersForCallAndExceptionHandling(false) 200 201 , m_needsToRestoreRegistersIfException(false) … … 224 225 ECMAMode m_ecmaMode { ECMAMode::sloppy() }; 225 226 std::unique_ptr<WatchpointsOnStructureStubInfo> watchpoints; 226 Vector< WriteBarrier<JSCell>> weakReferences;227 Vector<StructureID> weakStructures; 227 228 Bag<CallLinkInfo> m_callLinkInfos; 228 229 void installWatchpoint(const ObjectPropertyCondition&); 229 bool m_doesJSGetterSetterCalls : 1; 230 bool m_doesCalls : 1; 231 232 void installWatchpoint(CodeBlock*, const ObjectPropertyCondition&); 230 233 231 234 void restoreScratch(); … … 249 252 250 253 SpillState preserveLiveRegistersToStackForCall(const RegisterSet& extra = { }); 251 SpillState preserveLiveRegistersToStackForCallWithoutExceptions( );254 SpillState preserveLiveRegistersToStackForCallWithoutExceptions(const RegisterSet& extra = { }); 252 255 253 256 void restoreLiveRegistersFromStackForCallWithThrownException(const SpillState&); -
trunk/Source/JavaScriptCore/bytecode/ProxyableAccessCase.cpp
r275490 r278656 39 39 } 40 40 41 std::unique_ptr<AccessCase> ProxyableAccessCase::create(VM& vm, JSCell* owner, AccessType type, CacheableIdentifier identifier, PropertyOffset offset, Structure* structure, const ObjectPropertyConditionSet& conditionSet, bool viaProxy, WatchpointSet* additionalSet, RefPtr<PolyProtoAccessChain>&& prototypeAccessChain)41 Ref<AccessCase> ProxyableAccessCase::create(VM& vm, JSCell* owner, AccessType type, CacheableIdentifier identifier, PropertyOffset offset, Structure* structure, const ObjectPropertyConditionSet& conditionSet, bool viaProxy, WatchpointSet* additionalSet, RefPtr<PolyProtoAccessChain>&& prototypeAccessChain) 42 42 { 43 43 ASSERT(type == Load || type == Miss || type == GetGetter || type == Replace); 44 return std::unique_ptr<AccessCase>(new ProxyableAccessCase(vm, owner, type, identifier, offset, structure, conditionSet, viaProxy, additionalSet, WTFMove(prototypeAccessChain)));44 return adoptRef(*new ProxyableAccessCase(vm, owner, type, identifier, offset, structure, conditionSet, viaProxy, additionalSet, WTFMove(prototypeAccessChain))); 45 45 } 46 46 … … 49 49 } 50 50 51 std::unique_ptr<AccessCase> ProxyableAccessCase::clone() const51 Ref<AccessCase> ProxyableAccessCase::clone() const 52 52 { 53 std::unique_ptr<ProxyableAccessCase> result(new ProxyableAccessCase(*this));53 auto result = adoptRef(*new ProxyableAccessCase(*this)); 54 54 result->resetState(); 55 55 return result; -
trunk/Source/JavaScriptCore/bytecode/ProxyableAccessCase.h
r275490 r278656 38 38 WatchpointSet* additionalSet() const override { return m_additionalSet.get(); } 39 39 40 static std::unique_ptr<AccessCase> create(VM&, JSCell*, AccessType, CacheableIdentifier, PropertyOffset, Structure*, const ObjectPropertyConditionSet& = ObjectPropertyConditionSet(),40 static Ref<AccessCase> create(VM&, JSCell*, AccessType, CacheableIdentifier, PropertyOffset, Structure*, const ObjectPropertyConditionSet& = ObjectPropertyConditionSet(), 41 41 bool viaProxy = false, WatchpointSet* additionalSet = nullptr, RefPtr<PolyProtoAccessChain>&& = nullptr); 42 42 43 43 void dumpImpl(PrintStream&, CommaPrinter&) const override; 44 std::unique_ptr<AccessCase> clone() const override;44 Ref<AccessCase> clone() const override; 45 45 46 46 ~ProxyableAccessCase() override; -
trunk/Source/JavaScriptCore/bytecode/StructureStubInfo.cpp
r278445 r278656 53 53 , propertyIsSymbol(false) 54 54 { 55 regs.thisGPR = InvalidGPRReg; 55 56 } 56 57 … … 140 141 141 142 AccessGenerationResult StructureStubInfo::addAccessCase( 142 const GCSafeConcurrentJSLocker& locker, JSGlobalObject* globalObject, CodeBlock* codeBlock, ECMAMode ecmaMode, CacheableIdentifier ident, std::unique_ptr<AccessCase> accessCase)143 const GCSafeConcurrentJSLocker& locker, JSGlobalObject* globalObject, CodeBlock* codeBlock, ECMAMode ecmaMode, CacheableIdentifier ident, RefPtr<AccessCase> accessCase) 143 144 { 144 145 checkConsistency(); … … 156 157 157 158 if (m_cacheType == CacheType::Stub) { 158 result = u.stub->addCase(locker, vm, codeBlock, *this, WTFMove(accessCase));159 result = u.stub->addCase(locker, vm, codeBlock, *this, accessCase.releaseNonNull()); 159 160 160 161 if (StructureStubInfoInternal::verbose) … … 171 172 std::unique_ptr<PolymorphicAccess> access = makeUnique<PolymorphicAccess>(); 172 173 173 Vector< std::unique_ptr<AccessCase>, 2> accessCases;174 175 std::unique_ptr<AccessCase>previousCase = AccessCase::fromStructureStubInfo(vm, codeBlock, ident, *this);174 Vector<RefPtr<AccessCase>, 2> accessCases; 175 176 auto previousCase = AccessCase::fromStructureStubInfo(vm, codeBlock, ident, *this); 176 177 if (previousCase) 177 178 accessCases.append(WTFMove(previousCase)); … … 280 281 break; 281 282 case AccessType::InstanceOf: 282 resetInstanceOf( *this);283 resetInstanceOf(codeBlock, *this); 283 284 break; 284 285 case AccessType::DeleteByID: -
trunk/Source/JavaScriptCore/bytecode/StructureStubInfo.h
r278445 r278656 89 89 void initInByIdSelf(const ConcurrentJSLockerBase&, CodeBlock*, Structure* baseObjectStructure, PropertyOffset, CacheableIdentifier); 90 90 91 AccessGenerationResult addAccessCase(const GCSafeConcurrentJSLocker&, JSGlobalObject*, CodeBlock*, ECMAMode, CacheableIdentifier, std::unique_ptr<AccessCase>);91 AccessGenerationResult addAccessCase(const GCSafeConcurrentJSLocker&, JSGlobalObject*, CodeBlock*, ECMAMode, CacheableIdentifier, RefPtr<AccessCase>); 92 92 93 93 void reset(const ConcurrentJSLockerBase&, CodeBlock*); … … 133 133 ASSERT(inlineSize >= 0); 134 134 return inlineSize; 135 }136 137 CodeLocationJump<JSInternalPtrTag> patchableJump()138 {139 ASSERT(accessType == AccessType::InstanceOf);140 return start.jumpAtOffset<JSInternalPtrTag>(0);141 135 } 142 136 … … 346 340 CodeLocationLabel<JITStubRoutinePtrTag> start; // This is either the start of the inline IC for *byId caches. or the location of patchable jump for 'instanceof' caches. 347 341 CodeLocationLabel<JSInternalPtrTag> doneLocation; 348 CodeLocationCall<JSInternalPtrTag> slowPathCallLocation;349 342 CodeLocationLabel<JITStubRoutinePtrTag> slowPathStartLocation; 350 343 344 union { 345 CodeLocationCall<JSInternalPtrTag> m_slowPathCallLocation; 346 FunctionPtr<OperationPtrTag> m_slowOperation; 347 }; 348 349 MacroAssemblerCodePtr<JITStubRoutinePtrTag> m_codePtr; 350 351 static ptrdiff_t offsetOfCodePtr() { return OBJECT_OFFSETOF(StructureStubInfo, m_codePtr); } 352 static ptrdiff_t offsetOfSlowPathStartLocation() { return OBJECT_OFFSETOF(StructureStubInfo, slowPathStartLocation); } 353 static ptrdiff_t offsetOfSlowOperation() { return OBJECT_OFFSETOF(StructureStubInfo, m_slowOperation); } 354 351 355 RegisterSet usedRegisters; 352 356 353 GPRReg baseGPR ;354 GPRReg valueGPR ;357 GPRReg baseGPR { InvalidGPRReg }; 358 GPRReg valueGPR { InvalidGPRReg }; 355 359 union { 356 360 GPRReg thisGPR; … … 359 363 GPRReg brandGPR; 360 364 } regs; 365 GPRReg m_stubInfoGPR { InvalidGPRReg }; 361 366 #if USE(JSVALUE32_64) 362 367 GPRReg valueTagGPR; -
trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.h
r278445 r278656 155 155 return functionCall; 156 156 } 157 158 void appendCall(CCallHelpers::Address address) 159 { 160 call(address, OperationPtrTag); 161 } 157 162 158 163 void exceptionCheck(); -
trunk/Source/JavaScriptCore/dfg/DFGSlowPathGenerator.h
r278213 r278656 265 265 } 266 266 267 template<typename JumpType, typename FunctionType, typename ResultType, typename... Arguments> 268 class CallResultAndArgumentsSlowPathICGenerator final : public CallSlowPathGenerator<JumpType, ResultType> { 269 public: 270 CallResultAndArgumentsSlowPathICGenerator( 271 JumpType from, SpeculativeJIT* jit, StructureStubInfo* stubInfo, GPRReg stubInfoGPR, CCallHelpers::Address slowPathOperationAddress, FunctionType function, 272 SpillRegistersMode spillMode, ExceptionCheckRequirement requirement, ResultType result, Arguments... arguments) 273 : CallSlowPathGenerator<JumpType, ResultType>(from, jit, spillMode, requirement, result) 274 , m_stubInfoGPR(stubInfoGPR) 275 , m_slowPathOperationAddress(slowPathOperationAddress) 276 , m_function(function) 277 , m_arguments(std::forward<Arguments>(arguments)...) 278 , m_stubInfo(stubInfo) 279 { 280 } 281 282 private: 283 template<size_t... ArgumentsIndex> 284 void unpackAndGenerate(SpeculativeJIT* jit, std::index_sequence<ArgumentsIndex...>) 285 { 286 ASSERT(JITCode::useDataIC(JITType::DFGJIT)); 287 this->setUp(jit); 288 m_stubInfo->m_slowOperation = m_function; 289 jit->m_jit.move(CCallHelpers::TrustedImmPtr(m_stubInfo), m_stubInfoGPR); 290 if constexpr (std::is_same<ResultType, NoResultTag>::value) 291 jit->callOperation<FunctionType>(m_slowPathOperationAddress, std::get<ArgumentsIndex>(m_arguments)...); 292 else 293 jit->callOperation<FunctionType>(m_slowPathOperationAddress, extractResult(this->m_result), std::get<ArgumentsIndex>(m_arguments)...); 294 this->tearDown(jit); 295 } 296 297 void generateInternal(SpeculativeJIT* jit) final 298 { 299 unpackAndGenerate(jit, std::make_index_sequence<std::tuple_size<std::tuple<Arguments...>>::value>()); 300 } 301 302 GPRReg m_stubInfoGPR; 303 CCallHelpers::Address m_slowPathOperationAddress; 304 FunctionType m_function; 305 std::tuple<Arguments...> m_arguments; 306 StructureStubInfo* m_stubInfo; 307 }; 308 309 template<typename JumpType, typename FunctionType, typename ResultType, typename... Arguments> 310 inline std::unique_ptr<SlowPathGenerator> slowPathICCall( 311 JumpType from, SpeculativeJIT* jit, StructureStubInfo* stubInfo, GPRReg stubInfoGPR, CCallHelpers::Address slowPathOperationAddress, FunctionType function, 312 SpillRegistersMode spillMode, ExceptionCheckRequirement requirement, 313 ResultType result, Arguments... arguments) 314 { 315 return makeUnique<CallResultAndArgumentsSlowPathICGenerator<JumpType, FunctionType, ResultType, Arguments...>>(from, jit, stubInfo, stubInfoGPR, slowPathOperationAddress, function, spillMode, requirement, result, arguments...); 316 } 317 318 template<typename JumpType, typename FunctionType, typename ResultType, typename... Arguments> 319 inline std::unique_ptr<SlowPathGenerator> slowPathICCall( 320 JumpType from, SpeculativeJIT* jit, StructureStubInfo* stubInfo, GPRReg stubInfoGPR, CCallHelpers::Address slowPathOperationAddress, FunctionType function, 321 ResultType result, Arguments... arguments) 322 { 323 return slowPathICCall(from, jit, stubInfo, stubInfoGPR, slowPathOperationAddress, function, NeedToSpill, ExceptionCheckRequirement::CheckNeeded, result, arguments...); 324 } 325 267 326 } } // namespace JSC::DFG 268 327 -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
r278642 r278656 1047 1047 switch (node->child1().useKind()) { 1048 1048 case CellUse: { 1049 std::optional<GPRTemporary> stubInfo; 1049 1050 SpeculateCellOperand base(this, node->child1()); 1050 1051 JSValueRegsTemporary result(this, Reuse, base); 1051 1052 1053 GPRReg stubInfoGPR = InvalidGPRReg; 1054 if (JITCode::useDataIC(JITType::DFGJIT)) { 1055 stubInfo.emplace(this); 1056 stubInfoGPR = stubInfo->gpr(); 1057 } 1052 1058 JSValueRegs baseRegs = JSValueRegs::payloadOnly(base.gpr()); 1053 1059 JSValueRegs resultRegs = result.regs(); … … 1055 1061 base.use(); 1056 1062 1057 cachedGetById(node->origin.semantic, baseRegs, resultRegs, node->cacheableIdentifier(), JITCompiler::Jump(), NeedToSpill, accessType);1063 cachedGetById(node->origin.semantic, baseRegs, resultRegs, stubInfoGPR, node->cacheableIdentifier(), JITCompiler::Jump(), NeedToSpill, accessType); 1058 1064 1059 1065 jsValueResult(resultRegs, node, DataFormatJS, UseChildrenCalledExplicitly); … … 1062 1068 1063 1069 case UntypedUse: { 1070 std::optional<GPRTemporary> stubInfo; 1064 1071 JSValueOperand base(this, node->child1()); 1065 1072 JSValueRegsTemporary result(this, Reuse, base); 1066 1073 1074 GPRReg stubInfoGPR = InvalidGPRReg; 1075 if (JITCode::useDataIC(JITType::DFGJIT)) { 1076 stubInfo.emplace(this); 1077 stubInfoGPR = stubInfo->gpr(); 1078 } 1067 1079 JSValueRegs baseRegs = base.jsValueRegs(); 1068 1080 JSValueRegs resultRegs = result.regs(); … … 1072 1084 JITCompiler::Jump notCell = m_jit.branchIfNotCell(baseRegs); 1073 1085 1074 cachedGetById(node->origin.semantic, baseRegs, resultRegs, node->cacheableIdentifier(), notCell, NeedToSpill, accessType);1086 cachedGetById(node->origin.semantic, baseRegs, resultRegs, stubInfoGPR, node->cacheableIdentifier(), notCell, NeedToSpill, accessType); 1075 1087 1076 1088 jsValueResult(resultRegs, node, DataFormatJS, UseChildrenCalledExplicitly); … … 1088 1100 switch (node->child1().useKind()) { 1089 1101 case CellUse: { 1102 std::optional<GPRTemporary> stubInfo; 1090 1103 SpeculateCellOperand base(this, node->child1()); 1104 JSValueRegsFlushedCallResult result(this); 1105 1106 GPRReg stubInfoGPR = InvalidGPRReg; 1107 if (JITCode::useDataIC(JITType::DFGJIT)) { 1108 stubInfo.emplace(this); 1109 stubInfoGPR = stubInfo->gpr(); 1110 } 1091 1111 JSValueRegs baseRegs = JSValueRegs::payloadOnly(base.gpr()); 1092 1112 JSValueRegs resultRegs = result.regs(); 1113 1114 base.use(); 1115 1116 flushRegisters(); 1117 1118 cachedGetById(node->origin.semantic, baseRegs, resultRegs, stubInfoGPR, node->cacheableIdentifier(), JITCompiler::Jump(), DontSpill, accessType); 1119 1120 jsValueResult(resultRegs, node, DataFormatJS, UseChildrenCalledExplicitly); 1121 break; 1122 } 1123 1124 case UntypedUse: { 1125 std::optional<GPRTemporary> stubInfo; 1126 JSValueOperand base(this, node->child1()); 1093 1127 JSValueRegsFlushedCallResult result(this); 1128 1129 GPRReg stubInfoGPR = InvalidGPRReg; 1130 if (JITCode::useDataIC(JITType::DFGJIT)) { 1131 stubInfo.emplace(this); 1132 stubInfoGPR = stubInfo->gpr(); 1133 } 1134 JSValueRegs baseRegs = base.jsValueRegs(); 1094 1135 JSValueRegs resultRegs = result.regs(); 1095 1136 … … 1098 1139 flushRegisters(); 1099 1140 1100 cachedGetById(node->origin.semantic, baseRegs, resultRegs, node->cacheableIdentifier(), JITCompiler::Jump(), DontSpill, accessType);1101 1102 jsValueResult(resultRegs, node, DataFormatJS, UseChildrenCalledExplicitly);1103 break;1104 }1105 1106 case UntypedUse: {1107 JSValueOperand base(this, node->child1());1108 JSValueRegs baseRegs = base.jsValueRegs();1109 1110 JSValueRegsFlushedCallResult result(this);1111 JSValueRegs resultRegs = result.regs();1112 1113 base.use();1114 1115 flushRegisters();1116 1117 1141 JITCompiler::Jump notCell = m_jit.branchIfNotCell(baseRegs); 1118 1142 1119 cachedGetById(node->origin.semantic, baseRegs, resultRegs, node->cacheableIdentifier(), notCell, DontSpill, accessType);1143 cachedGetById(node->origin.semantic, baseRegs, resultRegs, stubInfoGPR, node->cacheableIdentifier(), notCell, DontSpill, accessType); 1120 1144 1121 1145 jsValueResult(resultRegs, node, DataFormatJS, UseChildrenCalledExplicitly); … … 1132 1156 { 1133 1157 if (node->child1().useKind() == CellUse) { 1158 std::optional<GPRTemporary> stubInfo; 1134 1159 SpeculateCellOperand base(this, node->child1()); 1135 1160 JSValueRegsTemporary result(this); … … 1138 1163 JITCompiler::JumpList slowCases; 1139 1164 1165 GPRReg stubInfoGPR = InvalidGPRReg; 1166 if (JITCode::useDataIC(JITType::DFGJIT)) { 1167 stubInfo.emplace(this); 1168 stubInfoGPR = stubInfo->gpr(); 1169 } 1140 1170 JSValueRegs resultRegs = result.regs(); 1141 1142 1171 GPRReg baseGPR = base.gpr(); 1143 1172 GPRReg scratchGPR = scratch.gpr(); … … 1149 1178 1150 1179 JITDelByIdGenerator gen( 1151 m_jit.codeBlock(), codeOrigin, callSite, usedRegisters, node->cacheableIdentifier(),1152 JSValueRegs::payloadOnly(baseGPR), resultRegs, s cratchGPR);1180 m_jit.codeBlock(), JITType::DFGJIT, codeOrigin, callSite, usedRegisters, node->cacheableIdentifier(), 1181 JSValueRegs::payloadOnly(baseGPR), resultRegs, stubInfoGPR, scratchGPR); 1153 1182 1154 1183 gen.generateFastPath(m_jit); 1155 slowCases.append(gen.slowPathJump()); 1184 if (!JITCode::useDataIC(JITType::DFGJIT)) 1185 slowCases.append(gen.slowPathJump()); 1156 1186 1157 1187 #if USE(JSVALUE64) 1158 std::unique_ptr<SlowPathGenerator> slowPath = slowPathCall( 1159 slowCases, this, operationDeleteByIdOptimize, 1160 resultGPR, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(codeOrigin)), gen.stubInfo(), JSValueRegs(baseGPR), node->cacheableIdentifier().rawBits(), TrustedImm32(node->ecmaMode().value())); 1188 std::unique_ptr<SlowPathGenerator> slowPath; 1189 if (JITCode::useDataIC(JITType::DFGJIT)) { 1190 slowPath = slowPathICCall( 1191 slowCases, this, gen.stubInfo(), stubInfoGPR, CCallHelpers::Address(stubInfoGPR, StructureStubInfo::offsetOfSlowOperation()), operationDeleteByIdOptimize, 1192 resultGPR, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(codeOrigin)), stubInfoGPR, JSValueRegs(baseGPR), node->cacheableIdentifier().rawBits(), TrustedImm32(node->ecmaMode().value())); 1193 } else { 1194 slowPath = slowPathCall( 1195 slowCases, this, operationDeleteByIdOptimize, 1196 resultGPR, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(codeOrigin)), gen.stubInfo(), JSValueRegs(baseGPR), node->cacheableIdentifier().rawBits(), TrustedImm32(node->ecmaMode().value())); 1197 } 1161 1198 #else 1162 std::unique_ptr<SlowPathGenerator> slowPath = slowPathCall( 1163 slowCases, this, operationDeleteByIdOptimize, 1164 resultGPR, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(codeOrigin)), gen.stubInfo(), CCallHelpers::CellValue(baseGPR), node->cacheableIdentifier().rawBits(), TrustedImm32(node->ecmaMode().value())); 1199 std::unique_ptr<SlowPathGenerator> slowPath; 1200 if (JITCode::useDataIC(JITType::DFGJIT)) { 1201 slowPath = slowPathICCall( 1202 slowCases, this, gen.stubInfo(), stubInfoGPR, CCallHelpers::Address(stubInfoGPR, StructureStubInfo::offsetOfSlowOperation()), operationDeleteByIdOptimize, 1203 resultGPR, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(codeOrigin)), stubInfoGPR, CCallHelpers::CellValue(baseGPR), node->cacheableIdentifier().rawBits(), TrustedImm32(node->ecmaMode().value())); 1204 } else { 1205 slowPath = slowPathCall( 1206 slowCases, this, operationDeleteByIdOptimize, 1207 resultGPR, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(codeOrigin)), gen.stubInfo(), CCallHelpers::CellValue(baseGPR), node->cacheableIdentifier().rawBits(), TrustedImm32(node->ecmaMode().value())); 1208 } 1165 1209 #endif 1166 1210 … … 1191 1235 { 1192 1236 if (node->child1().useKind() == CellUse) { 1237 std::optional<GPRTemporary> stubInfo; 1193 1238 SpeculateCellOperand base(this, node->child1()); 1194 1195 1239 JSValueOperand key(this, node->child2(), ManualOperandSpeculation); 1196 speculate(node, node->child2());1197 1198 1240 JSValueRegsTemporary result(this, Reuse, key); 1199 1241 GPRTemporary scratch(this); … … 1201 1243 JITCompiler::JumpList slowCases; 1202 1244 1245 GPRReg stubInfoGPR = InvalidGPRReg; 1246 if (JITCode::useDataIC(JITType::DFGJIT)) { 1247 stubInfo.emplace(this); 1248 stubInfoGPR = stubInfo->gpr(); 1249 } 1203 1250 GPRReg baseGPR = base.gpr(); 1204 1251 JSValueRegs keyRegs = key.jsValueRegs(); … … 1207 1254 GPRReg resultGPR = resultRegs.payloadGPR(); 1208 1255 1256 speculate(node, node->child2()); 1257 1209 1258 if (needsTypeCheck(node->child2(), SpecCell)) 1210 1259 slowCases.append(m_jit.branchIfNotCell(keyRegs)); … … 1215 1264 1216 1265 JITDelByValGenerator gen( 1217 m_jit.codeBlock(), codeOrigin, callSite, usedRegisters,1218 JSValueRegs::payloadOnly(baseGPR), keyRegs, resultRegs, s cratchGPR);1266 m_jit.codeBlock(), JITType::DFGJIT, codeOrigin, callSite, usedRegisters, 1267 JSValueRegs::payloadOnly(baseGPR), keyRegs, resultRegs, stubInfoGPR, scratchGPR); 1219 1268 1220 1269 gen.generateFastPath(m_jit); 1221 slowCases.append(gen.slowPathJump()); 1270 if (!JITCode::useDataIC(JITType::DFGJIT)) 1271 slowCases.append(gen.slowPathJump()); 1222 1272 1223 1273 #if USE(JSVALUE64) 1224 std::unique_ptr<SlowPathGenerator> slowPath = slowPathCall( 1225 slowCases, this, operationDeleteByValOptimize, 1226 resultGPR, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(codeOrigin)), gen.stubInfo(), JSValueRegs(baseGPR), keyRegs, TrustedImm32(node->ecmaMode().value())); 1274 std::unique_ptr<SlowPathGenerator> slowPath; 1275 if (JITCode::useDataIC(JITType::DFGJIT)) { 1276 slowPath = slowPathICCall( 1277 slowCases, this, gen.stubInfo(), stubInfoGPR, CCallHelpers::Address(stubInfoGPR, StructureStubInfo::offsetOfSlowOperation()), operationDeleteByValOptimize, 1278 resultGPR, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(codeOrigin)), stubInfoGPR, JSValueRegs(baseGPR), keyRegs, TrustedImm32(node->ecmaMode().value())); 1279 } else { 1280 slowPath = slowPathCall( 1281 slowCases, this, operationDeleteByValOptimize, 1282 resultGPR, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(codeOrigin)), gen.stubInfo(), JSValueRegs(baseGPR), keyRegs, TrustedImm32(node->ecmaMode().value())); 1283 } 1227 1284 #else 1228 std::unique_ptr<SlowPathGenerator> slowPath = slowPathCall( 1229 slowCases, this, operationDeleteByValOptimize, 1230 resultGPR, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(codeOrigin)), gen.stubInfo(), CCallHelpers::CellValue(baseGPR), keyRegs, TrustedImm32(node->ecmaMode().value())); 1285 std::unique_ptr<SlowPathGenerator> slowPath; 1286 if (JITCode::useDataIC(JITType::DFGJIT)) { 1287 slowPath = slowPathICCall( 1288 slowCases, this, gen.stubInfo(), stubInfoGPR, CCallHelpers::Address(stubInfoGPR, StructureStubInfo::offsetOfSlowOperation()), operationDeleteByValOptimize, 1289 resultGPR, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(codeOrigin)), stubInfoGPR, CCallHelpers::CellValue(baseGPR), keyRegs, TrustedImm32(node->ecmaMode().value())); 1290 } else { 1291 slowPath = slowPathCall( 1292 slowCases, this, operationDeleteByValOptimize, 1293 resultGPR, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(codeOrigin)), gen.stubInfo(), CCallHelpers::CellValue(baseGPR), keyRegs, TrustedImm32(node->ecmaMode().value())); 1294 } 1231 1295 #endif 1232 1296 … … 1257 1321 void SpeculativeJIT::compileInById(Node* node) 1258 1322 { 1323 std::optional<GPRTemporary> stubInfo; 1259 1324 SpeculateCellOperand base(this, node->child1()); 1260 1325 JSValueRegsTemporary result(this, Reuse, base, PayloadWord); 1261 1326 1327 GPRReg stubInfoGPR = InvalidGPRReg; 1328 if (JITCode::useDataIC(JITType::DFGJIT)) { 1329 stubInfo.emplace(this); 1330 stubInfoGPR = stubInfo->gpr(); 1331 } 1262 1332 GPRReg baseGPR = base.gpr(); 1263 1333 JSValueRegs resultRegs = result.regs(); … … 1269 1339 RegisterSet usedRegisters = this->usedRegisters(); 1270 1340 JITInByIdGenerator gen( 1271 m_jit.codeBlock(), codeOrigin, callSite, usedRegisters, node->cacheableIdentifier(),1272 JSValueRegs::payloadOnly(baseGPR), resultRegs );1341 m_jit.codeBlock(), JITType::DFGJIT, codeOrigin, callSite, usedRegisters, node->cacheableIdentifier(), 1342 JSValueRegs::payloadOnly(baseGPR), resultRegs, stubInfoGPR); 1273 1343 gen.generateFastPath(m_jit); 1274 1344 1275 auto slowPath = slowPathCall( 1276 gen.slowPathJump(), this, operationInByIdOptimize, 1277 NeedToSpill, ExceptionCheckRequirement::CheckNeeded, 1278 resultRegs, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), gen.stubInfo(), CCallHelpers::CellValue(baseGPR), node->cacheableIdentifier().rawBits()); 1345 JITCompiler::JumpList slowCases; 1346 slowCases.append(gen.slowPathJump()); 1347 1348 std::unique_ptr<SlowPathGenerator> slowPath; 1349 if (JITCode::useDataIC(JITType::DFGJIT)) { 1350 slowPath = slowPathICCall( 1351 slowCases, this, gen.stubInfo(), stubInfoGPR, CCallHelpers::Address(stubInfoGPR, StructureStubInfo::offsetOfSlowOperation()), operationInByIdOptimize, 1352 NeedToSpill, ExceptionCheckRequirement::CheckNeeded, 1353 resultRegs, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), stubInfoGPR, CCallHelpers::CellValue(baseGPR), node->cacheableIdentifier().rawBits()); 1354 } else { 1355 slowPath = slowPathCall( 1356 slowCases, this, operationInByIdOptimize, 1357 NeedToSpill, ExceptionCheckRequirement::CheckNeeded, 1358 resultRegs, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), gen.stubInfo(), CCallHelpers::CellValue(baseGPR), node->cacheableIdentifier().rawBits()); 1359 } 1279 1360 1280 1361 m_jit.addInById(gen, slowPath.get()); … … 1289 1370 JSValueOperand key(this, node->child2()); 1290 1371 JSValueRegsTemporary result(this, Reuse, key); 1291 1372 std::optional<GPRTemporary> stubInfo; 1373 1374 GPRReg stubInfoGPR = InvalidGPRReg; 1375 if (JITCode::useDataIC(JITType::DFGJIT)) { 1376 stubInfo.emplace(this); 1377 stubInfoGPR = stubInfo->gpr(); 1378 } 1292 1379 GPRReg baseGPR = base.gpr(); 1293 1380 JSValueRegs keyRegs = key.jsValueRegs(); … … 1296 1383 base.use(); 1297 1384 key.use(); 1385 1386 CCallHelpers::JumpList slowCases; 1298 1387 1299 1388 CodeOrigin codeOrigin = node->origin.semantic; … … 1301 1390 RegisterSet usedRegisters = this->usedRegisters(); 1302 1391 JITInByValGenerator gen( 1303 m_jit.codeBlock(), codeOrigin, callSite, usedRegisters,1304 JSValueRegs::payloadOnly(baseGPR), keyRegs, resultRegs );1392 m_jit.codeBlock(), JITType::DFGJIT, codeOrigin, callSite, usedRegisters, 1393 JSValueRegs::payloadOnly(baseGPR), keyRegs, resultRegs, stubInfoGPR); 1305 1394 gen.generateFastPath(m_jit); 1306 1307 auto slowPath = slowPathCall( 1308 gen.slowPathJump(), this, operationInByValOptimize, 1309 NeedToSpill, ExceptionCheckRequirement::CheckNeeded, 1310 resultRegs, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), gen.stubInfo(), nullptr, CCallHelpers::CellValue(baseGPR), keyRegs); 1395 if (!JITCode::useDataIC(JITType::DFGJIT)) 1396 slowCases.append(gen.slowPathJump()); 1397 1398 std::unique_ptr<SlowPathGenerator> slowPath; 1399 if (JITCode::useDataIC(JITType::DFGJIT)) { 1400 slowPath = slowPathICCall( 1401 slowCases, this, gen.stubInfo(), stubInfoGPR, CCallHelpers::Address(stubInfoGPR, StructureStubInfo::offsetOfSlowOperation()), operationInByValOptimize, 1402 NeedToSpill, ExceptionCheckRequirement::CheckNeeded, 1403 resultRegs, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), stubInfoGPR, nullptr, CCallHelpers::CellValue(baseGPR), keyRegs); 1404 } else { 1405 slowPath = slowPathCall( 1406 slowCases, this, operationInByValOptimize, 1407 NeedToSpill, ExceptionCheckRequirement::CheckNeeded, 1408 resultRegs, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), gen.stubInfo(), nullptr, CCallHelpers::CellValue(baseGPR), keyRegs); 1409 } 1311 1410 1312 1411 m_jit.addInByVal(gen, slowPath.get()); … … 3604 3703 DFG_ASSERT(m_jit.graph(), node, node->op() == GetPrivateName); 3605 3704 DFG_ASSERT(m_jit.graph(), node, m_graph.child(node, 1).useKind() == SymbolUse); 3705 3706 std::optional<GPRTemporary> stubInfo; 3707 JSValueRegsTemporary result(this); 3708 3709 GPRReg stubInfoGPR = InvalidGPRReg; 3710 if (JITCode::useDataIC(JITType::DFGJIT)) { 3711 stubInfo.emplace(this); 3712 stubInfoGPR = stubInfo->gpr(); 3713 } 3714 JSValueRegs resultRegs = result.regs(); 3715 3606 3716 speculateSymbol(m_graph.child(node, 1)); 3607 3717 3608 JSValueRegsTemporary result(this);3609 3718 CodeOrigin codeOrigin = node->origin.semantic; 3610 3719 CallSiteIndex callSite = m_jit.recordCallSiteAndGenerateExceptionHandlingOSRExitIfNeeded(codeOrigin, m_stream->size()); … … 3617 3726 3618 3727 JITGetByValGenerator gen( 3619 m_jit.codeBlock(), codeOrigin, callSite, AccessType::GetPrivateName, usedRegisters,3620 base, property, result .regs());3728 m_jit.codeBlock(), JITType::DFGJIT, codeOrigin, callSite, AccessType::GetPrivateName, usedRegisters, 3729 base, property, resultRegs, stubInfoGPR); 3621 3730 gen.stubInfo()->propertyIsSymbol = true; 3622 3731 gen.generateFastPath(m_jit); 3623 3624 slowCases.append(gen.slowPathJump()); 3625 3626 auto makeSlowPathCall = [&](auto base) { 3732 if (!JITCode::useDataIC(JITType::DFGJIT)) 3733 slowCases.append(gen.slowPathJump()); 3734 3735 auto makeSlowPathICCall = [&](auto base) { 3736 if (JITCode::useDataIC(JITType::DFGJIT)) { 3737 return slowPathICCall( 3738 slowCases, this, gen.stubInfo(), stubInfoGPR, CCallHelpers::Address(stubInfoGPR, StructureStubInfo::offsetOfSlowOperation()), operationGetPrivateNameOptimize, 3739 result.regs(), TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(codeOrigin)), stubInfoGPR, 3740 base, CCallHelpers::CellValue(property.payloadGPR())); 3741 } 3627 3742 return slowPathCall( 3628 3743 slowCases, this, operationGetPrivateNameOptimize, … … 3632 3747 3633 3748 std::unique_ptr<SlowPathGenerator> slowPath = baseIsKnownCell 3634 ? makeSlowPath Call(CCallHelpers::CellValue(base.payloadGPR()))3635 : makeSlowPath Call(base);3749 ? makeSlowPathICCall(CCallHelpers::CellValue(base.payloadGPR())) 3750 : makeSlowPathICCall(base); 3636 3751 3637 3752 m_jit.addGetByVal(gen, slowPath.get()); … … 3645 3760 switch (m_graph.child(node, 0).useKind()) { 3646 3761 case CellUse: { 3762 std::optional<GPRTemporary> stubInfo; 3647 3763 SpeculateCellOperand base(this, m_graph.child(node, 0)); 3648 3764 JSValueRegsTemporary result(this, Reuse, base); 3649 3765 3766 GPRReg stubInfoGPR = InvalidGPRReg; 3767 if (JITCode::useDataIC(JITType::DFGJIT)) { 3768 stubInfo.emplace(this); 3769 stubInfoGPR = stubInfo->gpr(); 3770 } 3650 3771 JSValueRegs baseRegs = JSValueRegs::payloadOnly(base.gpr()); 3651 3772 JSValueRegs resultRegs = result.regs(); 3652 3773 3653 cachedGetById(node->origin.semantic, baseRegs, resultRegs, node->cacheableIdentifier(), JITCompiler::Jump(), NeedToSpill, AccessType::GetPrivateName);3774 cachedGetById(node->origin.semantic, baseRegs, resultRegs, stubInfoGPR, node->cacheableIdentifier(), JITCompiler::Jump(), NeedToSpill, AccessType::GetPrivateName); 3654 3775 3655 3776 jsValueResult(resultRegs, node, DataFormatJS); … … 3658 3779 3659 3780 case UntypedUse: { 3781 std::optional<GPRTemporary> stubInfo; 3660 3782 JSValueOperand base(this, m_graph.child(node, 0)); 3661 3783 JSValueRegsTemporary result(this, Reuse, base); 3662 3784 3785 GPRReg stubInfoGPR = InvalidGPRReg; 3786 if (JITCode::useDataIC(JITType::DFGJIT)) { 3787 stubInfo.emplace(this); 3788 stubInfoGPR = stubInfo->gpr(); 3789 } 3663 3790 JSValueRegs baseRegs = base.jsValueRegs(); 3664 3791 JSValueRegs resultRegs = result.regs(); … … 3666 3793 JITCompiler::Jump notCell = m_jit.branchIfNotCell(baseRegs); 3667 3794 3668 cachedGetById(node->origin.semantic, baseRegs, resultRegs, node->cacheableIdentifier(), notCell, NeedToSpill, AccessType::GetPrivateName);3795 cachedGetById(node->origin.semantic, baseRegs, resultRegs, stubInfoGPR, node->cacheableIdentifier(), notCell, NeedToSpill, AccessType::GetPrivateName); 3669 3796 3670 3797 jsValueResult(resultRegs, node, DataFormatJS); … … 3765 3892 void SpeculativeJIT::compilePutPrivateNameById(Node* node) 3766 3893 { 3894 std::optional<GPRTemporary> stubInfo; 3767 3895 SpeculateCellOperand base(this, node->child1()); 3768 3896 JSValueOperand value(this, node->child2()); 3897 GPRTemporary scratch(this); 3898 3899 GPRReg stubInfoGPR = InvalidGPRReg; 3900 if (JITCode::useDataIC(JITType::DFGJIT)) { 3901 stubInfo.emplace(this); 3902 stubInfoGPR = stubInfo->gpr(); 3903 } 3769 3904 JSValueRegs valueRegs = value.jsValueRegs(); 3770 3905 GPRReg baseGPR = base.gpr(); 3771 3772 GPRTemporary scratch(this);3773 3906 GPRReg scratchGPR = scratch.gpr(); 3774 3907 … … 3776 3909 // to check it here. 3777 3910 auto putKind = node->privateFieldPutKind().isDefine() ? PutKind::DirectPrivateFieldDefine : PutKind::DirectPrivateFieldSet; 3778 cachedPutById(node->origin.semantic, baseGPR, valueRegs, s cratchGPR, node->cacheableIdentifier(), putKind, ECMAMode::strict());3911 cachedPutById(node->origin.semantic, baseGPR, valueRegs, stubInfoGPR, scratchGPR, node->cacheableIdentifier(), putKind, ECMAMode::strict()); 3779 3912 3780 3913 noResult(node); … … 3783 3916 void SpeculativeJIT::compileCheckPrivateBrand(Node* node) 3784 3917 { 3918 std::optional<GPRTemporary> stubInfo; 3785 3919 JSValueOperand base(this, node->child1()); 3786 3920 SpeculateCellOperand brandValue(this, node->child2()); 3787 3921 3922 GPRReg stubInfoGPR = InvalidGPRReg; 3923 if (JITCode::useDataIC(JITType::DFGJIT)) { 3924 stubInfo.emplace(this); 3925 stubInfoGPR = stubInfo->gpr(); 3926 } 3788 3927 JSValueRegs baseRegs = base.jsValueRegs(); 3789 3790 3928 GPRReg brandGPR = brandValue.gpr(); 3791 3929 … … 3801 3939 3802 3940 JITPrivateBrandAccessGenerator gen( 3803 m_jit.codeBlock(), codeOrigin, callSite, AccessType::CheckPrivateBrand, usedRegisters,3804 baseRegs, JSValueRegs::payloadOnly(brandGPR) );3941 m_jit.codeBlock(), JITType::DFGJIT, codeOrigin, callSite, AccessType::CheckPrivateBrand, usedRegisters, 3942 baseRegs, JSValueRegs::payloadOnly(brandGPR), stubInfoGPR); 3805 3943 3806 3944 gen.stubInfo()->propertyIsSymbol = true; 3807 3945 gen.generateFastPath(m_jit); 3808 slowCases.append(gen.slowPathJump()); 3809 3810 std::unique_ptr<SlowPathGenerator> slowPath = slowPathCall( 3811 slowCases, this, operationCheckPrivateBrandOptimize, NoResult, 3812 TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(codeOrigin)), gen.stubInfo(), baseRegs, CCallHelpers::CellValue(brandGPR)); 3946 if (!JITCode::useDataIC(JITType::DFGJIT)) 3947 slowCases.append(gen.slowPathJump()); 3948 3949 std::unique_ptr<SlowPathGenerator> slowPath; 3950 if (JITCode::useDataIC(JITType::DFGJIT)) { 3951 slowPath = slowPathICCall( 3952 slowCases, this, gen.stubInfo(), stubInfoGPR, CCallHelpers::Address(stubInfoGPR, StructureStubInfo::offsetOfSlowOperation()), operationCheckPrivateBrandOptimize, NoResult, 3953 TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(codeOrigin)), stubInfoGPR, baseRegs, CCallHelpers::CellValue(brandGPR)); 3954 } else { 3955 slowPath = slowPathCall( 3956 slowCases, this, operationCheckPrivateBrandOptimize, NoResult, 3957 TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(codeOrigin)), gen.stubInfo(), baseRegs, CCallHelpers::CellValue(brandGPR)); 3958 } 3813 3959 3814 3960 m_jit.addPrivateBrandAccess(gen, slowPath.get()); … … 3821 3967 { 3822 3968 ASSERT(node->child1().useKind() == CellUse); 3969 std::optional<GPRTemporary> stubInfo; 3823 3970 SpeculateCellOperand base(this, node->child1()); 3824 3971 SpeculateCellOperand brandValue(this, node->child2()); 3825 3972 3973 GPRReg stubInfoGPR = InvalidGPRReg; 3974 if (JITCode::useDataIC(JITType::DFGJIT)) { 3975 stubInfo.emplace(this); 3976 stubInfoGPR = stubInfo->gpr(); 3977 } 3826 3978 GPRReg baseGPR = base.gpr(); 3827 3979 GPRReg brandGPR = brandValue.gpr(); … … 3835 3987 JITCompiler::JumpList slowCases; 3836 3988 JITPrivateBrandAccessGenerator gen( 3837 m_jit.codeBlock(), codeOrigin, callSite, AccessType::SetPrivateBrand, usedRegisters,3838 JSValueRegs::payloadOnly(baseGPR), JSValueRegs::payloadOnly(brandGPR) );3989 m_jit.codeBlock(), JITType::DFGJIT, codeOrigin, callSite, AccessType::SetPrivateBrand, usedRegisters, 3990 JSValueRegs::payloadOnly(baseGPR), JSValueRegs::payloadOnly(brandGPR), stubInfoGPR); 3839 3991 3840 3992 gen.stubInfo()->propertyIsSymbol = true; 3841 3993 gen.generateFastPath(m_jit); 3842 slowCases.append(gen.slowPathJump()); 3843 3844 std::unique_ptr<SlowPathGenerator> slowPath = slowPathCall( 3845 slowCases, this, operationSetPrivateBrandOptimize, NoResult, 3846 TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(codeOrigin)), gen.stubInfo(), CCallHelpers::CellValue(baseGPR), CCallHelpers::CellValue(brandGPR)); 3994 if (!JITCode::useDataIC(JITType::DFGJIT)) 3995 slowCases.append(gen.slowPathJump()); 3996 3997 std::unique_ptr<SlowPathGenerator> slowPath; 3998 if (JITCode::useDataIC(JITType::DFGJIT)) { 3999 slowPath = slowPathICCall( 4000 slowCases, this, gen.stubInfo(), stubInfoGPR, CCallHelpers::Address(stubInfoGPR, StructureStubInfo::offsetOfSlowOperation()), operationSetPrivateBrandOptimize, NoResult, 4001 TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(codeOrigin)), stubInfoGPR, CCallHelpers::CellValue(baseGPR), CCallHelpers::CellValue(brandGPR)); 4002 } else { 4003 slowPath = slowPathCall( 4004 slowCases, this, operationSetPrivateBrandOptimize, NoResult, 4005 TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(codeOrigin)), gen.stubInfo(), CCallHelpers::CellValue(baseGPR), CCallHelpers::CellValue(brandGPR)); 4006 } 3847 4007 3848 4008 m_jit.addPrivateBrandAccess(gen, slowPath.get()); … … 3962 4122 } 3963 4123 3964 void SpeculativeJIT::compileInstanceOfForCells(Node* node, JSValueRegs valueRegs, JSValueRegs prototypeRegs, GPRReg resultGPR, GPRReg s cratchGPR, GPRReg scratch2GPR, JITCompiler::Jump slowCase)4124 void SpeculativeJIT::compileInstanceOfForCells(Node* node, JSValueRegs valueRegs, JSValueRegs prototypeRegs, GPRReg resultGPR, GPRReg stubInfoGPR, GPRReg scratchGPR, GPRReg scratch2GPR, JITCompiler::Jump slowCase) 3965 4125 { 3966 4126 CallSiteIndex callSiteIndex = m_jit.addCallSite(node->origin.semantic); 3967 4127 3968 4128 JITInstanceOfGenerator gen( 3969 m_jit.codeBlock(), node->origin.semantic, callSiteIndex, usedRegisters(), resultGPR,3970 valueRegs.payloadGPR(), prototypeRegs.payloadGPR(), s cratchGPR, scratch2GPR,4129 m_jit.codeBlock(), JITType::DFGJIT, node->origin.semantic, callSiteIndex, usedRegisters(), resultGPR, 4130 valueRegs.payloadGPR(), prototypeRegs.payloadGPR(), stubInfoGPR, scratchGPR, scratch2GPR, 3971 4131 m_state.forNode(node->child2()).isType(SpecObject | ~SpecCell)); 3972 4132 gen.generateFastPath(m_jit); 3973 3974 4133 JITCompiler::JumpList slowCases; 4134 if (!JITCode::useDataIC(JITType::DFGJIT)) 4135 slowCases.append(gen.slowPathJump()); 3975 4136 slowCases.append(slowCase); 3976 3977 std::unique_ptr<SlowPathGenerator> slowPath = slowPathCall( 3978 slowCases, this, operationInstanceOfOptimize, resultGPR, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), gen.stubInfo(), valueRegs, 3979 prototypeRegs); 4137 4138 std::unique_ptr<SlowPathGenerator> slowPath; 4139 if (JITCode::useDataIC(JITType::DFGJIT)) { 4140 slowPath = slowPathICCall( 4141 slowCases, this, gen.stubInfo(), stubInfoGPR, CCallHelpers::Address(stubInfoGPR, StructureStubInfo::offsetOfSlowOperation()), operationInstanceOfOptimize, resultGPR, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), stubInfoGPR, valueRegs, prototypeRegs); 4142 } else { 4143 slowPath = slowPathCall( 4144 slowCases, this, operationInstanceOfOptimize, resultGPR, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), gen.stubInfo(), valueRegs, prototypeRegs); 4145 } 3980 4146 3981 4147 m_jit.addInstanceOf(gen, slowPath.get()); … … 3988 4154 if (node->child1().useKind() == CellUse 3989 4155 && node->child2().useKind() == CellUse) { 4156 std::optional<GPRTemporary> stubInfo; 3990 4157 SpeculateCellOperand value(this, node->child1()); 3991 4158 SpeculateCellOperand prototype(this, node->child2()); … … 3995 4162 GPRTemporary scratch2(this); 3996 4163 4164 GPRReg stubInfoGPR = InvalidGPRReg; 4165 if (JITCode::useDataIC(JITType::DFGJIT)) { 4166 stubInfo.emplace(this); 4167 stubInfoGPR = stubInfo->gpr(); 4168 } 3997 4169 GPRReg valueGPR = value.gpr(); 3998 4170 GPRReg prototypeGPR = prototype.gpr(); … … 4001 4173 GPRReg scratch2GPR = scratch2.gpr(); 4002 4174 4003 compileInstanceOfForCells(node, JSValueRegs(valueGPR), JSValueRegs(prototypeGPR), resultGPR, s cratchGPR, scratch2GPR);4175 compileInstanceOfForCells(node, JSValueRegs(valueGPR), JSValueRegs(prototypeGPR), resultGPR, stubInfoGPR, scratchGPR, scratch2GPR); 4004 4176 4005 4177 blessedBooleanResult(resultGPR, node); … … 4011 4183 DFG_ASSERT(m_jit.graph(), node, node->child2().useKind() == UntypedUse); 4012 4184 4185 std::optional<GPRTemporary> stubInfo; 4013 4186 JSValueOperand value(this, node->child1()); 4014 4187 JSValueOperand prototype(this, node->child2()); … … 4017 4190 GPRTemporary scratch(this); 4018 4191 4192 GPRReg stubInfoGPR = InvalidGPRReg; 4193 if (JITCode::useDataIC(JITType::DFGJIT)) { 4194 stubInfo.emplace(this); 4195 stubInfoGPR = stubInfo->gpr(); 4196 } 4019 4197 JSValueRegs valueRegs = value.jsValueRegs(); 4020 4198 JSValueRegs prototypeRegs = prototype.jsValueRegs(); … … 4032 4210 JITCompiler::Jump slowCase = m_jit.branchIfNotCell(prototypeRegs); 4033 4211 4034 compileInstanceOfForCells(node, valueRegs, prototypeRegs, resultGPR, s cratchGPR, InvalidGPRReg, slowCase);4212 compileInstanceOfForCells(node, valueRegs, prototypeRegs, resultGPR, stubInfoGPR, scratchGPR, InvalidGPRReg, slowCase); 4035 4213 4036 4214 done.link(&m_jit); … … 13277 13455 void SpeculativeJIT::compilePutByIdFlush(Node* node) 13278 13456 { 13457 std::optional<GPRTemporary> stubInfo; 13279 13458 SpeculateCellOperand base(this, node->child1()); 13280 13459 JSValueOperand value(this, node->child2()); 13281 13460 GPRTemporary scratch(this); 13282 13461 13462 GPRReg stubInfoGPR = InvalidGPRReg; 13463 if (JITCode::useDataIC(JITType::DFGJIT)) { 13464 stubInfo.emplace(this); 13465 stubInfoGPR = stubInfo->gpr(); 13466 } 13283 13467 GPRReg baseGPR = base.gpr(); 13284 13468 JSValueRegs valueRegs = value.jsValueRegs(); … … 13286 13470 flushRegisters(); 13287 13471 13288 cachedPutById(node->origin.semantic, baseGPR, valueRegs, s cratchGPR, node->cacheableIdentifier(), PutKind::NotDirect, node->ecmaMode(), MacroAssembler::Jump(), DontSpill);13472 cachedPutById(node->origin.semantic, baseGPR, valueRegs, stubInfoGPR, scratchGPR, node->cacheableIdentifier(), PutKind::NotDirect, node->ecmaMode(), MacroAssembler::Jump(), DontSpill); 13289 13473 13290 13474 noResult(node); … … 13293 13477 void SpeculativeJIT::compilePutById(Node* node) 13294 13478 { 13479 std::optional<GPRTemporary> stubInfo; 13295 13480 SpeculateCellOperand base(this, node->child1()); 13296 13481 JSValueOperand value(this, node->child2()); 13297 13482 GPRTemporary scratch(this); 13298 13483 13484 GPRReg stubInfoGPR = InvalidGPRReg; 13485 if (JITCode::useDataIC(JITType::DFGJIT)) { 13486 stubInfo.emplace(this); 13487 stubInfoGPR = stubInfo->gpr(); 13488 } 13299 13489 GPRReg baseGPR = base.gpr(); 13300 13490 JSValueRegs valueRegs = value.jsValueRegs(); 13301 13491 GPRReg scratchGPR = scratch.gpr(); 13302 13492 13303 cachedPutById(node->origin.semantic, baseGPR, valueRegs, s cratchGPR, node->cacheableIdentifier(), PutKind::NotDirect, node->ecmaMode());13493 cachedPutById(node->origin.semantic, baseGPR, valueRegs, stubInfoGPR, scratchGPR, node->cacheableIdentifier(), PutKind::NotDirect, node->ecmaMode()); 13304 13494 13305 13495 noResult(node); … … 13308 13498 void SpeculativeJIT::compilePutByIdDirect(Node* node) 13309 13499 { 13500 std::optional<GPRTemporary> stubInfo; 13310 13501 SpeculateCellOperand base(this, node->child1()); 13311 13502 JSValueOperand value(this, node->child2()); 13312 13503 GPRTemporary scratch(this); 13313 13504 13505 GPRReg stubInfoGPR = InvalidGPRReg; 13506 if (JITCode::useDataIC(JITType::DFGJIT)) { 13507 stubInfo.emplace(this); 13508 stubInfoGPR = stubInfo->gpr(); 13509 } 13314 13510 GPRReg baseGPR = base.gpr(); 13315 13511 JSValueRegs valueRegs = value.jsValueRegs(); 13316 13512 GPRReg scratchGPR = scratch.gpr(); 13317 13513 13318 cachedPutById(node->origin.semantic, baseGPR, valueRegs, s cratchGPR, node->cacheableIdentifier(), PutKind::Direct, node->ecmaMode());13514 cachedPutById(node->origin.semantic, baseGPR, valueRegs, stubInfoGPR, scratchGPR, node->cacheableIdentifier(), PutKind::Direct, node->ecmaMode()); 13319 13515 13320 13516 noResult(node); … … 14943 15139 } 14944 15140 14945 void SpeculativeJIT::cachedPutById(CodeOrigin codeOrigin, GPRReg baseGPR, JSValueRegs valueRegs, GPRReg s cratchGPR, CacheableIdentifier identifier, PutKind putKind, ECMAMode ecmaMode, JITCompiler::Jump slowPathTarget, SpillRegistersMode spillMode)15141 void SpeculativeJIT::cachedPutById(CodeOrigin codeOrigin, GPRReg baseGPR, JSValueRegs valueRegs, GPRReg stubInfoGPR, GPRReg scratchGPR, CacheableIdentifier identifier, PutKind putKind, ECMAMode ecmaMode, JITCompiler::Jump slowPathTarget, SpillRegistersMode spillMode) 14946 15142 { 14947 15143 RegisterSet usedRegisters = this->usedRegisters(); … … 14950 15146 usedRegisters.set(baseGPR, false); 14951 15147 usedRegisters.set(valueRegs, false); 15148 if (stubInfoGPR != InvalidGPRReg) 15149 usedRegisters.set(stubInfoGPR, false); 14952 15150 } 14953 15151 CallSiteIndex callSite = m_jit.recordCallSiteAndGenerateExceptionHandlingOSRExitIfNeeded(codeOrigin, m_stream->size()); 14954 15152 JITPutByIdGenerator gen( 14955 m_jit.codeBlock(), codeOrigin, callSite, usedRegisters, identifier,14956 JSValueRegs::payloadOnly(baseGPR), valueRegs, 15153 m_jit.codeBlock(), JITType::DFGJIT, codeOrigin, callSite, usedRegisters, identifier, 15154 JSValueRegs::payloadOnly(baseGPR), valueRegs, stubInfoGPR, 14957 15155 scratchGPR, ecmaMode, putKind); 14958 15156 … … 14964 15162 slowCases.append(gen.slowPathJump()); 14965 15163 14966 auto slowPath = slowPathCall( 14967 slowCases, this, gen.slowPathFunction(), NoResult, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(codeOrigin)), gen.stubInfo(), valueRegs, 14968 CCallHelpers::CellValue(baseGPR), identifier.rawBits()); 15164 std::unique_ptr<SlowPathGenerator> slowPath; 15165 if (JITCode::useDataIC(JITType::DFGJIT)) { 15166 slowPath = slowPathICCall( 15167 slowCases, this, gen.stubInfo(), stubInfoGPR, CCallHelpers::Address(stubInfoGPR, StructureStubInfo::offsetOfSlowOperation()), gen.slowPathFunction(), NoResult, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(codeOrigin)), stubInfoGPR, valueRegs, 15168 CCallHelpers::CellValue(baseGPR), identifier.rawBits()); 15169 } else { 15170 slowPath = slowPathCall( 15171 slowCases, this, gen.slowPathFunction(), NoResult, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(codeOrigin)), gen.stubInfo(), valueRegs, 15172 CCallHelpers::CellValue(baseGPR), identifier.rawBits()); 15173 } 14969 15174 14970 15175 m_jit.addPutById(gen, slowPath.get()); -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
r278568 r278656 720 720 void compileCheckDetached(Node*); 721 721 722 void cachedGetById(CodeOrigin, JSValueRegs base, JSValueRegs result, CacheableIdentifier, JITCompiler::Jump slowPathTarget, SpillRegistersMode, AccessType);723 void cachedPutById(CodeOrigin, GPRReg baseGPR, JSValueRegs valueRegs, GPRReg s cratchGPR, CacheableIdentifier, PutKind, ECMAMode, JITCompiler::Jump slowPathTarget = JITCompiler::Jump(), SpillRegistersMode = NeedToSpill);722 void cachedGetById(CodeOrigin, JSValueRegs base, JSValueRegs result, GPRReg stubInfoGPR, CacheableIdentifier, JITCompiler::Jump slowPathTarget, SpillRegistersMode, AccessType); 723 void cachedPutById(CodeOrigin, GPRReg baseGPR, JSValueRegs valueRegs, GPRReg stubInfoGPR, GPRReg scratchGPR, CacheableIdentifier, PutKind, ECMAMode, JITCompiler::Jump slowPathTarget = JITCompiler::Jump(), SpillRegistersMode = NeedToSpill); 724 724 void cachedGetByVal(CodeOrigin, JSValueRegs base, JSValueRegs property, JSValueRegs result, JITCompiler::Jump slowPathTarget); 725 725 726 726 #if USE(JSVALUE64) 727 void cachedGetById(CodeOrigin, GPRReg baseGPR, GPRReg resultGPR, CacheableIdentifier, JITCompiler::Jump slowPathTarget, SpillRegistersMode, AccessType);728 void cachedGetByIdWithThis(CodeOrigin, GPRReg baseGPR, GPRReg thisGPR, GPRReg resultGPR, CacheableIdentifier, const JITCompiler::JumpList& slowPathTarget = JITCompiler::JumpList());727 void cachedGetById(CodeOrigin, GPRReg baseGPR, GPRReg resultGPR, GPRReg stubInfoGPR, CacheableIdentifier, JITCompiler::Jump slowPathTarget, SpillRegistersMode, AccessType); 728 void cachedGetByIdWithThis(CodeOrigin, GPRReg baseGPR, GPRReg thisGPR, GPRReg resultGPR, GPRReg stubInfoGPR, CacheableIdentifier, const JITCompiler::JumpList& slowPathTarget = JITCompiler::JumpList()); 729 729 #elif USE(JSVALUE32_64) 730 void cachedGetById(CodeOrigin, GPRReg baseTagGPROrNone, GPRReg basePayloadGPR, GPRReg resultTagGPR, GPRReg resultPayloadGPR, CacheableIdentifier, JITCompiler::Jump slowPathTarget, SpillRegistersMode, AccessType);731 void cachedGetByIdWithThis(CodeOrigin, GPRReg baseTagGPROrNone, GPRReg basePayloadGPR, GPRReg thisTagGPROrNone, GPRReg thisPayloadGPR, GPRReg resultTagGPR, GPRReg resultPayloadGPR, CacheableIdentifier, const JITCompiler::JumpList& slowPathTarget = JITCompiler::JumpList());730 void cachedGetById(CodeOrigin, GPRReg baseTagGPROrNone, GPRReg basePayloadGPR, GPRReg resultTagGPR, GPRReg resultPayloadGPR, GPRReg stubInfoGPR, CacheableIdentifier, JITCompiler::Jump slowPathTarget, SpillRegistersMode, AccessType); 731 void cachedGetByIdWithThis(CodeOrigin, GPRReg baseTagGPROrNone, GPRReg basePayloadGPR, GPRReg thisTagGPROrNone, GPRReg thisPayloadGPR, GPRReg resultTagGPR, GPRReg resultPayloadGPR, GPRReg stubInfoGPR, CacheableIdentifier, const JITCompiler::JumpList& slowPathTarget = JITCompiler::JumpList()); 732 732 #endif 733 733 … … 752 752 bool genericJSValueStrictEq(Node*, bool invert = false); 753 753 754 void compileInstanceOfForCells(Node*, JSValueRegs valueGPR, JSValueRegs prototypeGPR, GPRReg resultGPT, GPRReg s cratchGPR, GPRReg scratch2GPR, JITCompiler::Jump slowCase = JITCompiler::Jump());754 void compileInstanceOfForCells(Node*, JSValueRegs valueGPR, JSValueRegs prototypeGPR, GPRReg resultGPT, GPRReg stubInfoGPR, GPRReg scratchGPR, GPRReg scratch2GPR, JITCompiler::Jump slowCase = JITCompiler::Jump()); 755 755 void compileInstanceOf(Node*); 756 756 void compileInstanceOfCustom(Node*); … … 950 950 } 951 951 952 template<typename OperationType, typename ResultRegType, typename... Args> 953 std::enable_if_t< 954 FunctionTraits<OperationType>::hasResult, 955 void> 956 callOperation(CCallHelpers::Address address, ResultRegType result, Args... args) 957 { 958 m_jit.setupArgumentsForIndirectCall<OperationType>(address, args...); 959 appendCallSetResult(CCallHelpers::Address(GPRInfo::nonArgGPR0, address.offset), result); 960 } 961 962 template<typename OperationType, typename... Args> 963 std::enable_if_t< 964 !FunctionTraits<OperationType>::hasResult, 965 void> 966 callOperation(CCallHelpers::Address address, Args... args) 967 { 968 m_jit.setupArgumentsForIndirectCall<OperationType>(address, args...); 969 appendCall(CCallHelpers::Address(GPRInfo::nonArgGPR0, address.offset)); 970 } 971 952 972 JITCompiler::Call callOperationWithCallFrameRollbackOnException(V_JITOperation_Cb operation, CodeBlock* codeBlock) 953 973 { … … 989 1009 } 990 1010 1011 void appendCall(CCallHelpers::Address address) 1012 { 1013 prepareForExternalCall(); 1014 m_jit.emitStoreCodeOrigin(m_currentNode->origin.semantic); 1015 m_jit.appendCall(address); 1016 } 1017 991 1018 JITCompiler::Call appendOperationCall(const FunctionPtr<OperationPtrTag> function) 992 1019 { … … 1009 1036 m_jit.move(GPRInfo::returnValueGPR, result); 1010 1037 return call; 1038 } 1039 1040 void appendCallSetResult(CCallHelpers::Address address, GPRReg result) 1041 { 1042 appendCall(address); 1043 if (result != InvalidGPRReg) 1044 m_jit.move(GPRInfo::returnValueGPR, result); 1045 } 1046 1047 void appendCallSetResult(CCallHelpers::Address address, GPRReg result1, GPRReg result2) 1048 { 1049 appendCall(address); 1050 m_jit.setupResults(result1, result2); 1051 } 1052 1053 void appendCallSetResult(CCallHelpers::Address address, JSValueRegs resultRegs) 1054 { 1055 #if USE(JSVALUE64) 1056 appendCallSetResult(address, resultRegs.gpr()); 1057 #else 1058 appendCallSetResult(address, resultRegs.payloadGPR(), resultRegs.tagGPR()); 1059 #endif 1011 1060 } 1012 1061 -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
r278462 r278656 169 169 } 170 170 171 void SpeculativeJIT::cachedGetById(CodeOrigin origin, JSValueRegs base, JSValueRegs result, CacheableIdentifier identifier, JITCompiler::Jump slowPathTarget , SpillRegistersMode mode, AccessType type)171 void SpeculativeJIT::cachedGetById(CodeOrigin origin, JSValueRegs base, JSValueRegs result, GPRReg stubInfoGPR, CacheableIdentifier identifier, JITCompiler::Jump slowPathTarget , SpillRegistersMode mode, AccessType type) 172 172 { 173 cachedGetById(origin, base.tagGPR(), base.payloadGPR(), result.tagGPR(), result.payloadGPR(), identifier, slowPathTarget, mode, type);173 cachedGetById(origin, base.tagGPR(), base.payloadGPR(), result.tagGPR(), result.payloadGPR(), stubInfoGPR, identifier, slowPathTarget, mode, type); 174 174 } 175 175 176 176 void SpeculativeJIT::cachedGetById( 177 CodeOrigin codeOrigin, GPRReg baseTagGPROrNone, GPRReg basePayloadGPR, GPRReg resultTagGPR, GPRReg resultPayloadGPR, 177 CodeOrigin codeOrigin, GPRReg baseTagGPROrNone, GPRReg basePayloadGPR, GPRReg resultTagGPR, GPRReg resultPayloadGPR, GPRReg stubInfoGPR, 178 178 CacheableIdentifier identifier, JITCompiler::Jump slowPathTarget, SpillRegistersMode spillMode, AccessType type) 179 179 { 180 UNUSED_PARAM(stubInfoGPR); 180 181 // This is a hacky fix for when the register allocator decides to alias the base payload with the result tag. This only happens 181 182 // in the case of GetByIdFlush/GetByIdDirectFlush, which has a relatively expensive register allocation story already so we probably don't need to … … 201 202 CallSiteIndex callSite = m_jit.recordCallSiteAndGenerateExceptionHandlingOSRExitIfNeeded(codeOrigin, m_stream->size()); 202 203 JITGetByIdGenerator gen( 203 m_jit.codeBlock(), codeOrigin, callSite, usedRegisters, identifier,204 JSValueRegs(baseTagGPROrNone, basePayloadGPR), JSValueRegs(resultTagGPR, resultPayloadGPR), type);204 m_jit.codeBlock(), JITType::DFGJIT, codeOrigin, callSite, usedRegisters, identifier, 205 JSValueRegs(baseTagGPROrNone, basePayloadGPR), JSValueRegs(resultTagGPR, resultPayloadGPR), InvalidGPRReg, type); 205 206 206 207 gen.generateFastPath(m_jit); … … 229 230 230 231 void SpeculativeJIT::cachedGetByIdWithThis( 231 CodeOrigin codeOrigin, GPRReg baseTagGPROrNone, GPRReg basePayloadGPR, GPRReg thisTagGPR, GPRReg thisPayloadGPR, GPRReg resultTagGPR, GPRReg resultPayloadGPR, 232 CodeOrigin codeOrigin, GPRReg baseTagGPROrNone, GPRReg basePayloadGPR, GPRReg thisTagGPR, GPRReg thisPayloadGPR, GPRReg resultTagGPR, GPRReg resultPayloadGPR, GPRReg stubInfoGPR, 232 233 CacheableIdentifier identifier, const JITCompiler::JumpList& slowPathTarget) 233 234 { 235 UNUSED_PARAM(stubInfoGPR); 234 236 RegisterSet usedRegisters = this->usedRegisters(); 235 237 236 238 CallSiteIndex callSite = m_jit.recordCallSiteAndGenerateExceptionHandlingOSRExitIfNeeded(codeOrigin, m_stream->size()); 237 239 JITGetByIdWithThisGenerator gen( 238 m_jit.codeBlock(), codeOrigin, callSite, usedRegisters, identifier,239 JSValueRegs(resultTagGPR, resultPayloadGPR), JSValueRegs(baseTagGPROrNone, basePayloadGPR), JSValueRegs(thisTagGPR, thisPayloadGPR) );240 m_jit.codeBlock(), JITType::DFGJIT, codeOrigin, callSite, usedRegisters, identifier, 241 JSValueRegs(resultTagGPR, resultPayloadGPR), JSValueRegs(baseTagGPROrNone, basePayloadGPR), JSValueRegs(thisTagGPR, thisPayloadGPR), InvalidGPRReg); 240 242 241 243 gen.generateFastPath(m_jit); … … 2342 2344 2343 2345 JITGetByValGenerator gen( 2344 m_jit.codeBlock(), codeOrigin, callSite, AccessType::GetByVal, usedRegisters,2345 baseRegs, propertyRegs, resultRegs );2346 m_jit.codeBlock(), JITType::DFGJIT, codeOrigin, callSite, AccessType::GetByVal, usedRegisters, 2347 baseRegs, propertyRegs, resultRegs, InvalidGPRReg); 2346 2348 2347 2349 if (m_state.forNode(m_graph.varArgChild(node, 1)).isType(SpecString)) … … 3410 3412 GPRReg resultPayloadGPR = resultPayload.gpr(); 3411 3413 3412 cachedGetByIdWithThis(node->origin.semantic, InvalidGPRReg, baseGPR, InvalidGPRReg, thisGPR, resultTagGPR, resultPayloadGPR, node->cacheableIdentifier());3414 cachedGetByIdWithThis(node->origin.semantic, InvalidGPRReg, baseGPR, InvalidGPRReg, thisGPR, resultTagGPR, resultPayloadGPR, InvalidGPRReg, node->cacheableIdentifier()); 3413 3415 3414 3416 jsValueResult(resultTagGPR, resultPayloadGPR, node); … … 3430 3432 notCellList.append(m_jit.branchIfNotCell(thisValue.jsValueRegs())); 3431 3433 3432 cachedGetByIdWithThis(node->origin.semantic, baseTagGPR, basePayloadGPR, thisTagGPR, thisPayloadGPR, resultTagGPR, resultPayloadGPR, node->cacheableIdentifier(), notCellList);3434 cachedGetByIdWithThis(node->origin.semantic, baseTagGPR, basePayloadGPR, thisTagGPR, thisPayloadGPR, resultTagGPR, resultPayloadGPR, InvalidGPRReg, node->cacheableIdentifier(), notCellList); 3433 3435 3434 3436 jsValueResult(resultTagGPR, resultPayloadGPR, node); -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
r278462 r278656 148 148 } 149 149 150 void SpeculativeJIT::cachedGetById(CodeOrigin origin, JSValueRegs base, JSValueRegs result, CacheableIdentifier identifier, JITCompiler::Jump slowPathTarget , SpillRegistersMode mode, AccessType type)150 void SpeculativeJIT::cachedGetById(CodeOrigin origin, JSValueRegs base, JSValueRegs result, GPRReg stubInfoGPR, CacheableIdentifier identifier, JITCompiler::Jump slowPathTarget , SpillRegistersMode mode, AccessType type) 151 151 { 152 cachedGetById(origin, base.gpr(), result.gpr(), identifier, slowPathTarget, mode, type);152 cachedGetById(origin, base.gpr(), result.gpr(), stubInfoGPR, identifier, slowPathTarget, mode, type); 153 153 } 154 154 155 void SpeculativeJIT::cachedGetById(CodeOrigin codeOrigin, GPRReg baseGPR, GPRReg resultGPR, CacheableIdentifier identifier, JITCompiler::Jump slowPathTarget, SpillRegistersMode spillMode, AccessType type)155 void SpeculativeJIT::cachedGetById(CodeOrigin codeOrigin, GPRReg baseGPR, GPRReg resultGPR, GPRReg stubInfoGPR, CacheableIdentifier identifier, JITCompiler::Jump slowPathTarget, SpillRegistersMode spillMode, AccessType type) 156 156 { 157 157 CallSiteIndex callSite = m_jit.recordCallSiteAndGenerateExceptionHandlingOSRExitIfNeeded(codeOrigin, m_stream->size()); … … 161 161 usedRegisters.set(baseGPR, false); 162 162 usedRegisters.set(resultGPR, false); 163 if (stubInfoGPR != InvalidGPRReg) 164 usedRegisters.set(stubInfoGPR, false); 163 165 } 164 166 JITGetByIdGenerator gen( 165 m_jit.codeBlock(), codeOrigin, callSite, usedRegisters, identifier,166 JSValueRegs(baseGPR), JSValueRegs(resultGPR), type);167 m_jit.codeBlock(), JITType::DFGJIT, codeOrigin, callSite, usedRegisters, identifier, 168 JSValueRegs(baseGPR), JSValueRegs(resultGPR), stubInfoGPR, type); 167 169 gen.generateFastPath(m_jit); 168 170 … … 171 173 slowCases.append(gen.slowPathJump()); 172 174 173 std::unique_ptr<SlowPathGenerator> slowPath = slowPathCall( 174 slowCases, this, appropriateOptimizingGetByIdFunction(type), 175 spillMode, ExceptionCheckRequirement::CheckNeeded, 176 resultGPR, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(codeOrigin)), gen.stubInfo(), baseGPR, identifier.rawBits()); 175 std::unique_ptr<SlowPathGenerator> slowPath; 176 if (JITCode::useDataIC(JITType::DFGJIT)) { 177 slowPath = slowPathICCall( 178 slowCases, this, gen.stubInfo(), stubInfoGPR, CCallHelpers::Address(stubInfoGPR, StructureStubInfo::offsetOfSlowOperation()), appropriateOptimizingGetByIdFunction(type), 179 spillMode, ExceptionCheckRequirement::CheckNeeded, 180 resultGPR, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(codeOrigin)), stubInfoGPR, baseGPR, identifier.rawBits()); 181 } else { 182 slowPath = slowPathCall( 183 slowCases, this, appropriateOptimizingGetByIdFunction(type), 184 spillMode, ExceptionCheckRequirement::CheckNeeded, 185 resultGPR, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(codeOrigin)), gen.stubInfo(), baseGPR, identifier.rawBits()); 186 } 177 187 178 188 m_jit.addGetById(gen, slowPath.get()); … … 180 190 } 181 191 182 void SpeculativeJIT::cachedGetByIdWithThis(CodeOrigin codeOrigin, GPRReg baseGPR, GPRReg thisGPR, GPRReg resultGPR, CacheableIdentifier identifier, const JITCompiler::JumpList& slowPathTarget)192 void SpeculativeJIT::cachedGetByIdWithThis(CodeOrigin codeOrigin, GPRReg baseGPR, GPRReg thisGPR, GPRReg resultGPR, GPRReg stubInfoGPR, CacheableIdentifier identifier, const JITCompiler::JumpList& slowPathTarget) 183 193 { 184 194 CallSiteIndex callSite = m_jit.recordCallSiteAndGenerateExceptionHandlingOSRExitIfNeeded(codeOrigin, m_stream->size()); … … 188 198 usedRegisters.set(thisGPR, false); 189 199 usedRegisters.set(resultGPR, false); 200 if (stubInfoGPR != InvalidGPRReg) 201 usedRegisters.set(stubInfoGPR, false); 190 202 191 203 JITGetByIdWithThisGenerator gen( 192 m_jit.codeBlock(), codeOrigin, callSite, usedRegisters, identifier,193 JSValueRegs(resultGPR), JSValueRegs(baseGPR), JSValueRegs(thisGPR) );204 m_jit.codeBlock(), JITType::DFGJIT, codeOrigin, callSite, usedRegisters, identifier, 205 JSValueRegs(resultGPR), JSValueRegs(baseGPR), JSValueRegs(thisGPR), stubInfoGPR); 194 206 gen.generateFastPath(m_jit); 195 207 … … 198 210 slowCases.append(gen.slowPathJump()); 199 211 200 std::unique_ptr<SlowPathGenerator> slowPath = slowPathCall( 201 slowCases, this, operationGetByIdWithThisOptimize, 202 DontSpill, ExceptionCheckRequirement::CheckNeeded, 203 resultGPR, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(codeOrigin)), gen.stubInfo(), baseGPR, thisGPR, identifier.rawBits()); 212 std::unique_ptr<SlowPathGenerator> slowPath; 213 if (JITCode::useDataIC(JITType::DFGJIT)) { 214 slowPath = slowPathICCall( 215 slowCases, this, gen.stubInfo(), stubInfoGPR, CCallHelpers::Address(stubInfoGPR, StructureStubInfo::offsetOfSlowOperation()), operationGetByIdWithThisOptimize, 216 DontSpill, ExceptionCheckRequirement::CheckNeeded, 217 resultGPR, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(codeOrigin)), stubInfoGPR, baseGPR, thisGPR, identifier.rawBits()); 218 } else { 219 slowPath = slowPathCall( 220 slowCases, this, operationGetByIdWithThisOptimize, 221 DontSpill, ExceptionCheckRequirement::CheckNeeded, 222 resultGPR, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(codeOrigin)), gen.stubInfo(), baseGPR, thisGPR, identifier.rawBits()); 223 } 204 224 205 225 m_jit.addGetByIdWithThis(gen, slowPath.get()); … … 2682 2702 } 2683 2703 2684 speculate(node, m_graph.varArgChild(node, 0)); 2685 speculate(node, m_graph.varArgChild(node, 1)); 2686 2704 std::optional<GPRTemporary> stubInfo; 2687 2705 JSValueOperand base(this, m_graph.varArgChild(node, 0), ManualOperandSpeculation); 2688 2706 JSValueOperand property(this, m_graph.varArgChild(node, 1), ManualOperandSpeculation); 2689 2707 GPRTemporary result(this, Reuse, property); 2708 2709 GPRReg stubInfoGPR = InvalidGPRReg; 2710 if (JITCode::useDataIC(JITType::DFGJIT)) { 2711 stubInfo.emplace(this); 2712 stubInfoGPR = stubInfo->gpr(); 2713 } 2690 2714 GPRReg baseGPR = base.gpr(); 2691 2715 GPRReg propertyGPR = property.gpr(); 2692 2716 GPRReg resultGPR = result.gpr(); 2693 2717 2718 speculate(node, m_graph.varArgChild(node, 0)); 2719 speculate(node, m_graph.varArgChild(node, 1)); 2720 2694 2721 CodeOrigin codeOrigin = node->origin.semantic; 2695 2722 CallSiteIndex callSite = m_jit.recordCallSiteAndGenerateExceptionHandlingOSRExitIfNeeded(codeOrigin, m_stream->size()); … … 2701 2728 2702 2729 JITGetByValGenerator gen( 2703 m_jit.codeBlock(), codeOrigin, callSite, AccessType::GetByVal, usedRegisters,2704 JSValueRegs(baseGPR), JSValueRegs(propertyGPR), JSValueRegs(resultGPR) );2730 m_jit.codeBlock(), JITType::DFGJIT, codeOrigin, callSite, AccessType::GetByVal, usedRegisters, 2731 JSValueRegs(baseGPR), JSValueRegs(propertyGPR), JSValueRegs(resultGPR), stubInfoGPR); 2705 2732 2706 2733 if (m_state.forNode(m_graph.varArgChild(node, 1)).isType(SpecString)) … … 2713 2740 gen.generateFastPath(m_jit); 2714 2741 2715 slowCases.append(gen.slowPathJump()); 2716 2717 std::unique_ptr<SlowPathGenerator> slowPath = slowPathCall( 2718 slowCases, this, operationGetByValOptimize, 2719 resultGPR, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(codeOrigin)), gen.stubInfo(), nullptr, baseGPR, propertyGPR); 2742 if (!JITCode::useDataIC(JITType::DFGJIT)) 2743 slowCases.append(gen.slowPathJump()); 2744 2745 std::unique_ptr<SlowPathGenerator> slowPath; 2746 if (JITCode::useDataIC(JITType::DFGJIT)) { 2747 slowPath = slowPathICCall( 2748 slowCases, this, gen.stubInfo(), stubInfoGPR, CCallHelpers::Address(stubInfoGPR, StructureStubInfo::offsetOfSlowOperation()), operationGetByValOptimize, 2749 resultGPR, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(codeOrigin)), stubInfoGPR, nullptr, baseGPR, propertyGPR); 2750 } else { 2751 slowPath = slowPathCall( 2752 slowCases, this, operationGetByValOptimize, 2753 resultGPR, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(codeOrigin)), gen.stubInfo(), nullptr, baseGPR, propertyGPR); 2754 } 2720 2755 2721 2756 m_jit.addGetByVal(gen, slowPath.get()); … … 3989 4024 case GetByIdWithThis: { 3990 4025 if (node->child1().useKind() == CellUse && node->child2().useKind() == CellUse) { 4026 std::optional<GPRTemporary> stubInfo; 3991 4027 SpeculateCellOperand base(this, node->child1()); 4028 SpeculateCellOperand thisValue(this, node->child2()); 4029 4030 GPRReg stubInfoGPR = InvalidGPRReg; 4031 if (JITCode::useDataIC(JITType::DFGJIT)) { 4032 stubInfo.emplace(this); 4033 stubInfoGPR = stubInfo->gpr(); 4034 } 3992 4035 GPRReg baseGPR = base.gpr(); 3993 SpeculateCellOperand thisValue(this, node->child2());3994 4036 GPRReg thisValueGPR = thisValue.gpr(); 3995 4037 … … 3999 4041 flushRegisters(); 4000 4042 4001 cachedGetByIdWithThis(node->origin.semantic, baseGPR, thisValueGPR, resultGPR, node->cacheableIdentifier(), JITCompiler::JumpList());4043 cachedGetByIdWithThis(node->origin.semantic, baseGPR, thisValueGPR, resultGPR, stubInfoGPR, node->cacheableIdentifier(), JITCompiler::JumpList()); 4002 4044 4003 4045 jsValueResult(resultGPR, node); 4004 4046 4005 4047 } else { 4048 std::optional<GPRTemporary> stubInfo; 4006 4049 JSValueOperand base(this, node->child1()); 4050 JSValueOperand thisValue(this, node->child2()); 4051 4052 GPRReg stubInfoGPR = InvalidGPRReg; 4053 if (JITCode::useDataIC(JITType::DFGJIT)) { 4054 stubInfo.emplace(this); 4055 stubInfoGPR = stubInfo->gpr(); 4056 } 4007 4057 GPRReg baseGPR = base.gpr(); 4008 JSValueOperand thisValue(this, node->child2());4009 4058 GPRReg thisValueGPR = thisValue.gpr(); 4010 4059 … … 4018 4067 notCellList.append(m_jit.branchIfNotCell(JSValueRegs(thisValueGPR))); 4019 4068 4020 cachedGetByIdWithThis(node->origin.semantic, baseGPR, thisValueGPR, resultGPR, node->cacheableIdentifier(), notCellList);4069 cachedGetByIdWithThis(node->origin.semantic, baseGPR, thisValueGPR, resultGPR, stubInfoGPR, node->cacheableIdentifier(), notCellList); 4021 4070 4022 4071 jsValueResult(resultGPR, node); -
trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp
r278587 r278656 3989 3989 patchpoint->append(m_numberTag, ValueRep::lateReg(GPRInfo::numberTagRegister)); 3990 3990 patchpoint->clobber(RegisterSet::macroScratchRegisters()); 3991 patchpoint->numGPScratchRegisters = JITCode::useDataIC(JITType::FTLJIT) ? 1 : 0; 3991 3992 3992 3993 RefPtr<PatchpointExceptionHandle> exceptionHandle = preparePatchpointForExceptions(patchpoint); … … 4010 4011 GPRReg baseGPR = params[1].gpr(); 4011 4012 GPRReg propertyGPR = params[2].gpr(); 4013 GPRReg stubInfoGPR = JITCode::useDataIC(JITType::FTLJIT) ? params.gpScratch(0) : InvalidGPRReg; 4012 4014 4013 4015 auto generator = Box<JITGetByValGenerator>::create( 4014 jit.codeBlock(), node->origin.semantic, callSiteIndex, AccessType::GetPrivateName,4015 params.unavailableRegisters(), JSValueRegs(baseGPR), JSValueRegs(propertyGPR), JSValueRegs(resultGPR) );4016 jit.codeBlock(), JITType::FTLJIT, node->origin.semantic, callSiteIndex, AccessType::GetPrivateName, 4017 params.unavailableRegisters(), JSValueRegs(baseGPR), JSValueRegs(propertyGPR), JSValueRegs(resultGPR), stubInfoGPR); 4016 4018 4017 4019 CCallHelpers::Jump notCell; … … 4027 4029 if (notCell.isSet()) 4028 4030 notCell.link(&jit); 4029 generator->slowPathJump().link(&jit); 4031 if (!JITCode::useDataIC(JITType::FTLJIT)) 4032 generator->slowPathJump().link(&jit); 4030 4033 CCallHelpers::Label slowPathBegin = jit.label(); 4031 CCallHelpers::Call slowPathCall = callOperation( 4032 *state, params.unavailableRegisters(), jit, node->origin.semantic, 4033 exceptions.get(), operationGetPrivateNameOptimize, resultGPR, 4034 jit.codeBlock()->globalObjectFor(node->origin.semantic), 4035 CCallHelpers::TrustedImmPtr(generator->stubInfo()), baseGPR, propertyGPR).call(); 4034 CCallHelpers::Call slowPathCall; 4035 if (JITCode::useDataIC(JITType::FTLJIT)) { 4036 jit.move(CCallHelpers::TrustedImmPtr(generator->stubInfo()), stubInfoGPR); 4037 generator->stubInfo()->m_slowOperation = operationGetPrivateNameOptimize; 4038 slowPathCall = callOperation( 4039 *state, params.unavailableRegisters(), jit, node->origin.semantic, 4040 exceptions.get(), CCallHelpers::Address(stubInfoGPR, StructureStubInfo::offsetOfSlowOperation()), resultGPR, 4041 jit.codeBlock()->globalObjectFor(node->origin.semantic), 4042 stubInfoGPR, baseGPR, propertyGPR).call(); 4043 } else { 4044 slowPathCall = callOperation( 4045 *state, params.unavailableRegisters(), jit, node->origin.semantic, 4046 exceptions.get(), operationGetPrivateNameOptimize, resultGPR, 4047 jit.codeBlock()->globalObjectFor(node->origin.semantic), 4048 CCallHelpers::TrustedImmPtr(generator->stubInfo()), baseGPR, propertyGPR).call(); 4049 } 4036 4050 jit.jump().linkTo(done, &jit); 4037 4051 … … 4121 4135 patchpoint->append(m_numberTag, ValueRep::lateReg(GPRInfo::numberTagRegister)); 4122 4136 patchpoint->clobber(RegisterSet::macroScratchRegisters()); 4137 patchpoint->numGPScratchRegisters = JITCode::useDataIC(JITType::FTLJIT) ? 1 : 0; 4123 4138 4124 4139 RefPtr<PatchpointExceptionHandle> exceptionHandle = preparePatchpointForExceptions(patchpoint); … … 4141 4156 GPRReg baseGPR = params[0].gpr(); 4142 4157 GPRReg brandGPR = params[1].gpr(); 4158 GPRReg stubInfoGPR = JITCode::useDataIC(JITType::FTLJIT) ? params.gpScratch(0) : InvalidGPRReg; 4143 4159 4144 4160 auto generator = Box<JITPrivateBrandAccessGenerator>::create( 4145 jit.codeBlock(), node->origin.semantic, callSiteIndex, accessType,4146 params.unavailableRegisters(), JSValueRegs(baseGPR), JSValueRegs(brandGPR) );4161 jit.codeBlock(), JITType::FTLJIT, node->origin.semantic, callSiteIndex, accessType, 4162 params.unavailableRegisters(), JSValueRegs(baseGPR), JSValueRegs(brandGPR), stubInfoGPR); 4147 4163 4148 4164 CCallHelpers::Jump notCell; … … 4170 4186 if (notCell.isSet()) 4171 4187 notCell.link(&jit); 4172 generator->slowPathJump().link(&jit); 4188 if (!JITCode::useDataIC(JITType::FTLJIT)) 4189 generator->slowPathJump().link(&jit); 4173 4190 CCallHelpers::Label slowPathBegin = jit.label(); 4174 CCallHelpers::Call slowPathCall = callOperation( 4175 *state, params.unavailableRegisters(), jit, node->origin.semantic, 4176 exceptions.get(), appropriatePrivateAccessFunction(accessType), InvalidGPRReg, 4177 jit.codeBlock()->globalObjectFor(node->origin.semantic), 4178 CCallHelpers::TrustedImmPtr(generator->stubInfo()), baseGPR, brandGPR).call(); 4191 CCallHelpers::Call slowPathCall; 4192 if (JITCode::useDataIC(JITType::FTLJIT)) { 4193 jit.move(CCallHelpers::TrustedImmPtr(generator->stubInfo()), stubInfoGPR); 4194 generator->stubInfo()->m_slowOperation = appropriatePrivateAccessFunction(accessType); 4195 slowPathCall = callOperation( 4196 *state, params.unavailableRegisters(), jit, node->origin.semantic, 4197 exceptions.get(), CCallHelpers::Address(stubInfoGPR, StructureStubInfo::offsetOfSlowOperation()), InvalidGPRReg, 4198 jit.codeBlock()->globalObjectFor(node->origin.semantic), 4199 stubInfoGPR, baseGPR, brandGPR).call(); 4200 } else { 4201 slowPathCall = callOperation( 4202 *state, params.unavailableRegisters(), jit, node->origin.semantic, 4203 exceptions.get(), appropriatePrivateAccessFunction(accessType), InvalidGPRReg, 4204 jit.codeBlock()->globalObjectFor(node->origin.semantic), 4205 CCallHelpers::TrustedImmPtr(generator->stubInfo()), baseGPR, brandGPR).call(); 4206 } 4179 4207 jit.jump().linkTo(done, &jit); 4180 4208 … … 4527 4555 patchpoint->append(m_numberTag, ValueRep::reg(GPRInfo::numberTagRegister)); 4528 4556 patchpoint->clobber(RegisterSet::macroScratchRegisters()); 4557 patchpoint->numGPScratchRegisters = JITCode::useDataIC(JITType::FTLJIT) ? 1 : 0; 4529 4558 4530 4559 // FIXME: If this is a PutByIdFlush, we might want to late-clobber volatile registers. … … 4549 4578 exceptionHandle->scheduleExitCreationForUnwind(params, callSiteIndex); 4550 4579 4580 GPRReg stubInfoGPR = JITCode::useDataIC(JITType::FTLJIT) ? params.gpScratch(0) : InvalidGPRReg; 4581 4551 4582 auto generator = Box<JITPutByIdGenerator>::create( 4552 jit.codeBlock(), node->origin.semantic, callSiteIndex,4583 jit.codeBlock(), JITType::FTLJIT, node->origin.semantic, callSiteIndex, 4553 4584 params.unavailableRegisters(), identifier, JSValueRegs(params[0].gpr()), 4554 JSValueRegs(params[1].gpr()), GPRInfo::patchpointScratchRegister, ecmaMode,4585 JSValueRegs(params[1].gpr()), stubInfoGPR, GPRInfo::patchpointScratchRegister, ecmaMode, 4555 4586 putKind); 4556 4587 … … 4564 4595 generator->slowPathJump().link(&jit); 4565 4596 CCallHelpers::Label slowPathBegin = jit.label(); 4566 CCallHelpers::Call slowPathCall = callOperation( 4567 *state, params.unavailableRegisters(), jit, node->origin.semantic, 4568 exceptions.get(), generator->slowPathFunction(), InvalidGPRReg, 4569 jit.codeBlock()->globalObjectFor(node->origin.semantic), 4570 CCallHelpers::TrustedImmPtr(generator->stubInfo()), params[1].gpr(), 4571 params[0].gpr(), identifier.rawBits()).call(); 4597 CCallHelpers::Call slowPathCall; 4598 if (JITCode::useDataIC(JITType::FTLJIT)) { 4599 jit.move(CCallHelpers::TrustedImmPtr(generator->stubInfo()), stubInfoGPR); 4600 generator->stubInfo()->m_slowOperation = generator->slowPathFunction(); 4601 slowPathCall = callOperation( 4602 *state, params.unavailableRegisters(), jit, node->origin.semantic, 4603 exceptions.get(), CCallHelpers::Address(stubInfoGPR, StructureStubInfo::offsetOfSlowOperation()), InvalidGPRReg, 4604 jit.codeBlock()->globalObjectFor(node->origin.semantic), 4605 stubInfoGPR, params[1].gpr(), 4606 params[0].gpr(), identifier.rawBits()).call(); 4607 } else { 4608 slowPathCall = callOperation( 4609 *state, params.unavailableRegisters(), jit, node->origin.semantic, 4610 exceptions.get(), generator->slowPathFunction(), InvalidGPRReg, 4611 jit.codeBlock()->globalObjectFor(node->origin.semantic), 4612 CCallHelpers::TrustedImmPtr(generator->stubInfo()), params[1].gpr(), 4613 params[0].gpr(), identifier.rawBits()).call(); 4614 } 4572 4615 jit.jump().linkTo(done, &jit); 4573 4616 … … 5250 5293 patchpoint->append(m_numberTag, ValueRep::lateReg(GPRInfo::numberTagRegister)); 5251 5294 patchpoint->clobber(RegisterSet::macroScratchRegisters()); 5295 patchpoint->numGPScratchRegisters = JITCode::useDataIC(JITType::FTLJIT) ? 1 : 0; 5252 5296 5253 5297 RefPtr<PatchpointExceptionHandle> exceptionHandle = preparePatchpointForExceptions(patchpoint); … … 5270 5314 GPRReg baseGPR = params[1].gpr(); 5271 5315 GPRReg propertyGPR = params[2].gpr(); 5316 GPRReg stubInfoGPR = JITCode::useDataIC(JITType::FTLJIT) ? params.gpScratch(0) : InvalidGPRReg; 5272 5317 5273 5318 auto generator = Box<JITGetByValGenerator>::create( 5274 jit.codeBlock(), node->origin.semantic, callSiteIndex, AccessType::GetByVal,5275 params.unavailableRegisters(), JSValueRegs(baseGPR), JSValueRegs(propertyGPR), JSValueRegs(resultGPR) );5319 jit.codeBlock(), JITType::FTLJIT, node->origin.semantic, callSiteIndex, AccessType::GetByVal, 5320 params.unavailableRegisters(), JSValueRegs(baseGPR), JSValueRegs(propertyGPR), JSValueRegs(resultGPR), stubInfoGPR); 5276 5321 5277 5322 generator->stubInfo()->propertyIsString = propertyIsString; … … 5291 5336 if (notCell.isSet()) 5292 5337 notCell.link(&jit); 5293 generator->slowPathJump().link(&jit); 5338 if (!JITCode::useDataIC(JITType::FTLJIT)) 5339 generator->slowPathJump().link(&jit); 5294 5340 CCallHelpers::Label slowPathBegin = jit.label(); 5295 CCallHelpers::Call slowPathCall = callOperation( 5296 *state, params.unavailableRegisters(), jit, node->origin.semantic, 5297 exceptions.get(), operationGetByValOptimize, resultGPR, 5298 jit.codeBlock()->globalObjectFor(node->origin.semantic), 5299 CCallHelpers::TrustedImmPtr(generator->stubInfo()), CCallHelpers::TrustedImmPtr(nullptr), baseGPR, propertyGPR).call(); 5341 CCallHelpers::Call slowPathCall; 5342 if (JITCode::useDataIC(JITType::FTLJIT)) { 5343 jit.move(CCallHelpers::TrustedImmPtr(generator->stubInfo()), stubInfoGPR); 5344 generator->stubInfo()->m_slowOperation = operationGetByValOptimize; 5345 slowPathCall = callOperation( 5346 *state, params.unavailableRegisters(), jit, node->origin.semantic, 5347 exceptions.get(), CCallHelpers::Address(stubInfoGPR, StructureStubInfo::offsetOfSlowOperation()), resultGPR, 5348 jit.codeBlock()->globalObjectFor(node->origin.semantic), 5349 stubInfoGPR, CCallHelpers::TrustedImmPtr(nullptr), baseGPR, propertyGPR).call(); 5350 } else { 5351 slowPathCall = callOperation( 5352 *state, params.unavailableRegisters(), jit, node->origin.semantic, 5353 exceptions.get(), operationGetByValOptimize, resultGPR, 5354 jit.codeBlock()->globalObjectFor(node->origin.semantic), 5355 CCallHelpers::TrustedImmPtr(generator->stubInfo()), CCallHelpers::TrustedImmPtr(nullptr), baseGPR, propertyGPR).call(); 5356 } 5300 5357 jit.jump().linkTo(done, &jit); 5301 5358 … … 5847 5904 patchpoint->append(m_numberTag, ValueRep::lateReg(GPRInfo::numberTagRegister)); 5848 5905 patchpoint->clobber(RegisterSet::macroScratchRegisters()); 5849 patchpoint->numGPScratchRegisters = 1;5906 patchpoint->numGPScratchRegisters = JITCode::useDataIC(JITType::FTLJIT) ? 2 : 1; 5850 5907 5851 5908 RefPtr<PatchpointExceptionHandle> exceptionHandle = … … 5867 5924 auto base = JSValueRegs(params[1].gpr()); 5868 5925 auto returnGPR = params[0].gpr(); 5926 auto scratchGPR = params.gpScratch(0); 5927 auto stubInfoGPR = JITCode::useDataIC(JITType::FTLJIT) ? params.gpScratch(1) : InvalidGPRReg; 5869 5928 ASSERT(base.gpr() != returnGPR); 5870 ASSERT(base.gpr() != params.gpScratch(0));5871 ASSERT(returnGPR != params.gpScratch(0));5929 ASSERT(base.gpr() != scratchGPR); 5930 ASSERT(returnGPR != scratchGPR); 5872 5931 5873 5932 if (node->child1().useKind() == UntypedUse) … … 5885 5944 return CCallHelpers::TrustedImmPtr(subscriptValue.rawBits()); 5886 5945 else { 5887 ASSERT( params.gpScratch(0)!= params[2].gpr());5946 ASSERT(scratchGPR != params[2].gpr()); 5888 5947 if (node->child2().useKind() == UntypedUse) 5889 5948 slowCases.append(jit.branchIfNotCell(JSValueRegs(params[2].gpr()))); … … 5895 5954 if constexpr (kind == DelByKind::Normal) { 5896 5955 return Box<JITDelByIdGenerator>::create( 5897 jit.codeBlock(), node->origin.semantic, callSiteIndex,5956 jit.codeBlock(), JITType::FTLJIT, node->origin.semantic, callSiteIndex, 5898 5957 params.unavailableRegisters(), subscriptValue, base, 5899 JSValueRegs(returnGPR), params.gpScratch(0));5958 JSValueRegs(returnGPR), stubInfoGPR, scratchGPR); 5900 5959 } else { 5901 5960 return Box<JITDelByValGenerator>::create( 5902 jit.codeBlock(), node->origin.semantic, callSiteIndex,5961 jit.codeBlock(), JITType::FTLJIT, node->origin.semantic, callSiteIndex, 5903 5962 params.unavailableRegisters(), base, 5904 subscript, JSValueRegs(returnGPR), params.gpScratch(0));5963 subscript, JSValueRegs(returnGPR), stubInfoGPR, scratchGPR); 5905 5964 } 5906 5965 }(); 5907 5966 5908 5967 generator->generateFastPath(jit); 5909 slowCases.append(generator->slowPathJump()); 5968 if (!JITCode::useDataIC(JITType::FTLJIT)) 5969 slowCases.append(generator->slowPathJump()); 5910 5970 CCallHelpers::Label done = jit.label(); 5911 5971 … … 5916 5976 slowCases.link(&jit); 5917 5977 CCallHelpers::Label slowPathBegin = jit.label(); 5918 CCallHelpers::Call slowPathCall = callOperation( 5919 *state, params.unavailableRegisters(), jit, node->origin.semantic, 5920 exceptions.get(), optimizationFunction, returnGPR, 5921 jit.codeBlock()->globalObjectFor(node->origin.semantic), 5922 CCallHelpers::TrustedImmPtr(generator->stubInfo()), base, 5923 subscript, CCallHelpers::TrustedImm32(node->ecmaMode().value())).call(); 5978 CCallHelpers::Call slowPathCall; 5979 if (JITCode::useDataIC(JITType::FTLJIT)) { 5980 jit.move(CCallHelpers::TrustedImmPtr(generator->stubInfo()), stubInfoGPR); 5981 generator->stubInfo()->m_slowOperation = optimizationFunction; 5982 slowPathCall = callOperation( 5983 *state, params.unavailableRegisters(), jit, node->origin.semantic, 5984 exceptions.get(), CCallHelpers::Address(stubInfoGPR, StructureStubInfo::offsetOfSlowOperation()), returnGPR, 5985 jit.codeBlock()->globalObjectFor(node->origin.semantic), 5986 stubInfoGPR, base, 5987 subscript, CCallHelpers::TrustedImm32(node->ecmaMode().value())).call(); 5988 } else { 5989 slowPathCall = callOperation( 5990 *state, params.unavailableRegisters(), jit, node->origin.semantic, 5991 exceptions.get(), optimizationFunction, returnGPR, 5992 jit.codeBlock()->globalObjectFor(node->origin.semantic), 5993 CCallHelpers::TrustedImmPtr(generator->stubInfo()), base, 5994 subscript, CCallHelpers::TrustedImm32(node->ecmaMode().value())).call(); 5995 } 5924 5996 jit.jump().linkTo(done, &jit); 5925 5997 … … 12302 12374 patchpoint->append(m_numberTag, ValueRep::lateReg(GPRInfo::numberTagRegister)); 12303 12375 patchpoint->clobber(RegisterSet::macroScratchRegisters()); 12376 patchpoint->numGPScratchRegisters = JITCode::useDataIC(JITType::FTLJIT) ? 1 : 0; 12304 12377 12305 12378 RefPtr<PatchpointExceptionHandle> exceptionHandle = preparePatchpointForExceptions(patchpoint); … … 12316 12389 Box<CCallHelpers::JumpList> exceptions = exceptionHandle->scheduleExitCreation(params)->jumps(jit); 12317 12390 12391 GPRReg stubInfoGPR = JITCode::useDataIC(JITType::FTLJIT) ? params.gpScratch(0) : InvalidGPRReg; 12318 12392 auto returnGPR = params[0].gpr(); 12319 12393 auto base = JSValueRegs(params[1].gpr()); … … 12329 12403 if constexpr (kind == InByKind::Normal) { 12330 12404 return Box<JITInByIdGenerator>::create( 12331 jit.codeBlock(), node->origin.semantic, callSiteIndex,12405 jit.codeBlock(), JITType::FTLJIT, node->origin.semantic, callSiteIndex, 12332 12406 params.unavailableRegisters(), subscriptValue, base, 12333 JSValueRegs(returnGPR) );12407 JSValueRegs(returnGPR), stubInfoGPR); 12334 12408 } else { 12335 12409 return Box<JITInByValGenerator>::create( 12336 jit.codeBlock(), node->origin.semantic, callSiteIndex,12410 jit.codeBlock(), JITType::FTLJIT, node->origin.semantic, callSiteIndex, 12337 12411 params.unavailableRegisters(), base, subscript, 12338 JSValueRegs(returnGPR) );12412 JSValueRegs(returnGPR), stubInfoGPR); 12339 12413 } 12340 12414 }(); 12341 12415 12416 CCallHelpers::JumpList slowCases; 12342 12417 generator->generateFastPath(jit); 12418 if constexpr (kind == InByKind::Normal) 12419 slowCases.append(generator->slowPathJump()); 12420 else { 12421 if (!JITCode::useDataIC(JITType::FTLJIT)) 12422 slowCases.append(generator->slowPathJump()); 12423 } 12343 12424 CCallHelpers::Label done = jit.label(); 12344 12425 … … 12347 12428 AllowMacroScratchRegisterUsage allowScratch(jit); 12348 12429 12349 generator->slowPathJump().link(&jit);12430 slowCases.link(&jit); 12350 12431 CCallHelpers::Label slowPathBegin = jit.label(); 12351 12432 CCallHelpers::Call slowPathCall; 12352 12433 if constexpr (kind == InByKind::Normal) { 12353 slowPathCall = callOperation( 12354 *state, params.unavailableRegisters(), jit, node->origin.semantic, 12355 exceptions.get(), operationInByIdOptimize, returnGPR, 12356 jit.codeBlock()->globalObjectFor(node->origin.semantic), 12357 CCallHelpers::TrustedImmPtr(generator->stubInfo()), 12358 base, subscript).call(); 12434 if (JITCode::useDataIC(JITType::FTLJIT)) { 12435 jit.move(CCallHelpers::TrustedImmPtr(generator->stubInfo()), stubInfoGPR); 12436 generator->stubInfo()->m_slowOperation = operationInByIdOptimize; 12437 slowPathCall = callOperation( 12438 *state, params.unavailableRegisters(), jit, node->origin.semantic, 12439 exceptions.get(), CCallHelpers::Address(stubInfoGPR, StructureStubInfo::offsetOfSlowOperation()), returnGPR, 12440 jit.codeBlock()->globalObjectFor(node->origin.semantic), 12441 stubInfoGPR, base, subscript).call(); 12442 } else { 12443 slowPathCall = callOperation( 12444 *state, params.unavailableRegisters(), jit, node->origin.semantic, 12445 exceptions.get(), operationInByIdOptimize, returnGPR, 12446 jit.codeBlock()->globalObjectFor(node->origin.semantic), 12447 CCallHelpers::TrustedImmPtr(generator->stubInfo()), base, subscript).call(); 12448 } 12359 12449 } else { 12360 slowPathCall = callOperation( 12361 *state, params.unavailableRegisters(), jit, node->origin.semantic, 12362 exceptions.get(), operationInByValOptimize, returnGPR, 12363 jit.codeBlock()->globalObjectFor(node->origin.semantic), 12364 CCallHelpers::TrustedImmPtr(generator->stubInfo()), 12365 CCallHelpers::TrustedImmPtr(nullptr), base, subscript).call(); 12450 if (JITCode::useDataIC(JITType::FTLJIT)) { 12451 jit.move(CCallHelpers::TrustedImmPtr(generator->stubInfo()), stubInfoGPR); 12452 generator->stubInfo()->m_slowOperation = operationInByValOptimize; 12453 slowPathCall = callOperation( 12454 *state, params.unavailableRegisters(), jit, node->origin.semantic, 12455 exceptions.get(), CCallHelpers::Address(stubInfoGPR, StructureStubInfo::offsetOfSlowOperation()), returnGPR, 12456 jit.codeBlock()->globalObjectFor(node->origin.semantic), 12457 stubInfoGPR, 12458 CCallHelpers::TrustedImmPtr(nullptr), base, subscript).call(); 12459 } else { 12460 slowPathCall = callOperation( 12461 *state, params.unavailableRegisters(), jit, node->origin.semantic, 12462 exceptions.get(), operationInByValOptimize, returnGPR, 12463 jit.codeBlock()->globalObjectFor(node->origin.semantic), 12464 CCallHelpers::TrustedImmPtr(generator->stubInfo()), 12465 CCallHelpers::TrustedImmPtr(nullptr), base, subscript).call(); 12466 } 12366 12467 } 12367 12468 jit.jump().linkTo(done, &jit); … … 12581 12682 patchpoint->append(m_notCellMask, ValueRep::lateReg(GPRInfo::notCellMaskRegister)); 12582 12683 patchpoint->append(m_numberTag, ValueRep::lateReg(GPRInfo::numberTagRegister)); 12583 patchpoint->numGPScratchRegisters = 2;12684 patchpoint->numGPScratchRegisters = JITCode::useDataIC(JITType::FTLJIT) ? 3 : 2; 12584 12685 patchpoint->resultConstraints = { ValueRep::SomeEarlyRegister }; 12585 12686 patchpoint->clobber(RegisterSet::macroScratchRegisters()); … … 12597 12698 GPRReg scratchGPR = params.gpScratch(0); 12598 12699 GPRReg scratch2GPR = params.gpScratch(1); 12700 GPRReg stubInfoGPR = JITCode::useDataIC(JITType::FTLJIT) ? params.gpScratch(2) : InvalidGPRReg; 12599 12701 12600 12702 CCallHelpers::Jump doneJump; … … 12618 12720 12619 12721 auto generator = Box<JITInstanceOfGenerator>::create( 12620 jit.codeBlock(), node->origin.semantic, callSiteIndex,12621 params.unavailableRegisters(), resultGPR, valueGPR, prototypeGPR, s cratchGPR,12722 jit.codeBlock(), JITType::FTLJIT, node->origin.semantic, callSiteIndex, 12723 params.unavailableRegisters(), resultGPR, valueGPR, prototypeGPR, stubInfoGPR, scratchGPR, 12622 12724 scratch2GPR, prototypeIsObject); 12623 12725 generator->generateFastPath(jit); 12726 if (!JITCode::useDataIC(JITType::FTLJIT)) 12727 slowCases.append(generator->slowPathJump()); 12624 12728 CCallHelpers::Label done = jit.label(); 12625 12729 … … 12632 12736 slowCases.link(&jit); 12633 12737 CCallHelpers::Label slowPathBegin = jit.label(); 12634 CCallHelpers::Call slowPathCall = callOperation( 12635 *state, params.unavailableRegisters(), jit, node->origin.semantic, 12636 exceptions.get(), optimizationFunction, resultGPR, 12637 jit.codeBlock()->globalObjectFor(node->origin.semantic), 12638 CCallHelpers::TrustedImmPtr(generator->stubInfo()), valueGPR, 12639 prototypeGPR).call(); 12738 CCallHelpers::Call slowPathCall; 12739 if (JITCode::useDataIC(JITType::FTLJIT)) { 12740 jit.move(CCallHelpers::TrustedImmPtr(generator->stubInfo()), stubInfoGPR); 12741 generator->stubInfo()->m_slowOperation = optimizationFunction; 12742 slowPathCall = callOperation( 12743 *state, params.unavailableRegisters(), jit, node->origin.semantic, 12744 exceptions.get(), CCallHelpers::Address(stubInfoGPR, StructureStubInfo::offsetOfSlowOperation()), resultGPR, 12745 jit.codeBlock()->globalObjectFor(node->origin.semantic), 12746 stubInfoGPR, valueGPR, 12747 prototypeGPR).call(); 12748 } else { 12749 slowPathCall = callOperation( 12750 *state, params.unavailableRegisters(), jit, node->origin.semantic, 12751 exceptions.get(), optimizationFunction, resultGPR, 12752 jit.codeBlock()->globalObjectFor(node->origin.semantic), 12753 CCallHelpers::TrustedImmPtr(generator->stubInfo()), valueGPR, 12754 prototypeGPR).call(); 12755 } 12640 12756 jit.jump().linkTo(done, &jit); 12641 12757 … … 14081 14197 patchpoint->append(m_notCellMask, ValueRep::lateReg(GPRInfo::notCellMaskRegister)); 14082 14198 patchpoint->append(m_numberTag, ValueRep::lateReg(GPRInfo::numberTagRegister)); 14199 patchpoint->numGPScratchRegisters = JITCode::useDataIC(JITType::FTLJIT) ? 1 : 0; 14083 14200 14084 14201 // FIXME: If this is a GetByIdFlush/GetByIdDirectFlush, we might get some performance boost if we claim that it … … 14109 14226 exceptionHandle->scheduleExitCreationForUnwind(params, callSiteIndex); 14110 14227 14228 GPRReg stubInfoGPR = JITCode::useDataIC(JITType::FTLJIT) ? params.gpScratch(0) : InvalidGPRReg; 14229 14111 14230 auto generator = Box<JITGetByIdGenerator>::create( 14112 jit.codeBlock(), node->origin.semantic, callSiteIndex,14231 jit.codeBlock(), JITType::FTLJIT, node->origin.semantic, callSiteIndex, 14113 14232 params.unavailableRegisters(), identifier, JSValueRegs(params[1].gpr()), 14114 JSValueRegs(params[0].gpr()), type);14233 JSValueRegs(params[0].gpr()), stubInfoGPR, type); 14115 14234 14116 14235 generator->generateFastPath(jit); … … 14125 14244 generator->slowPathJump().link(&jit); 14126 14245 CCallHelpers::Label slowPathBegin = jit.label(); 14127 CCallHelpers::Call slowPathCall = callOperation( 14128 *state, params.unavailableRegisters(), jit, node->origin.semantic, 14129 exceptions.get(), optimizationFunction, params[0].gpr(), 14130 jit.codeBlock()->globalObjectFor(node->origin.semantic), 14131 CCallHelpers::TrustedImmPtr(generator->stubInfo()), params[1].gpr(), 14132 CCallHelpers::TrustedImmPtr(identifier.rawBits())).call(); 14246 CCallHelpers::Call slowPathCall; 14247 if (JITCode::useDataIC(JITType::FTLJIT)) { 14248 jit.move(CCallHelpers::TrustedImmPtr(generator->stubInfo()), stubInfoGPR); 14249 generator->stubInfo()->m_slowOperation = optimizationFunction; 14250 slowPathCall = callOperation( 14251 *state, params.unavailableRegisters(), jit, node->origin.semantic, 14252 exceptions.get(), CCallHelpers::Address(stubInfoGPR, StructureStubInfo::offsetOfSlowOperation()), params[0].gpr(), 14253 jit.codeBlock()->globalObjectFor(node->origin.semantic), 14254 stubInfoGPR, params[1].gpr(), 14255 CCallHelpers::TrustedImmPtr(identifier.rawBits())).call(); 14256 } else { 14257 slowPathCall = callOperation( 14258 *state, params.unavailableRegisters(), jit, node->origin.semantic, 14259 exceptions.get(), optimizationFunction, params[0].gpr(), 14260 jit.codeBlock()->globalObjectFor(node->origin.semantic), 14261 CCallHelpers::TrustedImmPtr(generator->stubInfo()), params[1].gpr(), 14262 CCallHelpers::TrustedImmPtr(identifier.rawBits())).call(); 14263 } 14133 14264 jit.jump().linkTo(done, &jit); 14134 14265 … … 14155 14286 patchpoint->append(m_notCellMask, ValueRep::lateReg(GPRInfo::notCellMaskRegister)); 14156 14287 patchpoint->append(m_numberTag, ValueRep::lateReg(GPRInfo::numberTagRegister)); 14157 14158 14288 patchpoint->clobber(RegisterSet::macroScratchRegisters()); 14289 patchpoint->numGPScratchRegisters = JITCode::useDataIC(JITType::FTLJIT) ? 1 : 0; 14159 14290 14160 14291 RefPtr<PatchpointExceptionHandle> exceptionHandle = … … 14178 14309 exceptionHandle->scheduleExitCreationForUnwind(params, callSiteIndex); 14179 14310 14311 GPRReg stubInfoGPR = JITCode::useDataIC(JITType::FTLJIT) ? params.gpScratch(0) : InvalidGPRReg; 14312 14180 14313 auto generator = Box<JITGetByIdWithThisGenerator>::create( 14181 jit.codeBlock(), node->origin.semantic, callSiteIndex,14314 jit.codeBlock(), JITType::FTLJIT, node->origin.semantic, callSiteIndex, 14182 14315 params.unavailableRegisters(), identifier, JSValueRegs(params[0].gpr()), 14183 JSValueRegs(params[1].gpr()), JSValueRegs(params[2].gpr()) );14316 JSValueRegs(params[1].gpr()), JSValueRegs(params[2].gpr()), stubInfoGPR); 14184 14317 14185 14318 generator->generateFastPath(jit); … … 14194 14327 generator->slowPathJump().link(&jit); 14195 14328 CCallHelpers::Label slowPathBegin = jit.label(); 14196 CCallHelpers::Call slowPathCall = callOperation( 14197 *state, params.unavailableRegisters(), jit, node->origin.semantic, 14198 exceptions.get(), optimizationFunction, params[0].gpr(), 14199 jit.codeBlock()->globalObjectFor(node->origin.semantic), 14200 CCallHelpers::TrustedImmPtr(generator->stubInfo()), params[1].gpr(), 14201 params[2].gpr(), CCallHelpers::TrustedImmPtr(identifier.rawBits())).call(); 14329 CCallHelpers::Call slowPathCall; 14330 if (JITCode::useDataIC(JITType::FTLJIT)) { 14331 jit.move(CCallHelpers::TrustedImmPtr(generator->stubInfo()), stubInfoGPR); 14332 generator->stubInfo()->m_slowOperation = optimizationFunction; 14333 slowPathCall = callOperation( 14334 *state, params.unavailableRegisters(), jit, node->origin.semantic, 14335 exceptions.get(), CCallHelpers::Address(stubInfoGPR, StructureStubInfo::offsetOfSlowOperation()), params[0].gpr(), 14336 jit.codeBlock()->globalObjectFor(node->origin.semantic), 14337 stubInfoGPR, params[1].gpr(), 14338 params[2].gpr(), CCallHelpers::TrustedImmPtr(identifier.rawBits())).call(); 14339 } else { 14340 slowPathCall = callOperation( 14341 *state, params.unavailableRegisters(), jit, node->origin.semantic, 14342 exceptions.get(), optimizationFunction, params[0].gpr(), 14343 jit.codeBlock()->globalObjectFor(node->origin.semantic), 14344 CCallHelpers::TrustedImmPtr(generator->stubInfo()), params[1].gpr(), 14345 params[2].gpr(), CCallHelpers::TrustedImmPtr(identifier.rawBits())).call(); 14346 } 14202 14347 jit.jump().linkTo(done, &jit); 14203 14348 -
trunk/Source/JavaScriptCore/ftl/FTLSlowPathCall.cpp
r268247 r278656 40 40 41 41 SlowPathCallContext::SlowPathCallContext( 42 RegisterSet usedRegisters, CCallHelpers& jit, unsigned numArgs, GPRReg returnRegister )42 RegisterSet usedRegisters, CCallHelpers& jit, unsigned numArgs, GPRReg returnRegister, GPRReg indirectCallTargetRegister) 43 43 : m_jit(jit) 44 44 , m_numArgs(numArgs) … … 64 64 if (returnRegister != InvalidGPRReg) 65 65 m_callingConventionRegisters.set(GPRInfo::returnValueGPR); 66 if (indirectCallTargetRegister != InvalidGPRReg) 67 m_callingConventionRegisters.set(indirectCallTargetRegister); 66 68 m_callingConventionRegisters.filter(usedRegisters); 67 69 … … 115 117 SlowPathCallKey SlowPathCallContext::keyWithTarget(FunctionPtr<CFunctionPtrTag> callTarget) const 116 118 { 117 return SlowPathCallKey(m_thunkSaveSet, callTarget, m_argumentRegisters, m_offset); 119 return SlowPathCallKey(m_thunkSaveSet, callTarget, m_argumentRegisters, m_offset, 0); 120 } 121 122 SlowPathCallKey SlowPathCallContext::keyWithTarget(CCallHelpers::Address address) const 123 { 124 return SlowPathCallKey(m_thunkSaveSet, nullptr, m_argumentRegisters, m_offset, address.offset); 118 125 } 119 126 … … 134 141 } 135 142 143 SlowPathCall SlowPathCallContext::makeCall(VM& vm, CCallHelpers::Address callTarget) 144 { 145 SlowPathCallKey key = keyWithTarget(callTarget); 146 SlowPathCall result = SlowPathCall(m_jit.call(JITThunkPtrTag), key); 147 148 m_jit.addLinkTask( 149 [result, &vm] (LinkBuffer& linkBuffer) { 150 MacroAssemblerCodeRef<JITThunkPtrTag> thunk = 151 vm.ftlThunks->getSlowPathCallThunk(vm, result.key()); 152 153 linkBuffer.link(result.call(), CodeLocationLabel<JITThunkPtrTag>(thunk.code())); 154 }); 155 156 return result; 157 } 158 136 159 CallSiteIndex callSiteIndexForCodeOrigin(State& state, CodeOrigin codeOrigin) 137 160 { -
trunk/Source/JavaScriptCore/ftl/FTLSlowPathCall.h
r254735 r278656 55 55 class SlowPathCallContext { 56 56 public: 57 SlowPathCallContext(RegisterSet usedRegisters, CCallHelpers&, unsigned numArgs, GPRReg returnRegister );57 SlowPathCallContext(RegisterSet usedRegisters, CCallHelpers&, unsigned numArgs, GPRReg returnRegister, GPRReg indirectCallTargetRegister); 58 58 ~SlowPathCallContext(); 59 59 … … 61 61 // so there is no need for you to link it yourself. 62 62 SlowPathCall makeCall(VM&, FunctionPtr<CFunctionPtrTag> callTarget); 63 SlowPathCall makeCall(VM&, CCallHelpers::Address); 63 64 64 65 private: 65 66 SlowPathCallKey keyWithTarget(FunctionPtr<CFunctionPtrTag> callTarget) const; 67 SlowPathCallKey keyWithTarget(CCallHelpers::Address) const; 66 68 67 69 RegisterSet m_argumentRegisters; … … 83 85 SlowPathCall call; 84 86 { 85 SlowPathCallContext context(usedRegisters, jit, sizeof...(ArgumentTypes) + 1, resultGPR );87 SlowPathCallContext context(usedRegisters, jit, sizeof...(ArgumentTypes) + 1, resultGPR, InvalidGPRReg); 86 88 jit.setupArguments<void(ArgumentTypes...)>(arguments...); 87 89 call = context.makeCall(vm, function); … … 118 120 } 119 121 122 template<typename... ArgumentTypes> 123 SlowPathCall callOperation( 124 VM& vm, const RegisterSet& usedRegisters, CCallHelpers& jit, CCallHelpers::JumpList* exceptionTarget, 125 CCallHelpers::Address function, GPRReg resultGPR, ArgumentTypes... arguments) 126 { 127 SlowPathCall call; 128 { 129 SlowPathCallContext context(usedRegisters, jit, sizeof...(ArgumentTypes) + 1, resultGPR, GPRInfo::nonArgGPR0); 130 jit.setupArgumentsForIndirectCall<void(ArgumentTypes...)>(function, arguments...); 131 call = context.makeCall(vm, CCallHelpers::Address(GPRInfo::nonArgGPR0, function.offset)); 132 } 133 if (exceptionTarget) 134 exceptionTarget->append(jit.emitExceptionCheck(vm)); 135 return call; 136 } 137 138 template<typename... ArgumentTypes> 139 SlowPathCall callOperation( 140 VM& vm, const RegisterSet& usedRegisters, CCallHelpers& jit, CallSiteIndex callSiteIndex, 141 CCallHelpers::JumpList* exceptionTarget, CCallHelpers::Address function, GPRReg resultGPR, 142 ArgumentTypes... arguments) 143 { 144 if (callSiteIndex) { 145 jit.store32( 146 CCallHelpers::TrustedImm32(callSiteIndex.bits()), 147 CCallHelpers::tagFor(VirtualRegister(CallFrameSlot::argumentCountIncludingThis))); 148 } 149 return callOperation(vm, usedRegisters, jit, exceptionTarget, function, resultGPR, arguments...); 150 } 151 152 CallSiteIndex callSiteIndexForCodeOrigin(State&, CodeOrigin); 153 154 template<typename... ArgumentTypes> 155 SlowPathCall callOperation( 156 State& state, const RegisterSet& usedRegisters, CCallHelpers& jit, CodeOrigin codeOrigin, 157 CCallHelpers::JumpList* exceptionTarget, CCallHelpers::Address function, GPRReg result, ArgumentTypes... arguments) 158 { 159 return callOperation( 160 state.vm(), usedRegisters, jit, callSiteIndexForCodeOrigin(state, codeOrigin), exceptionTarget, function, 161 result, arguments...); 162 } 163 120 164 } } // namespace JSC::FTL 121 165 -
trunk/Source/JavaScriptCore/ftl/FTLSlowPathCallKey.cpp
r230748 r278656 33 33 void SlowPathCallKey::dump(PrintStream& out) const 34 34 { 35 out.print("<usedRegisters = ", m_usedRegisters, ", offset = ", m_offset, ", callTarget = ", RawPointer(m_callTarget.executableAddress()), ", argumentRegisters = ", m_argumentRegisters, ">");35 out.print("<usedRegisters = ", m_usedRegisters, ", offset = ", m_offset, ", indirectOffset = ", m_indirectOffset, ", callTarget = ", RawPointer(m_callTarget.executableAddress()), ", argumentRegisters = ", m_argumentRegisters, ">"); 36 36 } 37 37 -
trunk/Source/JavaScriptCore/ftl/FTLSlowPathCallKey.h
r264488 r278656 52 52 SlowPathCallKey( 53 53 const RegisterSet& set, FunctionPtr<CFunctionPtrTag> callTarget, const RegisterSet& argumentRegisters, 54 ptrdiff_t offset )54 ptrdiff_t offset, int32_t indirectOffset) 55 55 : m_usedRegisters(set) 56 56 , m_callTarget(callTarget.retagged<OperationPtrTag>()) 57 57 , m_argumentRegisters(argumentRegisters) 58 58 , m_offset(offset) 59 , m_indirectOffset(indirectOffset) 59 60 { 60 61 } … … 64 65 const RegisterSet& argumentRegisters() const { return m_argumentRegisters; } 65 66 ptrdiff_t offset() const { return m_offset; } 67 int32_t indirectOffset() const { return m_indirectOffset; } 66 68 67 69 SlowPathCallKey withCallTarget(FunctionPtr<CFunctionPtrTag> callTarget) 68 70 { 69 return SlowPathCallKey(usedRegisters(), callTarget, argumentRegisters(), offset() );71 return SlowPathCallKey(usedRegisters(), callTarget, argumentRegisters(), offset(), indirectOffset()); 70 72 } 71 73 … … 77 79 SlowPathCallKey(EmptyValueTag) 78 80 : m_usedRegisters(RegisterSet::EmptyValue) 79 , m_offset(0)80 81 { 81 82 } … … 83 84 SlowPathCallKey(DeletedValueTag) 84 85 : m_usedRegisters(RegisterSet::DeletedValue) 85 , m_offset(0)86 86 { 87 87 } … … 94 94 return m_usedRegisters == other.m_usedRegisters 95 95 && m_callTarget == other.m_callTarget 96 && m_offset == other.m_offset; 96 && m_offset == other.m_offset 97 && m_indirectOffset == other.m_indirectOffset; 97 98 } 98 99 unsigned hash() const 99 100 { 100 return m_usedRegisters.hash() + PtrHash<void*>::hash(m_callTarget.executableAddress()) + m_offset ;101 return m_usedRegisters.hash() + PtrHash<void*>::hash(m_callTarget.executableAddress()) + m_offset + m_indirectOffset; 101 102 } 102 103 … … 105 106 FunctionPtr<OperationPtrTag> m_callTarget; 106 107 RegisterSet m_argumentRegisters; 107 ptrdiff_t m_offset; 108 ptrdiff_t m_offset { 0 }; 109 int32_t m_indirectOffset { 0 }; 108 110 }; 109 111 -
trunk/Source/JavaScriptCore/ftl/FTLThunks.cpp
r277928 r278656 79 79 80 80 // Tell GC mark phase how much of the scratch buffer is active during call. 81 jit.move(MacroAssembler::TrustedImmPtr(scratchBuffer->addressOfActiveLength()), GPRInfo::nonArgGPR 0);82 jit.storePtr(MacroAssembler::TrustedImmPtr(requiredScratchMemorySizeInBytes()), GPRInfo::nonArgGPR 0);81 jit.move(MacroAssembler::TrustedImmPtr(scratchBuffer->addressOfActiveLength()), GPRInfo::nonArgGPR1); 82 jit.storePtr(MacroAssembler::TrustedImmPtr(requiredScratchMemorySizeInBytes()), GPRInfo::nonArgGPR1); 83 83 84 84 jit.loadPtr(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); … … 201 201 } 202 202 203 jit.preserveReturnAddressAfterCall(GPRInfo::nonArgGPR 0);204 jit.storePtr(GPRInfo::nonArgGPR 0, AssemblyHelpers::Address(MacroAssembler::stackPointerRegister, key.offset()));203 jit.preserveReturnAddressAfterCall(GPRInfo::nonArgGPR1); 204 jit.storePtr(GPRInfo::nonArgGPR1, AssemblyHelpers::Address(MacroAssembler::stackPointerRegister, key.offset())); 205 205 jit.prepareCallOperation(vm); 206 206 207 registerClobberCheck(jit, key.argumentRegisters()); 208 209 AssemblyHelpers::Call call = jit.call(OperationPtrTag); 207 RegisterSet dontClobber = key.argumentRegisters(); 208 if (!key.callTarget()) 209 dontClobber.set(GPRInfo::nonArgGPR0); 210 registerClobberCheck(jit, WTFMove(dontClobber)); 211 212 AssemblyHelpers::Call call; 213 if (key.callTarget()) 214 call = jit.call(OperationPtrTag); 215 else 216 jit.call(CCallHelpers::Address(GPRInfo::nonArgGPR0, key.indirectOffset()), OperationPtrTag); 210 217 211 218 jit.loadPtr(AssemblyHelpers::Address(MacroAssembler::stackPointerRegister, key.offset()), GPRInfo::nonPreservedNonReturnGPR); … … 233 240 234 241 LinkBuffer patchBuffer(jit, GLOBAL_THUNK_ID, LinkBuffer::Profile::FTLThunk); 235 patchBuffer.link(call, key.callTarget()); 242 if (key.callTarget()) 243 patchBuffer.link(call, key.callTarget()); 236 244 return FINALIZE_CODE(patchBuffer, JITThunkPtrTag, "FTL slow path call thunk for %s", toCString(key).data()); 237 245 } -
trunk/Source/JavaScriptCore/jit/AssemblyHelpers.cpp
r278030 r278656 29 29 #if ENABLE(JIT) 30 30 31 #include "AccessCase.h" 31 32 #include "JITOperations.h" 32 33 #include "JSArrayBufferView.h" … … 653 654 linkBuffer.addMainThreadFinalizationTask([=, &vm] () { 654 655 MacroAssemblerCodeRef<JITStubRoutinePtrTag> virtualThunk = virtualThunkFor(vm, *info); 655 info->setSlowStub(GCAwareJITStubRoutine::create(v irtualThunk, vm));656 info->setSlowStub(GCAwareJITStubRoutine::create(vm, virtualThunk)); 656 657 MacroAssembler::repatchNearCall(callLocation, CodeLocationLabel<JITStubRoutinePtrTag>(virtualThunk.code())); 657 658 }); -
trunk/Source/JavaScriptCore/jit/CCallHelpers.cpp
r277858 r278656 73 73 } 74 74 75 void CCallHelpers::emitJITCodeOver(MacroAssemblerCodePtr<JSInternalPtrTag> where, WTF::Function<void(CCallHelpers&)> emitCode, const char* description)75 void CCallHelpers::emitJITCodeOver(MacroAssemblerCodePtr<JSInternalPtrTag> where, ScopedLambda<void(CCallHelpers&)> emitCode, const char* description) 76 76 { 77 77 CCallHelpers jit; -
trunk/Source/JavaScriptCore/jit/CCallHelpers.h
r277680 r278656 33 33 #include "StackAlignment.h" 34 34 #include <wtf/FunctionTraits.h> 35 #include <wtf/ScopedLambda.h> 35 36 36 37 namespace JSC { … … 208 209 // extraGPRArgs is used to track 64-bit argument types passed in register on 32-bit architectures. 209 210 // extraPoke is used to track 64-bit argument types passed on the stack. 210 template<unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned extraPoke>211 template<unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned nonArgGPRs, unsigned extraPoke> 211 212 struct ArgCollection { 212 213 ArgCollection() … … 220 221 } 221 222 222 template<unsigned a, unsigned b, unsigned c, unsigned d, unsigned e, unsigned f, unsigned g >223 ArgCollection(ArgCollection<a, b, c, d, e, f, g >& other)223 template<unsigned a, unsigned b, unsigned c, unsigned d, unsigned e, unsigned f, unsigned g, unsigned h> 224 ArgCollection(ArgCollection<a, b, c, d, e, f, g, h>& other) 224 225 { 225 226 gprSources = other.gprSources; … … 231 232 } 232 233 233 ArgCollection<numGPRArgs + 1, numGPRSources + 1, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> pushRegArg(GPRReg argument, GPRReg destination)234 { 235 ArgCollection<numGPRArgs + 1, numGPRSources + 1, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> result(*this);234 ArgCollection<numGPRArgs + 1, numGPRSources + 1, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, nonArgGPRs, extraPoke> pushRegArg(GPRReg argument, GPRReg destination) 235 { 236 ArgCollection<numGPRArgs + 1, numGPRSources + 1, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, nonArgGPRs, extraPoke> result(*this); 236 237 237 238 result.gprSources[numGPRSources] = argument; … … 240 241 } 241 242 242 ArgCollection<numGPRArgs, numGPRSources, numFPRArgs + 1, numFPRSources + 1, numCrossSources, extraGPRArgs, extraPoke> pushRegArg(FPRReg argument, FPRReg destination)243 { 244 ArgCollection<numGPRArgs, numGPRSources, numFPRArgs + 1, numFPRSources + 1, numCrossSources, extraGPRArgs, extraPoke> result(*this);243 ArgCollection<numGPRArgs, numGPRSources, numFPRArgs + 1, numFPRSources + 1, numCrossSources, extraGPRArgs, nonArgGPRs, extraPoke> pushRegArg(FPRReg argument, FPRReg destination) 244 { 245 ArgCollection<numGPRArgs, numGPRSources, numFPRArgs + 1, numFPRSources + 1, numCrossSources, extraGPRArgs, nonArgGPRs, extraPoke> result(*this); 245 246 246 247 result.fprSources[numFPRSources] = argument; … … 249 250 } 250 251 251 ArgCollection<numGPRArgs, numGPRSources, numFPRArgs + 1, numFPRSources, numCrossSources + 1, extraGPRArgs, extraPoke> pushRegArg(FPRReg argument, GPRReg destination)252 { 253 ArgCollection<numGPRArgs, numGPRSources, numFPRArgs + 1, numFPRSources, numCrossSources + 1, extraGPRArgs, extraPoke> result(*this);252 ArgCollection<numGPRArgs, numGPRSources, numFPRArgs + 1, numFPRSources, numCrossSources + 1, extraGPRArgs, nonArgGPRs, extraPoke> pushRegArg(FPRReg argument, GPRReg destination) 253 { 254 ArgCollection<numGPRArgs, numGPRSources, numFPRArgs + 1, numFPRSources, numCrossSources + 1, extraGPRArgs, nonArgGPRs, extraPoke> result(*this); 254 255 255 256 result.crossSources[numCrossSources] = argument; … … 258 259 } 259 260 260 ArgCollection<numGPRArgs, numGPRSources + 1, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs + 1, extraPoke> pushExtraRegArg(GPRReg argument, GPRReg destination)261 { 262 ArgCollection<numGPRArgs, numGPRSources + 1, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs + 1, extraPoke> result(*this);261 ArgCollection<numGPRArgs, numGPRSources + 1, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs + 1, nonArgGPRs, extraPoke> pushExtraRegArg(GPRReg argument, GPRReg destination) 262 { 263 ArgCollection<numGPRArgs, numGPRSources + 1, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs + 1, nonArgGPRs, extraPoke> result(*this); 263 264 264 265 result.gprSources[numGPRSources] = argument; … … 267 268 } 268 269 269 ArgCollection<numGPRArgs + 1, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> addGPRArg() 270 { 271 return ArgCollection<numGPRArgs + 1, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke>(*this); 272 } 273 274 ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs + 1, extraPoke> addGPRExtraArg() 275 { 276 return ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs + 1, extraPoke>(*this); 277 } 278 279 ArgCollection<numGPRArgs + 1, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> addStackArg(GPRReg) 280 { 281 return ArgCollection<numGPRArgs + 1, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke>(*this); 282 } 283 284 ArgCollection<numGPRArgs, numGPRSources, numFPRArgs + 1, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> addStackArg(FPRReg) 285 { 286 return ArgCollection<numGPRArgs, numGPRSources, numFPRArgs + 1, numFPRSources, numCrossSources, extraGPRArgs, extraPoke>(*this); 287 } 288 289 ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke + 1> addPoke() 290 { 291 return ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke + 1>(*this); 270 ArgCollection<numGPRArgs, numGPRSources + 1, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, nonArgGPRs + 1, extraPoke> pushNonArg(GPRReg argument, GPRReg destination) 271 { 272 ArgCollection<numGPRArgs, numGPRSources + 1, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, nonArgGPRs + 1, extraPoke> result(*this); 273 274 result.gprSources[numGPRSources] = argument; 275 result.gprDestinations[numGPRSources] = destination; 276 return result; 277 } 278 279 ArgCollection<numGPRArgs + 1, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, nonArgGPRs, extraPoke> addGPRArg() 280 { 281 return ArgCollection<numGPRArgs + 1, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, nonArgGPRs, extraPoke>(*this); 282 } 283 284 ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs + 1, nonArgGPRs, extraPoke> addGPRExtraArg() 285 { 286 return ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs + 1, nonArgGPRs, extraPoke>(*this); 287 } 288 289 ArgCollection<numGPRArgs + 1, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, nonArgGPRs, extraPoke> addStackArg(GPRReg) 290 { 291 return ArgCollection<numGPRArgs + 1, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, nonArgGPRs, extraPoke>(*this); 292 } 293 294 ArgCollection<numGPRArgs, numGPRSources, numFPRArgs + 1, numFPRSources, numCrossSources, extraGPRArgs, nonArgGPRs, extraPoke> addStackArg(FPRReg) 295 { 296 return ArgCollection<numGPRArgs, numGPRSources, numFPRArgs + 1, numFPRSources, numCrossSources, extraGPRArgs, nonArgGPRs, extraPoke>(*this); 297 } 298 299 ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, nonArgGPRs, extraPoke + 1> addPoke() 300 { 301 return ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, nonArgGPRs, extraPoke + 1>(*this); 292 302 } 293 303 … … 332 342 } 333 343 334 ALWAYS_INLINE unsigned calculatePokeOffset(unsigned currentGPRArgument, unsigned currentFPRArgument, unsigned numCrossSources, unsigned extraGPRArgs, unsigned extraPoke)344 ALWAYS_INLINE unsigned calculatePokeOffset(unsigned currentGPRArgument, unsigned currentFPRArgument, unsigned numCrossSources, unsigned extraGPRArgs, unsigned nonArgGPRs, unsigned extraPoke) 335 345 { 336 346 // Clang claims that it cannot find the symbol for FPRReg/GPRReg::numberOfArgumentRegisters when they are passed directly to std::max... seems like a bug 337 347 unsigned numberOfFPArgumentRegisters = FPRInfo::numberOfArgumentRegisters; 338 348 unsigned numberOfGPArgumentRegisters = GPRInfo::numberOfArgumentRegisters; 349 350 UNUSED_PARAM(nonArgGPRs); 339 351 340 352 currentGPRArgument += extraGPRArgs; … … 351 363 352 364 template<typename ArgType> 353 ALWAYS_INLINE void pokeForArgument(ArgType arg, unsigned currentGPRArgument, unsigned currentFPRArgument, unsigned numCrossSources, unsigned extraGPRArgs, unsigned extraPoke)354 { 355 unsigned pokeOffset = calculatePokeOffset(currentGPRArgument, currentFPRArgument, numCrossSources, extraGPRArgs, extraPoke);365 ALWAYS_INLINE void pokeForArgument(ArgType arg, unsigned currentGPRArgument, unsigned currentFPRArgument, unsigned numCrossSources, unsigned extraGPRArgs, unsigned nonArgGPRs, unsigned extraPoke) 366 { 367 unsigned pokeOffset = calculatePokeOffset(currentGPRArgument, currentFPRArgument, numCrossSources, extraGPRArgs, nonArgGPRs, extraPoke); 356 368 poke(arg, pokeOffset); 357 369 } 358 370 359 ALWAYS_INLINE bool stackAligned(unsigned currentGPRArgument, unsigned currentFPRArgument, unsigned numCrossSources, unsigned extraGPRArgs, unsigned extraPoke)360 { 361 unsigned pokeOffset = calculatePokeOffset(currentGPRArgument, currentFPRArgument, numCrossSources, extraGPRArgs, extraPoke);371 ALWAYS_INLINE bool stackAligned(unsigned currentGPRArgument, unsigned currentFPRArgument, unsigned numCrossSources, unsigned extraGPRArgs, unsigned nonArgGPRs, unsigned extraPoke) 372 { 373 unsigned pokeOffset = calculatePokeOffset(currentGPRArgument, currentFPRArgument, numCrossSources, extraGPRArgs, nonArgGPRs, extraPoke); 362 374 return !(pokeOffset & 1); 363 375 } … … 377 389 378 390 // Avoid MSVC optimization time explosion associated with __forceinline in recursive templates. 379 template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned extraPoke, typename RegType, typename... Args>380 ALWAYS_INLINE_EXCEPT_MSVC void marshallArgumentRegister(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> argSourceRegs, RegType arg, Args... args)391 template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned nonArgGPRs, unsigned extraPoke, typename RegType, typename... Args> 392 ALWAYS_INLINE_EXCEPT_MSVC void marshallArgumentRegister(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, nonArgGPRs, extraPoke> argSourceRegs, RegType arg, Args... args) 381 393 { 382 394 using InfoType = InfoTypeForReg<RegType>; … … 393 405 } 394 406 395 pokeForArgument(arg, numGPRArgs, numFPRArgs, numCrossSources, extraGPRArgs, extraPoke);407 pokeForArgument(arg, numGPRArgs, numFPRArgs, numCrossSources, extraGPRArgs, nonArgGPRs, extraPoke); 396 408 setupArgumentsImpl<OperationType>(argSourceRegs.addStackArg(arg), args...); 397 409 } 398 410 399 template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned extraPoke, typename... Args>400 ALWAYS_INLINE void setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> argSourceRegs, FPRReg arg, Args... args)411 template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned nonArgGPRs, unsigned extraPoke, typename... Args> 412 ALWAYS_INLINE void setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, nonArgGPRs, extraPoke> argSourceRegs, FPRReg arg, Args... args) 401 413 { 402 414 static_assert(std::is_same<CURRENT_ARGUMENT_TYPE, double>::value, "We should only be passing FPRRegs to a double"); … … 404 416 } 405 417 406 template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned extraPoke, typename... Args>407 ALWAYS_INLINE void setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> argSourceRegs, GPRReg arg, Args... args)418 template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned nonArgGPRs, unsigned extraPoke, typename... Args> 419 ALWAYS_INLINE void setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, nonArgGPRs, extraPoke> argSourceRegs, GPRReg arg, Args... args) 408 420 { 409 421 marshallArgumentRegister<OperationType>(argSourceRegs, arg, args...); 410 422 } 411 423 412 template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned extraPoke, typename... Args>413 ALWAYS_INLINE void setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> argSourceRegs, JSValueRegs arg, Args... args)424 template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned nonArgGPRs, unsigned extraPoke, typename... Args> 425 ALWAYS_INLINE void setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, nonArgGPRs, extraPoke> argSourceRegs, JSValueRegs arg, Args... args) 414 426 { 415 427 marshallArgumentRegister<OperationType>(argSourceRegs, arg.gpr(), args...); 416 428 } 417 429 418 template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned extraPoke, typename... Args>419 ALWAYS_INLINE void setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> argSourceRegs, CellValue arg, Args... args)430 template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned nonArgGPRs, unsigned extraPoke, typename... Args> 431 ALWAYS_INLINE void setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, nonArgGPRs, extraPoke> argSourceRegs, CellValue arg, Args... args) 420 432 { 421 433 marshallArgumentRegister<OperationType>(argSourceRegs, arg.gpr(), args...); … … 425 437 #if CPU(ARM_THUMB2) || CPU(MIPS) 426 438 427 template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned extraPoke, typename... Args>428 void setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> argSourceRegs, FPRReg arg, Args... args)439 template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned nonArgGPRs, unsigned extraPoke, typename... Args> 440 void setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, nonArgGPRs, extraPoke> argSourceRegs, FPRReg arg, Args... args) 429 441 { 430 442 static_assert(std::is_same<CURRENT_ARGUMENT_TYPE, double>::value, "We should only be passing FPRRegs to a double"); … … 470 482 471 483 if (currentGPArgCount < numberOfGPArgumentRegisters) { 472 pokeForArgument(arg, numGPRArgs, numFPRArgs, numCrossSources, extraGPRArgs + 1, extraPoke);484 pokeForArgument(arg, numGPRArgs, numFPRArgs, numCrossSources, extraGPRArgs + 1, nonArgGPRs, extraPoke); 473 485 setupArgumentsImpl<OperationType>(argSourceRegs.addGPRExtraArg().addStackArg(arg).addPoke(), args...); 474 486 return; … … 477 489 478 490 // Otherwise pass FP argument on stack. 479 if (stackAligned(numGPRArgs, numFPRArgs, numCrossSources, extraGPRArgs, extraPoke)) {480 pokeForArgument(arg, numGPRArgs, numFPRArgs, numCrossSources, extraGPRArgs, extraPoke);491 if (stackAligned(numGPRArgs, numFPRArgs, numCrossSources, extraGPRArgs, nonArgGPRs, extraPoke)) { 492 pokeForArgument(arg, numGPRArgs, numFPRArgs, numCrossSources, extraGPRArgs, nonArgGPRs, extraPoke); 481 493 setupArgumentsImpl<OperationType>(argSourceRegs.addStackArg(arg).addPoke(), args...); 482 494 } else { 483 pokeForArgument(arg, numGPRArgs, numFPRArgs, numCrossSources, extraGPRArgs, extraPoke + 1);495 pokeForArgument(arg, numGPRArgs, numFPRArgs, numCrossSources, extraGPRArgs, nonArgGPRs, extraPoke + 1); 484 496 setupArgumentsImpl<OperationType>(argSourceRegs.addStackArg(arg).addPoke().addPoke(), args...); 485 497 } 486 498 } 487 499 488 template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned extraPoke, typename... Args>500 template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned nonArgGPRs, unsigned extraPoke, typename... Args> 489 501 std::enable_if_t<sizeof(CURRENT_ARGUMENT_TYPE) <= 4> 490 setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> argSourceRegs, GPRReg arg, Args... args)502 setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, nonArgGPRs, extraPoke> argSourceRegs, GPRReg arg, Args... args) 491 503 { 492 504 unsigned numArgRegisters = GPRInfo::numberOfArgumentRegisters; … … 498 510 } 499 511 500 pokeForArgument(arg, numGPRArgs, numFPRArgs, numCrossSources, extraGPRArgs, extraPoke);512 pokeForArgument(arg, numGPRArgs, numFPRArgs, numCrossSources, extraGPRArgs, nonArgGPRs, extraPoke); 501 513 setupArgumentsImpl<OperationType>(argSourceRegs.addStackArg(arg), args...); 502 514 } 503 515 504 template<typename OperationType, typename Arg1, typename Arg2, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned extraPoke, typename... Args>505 void pokeArgumentsAligned(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> argSourceRegs, Arg1 arg1, Arg2 arg2, Args... args)516 template<typename OperationType, typename Arg1, typename Arg2, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned nonArgGPRs, unsigned extraPoke, typename... Args> 517 void pokeArgumentsAligned(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, nonArgGPRs, extraPoke> argSourceRegs, Arg1 arg1, Arg2 arg2, Args... args) 506 518 { 507 519 unsigned numArgRegisters = GPRInfo::numberOfArgumentRegisters; … … 509 521 510 522 if (currentArgCount + 1 == numArgRegisters) { 511 pokeForArgument(arg1, numGPRArgs, numFPRArgs, numCrossSources, extraGPRArgs + 1, extraPoke);512 pokeForArgument(arg2, numGPRArgs, numFPRArgs, numCrossSources, extraGPRArgs + 1, extraPoke + 1);523 pokeForArgument(arg1, numGPRArgs, numFPRArgs, numCrossSources, extraGPRArgs + 1, nonArgGPRs, extraPoke); 524 pokeForArgument(arg2, numGPRArgs, numFPRArgs, numCrossSources, extraGPRArgs + 1, nonArgGPRs, extraPoke + 1); 513 525 setupArgumentsImpl<OperationType>(argSourceRegs.addGPRExtraArg().addGPRArg().addPoke(), args...); 514 } else if (stackAligned(numGPRArgs, numFPRArgs, numCrossSources, extraGPRArgs, extraPoke)) {515 pokeForArgument(arg1, numGPRArgs, numFPRArgs, numCrossSources, extraGPRArgs, extraPoke);516 pokeForArgument(arg2, numGPRArgs, numFPRArgs, numCrossSources, extraGPRArgs, extraPoke + 1);526 } else if (stackAligned(numGPRArgs, numFPRArgs, numCrossSources, extraGPRArgs, nonArgGPRs, extraPoke)) { 527 pokeForArgument(arg1, numGPRArgs, numFPRArgs, numCrossSources, extraGPRArgs, nonArgGPRs, extraPoke); 528 pokeForArgument(arg2, numGPRArgs, numFPRArgs, numCrossSources, extraGPRArgs, nonArgGPRs, extraPoke + 1); 517 529 setupArgumentsImpl<OperationType>(argSourceRegs.addGPRArg().addPoke(), args...); 518 530 } else { 519 pokeForArgument(arg1, numGPRArgs, numFPRArgs, numCrossSources, extraGPRArgs, extraPoke + 1);520 pokeForArgument(arg2, numGPRArgs, numFPRArgs, numCrossSources, extraGPRArgs, extraPoke + 2);531 pokeForArgument(arg1, numGPRArgs, numFPRArgs, numCrossSources, extraGPRArgs, nonArgGPRs, extraPoke + 1); 532 pokeForArgument(arg2, numGPRArgs, numFPRArgs, numCrossSources, extraGPRArgs, nonArgGPRs, extraPoke + 2); 521 533 setupArgumentsImpl<OperationType>(argSourceRegs.addGPRArg().addPoke().addPoke(), args...); 522 534 } 523 535 } 524 536 525 template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned extraPoke, typename... Args>537 template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned nonArgGPRs, unsigned extraPoke, typename... Args> 526 538 std::enable_if_t<std::is_same<CURRENT_ARGUMENT_TYPE, EncodedJSValue>::value> 527 setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> argSourceRegs, CellValue payload, Args... args)539 setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, nonArgGPRs, extraPoke> argSourceRegs, CellValue payload, Args... args) 528 540 { 529 541 unsigned numArgRegisters = GPRInfo::numberOfArgumentRegisters; … … 545 557 } 546 558 547 template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned extraPoke, typename... Args>559 template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned nonArgGPRs, unsigned extraPoke, typename... Args> 548 560 std::enable_if_t<std::is_same<CURRENT_ARGUMENT_TYPE, EncodedJSValue>::value> 549 setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> argSourceRegs, JSValueRegs arg, Args... args)561 setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, nonArgGPRs, extraPoke> argSourceRegs, JSValueRegs arg, Args... args) 550 562 { 551 563 unsigned numArgRegisters = GPRInfo::numberOfArgumentRegisters; … … 570 582 #endif // USE(JSVALUE64) 571 583 572 template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned extraPoke, typename Arg, typename... Args>584 template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned nonArgGPRs, unsigned extraPoke, typename Arg, typename... Args> 573 585 ALWAYS_INLINE std::enable_if_t< 574 586 std::is_base_of<TrustedImm, Arg>::value 575 587 || std::is_convertible<Arg, TrustedImm>::value> // We have this since DFGSpeculativeJIT has it's own implementation of TrustedImmPtr 576 setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> argSourceRegs, Arg arg, Args... args)588 setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, nonArgGPRs, extraPoke> argSourceRegs, Arg arg, Args... args) 577 589 { 578 590 // Right now this only supports non-floating point immediate arguments since we never call operations with non-register values. … … 592 604 } 593 605 594 pokeForArgument(arg, numGPRArgs, numFPRArgs, numCrossSources, extraGPRArgs, extraPoke);606 pokeForArgument(arg, numGPRArgs, numFPRArgs, numCrossSources, extraGPRArgs, nonArgGPRs, extraPoke); 595 607 setupArgumentsImpl<OperationType>(argSourceRegs.addGPRArg(), args...); 596 608 } 597 609 598 template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned extraPoke, typename Arg, typename... Args>610 template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned nonArgGPRs, unsigned extraPoke, typename Arg, typename... Args> 599 611 ALWAYS_INLINE std::enable_if_t< 600 612 std::is_same<CURRENT_ARGUMENT_TYPE, Arg>::value 601 613 && std::is_integral<CURRENT_ARGUMENT_TYPE>::value 602 614 && (sizeof(CURRENT_ARGUMENT_TYPE) <= 4)> 603 setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> argSourceRegs, Arg arg, Args... args)615 setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, nonArgGPRs, extraPoke> argSourceRegs, Arg arg, Args... args) 604 616 { 605 617 setupArgumentsImpl<OperationType>(argSourceRegs, TrustedImm32(arg), args...); 606 618 } 607 619 608 template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned extraPoke, typename Arg, typename... Args>620 template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned nonArgGPRs, unsigned extraPoke, typename Arg, typename... Args> 609 621 ALWAYS_INLINE std::enable_if_t< 610 622 std::is_same<CURRENT_ARGUMENT_TYPE, Arg>::value 611 623 && std::is_integral<CURRENT_ARGUMENT_TYPE>::value 612 624 && (sizeof(CURRENT_ARGUMENT_TYPE) == 8)> 613 setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> argSourceRegs, Arg arg, Args... args)625 setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, nonArgGPRs, extraPoke> argSourceRegs, Arg arg, Args... args) 614 626 { 615 627 setupArgumentsImpl<OperationType>(argSourceRegs, TrustedImm64(arg), args...); 616 628 } 617 629 618 template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned extraPoke, typename Arg, typename... Args>630 template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned nonArgGPRs, unsigned extraPoke, typename Arg, typename... Args> 619 631 ALWAYS_INLINE std::enable_if_t< 620 632 std::is_pointer<CURRENT_ARGUMENT_TYPE>::value 621 633 && ((std::is_pointer<Arg>::value && std::is_convertible<std::remove_const_t<std::remove_pointer_t<Arg>>*, CURRENT_ARGUMENT_TYPE>::value) 622 634 || std::is_same<Arg, std::nullptr_t>::value)> 623 setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> argSourceRegs, Arg arg, Args... args)635 setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, nonArgGPRs, extraPoke> argSourceRegs, Arg arg, Args... args) 624 636 { 625 637 setupArgumentsImpl<OperationType>(argSourceRegs, TrustedImmPtr(arg), args...); … … 627 639 628 640 // Special case DFG::RegisteredStructure because it's really annoying to deal with otherwise... 629 template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned extraPoke, typename Arg, typename... Args>641 template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned nonArgGPRs, unsigned extraPoke, typename Arg, typename... Args> 630 642 ALWAYS_INLINE std::enable_if_t< 631 643 std::is_same<CURRENT_ARGUMENT_TYPE, Structure*>::value 632 644 && std::is_same<Arg, DFG::RegisteredStructure>::value> 633 setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> argSourceRegs, Arg arg, Args... args)645 setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, nonArgGPRs, extraPoke> argSourceRegs, Arg arg, Args... args) 634 646 { 635 647 setupArgumentsImpl<OperationType>(argSourceRegs, TrustedImmPtr(arg.get()), args...); … … 640 652 641 653 // Base case; set up the argument registers. 642 template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned extraPoke>643 ALWAYS_INLINE void setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> argSourceRegs)654 template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned nonArgGPRs, unsigned extraPoke> 655 ALWAYS_INLINE void setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, nonArgGPRs, extraPoke> argSourceRegs) 644 656 { 645 657 static_assert(FunctionTraits<OperationType>::arity == numGPRArgs + numFPRArgs, "One last sanity check"); … … 656 668 } 657 669 670 template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned nonArgGPRs, unsigned extraPoke, typename... Args> 671 ALWAYS_INLINE void setupArgumentsEntryImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, nonArgGPRs, extraPoke> argSourceRegs, Args... args) 672 { 673 using FirstArgumentType = typename FunctionTraits<OperationType>::template ArgumentType<0>; 674 if constexpr (std::is_same<FirstArgumentType, CallFrame*>::value) { 675 #if USE(JSVALUE64) 676 // This only really works for 64-bit since jsvalue regs mess things up for 32-bit... 677 static_assert(FunctionTraits<OperationType>::cCallArity() == sizeof...(Args) + 1, "Basic sanity check"); 678 #endif 679 setupArgumentsImpl<OperationType>(argSourceRegs, GPRInfo::callFrameRegister, args...); 680 } else { 681 #if USE(JSVALUE64) 682 // This only really works for 64-bit since jsvalue regs mess things up for 32-bit... 683 static_assert(FunctionTraits<OperationType>::cCallArity() == sizeof...(Args), "Basic sanity check"); 684 #endif 685 setupArgumentsImpl<OperationType>(argSourceRegs, args...); 686 } 687 } 688 658 689 public: 659 690 660 #define FIRST_ARGUMENT_TYPE typename FunctionTraits<OperationType>::template ArgumentType<0>661 662 691 template<typename OperationType, typename... Args> 663 ALWAYS_INLINE std::enable_if_t<std::is_same<FIRST_ARGUMENT_TYPE, CallFrame*>::value> setupArguments(Args... args) 664 { 665 #if USE(JSVALUE64) 666 // This only really works for 64-bit since jsvalue regs mess things up for 32-bit... 667 static_assert(FunctionTraits<OperationType>::cCallArity() == sizeof...(Args) + 1, "Basic sanity check"); 668 #endif 669 setupArgumentsImpl<OperationType, 0, 0, 0, 0, 0, 0, 0>(ArgCollection<0, 0, 0, 0, 0, 0, 0>(), GPRInfo::callFrameRegister, args...); 692 ALWAYS_INLINE void setupArguments(Args... args) 693 { 694 setupArgumentsEntryImpl<OperationType>(ArgCollection<0, 0, 0, 0, 0, 0, 0, 0>(), args...); 670 695 } 671 696 672 697 template<typename OperationType, typename... Args> 673 ALWAYS_INLINE std::enable_if_t<!std::is_same<FIRST_ARGUMENT_TYPE, CallFrame*>::value> setupArguments(Args... args)674 { 675 #if USE(JSVALUE64) 676 // This only really works for 64-bit since jsvalue regs mess things up for 32-bit...677 static_assert(FunctionTraits<OperationType>::cCallArity() == sizeof...(Args), "Basic sanity check"); 678 #endif 679 setupArgumentsImpl<OperationType, 0, 0, 0, 0, 0, 0, 0>(ArgCollection<0, 0, 0, 0, 0, 0, 0>(), args...);680 }681 682 #undef FIRST_ARGUMENT_TYPE 698 ALWAYS_INLINE void setupArgumentsForIndirectCall(GPRReg functionGPR, Args... args) 699 { 700 setupArgumentsEntryImpl<OperationType>(ArgCollection<0, 0, 0, 0, 0, 0, 0, 0>().pushNonArg(functionGPR, GPRInfo::nonArgGPR0), args...); 701 } 702 703 template<typename OperationType, typename... Args> 704 ALWAYS_INLINE void setupArgumentsForIndirectCall(Address address, Args... args) 705 { 706 setupArgumentsEntryImpl<OperationType>(ArgCollection<0, 0, 0, 0, 0, 0, 0, 0>().pushNonArg(address.base, GPRInfo::nonArgGPR0), args...); 707 } 683 708 684 709 void setupResults(GPRReg destA, GPRReg destB) … … 820 845 void ensureShadowChickenPacket(VM&, GPRReg shadowPacket, GPRReg scratch1NonArgGPR, GPRReg scratch2); 821 846 822 static void emitJITCodeOver(MacroAssemblerCodePtr<JSInternalPtrTag> where, WTF::Function<void(CCallHelpers&)>, const char*);847 static void emitJITCodeOver(MacroAssemblerCodePtr<JSInternalPtrTag> where, ScopedLambda<void(CCallHelpers&)>, const char*); 823 848 }; 824 849 -
trunk/Source/JavaScriptCore/jit/GCAwareJITStubRoutine.cpp
r277027 r278656 29 29 #if ENABLE(JIT) 30 30 31 #include "AccessCase.h" 31 32 #include "CodeBlock.h" 32 33 #include "DFGCommonData.h" … … 39 40 namespace JSC { 40 41 41 GCAwareJITStubRoutine::GCAwareJITStubRoutine( 42 const MacroAssemblerCodeRef<JITStubRoutinePtrTag>& code, VM& vm) 42 GCAwareJITStubRoutine::GCAwareJITStubRoutine(const MacroAssemblerCodeRef<JITStubRoutinePtrTag>& code) 43 43 : JITStubRoutine(code) 44 44 { 45 } 46 47 GCAwareJITStubRoutine::~GCAwareJITStubRoutine() { } 48 49 void GCAwareJITStubRoutine::makeGCAware(VM& vm) 50 { 45 51 vm.heap.m_jitStubRoutines->add(this); 46 } 47 48 GCAwareJITStubRoutine::~GCAwareJITStubRoutine() { } 52 m_isGCAware = true; 53 } 49 54 50 55 void GCAwareJITStubRoutine::observeZeroRefCount() 51 56 { 52 if (m_isJettisoned ) {57 if (m_isJettisoned || !m_isGCAware) { 53 58 // This case is needed for when the system shuts down. It may be that 54 59 // the JIT stub routine set gets deleted before we get around to deleting … … 75 80 } 76 81 82 PolymorphicAccessJITStubRoutine::PolymorphicAccessJITStubRoutine(const MacroAssemblerCodeRef<JITStubRoutinePtrTag>& code, VM& vm, FixedVector<RefPtr<AccessCase>>&& cases, FixedVector<StructureID>&& weakStructures) 83 : GCAwareJITStubRoutine(code) 84 , m_vm(vm) 85 , m_cases(WTFMove(cases)) 86 , m_weakStructures(WTFMove(weakStructures)) 87 { 88 } 89 90 void PolymorphicAccessJITStubRoutine::observeZeroRefCount() 91 { 92 if (m_vm.m_sharedJITStubs) 93 m_vm.m_sharedJITStubs->remove(this); 94 Base::observeZeroRefCount(); 95 } 96 97 unsigned PolymorphicAccessJITStubRoutine::computeHash(const FixedVector<RefPtr<AccessCase>>& cases, const FixedVector<StructureID>& weakStructures) 98 { 99 Hasher hasher; 100 for (auto& key : cases) 101 WTF::add(hasher, key->hash()); 102 for (auto& structureID : weakStructures) 103 WTF::add(hasher, structureID); 104 return hasher.hash(); 105 } 106 77 107 MarkingGCAwareJITStubRoutine::MarkingGCAwareJITStubRoutine( 78 const MacroAssemblerCodeRef<JITStubRoutinePtrTag>& code, VM& vm, const JSCell* owner,108 const MacroAssemblerCodeRef<JITStubRoutinePtrTag>& code, VM& vm, FixedVector<RefPtr<AccessCase>>&& cases, FixedVector<StructureID>&& weakStructures, const JSCell* owner, 79 109 const Vector<JSCell*>& cells, Bag<CallLinkInfo>&& callLinkInfos) 80 : GCAwareJITStubRoutine(code, vm)110 : PolymorphicAccessJITStubRoutine(code, vm, WTFMove(cases), WTFMove(weakStructures)) 81 111 , m_cells(cells.size()) 82 112 , m_callLinkInfos(WTFMove(callLinkInfos)) … … 107 137 108 138 GCAwareJITStubRoutineWithExceptionHandler::GCAwareJITStubRoutineWithExceptionHandler( 109 const MacroAssemblerCodeRef<JITStubRoutinePtrTag>& code, VM& vm, const JSCell* owner, const Vector<JSCell*>& cells, Bag<CallLinkInfo>&& callLinkInfos,139 const MacroAssemblerCodeRef<JITStubRoutinePtrTag>& code, VM& vm, FixedVector<RefPtr<AccessCase>>&& cases, FixedVector<StructureID>&& weakStructures, const JSCell* owner, const Vector<JSCell*>& cells, Bag<CallLinkInfo>&& callLinkInfos, 110 140 CodeBlock* codeBlockForExceptionHandlers, DisposableCallSiteIndex exceptionHandlerCallSiteIndex) 111 : MarkingGCAwareJITStubRoutine(code, vm, owner, cells, WTFMove(callLinkInfos))141 : MarkingGCAwareJITStubRoutine(code, vm, WTFMove(cases), WTFMove(weakStructures), owner, cells, WTFMove(callLinkInfos)) 112 142 , m_codeBlockWithExceptionHandler(codeBlockForExceptionHandlers) 113 143 #if ENABLE(DFG_JIT) … … 153 183 154 184 155 Ref< JITStubRoutine> createJITStubRoutine(185 Ref<PolymorphicAccessJITStubRoutine> createICJITStubRoutine( 156 186 const MacroAssemblerCodeRef<JITStubRoutinePtrTag>& code, 187 FixedVector<RefPtr<AccessCase>>&& cases, 188 FixedVector<StructureID>&& weakStructures, 157 189 VM& vm, 158 190 const JSCell* owner, … … 166 198 // Allocating CallLinkInfos means we should have calls. 167 199 ASSERT(callLinkInfos.isEmpty()); 168 return adoptRef(*new JITStubRoutine(code));200 return adoptRef(*new PolymorphicAccessJITStubRoutine(code, vm, WTFMove(cases), WTFMove(weakStructures))); 169 201 } 170 202 171 203 if (codeBlockForExceptionHandlers) { 172 204 RELEASE_ASSERT(JITCode::isOptimizingJIT(codeBlockForExceptionHandlers->jitType())); 173 return adoptRef(*new GCAwareJITStubRoutineWithExceptionHandler(code, vm, owner, cells, WTFMove(callLinkInfos), codeBlockForExceptionHandlers, exceptionHandlerCallSiteIndex)); 174 } 175 176 if (cells.isEmpty() && callLinkInfos.isEmpty()) 177 return GCAwareJITStubRoutine::create(code, vm); 178 179 return adoptRef(*new MarkingGCAwareJITStubRoutine(code, vm, owner, cells, WTFMove(callLinkInfos))); 205 auto stub = adoptRef(*new GCAwareJITStubRoutineWithExceptionHandler(code, vm, WTFMove(cases), WTFMove(weakStructures), owner, cells, WTFMove(callLinkInfos), codeBlockForExceptionHandlers, exceptionHandlerCallSiteIndex)); 206 stub->makeGCAware(vm); 207 return stub; 208 } 209 210 if (cells.isEmpty() && callLinkInfos.isEmpty()) { 211 auto stub = adoptRef(*new PolymorphicAccessJITStubRoutine(code, vm, WTFMove(cases), WTFMove(weakStructures))); 212 stub->makeGCAware(vm); 213 return stub; 214 } 215 216 auto stub = adoptRef(*new MarkingGCAwareJITStubRoutine(code, vm, WTFMove(cases), WTFMove(weakStructures), owner, cells, WTFMove(callLinkInfos))); 217 stub->makeGCAware(vm); 218 return stub; 180 219 } 181 220 -
trunk/Source/JavaScriptCore/jit/GCAwareJITStubRoutine.h
r275542 r278656 32 32 #include "WriteBarrier.h" 33 33 #include <wtf/FixedVector.h> 34 #include <wtf/Hasher.h> 34 35 #include <wtf/Vector.h> 35 36 … … 39 40 } 40 41 42 class AccessCase; 41 43 class CallLinkInfo; 42 44 class JITStubRoutineSet; … … 55 57 class GCAwareJITStubRoutine : public JITStubRoutine { 56 58 public: 57 GCAwareJITStubRoutine(const MacroAssemblerCodeRef<JITStubRoutinePtrTag>& , VM&);59 GCAwareJITStubRoutine(const MacroAssemblerCodeRef<JITStubRoutinePtrTag>&); 58 60 ~GCAwareJITStubRoutine() override; 59 61 60 static Ref<JITStubRoutine> create( const MacroAssemblerCodeRef<JITStubRoutinePtrTag>& code, VM& vm)62 static Ref<JITStubRoutine> create(VM& vm, const MacroAssemblerCodeRef<JITStubRoutinePtrTag>& code) 61 63 { 62 return adoptRef(*new GCAwareJITStubRoutine(code, vm)); 64 auto stub = adoptRef(*new GCAwareJITStubRoutine(code)); 65 stub->makeGCAware(vm); 66 return stub; 63 67 } 64 68 … … 70 74 71 75 void deleteFromGC(); 76 77 void makeGCAware(VM&); 72 78 73 79 protected: … … 82 88 bool m_mayBeExecuting { false }; 83 89 bool m_isJettisoned { false }; 90 bool m_isGCAware { false }; 91 }; 92 93 class PolymorphicAccessJITStubRoutine : public GCAwareJITStubRoutine { 94 public: 95 using Base = GCAwareJITStubRoutine; 96 97 PolymorphicAccessJITStubRoutine(const MacroAssemblerCodeRef<JITStubRoutinePtrTag>&, VM&, FixedVector<RefPtr<AccessCase>>&&, FixedVector<StructureID>&&); 98 99 const FixedVector<RefPtr<AccessCase>>& cases() const { return m_cases; } 100 const FixedVector<StructureID>& weakStructures() const { return m_weakStructures; } 101 102 unsigned hash() const 103 { 104 if (!m_hash) 105 m_hash = computeHash(m_cases, m_weakStructures); 106 return m_hash; 107 } 108 109 static unsigned computeHash(const FixedVector<RefPtr<AccessCase>>&, const FixedVector<StructureID>&); 110 111 protected: 112 void observeZeroRefCount() override; 113 114 private: 115 VM& m_vm; 116 FixedVector<RefPtr<AccessCase>> m_cases; 117 FixedVector<StructureID> m_weakStructures; 84 118 }; 85 119 86 120 // Use this if you want to mark one additional object during GC if your stub 87 121 // routine is known to be executing. 88 class MarkingGCAwareJITStubRoutine : public GCAwareJITStubRoutine {122 class MarkingGCAwareJITStubRoutine : public PolymorphicAccessJITStubRoutine { 89 123 public: 124 using Base = PolymorphicAccessJITStubRoutine; 125 90 126 MarkingGCAwareJITStubRoutine( 91 const MacroAssemblerCodeRef<JITStubRoutinePtrTag>&, VM&, const JSCell* owner, const Vector<JSCell*>&, Bag<CallLinkInfo>&&);127 const MacroAssemblerCodeRef<JITStubRoutinePtrTag>&, VM&, FixedVector<RefPtr<AccessCase>>&&, FixedVector<StructureID>&&, const JSCell* owner, const Vector<JSCell*>&, Bag<CallLinkInfo>&&); 92 128 ~MarkingGCAwareJITStubRoutine() override; 93 129 … … 108 144 class GCAwareJITStubRoutineWithExceptionHandler final : public MarkingGCAwareJITStubRoutine { 109 145 public: 110 typedef GCAwareJITStubRoutine Base;146 using Base = MarkingGCAwareJITStubRoutine; 111 147 112 GCAwareJITStubRoutineWithExceptionHandler(const MacroAssemblerCodeRef<JITStubRoutinePtrTag>&, VM&, const JSCell* owner, const Vector<JSCell*>&, Bag<CallLinkInfo>&&, CodeBlock*, DisposableCallSiteIndex);148 GCAwareJITStubRoutineWithExceptionHandler(const MacroAssemblerCodeRef<JITStubRoutinePtrTag>&, VM&, FixedVector<RefPtr<AccessCase>>&&, FixedVector<StructureID>&&, const JSCell* owner, const Vector<JSCell*>&, Bag<CallLinkInfo>&&, CodeBlock*, DisposableCallSiteIndex); 113 149 ~GCAwareJITStubRoutineWithExceptionHandler() final; 114 150 … … 130 166 // after the first call to C++ or JS. 131 167 // 132 // Ref< JITStubRoutine> createJITStubRoutine(168 // Ref<PolymorphicAccessJITStubRoutine> createICJITStubRoutine( 133 169 // const MacroAssemblerCodeRef<JITStubRoutinePtrTag>& code, 134 170 // VM& vm, 171 // FixedVector<RefPtr<AccessCase>>&& cases, 135 172 // const JSCell* owner, 136 173 // bool makesCalls, … … 143 180 // way. 144 181 145 Ref< JITStubRoutine> createJITStubRoutine(146 const MacroAssemblerCodeRef<JITStubRoutinePtrTag>&, VM&, const JSCell* owner, bool makesCalls,182 Ref<PolymorphicAccessJITStubRoutine> createICJITStubRoutine( 183 const MacroAssemblerCodeRef<JITStubRoutinePtrTag>&, FixedVector<RefPtr<AccessCase>>&& cases, FixedVector<StructureID>&& weakStructures, VM&, const JSCell* owner, bool makesCalls, 147 184 const Vector<JSCell*>&, Bag<CallLinkInfo>&& callLinkInfos, 148 185 CodeBlock* codeBlockForExceptionHandlers, DisposableCallSiteIndex exceptionHandlingCallSiteIndex); -
trunk/Source/JavaScriptCore/jit/GPRInfo.h
r269349 r278656 461 461 #endif 462 462 static constexpr GPRReg nonArgGPR0 = X86Registers::r10; // regT5 (regT4 on Windows) 463 static constexpr GPRReg nonArgGPR1 = X86Registers::eax; // regT0 463 464 static constexpr GPRReg returnValueGPR = X86Registers::eax; // regT0 464 465 static constexpr GPRReg returnValueGPR2 = X86Registers::edx; // regT1 or regT2 … … 653 654 static constexpr GPRReg argumentGPR7 = ARM64Registers::x7; // regT7 654 655 static constexpr GPRReg nonArgGPR0 = ARM64Registers::x8; // regT8 656 static constexpr GPRReg nonArgGPR1 = ARM64Registers::x9; // regT9 655 657 static constexpr GPRReg returnValueGPR = ARM64Registers::x0; // regT0 656 658 static constexpr GPRReg returnValueGPR2 = ARM64Registers::x1; // regT1 -
trunk/Source/JavaScriptCore/jit/JIT.cpp
r278576 r278656 1266 1266 for (const auto& byValCompilationInfo : m_byValCompilationInfo) { 1267 1267 PatchableJump patchableNotIndexJump = byValCompilationInfo.notIndexJump; 1268 auto notIndexJump = CodeLocationJump<JSInternalPtrTag>();1268 CodeLocationJump<JSInternalPtrTag> notIndexJump; 1269 1269 if (Jump(patchableNotIndexJump).isSet()) 1270 1270 notIndexJump = CodeLocationJump<JSInternalPtrTag>(patchBuffer.locationOf<JSInternalPtrTag>(patchableNotIndexJump)); 1271 1271 1272 1272 PatchableJump patchableBadTypeJump = byValCompilationInfo.badTypeJump; 1273 auto badTypeJump = CodeLocationJump<JSInternalPtrTag>();1273 CodeLocationJump<JSInternalPtrTag> badTypeJump; 1274 1274 if (Jump(patchableBadTypeJump).isSet()) 1275 1275 badTypeJump = CodeLocationJump<JSInternalPtrTag>(patchBuffer.locationOf<JSInternalPtrTag>(byValCompilationInfo.badTypeJump)); … … 1280 1280 1281 1281 byValCompilationInfo.byValInfo->setUp( 1282 notIndexJump,1283 badTypeJump,1284 1282 exceptionHandler, 1285 1283 byValCompilationInfo.arrayMode, … … 1288 1286 nextHotPathTarget, 1289 1287 slowPathTarget); 1288 if (JITCode::useDataIC(JITType::BaselineJIT)) { 1289 byValCompilationInfo.byValInfo->m_notIndexJumpTarget = slowPathTarget.retagged<JITStubRoutinePtrTag>(); 1290 byValCompilationInfo.byValInfo->m_badTypeJumpTarget = slowPathTarget.retagged<JITStubRoutinePtrTag>(); 1291 } else { 1292 byValCompilationInfo.byValInfo->m_notIndexJump = notIndexJump; 1293 byValCompilationInfo.byValInfo->m_badTypeJump = badTypeJump; 1294 } 1290 1295 } 1291 1296 } -
trunk/Source/JavaScriptCore/jit/JIT.h
r278591 r278656 295 295 } 296 296 297 void appendCall(Address function) 298 { 299 call(function, OperationPtrTag); 300 } 301 297 302 #if OS(WINDOWS) && CPU(X86_64) 298 303 Call appendCallWithSlowPathReturnType(const FunctionPtr<CFunctionPtrTag> function) … … 398 403 // Structure is already profiled. Returns the slow cases. Fall-through 399 404 // case contains result in regT0, and it is not yet profiled. 400 JumpList emitInt32Load(const Instruction* instruction, PatchableJump& badType ) { return emitContiguousLoad(instruction, badType, Int32Shape); }401 JumpList emitDoubleLoad(const Instruction*, PatchableJump& badType );402 JumpList emitContiguousLoad(const Instruction*, PatchableJump& badType, IndexingType expectedShape = ContiguousShape);403 JumpList emitArrayStorageLoad(const Instruction*, PatchableJump& badType );404 JumpList emitLoadForArrayMode(const Instruction*, JITArrayMode, PatchableJump& badType );405 JumpList emitInt32Load(const Instruction* instruction, PatchableJump& badType, ByValInfo* byValInfo) { return emitContiguousLoad(instruction, badType, byValInfo, Int32Shape); } 406 JumpList emitDoubleLoad(const Instruction*, PatchableJump& badType, ByValInfo*); 407 JumpList emitContiguousLoad(const Instruction*, PatchableJump& badType, ByValInfo*, IndexingType expectedShape = ContiguousShape); 408 JumpList emitArrayStorageLoad(const Instruction*, PatchableJump& badType, ByValInfo*); 409 JumpList emitLoadForArrayMode(const Instruction*, JITArrayMode, PatchableJump& badType, ByValInfo*); 405 410 406 411 // Property is in regT1, base is in regT0. regT2 contains indecing type. … … 409 414 // returns the slow cases. 410 415 template<typename Op> 411 JumpList emitInt32PutByVal(Op bytecode, PatchableJump& badType )412 { 413 return emitGenericContiguousPutByVal(bytecode, badType, Int32Shape);414 } 415 template<typename Op> 416 JumpList emitDoublePutByVal(Op bytecode, PatchableJump& badType )417 { 418 return emitGenericContiguousPutByVal(bytecode, badType, DoubleShape);419 } 420 template<typename Op> 421 JumpList emitContiguousPutByVal(Op bytecode, PatchableJump& badType )422 { 423 return emitGenericContiguousPutByVal(bytecode, badType );424 } 425 template<typename Op> 426 JumpList emitGenericContiguousPutByVal(Op, PatchableJump& badType, IndexingType indexingShape = ContiguousShape);427 template<typename Op> 428 JumpList emitArrayStoragePutByVal(Op, PatchableJump& badType );429 template<typename Op> 430 JumpList emitIntTypedArrayPutByVal(Op, PatchableJump& badType, TypedArrayType);431 template<typename Op> 432 JumpList emitFloatTypedArrayPutByVal(Op, PatchableJump& badType, TypedArrayType);416 JumpList emitInt32PutByVal(Op bytecode, PatchableJump& badType, ByValInfo* byValInfo) 417 { 418 return emitGenericContiguousPutByVal(bytecode, badType, byValInfo, Int32Shape); 419 } 420 template<typename Op> 421 JumpList emitDoublePutByVal(Op bytecode, PatchableJump& badType, ByValInfo* byValInfo) 422 { 423 return emitGenericContiguousPutByVal(bytecode, badType, byValInfo, DoubleShape); 424 } 425 template<typename Op> 426 JumpList emitContiguousPutByVal(Op bytecode, PatchableJump& badType, ByValInfo* byValInfo) 427 { 428 return emitGenericContiguousPutByVal(bytecode, badType, byValInfo); 429 } 430 template<typename Op> 431 JumpList emitGenericContiguousPutByVal(Op, PatchableJump& badType, ByValInfo*, IndexingType indexingShape = ContiguousShape); 432 template<typename Op> 433 JumpList emitArrayStoragePutByVal(Op, PatchableJump& badType, ByValInfo*); 434 template<typename Op> 435 JumpList emitIntTypedArrayPutByVal(Op, PatchableJump& badType, ByValInfo*, TypedArrayType); 436 template<typename Op> 437 JumpList emitFloatTypedArrayPutByVal(Op, PatchableJump& badType, ByValInfo*, TypedArrayType); 433 438 434 439 template<typename Op> … … 902 907 903 908 MacroAssembler::Call appendCallWithExceptionCheck(const FunctionPtr<CFunctionPtrTag>); 909 void appendCallWithExceptionCheck(Address); 904 910 #if OS(WINDOWS) && CPU(X86_64) 905 911 MacroAssembler::Call appendCallWithExceptionCheckAndSlowPathReturnType(const FunctionPtr<CFunctionPtrTag>); … … 907 913 MacroAssembler::Call appendCallWithCallFrameRollbackOnException(const FunctionPtr<CFunctionPtrTag>); 908 914 MacroAssembler::Call appendCallWithExceptionCheckSetJSValueResult(const FunctionPtr<CFunctionPtrTag>, VirtualRegister result); 915 void appendCallWithExceptionCheckSetJSValueResult(Address, VirtualRegister result); 909 916 template<typename Metadata> 910 917 MacroAssembler::Call appendCallWithExceptionCheckSetJSValueResultWithProfile(Metadata&, const FunctionPtr<CFunctionPtrTag>, VirtualRegister result); 918 template<typename Metadata> 919 void appendCallWithExceptionCheckSetJSValueResultWithProfile(Metadata&, Address, VirtualRegister result); 911 920 912 921 template<typename OperationType, typename... Args> … … 916 925 setupArguments<OperationType>(args...); 917 926 return appendCallWithExceptionCheckSetJSValueResult(operation, result); 927 } 928 929 template<typename OperationType, typename... Args> 930 std::enable_if_t<FunctionTraits<OperationType>::hasResult, void> 931 callOperation(Address target, VirtualRegister result, Args... args) 932 { 933 setupArgumentsForIndirectCall<OperationType>(target, args...); 934 return appendCallWithExceptionCheckSetJSValueResult(Address(GPRInfo::nonArgGPR0, target.offset), result); 918 935 } 919 936 … … 938 955 return appendCallWithExceptionCheckAndSlowPathReturnType(operation); 939 956 } 957 958 template<typename OperationType, typename... Args> 959 void callOperation(Address target, Args... args) 960 { 961 setupArgumentsForIndirectCall<OperationType>(target, args...); 962 // x64 Windows cannot use standard call when the return type is larger than 64 bits. 963 if constexpr (is64BitType<typename FunctionTraits<OperationType>::ResultType>::value) 964 appendCallWithExceptionCheck(Address(GPRInfo::nonArgGPR0, target.offset)); 965 else 966 appendCallWithExceptionCheckAndSlowPathReturnType(Address(GPRInfo::nonArgGPR0, target.offset)); 967 } 940 968 #else // OS(WINDOWS) && CPU(X86_64) 941 969 template<typename OperationType, typename... Args> … … 945 973 return appendCallWithExceptionCheck(operation); 946 974 } 975 976 template<typename OperationType, typename... Args> 977 void callOperation(Address target, Args... args) 978 { 979 setupArgumentsForIndirectCall<OperationType>(target, args...); 980 appendCallWithExceptionCheck(Address(GPRInfo::nonArgGPR0, target.offset)); 981 } 947 982 #endif // OS(WINDOWS) && CPU(X86_64) 948 983 … … 953 988 setupArguments<OperationType>(args...); 954 989 return appendCallWithExceptionCheckSetJSValueResultWithProfile(metadata, operation, result); 990 } 991 992 template<typename OperationType, typename Metadata, typename... Args> 993 std::enable_if_t<FunctionTraits<OperationType>::hasResult, void> 994 callOperationWithProfile(Metadata& metadata, Address target, VirtualRegister result, Args... args) 995 { 996 setupArgumentsForIndirectCall<OperationType>(target, args...); 997 return appendCallWithExceptionCheckSetJSValueResultWithProfile(metadata, Address(GPRInfo::nonArgGPR0, target.offset), result); 955 998 } 956 999 -
trunk/Source/JavaScriptCore/jit/JITCall.cpp
r278030 r278656 399 399 400 400 JITGetByIdGenerator gen( 401 m_codeBlock, CodeOrigin(m_bytecodeIndex), CallSiteIndex(BytecodeIndex(m_bytecodeIndex.offset())), RegisterSet::stubUnavailableRegisters(),402 CacheableIdentifier::createFromImmortalIdentifier(ident->impl()), JSValueRegs(regT0), JSValueRegs(regT0), AccessType::GetById);401 m_codeBlock, JITType::BaselineJIT, CodeOrigin(m_bytecodeIndex), CallSiteIndex(BytecodeIndex(m_bytecodeIndex.offset())), RegisterSet::stubUnavailableRegisters(), 402 CacheableIdentifier::createFromImmortalIdentifier(ident->impl()), JSValueRegs(regT0), JSValueRegs(regT0), regT1, AccessType::GetById); 403 403 gen.generateFastPath(*this); 404 404 addSlowCase(gen.slowPathJump()); … … 433 433 Label coldPathBegin = label(); 434 434 435 Call call = callOperationWithProfile(bytecode.metadata(m_codeBlock), operationGetByIdOptimize, nextVReg, TrustedImmPtr(m_codeBlock->globalObject()), gen.stubInfo(), iteratorGPR, CacheableIdentifier::createFromImmortalIdentifier(ident).rawBits()); 435 Call call; 436 if (JITCode::useDataIC(JITType::BaselineJIT)) { 437 gen.stubInfo()->m_slowOperation = operationGetByIdOptimize; 438 move(TrustedImmPtr(gen.stubInfo()), GPRInfo::nonArgGPR0); 439 callOperationWithProfile<decltype(operationGetByIdOptimize)>(bytecode.metadata(m_codeBlock), Address(GPRInfo::nonArgGPR0, StructureStubInfo::offsetOfSlowOperation()), nextVReg, TrustedImmPtr(m_codeBlock->globalObject()), GPRInfo::nonArgGPR0, iteratorGPR, CacheableIdentifier::createFromImmortalIdentifier(ident).rawBits()); 440 } else 441 call = callOperationWithProfile(bytecode.metadata(m_codeBlock), operationGetByIdOptimize, nextVReg, TrustedImmPtr(m_codeBlock->globalObject()), gen.stubInfo(), iteratorGPR, CacheableIdentifier::createFromImmortalIdentifier(ident).rawBits()); 436 442 gen.reportSlowPathCall(coldPathBegin, call); 443 437 444 auto done = jump(); 438 445 … … 481 488 preservedRegs.add(valueGPR); 482 489 JITGetByIdGenerator gen( 483 m_codeBlock, CodeOrigin(m_bytecodeIndex), CallSiteIndex(BytecodeIndex(m_bytecodeIndex.offset())), preservedRegs,484 CacheableIdentifier::createFromImmortalIdentifier(vm().propertyNames->done.impl()), JSValueRegs(iterResultGPR), JSValueRegs(doneGPR), AccessType::GetById);490 m_codeBlock, JITType::BaselineJIT, CodeOrigin(m_bytecodeIndex), CallSiteIndex(BytecodeIndex(m_bytecodeIndex.offset())), preservedRegs, 491 CacheableIdentifier::createFromImmortalIdentifier(vm().propertyNames->done.impl()), JSValueRegs(iterResultGPR), JSValueRegs(doneGPR), regT3, AccessType::GetById); 485 492 gen.generateFastPath(*this); 486 493 addSlowCase(gen.slowPathJump()); … … 500 507 501 508 JITGetByIdGenerator gen( 502 m_codeBlock, CodeOrigin(m_bytecodeIndex), CallSiteIndex(BytecodeIndex(m_bytecodeIndex.offset())), RegisterSet::stubUnavailableRegisters(),503 CacheableIdentifier::createFromImmortalIdentifier(vm().propertyNames->value.impl()), JSValueRegs(valueGPR), JSValueRegs(valueGPR), AccessType::GetById);509 m_codeBlock, JITType::BaselineJIT, CodeOrigin(m_bytecodeIndex), CallSiteIndex(BytecodeIndex(m_bytecodeIndex.offset())), RegisterSet::stubUnavailableRegisters(), 510 CacheableIdentifier::createFromImmortalIdentifier(vm().propertyNames->value.impl()), JSValueRegs(valueGPR), JSValueRegs(valueGPR), regT4, AccessType::GetById); 504 511 gen.generateFastPath(*this); 505 512 addSlowCase(gen.slowPathJump()); … … 529 536 JumpList notObject; 530 537 notObject.append(branchIfNotCell(iterResultGPR)); 531 notObject.append(branchIfNotObject(iterResultGPR));532 538 533 539 UniquedStringImpl* ident = vm().propertyNames->done.impl(); … … 536 542 Label coldPathBegin = label(); 537 543 538 Call call = callOperationWithProfile(bytecode.metadata(m_codeBlock), operationGetByIdOptimize, doneVReg, TrustedImmPtr(m_codeBlock->globalObject()), gen.stubInfo(), iterResultGPR, CacheableIdentifier::createFromImmortalIdentifier(ident).rawBits()); 539 544 notObject.append(branchIfNotObject(iterResultGPR)); 545 546 Call call; 547 if (JITCode::useDataIC(JITType::BaselineJIT)) { 548 gen.stubInfo()->m_slowOperation = operationGetByIdOptimize; 549 move(TrustedImmPtr(gen.stubInfo()), GPRInfo::nonArgGPR0); 550 callOperationWithProfile<decltype(operationGetByIdOptimize)>(bytecode.metadata(m_codeBlock), Address(GPRInfo::nonArgGPR0, StructureStubInfo::offsetOfSlowOperation()), doneVReg, TrustedImmPtr(m_codeBlock->globalObject()), GPRInfo::nonArgGPR0, iterResultGPR, CacheableIdentifier::createFromImmortalIdentifier(ident).rawBits()); 551 } else 552 call = callOperationWithProfile(bytecode.metadata(m_codeBlock), operationGetByIdOptimize, doneVReg, TrustedImmPtr(m_codeBlock->globalObject()), gen.stubInfo(), iterResultGPR, CacheableIdentifier::createFromImmortalIdentifier(ident).rawBits()); 540 553 gen.reportSlowPathCall(coldPathBegin, call); 554 541 555 emitGetVirtualRegister(doneVReg, regT1); 542 556 emitGetVirtualRegister(bytecode.m_value, regT0); … … 557 571 Label coldPathBegin = label(); 558 572 559 Call call = callOperationWithProfile(bytecode.metadata(m_codeBlock), operationGetByIdOptimize, valueVReg, TrustedImmPtr(m_codeBlock->globalObject()), gen.stubInfo(), iterResultGPR, CacheableIdentifier::createFromImmortalIdentifier(ident).rawBits()); 560 573 Call call; 574 if (JITCode::useDataIC(JITType::BaselineJIT)) { 575 gen.stubInfo()->m_slowOperation = operationGetByIdOptimize; 576 move(TrustedImmPtr(gen.stubInfo()), GPRInfo::nonArgGPR0); 577 callOperationWithProfile<decltype(operationGetByIdOptimize)>(bytecode.metadata(m_codeBlock), Address(GPRInfo::nonArgGPR0, StructureStubInfo::offsetOfSlowOperation()), valueVReg, TrustedImmPtr(m_codeBlock->globalObject()), GPRInfo::nonArgGPR0, iterResultGPR, CacheableIdentifier::createFromImmortalIdentifier(ident).rawBits()); 578 } else 579 call = callOperationWithProfile(bytecode.metadata(m_codeBlock), operationGetByIdOptimize, valueVReg, TrustedImmPtr(m_codeBlock->globalObject()), gen.stubInfo(), iterResultGPR, CacheableIdentifier::createFromImmortalIdentifier(ident).rawBits()); 561 580 gen.reportSlowPathCall(coldPathBegin, call); 562 581 } -
trunk/Source/JavaScriptCore/jit/JITCall32_64.cpp
r278030 r278656 397 397 JITGetByIdGenerator gen( 398 398 m_codeBlock, 399 JITType::BaselineJIT, 399 400 CodeOrigin(m_bytecodeIndex), 400 401 CallSiteIndex(BytecodeIndex(m_bytecodeIndex.offset())), … … 403 404 JSValueRegs(tagIteratorGPR, payloadIteratorGPR), 404 405 nextRegs, 406 InvalidGPRReg, 405 407 AccessType::GetById); 406 408 … … 506 508 JITGetByIdGenerator gen( 507 509 m_codeBlock, 510 JITType::BaselineJIT, 508 511 CodeOrigin(m_bytecodeIndex), 509 512 CallSiteIndex(BytecodeIndex(m_bytecodeIndex.offset())), … … 512 515 JSValueRegs(tagIterResultGPR, payloadIterResultGPR), 513 516 doneRegs, 517 InvalidGPRReg, 514 518 AccessType::GetById); 515 519 gen.generateFastPath(*this); … … 534 538 JITGetByIdGenerator gen( 535 539 m_codeBlock, 540 JITType::BaselineJIT, 536 541 CodeOrigin(m_bytecodeIndex), 537 542 CallSiteIndex(BytecodeIndex(m_bytecodeIndex.offset())), … … 540 545 JSValueRegs(tagIterResultGPR, payloadIterResultGPR), 541 546 resultRegs, 547 InvalidGPRReg, 542 548 AccessType::GetById); 543 549 gen.generateFastPath(*this); -
trunk/Source/JavaScriptCore/jit/JITCode.h
r278340 r278656 52 52 53 53 enum class JITType : uint8_t { 54 None, 55 HostCallThunk, 56 InterpreterThunk, 57 BaselineJIT, 58 DFGJIT, 59 FTLJIT 60 }; 54 None = 0b000, 55 HostCallThunk = 0b001, 56 InterpreterThunk = 0b010, 57 BaselineJIT = 0b011, 58 DFGJIT = 0b100, 59 FTLJIT = 0b101, 60 }; 61 static constexpr unsigned widthOfJITType = 3; 62 static_assert(WTF::getMSBSetConstexpr(static_cast<std::underlying_type_t<JITType>>(JITType::FTLJIT)) + 1 == widthOfJITType); 61 63 62 64 class JITCode : public ThreadSafeRefCounted<JITCode> { … … 154 156 { 155 157 return jitType == JITType::InterpreterThunk || jitType == JITType::BaselineJIT; 158 } 159 160 static bool useDataIC(JITType jitType) 161 { 162 if (!Options::useDataIC()) 163 return false; 164 if (JITCode::isBaselineCode(jitType)) 165 return true; 166 return Options::useDataICInOptimizingJIT(); 156 167 } 157 168 -
trunk/Source/JavaScriptCore/jit/JITInlineCacheGenerator.cpp
r278445 r278656 44 44 45 45 JITInlineCacheGenerator::JITInlineCacheGenerator( 46 CodeBlock* codeBlock, CodeOrigin codeOrigin, CallSiteIndex callSite, AccessType accessType,46 CodeBlock* codeBlock, JITType jitType, CodeOrigin codeOrigin, CallSiteIndex callSite, AccessType accessType, 47 47 const RegisterSet& usedRegisters) 48 48 : m_codeBlock(codeBlock) 49 , m_jitType(jitType) 49 50 { 50 51 m_stubInfo = m_codeBlock ? m_codeBlock->addStubInfo(accessType, codeOrigin) : garbageStubInfo(); … … 61 62 m_stubInfo->doneLocation = fastPath.locationOf<JSInternalPtrTag>(m_done); 62 63 63 m_stubInfo->slowPathCallLocation = slowPath.locationOf<JSInternalPtrTag>(m_slowPathCall); 64 if (!JITCode::useDataIC(m_jitType)) 65 m_stubInfo->m_slowPathCallLocation = slowPath.locationOf<JSInternalPtrTag>(m_slowPathCall); 64 66 m_stubInfo->slowPathStartLocation = slowPath.locationOf<JITStubRoutinePtrTag>(m_slowPathBegin); 65 67 } 66 68 67 69 JITByIdGenerator::JITByIdGenerator( 68 CodeBlock* codeBlock, CodeOrigin codeOrigin, CallSiteIndex callSite, AccessType accessType,69 const RegisterSet& usedRegisters, JSValueRegs base, JSValueRegs value )70 : JITInlineCacheGenerator(codeBlock, codeOrigin, callSite, accessType, usedRegisters)70 CodeBlock* codeBlock, JITType jitType, CodeOrigin codeOrigin, CallSiteIndex callSite, AccessType accessType, 71 const RegisterSet& usedRegisters, JSValueRegs base, JSValueRegs value, GPRReg stubInfoGPR) 72 : JITInlineCacheGenerator(codeBlock, jitType, codeOrigin, callSite, accessType, usedRegisters) 71 73 , m_base(base) 72 74 , m_value(value) … … 75 77 m_stubInfo->valueGPR = value.payloadGPR(); 76 78 m_stubInfo->regs.thisGPR = InvalidGPRReg; 79 m_stubInfo->m_stubInfoGPR = stubInfoGPR; 77 80 #if USE(JSVALUE32_64) 78 81 m_stubInfo->baseTagGPR = base.tagGPR(); … … 84 87 void JITByIdGenerator::finalize(LinkBuffer& fastPath, LinkBuffer& slowPath) 85 88 { 86 ASSERT(m_start.isSet());87 JITInlineCacheGenerator::finalize(88 fastPath, slowPath, fastPath.locationOf<JITStubRoutinePtrTag>(m_start));89 JITInlineCacheGenerator::finalize(fastPath, slowPath, fastPath.locationOf<JITStubRoutinePtrTag>(m_start)); 90 if (JITCode::useDataIC(m_jitType)) 91 m_stubInfo->m_codePtr = m_stubInfo->slowPathStartLocation; 89 92 } 90 93 91 94 void JITByIdGenerator::generateFastCommon(MacroAssembler& jit, size_t inlineICSize) 92 95 { 96 // We generate the same code regardless of whether SharedIC is enabled because we still need to use InlineAccess 97 // for the performance reason. 93 98 m_start = jit.label(); 94 99 size_t startSize = jit.m_assembler.buffer().codeSize(); … … 102 107 103 108 JITGetByIdGenerator::JITGetByIdGenerator( 104 CodeBlock* codeBlock, CodeOrigin codeOrigin, CallSiteIndex callSite, const RegisterSet& usedRegisters,105 CacheableIdentifier propertyName, JSValueRegs base, JSValueRegs value, AccessType accessType)106 : JITByIdGenerator(codeBlock, codeOrigin, callSite, accessType, usedRegisters, base, value)109 CodeBlock* codeBlock, JITType jitType, CodeOrigin codeOrigin, CallSiteIndex callSite, const RegisterSet& usedRegisters, 110 CacheableIdentifier propertyName, JSValueRegs base, JSValueRegs value, GPRReg stubInfoGPR, AccessType accessType) 111 : JITByIdGenerator(codeBlock, jitType, codeOrigin, callSite, accessType, usedRegisters, base, value, stubInfoGPR) 107 112 , m_isLengthAccess(propertyName.uid() == codeBlock->vm().propertyNames->length.impl()) 108 113 { … … 116 121 117 122 JITGetByIdWithThisGenerator::JITGetByIdWithThisGenerator( 118 CodeBlock* codeBlock, CodeOrigin codeOrigin, CallSiteIndex callSite, const RegisterSet& usedRegisters,119 CacheableIdentifier, JSValueRegs value, JSValueRegs base, JSValueRegs thisRegs )120 : JITByIdGenerator(codeBlock, codeOrigin, callSite, AccessType::GetByIdWithThis, usedRegisters, base, value)123 CodeBlock* codeBlock, JITType jitType, CodeOrigin codeOrigin, CallSiteIndex callSite, const RegisterSet& usedRegisters, 124 CacheableIdentifier, JSValueRegs value, JSValueRegs base, JSValueRegs thisRegs, GPRReg stubInfoGPR) 125 : JITByIdGenerator(codeBlock, jitType, codeOrigin, callSite, AccessType::GetByIdWithThis, usedRegisters, base, value, stubInfoGPR) 121 126 { 122 127 RELEASE_ASSERT(thisRegs.payloadGPR() != thisRegs.tagGPR()); … … 134 139 135 140 JITPutByIdGenerator::JITPutByIdGenerator( 136 CodeBlock* codeBlock, CodeOrigin codeOrigin, CallSiteIndex callSite, const RegisterSet& usedRegisters, CacheableIdentifier,137 JSValueRegs base, JSValueRegs value, GPRReg s cratch,141 CodeBlock* codeBlock, JITType jitType, CodeOrigin codeOrigin, CallSiteIndex callSite, const RegisterSet& usedRegisters, CacheableIdentifier, 142 JSValueRegs base, JSValueRegs value, GPRReg stubInfoGPR, GPRReg scratch, 138 143 ECMAMode ecmaMode, PutKind putKind) 139 : JITByIdGenerator(codeBlock, codeOrigin, callSite, AccessType::Put, usedRegisters, base, value)144 : JITByIdGenerator(codeBlock, jitType, codeOrigin, callSite, AccessType::Put, usedRegisters, base, value, stubInfoGPR) 140 145 , m_ecmaMode(ecmaMode) 141 146 , m_putKind(putKind) … … 172 177 } 173 178 174 JITDelByValGenerator::JITDelByValGenerator(CodeBlock* codeBlock, CodeOrigin codeOrigin, CallSiteIndex callSiteIndex, const RegisterSet& usedRegisters, JSValueRegs base, JSValueRegs property, JSValueRegs result, GPRReg scratch)175 : Base(codeBlock, codeOrigin, callSiteIndex, AccessType::DeleteByVal, usedRegisters)179 JITDelByValGenerator::JITDelByValGenerator(CodeBlock* codeBlock, JITType jitType, CodeOrigin codeOrigin, CallSiteIndex callSiteIndex, const RegisterSet& usedRegisters, JSValueRegs base, JSValueRegs property, JSValueRegs result, GPRReg stubInfoGPR, GPRReg scratch) 180 : Base(codeBlock, jitType, codeOrigin, callSiteIndex, AccessType::DeleteByVal, usedRegisters) 176 181 { 177 182 m_stubInfo->hasConstantIdentifier = false; … … 180 185 m_stubInfo->regs.propertyGPR = property.payloadGPR(); 181 186 m_stubInfo->valueGPR = result.payloadGPR(); 187 m_stubInfo->m_stubInfoGPR = stubInfoGPR; 182 188 #if USE(JSVALUE32_64) 183 189 ASSERT(base.tagGPR() != result.tagGPR()); … … 192 198 { 193 199 m_start = jit.label(); 194 m_slowPathJump = jit.patchableJump(); 195 m_done = jit.label(); 196 } 197 198 void JITDelByValGenerator::finalize( 199 LinkBuffer& fastPath, LinkBuffer& slowPath) 200 { 201 ASSERT(m_slowPathJump.m_jump.isSet()); 202 Base::finalize( 203 fastPath, slowPath, fastPath.locationOf<JITStubRoutinePtrTag>(m_start)); 204 } 205 206 JITDelByIdGenerator::JITDelByIdGenerator(CodeBlock* codeBlock, CodeOrigin codeOrigin, CallSiteIndex callSiteIndex, const RegisterSet& usedRegisters, CacheableIdentifier, JSValueRegs base, JSValueRegs result, GPRReg scratch) 207 : Base(codeBlock, codeOrigin, callSiteIndex, AccessType::DeleteByID, usedRegisters) 200 if (JITCode::useDataIC(m_jitType)) { 201 jit.move(CCallHelpers::TrustedImmPtr(m_stubInfo), m_stubInfo->m_stubInfoGPR); 202 jit.call(CCallHelpers::Address(m_stubInfo->m_stubInfoGPR, StructureStubInfo::offsetOfCodePtr()), JITStubRoutinePtrTag); 203 } else 204 m_slowPathJump = jit.patchableJump(); 205 m_done = jit.label(); 206 } 207 208 void JITDelByValGenerator::finalize(LinkBuffer& fastPath, LinkBuffer& slowPath) 209 { 210 Base::finalize(fastPath, slowPath, fastPath.locationOf<JITStubRoutinePtrTag>(m_start)); 211 if (JITCode::useDataIC(m_jitType)) 212 m_stubInfo->m_codePtr = m_stubInfo->slowPathStartLocation; 213 } 214 215 JITDelByIdGenerator::JITDelByIdGenerator(CodeBlock* codeBlock, JITType jitType, CodeOrigin codeOrigin, CallSiteIndex callSiteIndex, const RegisterSet& usedRegisters, CacheableIdentifier, JSValueRegs base, JSValueRegs result, GPRReg stubInfoGPR, GPRReg scratch) 216 : Base(codeBlock, jitType, codeOrigin, callSiteIndex, AccessType::DeleteByID, usedRegisters) 208 217 { 209 218 m_stubInfo->hasConstantIdentifier = true; … … 212 221 m_stubInfo->regs.propertyGPR = InvalidGPRReg; 213 222 m_stubInfo->valueGPR = result.payloadGPR(); 223 m_stubInfo->m_stubInfoGPR = stubInfoGPR; 214 224 #if USE(JSVALUE32_64) 215 225 ASSERT(base.tagGPR() != result.tagGPR()); … … 224 234 { 225 235 m_start = jit.label(); 226 m_slowPathJump = jit.patchableJump(); 227 m_done = jit.label(); 228 } 229 230 void JITDelByIdGenerator::finalize( 231 LinkBuffer& fastPath, LinkBuffer& slowPath) 232 { 233 ASSERT(m_slowPathJump.m_jump.isSet()); 234 Base::finalize( 235 fastPath, slowPath, fastPath.locationOf<JITStubRoutinePtrTag>(m_start)); 236 } 237 238 JITInByValGenerator::JITInByValGenerator(CodeBlock* codeBlock, CodeOrigin codeOrigin, CallSiteIndex callSiteIndex, const RegisterSet& usedRegisters, JSValueRegs base, JSValueRegs property, JSValueRegs result) 239 : Base(codeBlock, codeOrigin, callSiteIndex, AccessType::InByVal, usedRegisters) 236 if (JITCode::useDataIC(m_jitType)) { 237 jit.move(CCallHelpers::TrustedImmPtr(m_stubInfo), m_stubInfo->m_stubInfoGPR); 238 jit.call(CCallHelpers::Address(m_stubInfo->m_stubInfoGPR, StructureStubInfo::offsetOfCodePtr()), JITStubRoutinePtrTag); 239 } else 240 m_slowPathJump = jit.patchableJump(); 241 m_done = jit.label(); 242 } 243 244 void JITDelByIdGenerator::finalize(LinkBuffer& fastPath, LinkBuffer& slowPath) 245 { 246 Base::finalize(fastPath, slowPath, fastPath.locationOf<JITStubRoutinePtrTag>(m_start)); 247 if (JITCode::useDataIC(m_jitType)) 248 m_stubInfo->m_codePtr = m_stubInfo->slowPathStartLocation; 249 } 250 251 JITInByValGenerator::JITInByValGenerator(CodeBlock* codeBlock, JITType jitType, CodeOrigin codeOrigin, CallSiteIndex callSiteIndex, const RegisterSet& usedRegisters, JSValueRegs base, JSValueRegs property, JSValueRegs result, GPRReg stubInfoGPR) 252 : Base(codeBlock, jitType, codeOrigin, callSiteIndex, AccessType::InByVal, usedRegisters) 240 253 { 241 254 m_stubInfo->hasConstantIdentifier = false; … … 244 257 m_stubInfo->regs.propertyGPR = property.payloadGPR(); 245 258 m_stubInfo->valueGPR = result.payloadGPR(); 259 m_stubInfo->m_stubInfoGPR = stubInfoGPR; 246 260 #if USE(JSVALUE32_64) 247 261 m_stubInfo->baseTagGPR = base.tagGPR(); … … 254 268 { 255 269 m_start = jit.label(); 256 m_slowPathJump = jit.patchableJump(); 270 if (JITCode::useDataIC(m_jitType)) { 271 jit.move(CCallHelpers::TrustedImmPtr(m_stubInfo), m_stubInfo->m_stubInfoGPR); 272 jit.call(CCallHelpers::Address(m_stubInfo->m_stubInfoGPR, StructureStubInfo::offsetOfCodePtr()), JITStubRoutinePtrTag); 273 } else 274 m_slowPathJump = jit.patchableJump(); 257 275 m_done = jit.label(); 258 276 } … … 262 280 { 263 281 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) 282 Base::finalize(fastPath, slowPath, fastPath.locationOf<JITStubRoutinePtrTag>(m_start)); 283 if (JITCode::useDataIC(m_jitType)) 284 m_stubInfo->m_codePtr = m_stubInfo->slowPathStartLocation; 285 } 286 287 JITInByIdGenerator::JITInByIdGenerator( 288 CodeBlock* codeBlock, JITType jitType, CodeOrigin codeOrigin, CallSiteIndex callSite, const RegisterSet& usedRegisters, 289 CacheableIdentifier propertyName, JSValueRegs base, JSValueRegs value, GPRReg stubInfoGPR) 290 : JITByIdGenerator(codeBlock, jitType, codeOrigin, callSite, AccessType::InById, usedRegisters, base, value, stubInfoGPR) 270 291 { 271 292 // FIXME: We are not supporting fast path for "length" property. … … 280 301 281 302 JITInstanceOfGenerator::JITInstanceOfGenerator( 282 CodeBlock* codeBlock, CodeOrigin codeOrigin, CallSiteIndex callSiteIndex,283 const RegisterSet& usedRegisters, GPRReg result, GPRReg value, GPRReg prototype, 303 CodeBlock* codeBlock, JITType jitType, CodeOrigin codeOrigin, CallSiteIndex callSiteIndex, 304 const RegisterSet& usedRegisters, GPRReg result, GPRReg value, GPRReg prototype, GPRReg stubInfoGPR, 284 305 GPRReg scratch1, GPRReg scratch2, bool prototypeIsKnownObject) 285 : JITInlineCacheGenerator( 286 codeBlock, codeOrigin, callSiteIndex, AccessType::InstanceOf, usedRegisters) 306 : JITInlineCacheGenerator(codeBlock, jitType, codeOrigin, callSiteIndex, AccessType::InstanceOf, usedRegisters) 287 307 { 288 308 m_stubInfo->baseGPR = value; 289 309 m_stubInfo->valueGPR = result; 290 310 m_stubInfo->regs.prototypeGPR = prototype; 311 m_stubInfo->m_stubInfoGPR = stubInfoGPR; 291 312 #if USE(JSVALUE32_64) 292 313 m_stubInfo->baseTagGPR = InvalidGPRReg; … … 308 329 void JITInstanceOfGenerator::generateFastPath(MacroAssembler& jit) 309 330 { 310 m_jump = jit.patchableJump(); 331 m_start = jit.label(); 332 if (JITCode::useDataIC(m_jitType)) { 333 jit.move(CCallHelpers::TrustedImmPtr(m_stubInfo), m_stubInfo->m_stubInfoGPR); 334 jit.call(CCallHelpers::Address(m_stubInfo->m_stubInfoGPR, StructureStubInfo::offsetOfCodePtr()), JITStubRoutinePtrTag); 335 } else 336 m_slowPathJump = jit.patchableJump(); 311 337 m_done = jit.label(); 312 338 } … … 314 340 void JITInstanceOfGenerator::finalize(LinkBuffer& fastPath, LinkBuffer& slowPath) 315 341 { 316 JITInlineCacheGenerator::finalize( 317 fastPath, slowPath, 318 fastPath.locationOf<JITStubRoutinePtrTag>(m_jump)); 319 320 fastPath.link(m_jump.m_jump, slowPath.locationOf<NoPtrTag>(m_slowPathBegin)); 321 } 322 323 JITGetByValGenerator::JITGetByValGenerator(CodeBlock* codeBlock, CodeOrigin codeOrigin, CallSiteIndex callSiteIndex, AccessType accessType, const RegisterSet& usedRegisters, JSValueRegs base, JSValueRegs property, JSValueRegs result) 324 : Base(codeBlock, codeOrigin, callSiteIndex, accessType, usedRegisters) 342 Base::finalize(fastPath, slowPath, fastPath.locationOf<JITStubRoutinePtrTag>(m_start)); 343 if (JITCode::useDataIC(m_jitType)) 344 m_stubInfo->m_codePtr = m_stubInfo->slowPathStartLocation; 345 } 346 347 JITGetByValGenerator::JITGetByValGenerator(CodeBlock* codeBlock, JITType jitType, CodeOrigin codeOrigin, CallSiteIndex callSiteIndex, AccessType accessType, const RegisterSet& usedRegisters, JSValueRegs base, JSValueRegs property, JSValueRegs result, GPRReg stubInfoGPR) 348 : Base(codeBlock, jitType, codeOrigin, callSiteIndex, accessType, usedRegisters) 325 349 , m_base(base) 326 350 , m_result(result) … … 331 355 m_stubInfo->regs.propertyGPR = property.payloadGPR(); 332 356 m_stubInfo->valueGPR = result.payloadGPR(); 357 m_stubInfo->m_stubInfoGPR = stubInfoGPR; 333 358 #if USE(JSVALUE32_64) 334 359 m_stubInfo->baseTagGPR = base.tagGPR(); … … 341 366 { 342 367 m_start = jit.label(); 343 m_slowPathJump = jit.patchableJump(); 344 m_done = jit.label(); 345 } 346 347 void JITGetByValGenerator::finalize( 348 LinkBuffer& fastPath, LinkBuffer& slowPath) 349 { 350 ASSERT(m_start.isSet()); 351 Base::finalize( 352 fastPath, slowPath, fastPath.locationOf<JITStubRoutinePtrTag>(m_start)); 353 } 354 355 JITPrivateBrandAccessGenerator::JITPrivateBrandAccessGenerator(CodeBlock* codeBlock, CodeOrigin codeOrigin, CallSiteIndex callSiteIndex, AccessType accessType, const RegisterSet& usedRegisters, JSValueRegs base, JSValueRegs brand) 356 : Base(codeBlock, codeOrigin, callSiteIndex, accessType, usedRegisters) 368 if (JITCode::useDataIC(m_jitType)) { 369 jit.move(CCallHelpers::TrustedImmPtr(m_stubInfo), m_stubInfo->m_stubInfoGPR); 370 jit.call(CCallHelpers::Address(m_stubInfo->m_stubInfoGPR, StructureStubInfo::offsetOfCodePtr()), JITStubRoutinePtrTag); 371 } else 372 m_slowPathJump = jit.patchableJump(); 373 m_done = jit.label(); 374 } 375 376 void JITGetByValGenerator::finalize(LinkBuffer& fastPath, LinkBuffer& slowPath) 377 { 378 Base::finalize(fastPath, slowPath, fastPath.locationOf<JITStubRoutinePtrTag>(m_start)); 379 if (JITCode::useDataIC(m_jitType)) 380 m_stubInfo->m_codePtr = m_stubInfo->slowPathStartLocation; 381 } 382 383 JITPrivateBrandAccessGenerator::JITPrivateBrandAccessGenerator(CodeBlock* codeBlock, JITType jitType, CodeOrigin codeOrigin, CallSiteIndex callSiteIndex, AccessType accessType, const RegisterSet& usedRegisters, JSValueRegs base, JSValueRegs brand, GPRReg stubInfoGPR) 384 : Base(codeBlock, jitType, codeOrigin, callSiteIndex, accessType, usedRegisters) 357 385 { 358 386 ASSERT(accessType == AccessType::CheckPrivateBrand || accessType == AccessType::SetPrivateBrand); … … 362 390 m_stubInfo->regs.brandGPR = brand.payloadGPR(); 363 391 m_stubInfo->valueGPR = InvalidGPRReg; 392 m_stubInfo->m_stubInfoGPR = stubInfoGPR; 364 393 #if USE(JSVALUE32_64) 365 394 m_stubInfo->baseTagGPR = base.tagGPR(); … … 372 401 { 373 402 m_start = jit.label(); 374 m_slowPathJump = jit.patchableJump(); 375 m_done = jit.label(); 376 } 377 378 void JITPrivateBrandAccessGenerator::finalize( 379 LinkBuffer& fastPath, LinkBuffer& slowPath) 380 { 381 ASSERT(m_start.isSet()); 382 Base::finalize( 383 fastPath, slowPath, fastPath.locationOf<JITStubRoutinePtrTag>(m_start)); 403 if (JITCode::useDataIC(m_jitType)) { 404 jit.move(CCallHelpers::TrustedImmPtr(m_stubInfo), m_stubInfo->m_stubInfoGPR); 405 jit.call(CCallHelpers::Address(m_stubInfo->m_stubInfoGPR, StructureStubInfo::offsetOfCodePtr()), JITStubRoutinePtrTag); 406 } else 407 m_slowPathJump = jit.patchableJump(); 408 m_done = jit.label(); 409 } 410 411 void JITPrivateBrandAccessGenerator::finalize(LinkBuffer& fastPath, LinkBuffer& slowPath) 412 { 413 Base::finalize(fastPath, slowPath, fastPath.locationOf<JITStubRoutinePtrTag>(m_start)); 414 if (JITCode::useDataIC(m_jitType)) 415 m_stubInfo->m_codePtr = m_stubInfo->slowPathStartLocation; 384 416 } 385 417 -
trunk/Source/JavaScriptCore/jit/JITInlineCacheGenerator.h
r278445 r278656 42 42 43 43 enum class AccessType : int8_t; 44 enum class JITType : uint8_t; 44 45 45 46 class JITInlineCacheGenerator { 46 47 protected: 47 48 JITInlineCacheGenerator() { } 48 JITInlineCacheGenerator( 49 CodeBlock*, CodeOrigin, CallSiteIndex, AccessType, const RegisterSet& usedRegisters); 49 JITInlineCacheGenerator(CodeBlock*, JITType, CodeOrigin, CallSiteIndex, AccessType, const RegisterSet& usedRegisters); 50 50 51 51 public: … … 66 66 protected: 67 67 CodeBlock* m_codeBlock; 68 JITType m_jitType; 68 69 StructureStubInfo* m_stubInfo; 69 70 … … 78 79 79 80 JITByIdGenerator( 80 CodeBlock*, CodeOrigin, CallSiteIndex, AccessType, const RegisterSet& usedRegisters,81 JSValueRegs base, JSValueRegs value );81 CodeBlock*, JITType, CodeOrigin, CallSiteIndex, AccessType, const RegisterSet& usedRegisters, 82 JSValueRegs base, JSValueRegs value, GPRReg stubInfoGPR); 82 83 83 84 public: … … 102 103 }; 103 104 104 class JITGetByIdGenerator : public JITByIdGenerator {105 class JITGetByIdGenerator final : public JITByIdGenerator { 105 106 public: 106 107 JITGetByIdGenerator() { } 107 108 108 109 JITGetByIdGenerator( 109 CodeBlock*, CodeOrigin, CallSiteIndex, const RegisterSet& usedRegisters, CacheableIdentifier,110 JSValueRegs base, JSValueRegs value, AccessType);110 CodeBlock*, JITType, CodeOrigin, CallSiteIndex, const RegisterSet& usedRegisters, CacheableIdentifier, 111 JSValueRegs base, JSValueRegs value, GPRReg stubInfoGPR, AccessType); 111 112 112 113 void generateFastPath(MacroAssembler&); … … 116 117 }; 117 118 118 class JITGetByIdWithThisGenerator : public JITByIdGenerator {119 class JITGetByIdWithThisGenerator final : public JITByIdGenerator { 119 120 public: 120 121 JITGetByIdWithThisGenerator() { } 121 122 122 123 JITGetByIdWithThisGenerator( 123 CodeBlock*, CodeOrigin, CallSiteIndex, const RegisterSet& usedRegisters, CacheableIdentifier,124 JSValueRegs value, JSValueRegs base, JSValueRegs thisRegs );125 126 void generateFastPath(MacroAssembler&); 127 }; 128 129 class JITPutByIdGenerator : public JITByIdGenerator {124 CodeBlock*, JITType, CodeOrigin, CallSiteIndex, const RegisterSet& usedRegisters, CacheableIdentifier, 125 JSValueRegs value, JSValueRegs base, JSValueRegs thisRegs, GPRReg stubInfoGPR); 126 127 void generateFastPath(MacroAssembler&); 128 }; 129 130 class JITPutByIdGenerator final : public JITByIdGenerator { 130 131 public: 131 132 JITPutByIdGenerator() … … 134 135 135 136 JITPutByIdGenerator( 136 CodeBlock*, CodeOrigin, CallSiteIndex, const RegisterSet& usedRegisters, CacheableIdentifier, JSValueRegs base,137 JSValueRegs value, GPRReg s cratch, ECMAMode, PutKind);137 CodeBlock*, JITType, CodeOrigin, CallSiteIndex, const RegisterSet& usedRegisters, CacheableIdentifier, JSValueRegs base, 138 JSValueRegs value, GPRReg stubInfoGPR, GPRReg scratch, ECMAMode, PutKind); 138 139 139 140 void generateFastPath(MacroAssembler&); … … 146 147 }; 147 148 148 class JITDelByValGenerator : public JITInlineCacheGenerator {149 class JITDelByValGenerator final : public JITInlineCacheGenerator { 149 150 using Base = JITInlineCacheGenerator; 150 151 public: … … 152 153 153 154 JITDelByValGenerator( 154 CodeBlock*, CodeOrigin, CallSiteIndex, const RegisterSet& usedRegisters,155 JSValueRegs base, JSValueRegs property, JSValueRegs result, GPRReg s cratch);156 157 MacroAssembler::Jump slowPathJump() const 158 { 159 ASSERT(m_slowPathJump.m_jump.isSet()); 160 return m_slowPathJump.m_jump; 161 } 162 163 void finalize( 164 LinkBuffer& fastPathLinkBuffer, LinkBuffer& slowPathLinkBuffer); 165 166 void generateFastPath(MacroAssembler&); 167 168 private: 169 MacroAssembler::Label m_start; 170 MacroAssembler::PatchableJump m_slowPathJump; 171 }; 172 173 class JITDelByIdGenerator : public JITInlineCacheGenerator {155 CodeBlock*, JITType, CodeOrigin, CallSiteIndex, const RegisterSet& usedRegisters, 156 JSValueRegs base, JSValueRegs property, JSValueRegs result, GPRReg stubInfoGPR, GPRReg scratch); 157 158 MacroAssembler::Jump slowPathJump() const 159 { 160 ASSERT(m_slowPathJump.m_jump.isSet()); 161 return m_slowPathJump.m_jump; 162 } 163 164 void finalize( 165 LinkBuffer& fastPathLinkBuffer, LinkBuffer& slowPathLinkBuffer); 166 167 void generateFastPath(MacroAssembler&); 168 169 private: 170 MacroAssembler::Label m_start; 171 MacroAssembler::PatchableJump m_slowPathJump; 172 }; 173 174 class JITDelByIdGenerator final : public JITInlineCacheGenerator { 174 175 using Base = JITInlineCacheGenerator; 175 176 public: … … 177 178 178 179 JITDelByIdGenerator( 179 CodeBlock*, CodeOrigin, CallSiteIndex, const RegisterSet& usedRegisters, CacheableIdentifier,180 JSValueRegs base, JSValueRegs result, GPRReg s cratch);180 CodeBlock*, JITType, CodeOrigin, CallSiteIndex, const RegisterSet& usedRegisters, CacheableIdentifier, 181 JSValueRegs base, JSValueRegs result, GPRReg stubInfoGPR, GPRReg scratch); 181 182 182 183 MacroAssembler::Jump slowPathJump() const … … 202 203 203 204 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 223 class JITInByIdGenerator : public JITByIdGenerator {205 CodeBlock*, JITType, CodeOrigin, CallSiteIndex, const RegisterSet& usedRegisters, 206 JSValueRegs base, JSValueRegs property, JSValueRegs result, GPRReg stubInfoGPR); 207 208 MacroAssembler::Jump slowPathJump() const 209 { 210 ASSERT(m_slowPathJump.m_jump.isSet()); 211 return m_slowPathJump.m_jump; 212 } 213 214 void finalize( 215 LinkBuffer& fastPathLinkBuffer, LinkBuffer& slowPathLinkBuffer); 216 217 void generateFastPath(MacroAssembler&); 218 219 private: 220 MacroAssembler::Label m_start; 221 MacroAssembler::PatchableJump m_slowPathJump; 222 }; 223 224 class JITInByIdGenerator final : public JITByIdGenerator { 224 225 public: 225 226 JITInByIdGenerator() { } 226 227 227 228 JITInByIdGenerator( 228 CodeBlock*, CodeOrigin, CallSiteIndex, const RegisterSet& usedRegisters, CacheableIdentifier, 229 JSValueRegs base, JSValueRegs value); 230 231 void generateFastPath(MacroAssembler&); 232 }; 233 234 class JITInstanceOfGenerator : public JITInlineCacheGenerator { 235 public: 229 CodeBlock*, JITType, CodeOrigin, CallSiteIndex, const RegisterSet& usedRegisters, CacheableIdentifier, 230 JSValueRegs base, JSValueRegs value, GPRReg stubInfoGPR); 231 232 void generateFastPath(MacroAssembler&); 233 }; 234 235 class JITInstanceOfGenerator final : public JITInlineCacheGenerator { 236 public: 237 using Base = JITInlineCacheGenerator; 236 238 JITInstanceOfGenerator() { } 237 239 238 240 JITInstanceOfGenerator( 239 CodeBlock*, CodeOrigin, CallSiteIndex, const RegisterSet& usedRegisters, GPRReg result,240 GPRReg value, GPRReg prototype, GPRReg s cratch1, GPRReg scratch2,241 CodeBlock*, JITType, CodeOrigin, CallSiteIndex, const RegisterSet& usedRegisters, GPRReg result, 242 GPRReg value, GPRReg prototype, GPRReg stubInfoGPR, GPRReg scratch1, GPRReg scratch2, 241 243 bool prototypeIsKnownObject = false); 242 244 243 245 void generateFastPath(MacroAssembler&); 244 246 247 MacroAssembler::Jump slowPathJump() const 248 { 249 ASSERT(m_slowPathJump.m_jump.isSet()); 250 return m_slowPathJump.m_jump; 251 } 252 245 253 void finalize(LinkBuffer& fastPathLinkBuffer, LinkBuffer& slowPathLinkBuffer); 246 254 247 255 private: 248 MacroAssembler::PatchableJump m_jump; 249 }; 250 251 class JITGetByValGenerator : public JITInlineCacheGenerator { 256 MacroAssembler::Label m_start; 257 MacroAssembler::PatchableJump m_slowPathJump; 258 }; 259 260 class JITGetByValGenerator final : public JITInlineCacheGenerator { 252 261 using Base = JITInlineCacheGenerator; 253 262 public: … … 255 264 256 265 JITGetByValGenerator( 257 CodeBlock*, CodeOrigin, CallSiteIndex, AccessType, const RegisterSet& usedRegisters,258 JSValueRegs base, JSValueRegs property, JSValueRegs result );266 CodeBlock*, JITType, CodeOrigin, CallSiteIndex, AccessType, const RegisterSet& usedRegisters, 267 JSValueRegs base, JSValueRegs property, JSValueRegs result, GPRReg stubInfoGPR); 259 268 260 269 MacroAssembler::Jump slowPathJump() const … … 277 286 }; 278 287 279 class JITPrivateBrandAccessGenerator : public JITInlineCacheGenerator {288 class JITPrivateBrandAccessGenerator final : public JITInlineCacheGenerator { 280 289 using Base = JITInlineCacheGenerator; 281 290 public: … … 283 292 284 293 JITPrivateBrandAccessGenerator( 285 CodeBlock*, CodeOrigin, CallSiteIndex, AccessType, const RegisterSet& usedRegisters,286 JSValueRegs base, JSValueRegs brand );294 CodeBlock*, JITType, CodeOrigin, CallSiteIndex, AccessType, const RegisterSet& usedRegisters, 295 JSValueRegs base, JSValueRegs brand, GPRReg stubInfoGPR); 287 296 288 297 MacroAssembler::Jump slowPathJump() const -
trunk/Source/JavaScriptCore/jit/JITInlines.h
r278576 r278656 34 34 namespace JSC { 35 35 36 ALWAYS_INLINE MacroAssembler::JumpList JIT::emitLoadForArrayMode(const Instruction* currentInstruction, JITArrayMode arrayMode, PatchableJump& badType )36 ALWAYS_INLINE MacroAssembler::JumpList JIT::emitLoadForArrayMode(const Instruction* currentInstruction, JITArrayMode arrayMode, PatchableJump& badType, ByValInfo* byValInfo) 37 37 { 38 38 switch (arrayMode) { 39 39 case JITInt32: 40 return emitInt32Load(currentInstruction, badType );40 return emitInt32Load(currentInstruction, badType, byValInfo); 41 41 case JITDouble: 42 return emitDoubleLoad(currentInstruction, badType );42 return emitDoubleLoad(currentInstruction, badType, byValInfo); 43 43 case JITContiguous: 44 return emitContiguousLoad(currentInstruction, badType );44 return emitContiguousLoad(currentInstruction, badType, byValInfo); 45 45 case JITArrayStorage: 46 return emitArrayStorageLoad(currentInstruction, badType );46 return emitArrayStorageLoad(currentInstruction, badType, byValInfo); 47 47 default: 48 48 break; … … 128 128 } 129 129 130 ALWAYS_INLINE void JIT::appendCallWithExceptionCheck(Address function) 131 { 132 updateTopCallFrame(); 133 appendCall(function); 134 exceptionCheck(); 135 } 136 130 137 #if OS(WINDOWS) && CPU(X86_64) 131 138 ALWAYS_INLINE MacroAssembler::Call JIT::appendCallWithExceptionCheckAndSlowPathReturnType(const FunctionPtr<CFunctionPtrTag> function) … … 155 162 #endif 156 163 return call; 164 } 165 166 ALWAYS_INLINE void JIT::appendCallWithExceptionCheckSetJSValueResult(Address function, VirtualRegister dst) 167 { 168 appendCallWithExceptionCheck(function); 169 #if USE(JSVALUE64) 170 emitPutVirtualRegister(dst, returnValueGPR); 171 #else 172 emitStore(dst, returnValueGPR2, returnValueGPR); 173 #endif 157 174 } 158 175 … … 169 186 #endif 170 187 return call; 188 } 189 190 template<typename Metadata> 191 ALWAYS_INLINE void JIT::appendCallWithExceptionCheckSetJSValueResultWithProfile(Metadata& metadata, Address function, VirtualRegister dst) 192 { 193 appendCallWithExceptionCheck(function); 194 #if USE(JSVALUE64) 195 emitValueProfilingSite(metadata, returnValueGPR); 196 emitPutVirtualRegister(dst, returnValueGPR); 197 #else 198 emitValueProfilingSite(metadata, JSValueRegs(returnValueGPR2, returnValueGPR)); 199 emitStore(dst, returnValueGPR2, returnValueGPR); 200 #endif 171 201 } 172 202 -
trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp
r278576 r278656 165 165 166 166 JITInstanceOfGenerator gen( 167 m_codeBlock, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex),167 m_codeBlock, JITType::BaselineJIT, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), 168 168 RegisterSet::stubUnavailableRegisters(), 169 169 regT0, // result 170 170 regT2, // value 171 171 regT1, // proto 172 regT5, 172 173 regT3, regT4); // scratch 173 174 gen.generateFastPath(*this); 175 if (!JITCode::useDataIC(JITType::BaselineJIT)) 176 addSlowCase(gen.slowPathJump()); 177 else 178 addSlowCase(); 174 179 m_instanceOfs.append(gen); 175 180 … … 187 192 188 193 Label coldPathBegin = label(); 189 Call call = callOperation(operationInstanceOfOptimize, resultVReg, TrustedImmPtr(m_codeBlock->globalObject()), gen.stubInfo(), regT2, regT1); 194 195 Call call; 196 if (JITCode::useDataIC(JITType::BaselineJIT)) { 197 gen.stubInfo()->m_slowOperation = operationInstanceOfOptimize; 198 move(TrustedImmPtr(gen.stubInfo()), GPRInfo::nonArgGPR0); 199 callOperation<decltype(operationInstanceOfOptimize)>(Address(GPRInfo::nonArgGPR0, StructureStubInfo::offsetOfSlowOperation()), resultVReg, TrustedImmPtr(m_codeBlock->globalObject()), GPRInfo::nonArgGPR0, regT2, regT1); 200 } else 201 call = callOperation(operationInstanceOfOptimize, resultVReg, TrustedImmPtr(m_codeBlock->globalObject()), gen.stubInfo(), regT2, regT1); 190 202 gen.reportSlowPathCall(coldPathBegin, call); 191 203 } … … 1805 1817 // FIXME: Add support for other types like TypedArrays and Arguments. 1806 1818 // See https://bugs.webkit.org/show_bug.cgi?id=135033 and https://bugs.webkit.org/show_bug.cgi?id=135034. 1807 JumpList slowCases = emitLoadForArrayMode(currentInstruction, arrayMode, badType );1819 JumpList slowCases = emitLoadForArrayMode(currentInstruction, arrayMode, badType, nullptr); 1808 1820 move(TrustedImm64(JSValue::encode(jsBoolean(true))), regT0); 1809 1821 Jump done = jump(); … … 1820 1832 "Baseline has_indexed_property stub for %s, return point %p", toCString(*m_codeBlock).data(), returnAddress.untaggedValue()); 1821 1833 1822 MacroAssembler::repatchJump(byValInfo->badTypeJump, CodeLocationLabel<JITStubRoutinePtrTag>(byValInfo->stubRoutine->code().code())); 1823 MacroAssembler::repatchCall(CodeLocationCall<ReturnAddressPtrTag>(MacroAssemblerCodePtr<ReturnAddressPtrTag>(returnAddress)), FunctionPtr<OperationPtrTag>(operationHasIndexedPropertyGeneric)); 1834 if (JITCode::useDataIC(JITType::BaselineJIT)) { 1835 byValInfo->m_badTypeJumpTarget = CodeLocationLabel<JITStubRoutinePtrTag>(byValInfo->stubRoutine->code().code()); 1836 byValInfo->m_slowOperation = operationHasIndexedPropertyGeneric; 1837 } else { 1838 MacroAssembler::repatchJump(byValInfo->m_badTypeJump, CodeLocationLabel<JITStubRoutinePtrTag>(byValInfo->stubRoutine->code().code())); 1839 MacroAssembler::repatchCall(CodeLocationCall<ReturnAddressPtrTag>(MacroAssemblerCodePtr<ReturnAddressPtrTag>(returnAddress)), FunctionPtr<OperationPtrTag>(operationHasIndexedPropertyGeneric)); 1840 } 1824 1841 } 1825 1842 … … 1855 1872 // FIXME: Add support for other types like TypedArrays and Arguments. 1856 1873 // See https://bugs.webkit.org/show_bug.cgi?id=135033 and https://bugs.webkit.org/show_bug.cgi?id=135034. 1857 JumpList slowCases = emitLoadForArrayMode(currentInstruction, mode, badType );1874 JumpList slowCases = emitLoadForArrayMode(currentInstruction, mode, badType, byValInfo); 1858 1875 1859 1876 move(TrustedImm64(JSValue::encode(jsBoolean(true))), regT0); 1860 1877 1861 addSlowCase(badType); 1878 if (!JITCode::useDataIC(JITType::BaselineJIT)) 1879 addSlowCase(badType); 1862 1880 addSlowCase(slowCases); 1863 1881 … … 1885 1903 emitGetVirtualRegister(base, regT0); 1886 1904 emitGetVirtualRegister(property, regT1); 1887 Call call = callOperation(operationHasIndexedPropertyDefault, dst, TrustedImmPtr(m_codeBlock->globalObject()), regT0, regT1, byValInfo); 1905 1906 Call call; 1907 if (JITCode::useDataIC(JITType::BaselineJIT)) { 1908 byValInfo->m_slowOperation = operationHasIndexedPropertyDefault; 1909 move(TrustedImmPtr(byValInfo), GPRInfo::nonArgGPR0); 1910 callOperation<decltype(operationHasIndexedPropertyDefault)>(Address(GPRInfo::nonArgGPR0, ByValInfo::offsetOfSlowOperation()), dst, TrustedImmPtr(m_codeBlock->globalObject()), regT0, regT1, GPRInfo::nonArgGPR0); 1911 } else 1912 call = callOperation(operationHasIndexedPropertyDefault, dst, TrustedImmPtr(m_codeBlock->globalObject()), regT0, regT1, byValInfo); 1888 1913 1889 1914 m_byValCompilationInfo[m_byValInstructionIndex].slowPathTarget = slowPath; -
trunk/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
r278576 r278656 163 163 164 164 JITInstanceOfGenerator gen( 165 m_codeBlock, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex),165 m_codeBlock, JITType::BaselineJIT, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), 166 166 RegisterSet::stubUnavailableRegisters(), 167 167 regT0, // result 168 168 regT2, // value 169 169 regT1, // proto 170 InvalidGPRReg, 170 171 regT3, regT4); // scratch 171 172 gen.generateFastPath(*this); 173 addSlowCase(gen.slowPathJump()); 172 174 m_instanceOfs.append(gen); 173 175 … … 1184 1186 // FIXME: Add support for other types like TypedArrays and Arguments. 1185 1187 // See https://bugs.webkit.org/show_bug.cgi?id=135033 and https://bugs.webkit.org/show_bug.cgi?id=135034. 1186 JumpList slowCases = emitLoadForArrayMode(currentInstruction, arrayMode, badType );1188 JumpList slowCases = emitLoadForArrayMode(currentInstruction, arrayMode, badType, nullptr); 1187 1189 move(TrustedImm32(1), regT0); 1188 1190 Jump done = jump(); … … 1199 1201 "Baseline has_indexed_property stub for %s, return point %p", toCString(*m_codeBlock).data(), returnAddress.untaggedValue()); 1200 1202 1201 MacroAssembler::repatchJump(byValInfo-> badTypeJump, CodeLocationLabel<JITStubRoutinePtrTag>(byValInfo->stubRoutine->code().code()));1203 MacroAssembler::repatchJump(byValInfo->m_badTypeJump, CodeLocationLabel<JITStubRoutinePtrTag>(byValInfo->stubRoutine->code().code())); 1202 1204 MacroAssembler::repatchCall(CodeLocationCall<ReturnAddressPtrTag>(MacroAssemblerCodePtr<ReturnAddressPtrTag>(returnAddress)), FunctionPtr<OperationPtrTag>(operationHasIndexedPropertyGeneric)); 1203 1205 } … … 1235 1237 // FIXME: Add support for other types like TypedArrays and Arguments. 1236 1238 // See https://bugs.webkit.org/show_bug.cgi?id=135033 and https://bugs.webkit.org/show_bug.cgi?id=135034. 1237 JumpList slowCases = emitLoadForArrayMode(currentInstruction, mode, badType );1239 JumpList slowCases = emitLoadForArrayMode(currentInstruction, mode, badType, byValInfo); 1238 1240 move(TrustedImm32(1), regT0); 1239 1241 -
trunk/Source/JavaScriptCore/jit/JITOperations.cpp
r278591 r278656 1048 1048 // Don't ever try to optimize. 1049 1049 byValInfo->tookSlowPath = true; 1050 ctiPatchCallByReturnAddress(ReturnAddressPtr(OUR_RETURN_ADDRESS), operationPutByValGeneric); 1050 if (codeBlock->useDataIC()) 1051 byValInfo->m_slowOperation = operationPutByValGeneric; 1052 else 1053 ctiPatchCallByReturnAddress(ReturnAddressPtr(OUR_RETURN_ADDRESS), operationPutByValGeneric); 1051 1054 } 1052 1055 RELEASE_AND_RETURN(scope, putByVal(globalObject, baseValue, subscript, value, byValInfo, ecmaMode)); … … 1140 1143 // Don't ever try to optimize. 1141 1144 byValInfo->tookSlowPath = true; 1142 ctiPatchCallByReturnAddress(ReturnAddressPtr(OUR_RETURN_ADDRESS), operationDirectPutByValGeneric); 1145 if (codeBlock->useDataIC()) 1146 byValInfo->m_slowOperation = operationDirectPutByValGeneric; 1147 else 1148 ctiPatchCallByReturnAddress(ReturnAddressPtr(OUR_RETURN_ADDRESS), operationDirectPutByValGeneric); 1143 1149 } 1144 1150 … … 1324 1330 // Don't ever try to optimize. 1325 1331 byValInfo->tookSlowPath = true; 1326 ctiPatchCallByReturnAddress(ReturnAddressPtr(OUR_RETURN_ADDRESS), operationPutPrivateNameGeneric); 1332 if (codeBlock->useDataIC()) 1333 byValInfo->m_slowOperation = operationPutPrivateNameGeneric; 1334 else 1335 ctiPatchCallByReturnAddress(ReturnAddressPtr(OUR_RETURN_ADDRESS), operationPutPrivateNameGeneric); 1327 1336 } 1328 1337 … … 2613 2622 || object->structure(vm)->typeInfo().interceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero()) { 2614 2623 // Don't ever try to optimize. 2615 ctiPatchCallByReturnAddress(ReturnAddressPtr(OUR_RETURN_ADDRESS), operationHasIndexedPropertyGeneric); 2624 CodeBlock* codeBlock = callFrame->codeBlock(); 2625 if (codeBlock->useDataIC()) 2626 byValInfo->m_slowOperation = operationHasIndexedPropertyGeneric; 2627 else 2628 ctiPatchCallByReturnAddress(ReturnAddressPtr(OUR_RETURN_ADDRESS), operationHasIndexedPropertyGeneric); 2616 2629 } 2617 2630 } -
trunk/Source/JavaScriptCore/jit/JITPropertyAccess.cpp
r278591 r278656 70 70 71 71 JITGetByValGenerator gen( 72 m_codeBlock, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), AccessType::GetByVal, RegisterSet::stubUnavailableRegisters(),73 JSValueRegs(regT0), JSValueRegs(regT1), resultRegs );72 m_codeBlock, JITType::BaselineJIT, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), AccessType::GetByVal, RegisterSet::stubUnavailableRegisters(), 73 JSValueRegs(regT0), JSValueRegs(regT1), resultRegs, regT2); 74 74 if (isOperandConstantInt(property)) 75 75 gen.stubInfo()->propertyIsInt32 = true; 76 76 gen.generateFastPath(*this); 77 addSlowCase(gen.slowPathJump()); 77 if (!JITCode::useDataIC(JITType::BaselineJIT)) 78 addSlowCase(gen.slowPathJump()); 79 else 80 addSlowCase(); 78 81 m_getByVals.append(gen); 79 82 … … 94 97 linkAllSlowCases(iter); 95 98 96 JITGetByValGenerator& gen = m_getByVals[m_getByValIndex ];97 ++m_getByValIndex; 99 JITGetByValGenerator& gen = m_getByVals[m_getByValIndex++]; 100 98 101 Label coldPathBegin = label(); 99 102 … … 119 122 emitNakedNearCall(vm.getCTIStub(slow_op_get_by_val_prepareCallGenerator).retaggedCode<NoPtrTag>()); 120 123 121 Call call = appendCall(operationGetByValOptimize); 124 Call call; 125 if (JITCode::useDataIC(JITType::BaselineJIT)) 126 gen.stubInfo()->m_slowOperation = operationGetByValOptimize; 127 else 128 call = appendCall(operationGetByValOptimize); 122 129 emitNakedNearCall(vm.getCTIStub(checkExceptionGenerator).retaggedCode<NoPtrTag>()); 123 130 … … 139 146 JIT jit(vm); 140 147 141 jit.tagReturnAddress(); 148 if (!JITCode::useDataIC(JITType::BaselineJIT)) 149 jit.tagReturnAddress(); 142 150 143 151 constexpr GPRReg bytecodeOffsetGPR = argumentGPR4; … … 158 166 jit.prepareCallOperation(vm); 159 167 160 // FIXME: Consider making this a tail call directly to the target operation instead 161 // of returning to the client to call it. 162 jit.ret(); 168 if (JITCode::useDataIC(JITType::BaselineJIT)) 169 jit.farJump(Address(argumentGPR1, StructureStubInfo::offsetOfSlowOperation()), OperationPtrTag); 170 else 171 jit.ret(); 163 172 164 173 LinkBuffer patchBuffer(jit, GLOBAL_THUNK_ID, LinkBuffer::Profile::ExtraCTIThunk); … … 183 192 184 193 JITGetByValGenerator gen( 185 m_codeBlock, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), AccessType::GetPrivateName,186 RegisterSet::stubUnavailableRegisters(), JSValueRegs(baseGPR), JSValueRegs(propertyGPR), resultRegs );194 m_codeBlock, JITType::BaselineJIT, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), AccessType::GetPrivateName, 195 RegisterSet::stubUnavailableRegisters(), JSValueRegs(baseGPR), JSValueRegs(propertyGPR), resultRegs, regT2); 187 196 gen.generateFastPath(*this); 188 addSlowCase(gen.slowPathJump()); 197 if (!JITCode::useDataIC(JITType::BaselineJIT)) 198 addSlowCase(gen.slowPathJump()); 199 else 200 addSlowCase(); 189 201 m_getByVals.append(gen); 190 202 … … 202 214 linkAllSlowCases(iter); 203 215 204 JITGetByValGenerator& gen = m_getByVals[m_getByValIndex]; 205 ++m_getByValIndex; 216 JITGetByValGenerator& gen = m_getByVals[m_getByValIndex++]; 206 217 Label coldPathBegin = label(); 207 218 … … 227 238 emitNakedNearCall(vm.getCTIStub(slow_op_get_private_name_prepareCallGenerator).retaggedCode<NoPtrTag>()); 228 239 229 Call call = appendCall(operationGetPrivateNameOptimize); 240 Call call; 241 if (JITCode::useDataIC(JITType::BaselineJIT)) 242 gen.stubInfo()->m_slowOperation = operationGetPrivateNameOptimize; 243 else 244 call = appendCall(operationGetPrivateNameOptimize); 230 245 emitNakedNearCall(vm.getCTIStub(checkExceptionGenerator).retaggedCode<NoPtrTag>()); 231 246 … … 246 261 JIT jit(vm); 247 262 248 jit.tagReturnAddress(); 263 if (!JITCode::useDataIC(JITType::BaselineJIT)) 264 jit.tagReturnAddress(); 249 265 250 266 constexpr GPRReg bytecodeOffsetGPR = argumentGPR3; … … 264 280 jit.prepareCallOperation(vm); 265 281 266 // FIXME: Consider making this a tail call directly to the target operation instead 267 // of returning to the client to call it. 268 jit.ret(); 282 if (JITCode::useDataIC(JITType::BaselineJIT)) 283 jit.farJump(Address(argumentGPR1, StructureStubInfo::offsetOfSlowOperation()), OperationPtrTag); 284 else 285 jit.ret(); 269 286 270 287 LinkBuffer patchBuffer(jit, GLOBAL_THUNK_ID, LinkBuffer::Profile::ExtraCTIThunk); … … 286 303 287 304 JITPrivateBrandAccessGenerator gen( 288 m_codeBlock, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), AccessType::SetPrivateBrand, RegisterSet::stubUnavailableRegisters(),289 JSValueRegs(baseGPR), JSValueRegs(brandGPR) );305 m_codeBlock, JITType::BaselineJIT, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), AccessType::SetPrivateBrand, RegisterSet::stubUnavailableRegisters(), 306 JSValueRegs(baseGPR), JSValueRegs(brandGPR), regT2); 290 307 gen.generateFastPath(*this); 291 addSlowCase(gen.slowPathJump()); 308 if (!JITCode::useDataIC(JITType::BaselineJIT)) 309 addSlowCase(gen.slowPathJump()); 310 else 311 addSlowCase(); 292 312 m_privateBrandAccesses.append(gen); 293 313 … … 303 323 linkAllSlowCases(iter); 304 324 305 JITPrivateBrandAccessGenerator& gen = m_privateBrandAccesses[m_privateBrandAccessIndex]; 306 ++m_privateBrandAccessIndex; 325 JITPrivateBrandAccessGenerator& gen = m_privateBrandAccesses[m_privateBrandAccessIndex++]; 307 326 Label coldPathBegin = label(); 308 327 … … 329 348 emitNakedNearCall(vm.getCTIStub(slow_op_get_private_name_prepareCallGenerator).retaggedCode<NoPtrTag>()); 330 349 331 Call call = appendCall(operationSetPrivateBrandOptimize); 350 Call call; 351 if (JITCode::useDataIC(JITType::BaselineJIT)) 352 gen.stubInfo()->m_slowOperation = operationSetPrivateBrandOptimize; 353 else 354 call = appendCall(operationSetPrivateBrandOptimize); 332 355 emitNakedNearCall(vm.getCTIStub(checkExceptionGenerator).retaggedCode<NoPtrTag>()); 333 356 #endif 357 334 358 gen.reportSlowPathCall(coldPathBegin, call); 335 359 } … … 347 371 348 372 JITPrivateBrandAccessGenerator gen( 349 m_codeBlock, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), AccessType::CheckPrivateBrand, RegisterSet::stubUnavailableRegisters(),350 JSValueRegs(regT0), JSValueRegs(regT1) );373 m_codeBlock, JITType::BaselineJIT, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), AccessType::CheckPrivateBrand, RegisterSet::stubUnavailableRegisters(), 374 JSValueRegs(regT0), JSValueRegs(regT1), regT2); 351 375 gen.generateFastPath(*this); 352 addSlowCase(gen.slowPathJump()); 376 if (!JITCode::useDataIC(JITType::BaselineJIT)) 377 addSlowCase(gen.slowPathJump()); 378 else 379 addSlowCase(); 353 380 m_privateBrandAccesses.append(gen); 354 381 } … … 358 385 linkAllSlowCases(iter); 359 386 360 JITPrivateBrandAccessGenerator& gen = m_privateBrandAccesses[m_privateBrandAccessIndex]; 361 ++m_privateBrandAccessIndex; 387 JITPrivateBrandAccessGenerator& gen = m_privateBrandAccesses[m_privateBrandAccessIndex++]; 362 388 Label coldPathBegin = label(); 363 389 … … 384 410 emitNakedNearCall(vm.getCTIStub(slow_op_get_private_name_prepareCallGenerator).retaggedCode<NoPtrTag>()); 385 411 386 Call call = appendCall(operationCheckPrivateBrandOptimize); 412 Call call; 413 if (JITCode::useDataIC(JITType::BaselineJIT)) 414 gen.stubInfo()->m_slowOperation = operationCheckPrivateBrandOptimize; 415 else 416 call = appendCall(operationCheckPrivateBrandOptimize); 387 417 emitNakedNearCall(vm.getCTIStub(checkExceptionGenerator).retaggedCode<NoPtrTag>()); 388 418 #endif // ENABLE(EXTRA_CTI_THUNKS) … … 416 446 PatchableJump notIndex; 417 447 if (!propertyNameIsIntegerConstant) { 418 notIndex = emitPatchableJumpIfNotInt(regT1); 419 addSlowCase(notIndex); 448 if (JITCode::useDataIC(JITType::BaselineJIT)) { 449 auto isInt32 = branchIfInt32(regT1); 450 farJump(AbsoluteAddress(&byValInfo->m_notIndexJumpTarget), JITStubRoutinePtrTag); 451 isInt32.link(this); 452 } else { 453 notIndex = emitPatchableJumpIfNotInt(regT1); 454 addSlowCase(notIndex); 455 } 420 456 // See comment in op_get_by_val. 421 457 zeroExtend32ToWord(regT1, regT1); … … 433 469 switch (mode) { 434 470 case JITInt32: 435 slowCases = emitInt32PutByVal(bytecode, badType );471 slowCases = emitInt32PutByVal(bytecode, badType, byValInfo); 436 472 break; 437 473 case JITDouble: 438 slowCases = emitDoublePutByVal(bytecode, badType );474 slowCases = emitDoublePutByVal(bytecode, badType, byValInfo); 439 475 break; 440 476 case JITContiguous: 441 slowCases = emitContiguousPutByVal(bytecode, badType );477 slowCases = emitContiguousPutByVal(bytecode, badType, byValInfo); 442 478 break; 443 479 case JITArrayStorage: 444 slowCases = emitArrayStoragePutByVal(bytecode, badType );480 slowCases = emitArrayStoragePutByVal(bytecode, badType, byValInfo); 445 481 break; 446 482 default: … … 449 485 } 450 486 451 addSlowCase(badType); 487 if (!JITCode::useDataIC(JITType::BaselineJIT)) 488 addSlowCase(badType); 452 489 addSlowCase(slowCases); 453 490 … … 458 495 459 496 template<typename Op> 460 JIT::JumpList JIT::emitGenericContiguousPutByVal(Op bytecode, PatchableJump& badType, IndexingType indexingShape)497 JIT::JumpList JIT::emitGenericContiguousPutByVal(Op bytecode, PatchableJump& badType, ByValInfo* byValInfo, IndexingType indexingShape) 461 498 { 462 499 auto& metadata = bytecode.metadata(m_codeBlock); … … 466 503 JumpList slowCases; 467 504 468 badType = patchableBranch32(NotEqual, regT2, TrustedImm32(indexingShape)); 505 if (JITCode::useDataIC(JITType::BaselineJIT)) { 506 if (byValInfo) { 507 auto isCorrectType = branch32(Equal, regT2, TrustedImm32(indexingShape)); 508 farJump(AbsoluteAddress(&byValInfo->m_badTypeJumpTarget), JITStubRoutinePtrTag); 509 isCorrectType.link(this); 510 } else 511 badType = patchableBranch32(NotEqual, regT2, TrustedImm32(indexingShape)); 512 } else 513 badType = patchableBranch32(NotEqual, regT2, TrustedImm32(indexingShape)); 514 469 515 470 516 loadPtr(Address(regT0, JSObject::butterflyOffset()), regT2); … … 516 562 517 563 template<typename Op> 518 JIT::JumpList JIT::emitArrayStoragePutByVal(Op bytecode, PatchableJump& badType )564 JIT::JumpList JIT::emitArrayStoragePutByVal(Op bytecode, PatchableJump& badType, ByValInfo* byValInfo) 519 565 { 520 566 auto& metadata = bytecode.metadata(m_codeBlock); … … 524 570 JumpList slowCases; 525 571 526 badType = patchableBranch32(NotEqual, regT2, TrustedImm32(ArrayStorageShape)); 572 if (JITCode::useDataIC(JITType::BaselineJIT)) { 573 if (byValInfo) { 574 auto isCorrectType = branch32(Equal, regT2, TrustedImm32(ArrayStorageShape)); 575 farJump(AbsoluteAddress(&byValInfo->m_badTypeJumpTarget), JITStubRoutinePtrTag); 576 isCorrectType.link(this); 577 } else 578 badType = patchableBranch32(NotEqual, regT2, TrustedImm32(ArrayStorageShape)); 579 } else 580 badType = patchableBranch32(NotEqual, regT2, TrustedImm32(ArrayStorageShape)); 581 527 582 loadPtr(Address(regT0, JSObject::butterflyOffset()), regT2); 528 583 slowCases.append(branch32(AboveOrEqual, regT1, Address(regT2, ArrayStorage::vectorLengthOffset()))); … … 569 624 570 625 JITPutByIdGenerator gen( 571 m_codeBlock, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), RegisterSet::stubUnavailableRegisters(), propertyName,572 JSValueRegs(regT0), JSValueRegs(regT1), regT 2, ecmaMode(bytecode), putKind);626 m_codeBlock, JITType::BaselineJIT, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), RegisterSet::stubUnavailableRegisters(), propertyName, 627 JSValueRegs(regT0), JSValueRegs(regT1), regT3, regT2, ecmaMode(bytecode), putKind); 573 628 gen.generateFastPath(*this); 574 629 // IC can write new Structure without write-barrier if a base is cell. … … 581 636 gen.slowPathJump().link(this); 582 637 583 Call call = callOperation(gen.slowPathFunction(), TrustedImmPtr(m_codeBlock->globalObject()), gen.stubInfo(), regT1, regT0, propertyName.rawBits()); 638 Call call; 639 if (JITCode::useDataIC(JITType::BaselineJIT)) { 640 gen.stubInfo()->m_slowOperation = gen.slowPathFunction(); 641 move(TrustedImmPtr(gen.stubInfo()), GPRInfo::nonArgGPR0); 642 callOperation<decltype(gen.slowPathFunction())>(Address(GPRInfo::nonArgGPR0, StructureStubInfo::offsetOfSlowOperation()), TrustedImmPtr(m_codeBlock->globalObject()), GPRInfo::nonArgGPR0, regT1, regT0, propertyName.rawBits()); 643 } else 644 call = callOperation(gen.slowPathFunction(), TrustedImmPtr(m_codeBlock->globalObject()), gen.stubInfo(), regT1, regT0, propertyName.rawBits()); 584 645 gen.reportSlowPathCall(coldPathBegin, call); 585 646 doneCases.append(jump()); … … 639 700 emitNakedNearCall(vm.getCTIStub(slow_op_put_by_val_prepareCallGenerator).retaggedCode<NoPtrTag>()); 640 701 641 auto* operation = isDirect ? operationDirectPutByValOptimize : operationPutByValOptimize; 642 Call call = appendCall(operation); 702 Call call; 703 if (JITCode::useDataIC(JITType::BaselineJIT)) 704 byValInfo->m_slowOperation = isDirect ? operationDirectPutByValOptimize : operationPutByValOptimize; 705 else 706 call = appendCall(isDirect ? operationDirectPutByValOptimize : operationPutByValOptimize); 643 707 emitNakedNearCall(vm.getCTIStub(checkExceptionGenerator).retaggedCode<NoPtrTag>()); 644 708 #endif // ENABLE(EXTRA_CTI_THUNKS) … … 658 722 JIT jit(vm); 659 723 660 jit.tagReturnAddress(); 724 if (!JITCode::useDataIC(JITType::BaselineJIT)) 725 jit.tagReturnAddress(); 661 726 662 727 constexpr GPRReg bytecodeOffsetGPR = argumentGPR0; … … 676 741 jit.prepareCallOperation(vm); 677 742 678 // FIXME: Consider making this a tail call directly to the target operation instead 679 // of returning to the client to call it. 680 jit.ret(); 743 if (JITCode::useDataIC(JITType::BaselineJIT)) 744 jit.farJump(Address(argumentGPR4, ByValInfo::offsetOfSlowOperation()), OperationPtrTag); 745 else 746 jit.ret(); 681 747 682 748 LinkBuffer patchBuffer(jit, GLOBAL_THUNK_ID, LinkBuffer::Profile::ExtraCTIThunk); … … 697 763 emitJumpSlowCaseIfNotJSCell(regT0, base); 698 764 699 PatchableJump fastPathJmp = patchableJump(); 700 addSlowCase(fastPathJmp); 765 PatchableJump fastPathJmp; 766 if (JITCode::useDataIC(JITType::BaselineJIT)) 767 farJump(AbsoluteAddress(&byValInfo->m_notIndexJumpTarget), JITStubRoutinePtrTag); 768 else { 769 fastPathJmp = patchableJump(); 770 addSlowCase(fastPathJmp); 771 } 701 772 702 773 Label done = label(); … … 744 815 emitNakedNearCall(vm.getCTIStub(slow_op_put_private_name_prepareCallGenerator).retaggedCode<NoPtrTag>()); 745 816 746 Call call = appendCall(operationPutPrivateNameOptimize); 817 Call call; 818 if (JITCode::useDataIC(JITType::BaselineJIT)) 819 byValInfo->m_slowOperation = operationPutPrivateNameOptimize; 820 else 821 call = appendCall(operationPutPrivateNameOptimize); 747 822 emitNakedNearCall(vm.getCTIStub(checkExceptionGenerator).retaggedCode<NoPtrTag>()); 748 823 #endif // ENABLE(EXTRA_CTI_THUNKS) … … 762 837 JIT jit(vm); 763 838 764 jit.tagReturnAddress(); 839 if (!JITCode::useDataIC(JITType::BaselineJIT)) 840 jit.tagReturnAddress(); 765 841 766 842 constexpr GPRReg bytecodeOffsetGPR = argumentGPR0; … … 780 856 jit.prepareCallOperation(vm); 781 857 782 // FIXME: Consider making this a tail call directly to the target operation instead 783 // of returning to the client to call it. 784 jit.ret(); 858 if (JITCode::useDataIC(JITType::BaselineJIT)) 859 jit.farJump(Address(argumentGPR4, ByValInfo::offsetOfSlowOperation()), OperationPtrTag); 860 else 861 jit.ret(); 785 862 786 863 LinkBuffer patchBuffer(jit, GLOBAL_THUNK_ID, LinkBuffer::Profile::ExtraCTIThunk); … … 847 924 emitJumpSlowCaseIfNotJSCell(regT1, base); 848 925 JITDelByIdGenerator gen( 849 m_codeBlock, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), RegisterSet::stubUnavailableRegisters(),926 m_codeBlock, JITType::BaselineJIT, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), RegisterSet::stubUnavailableRegisters(), 850 927 CacheableIdentifier::createFromIdentifierOwnedByCodeBlock(m_codeBlock, *ident), 851 JSValueRegs(regT1), JSValueRegs(regT0), regT 2);928 JSValueRegs(regT1), JSValueRegs(regT0), regT3, regT2); 852 929 gen.generateFastPath(*this); 853 addSlowCase(gen.slowPathJump()); 930 if (!JITCode::useDataIC(JITType::BaselineJIT)) 931 addSlowCase(gen.slowPathJump()); 932 else 933 addSlowCase(); 854 934 m_delByIds.append(gen); 855 935 … … 899 979 emitNakedNearCall(vm.getCTIStub(slow_op_del_by_id_prepareCallGenerator).retaggedCode<NoPtrTag>()); 900 980 901 Call call = appendCall(operationDeleteByIdOptimize); 981 Call call; 982 if (JITCode::useDataIC(JITType::BaselineJIT)) 983 gen.stubInfo()->m_slowOperation = operationDeleteByIdOptimize; 984 else 985 call = appendCall(operationDeleteByIdOptimize); 902 986 emitNakedNearCall(vm.getCTIStub(checkExceptionGenerator).retaggedCode<NoPtrTag>()); 903 987 static_assert(returnValueGPR == regT0); 904 988 #endif // ENABLE(EXTRA_CTI_THUNKS) 905 989 906 gen.reportSlowPathCall(coldPathBegin, call);907 908 990 boxBoolean(regT0, JSValueRegs(regT0)); 909 991 emitPutVirtualRegister(dst, JSValueRegs(regT0)); 992 gen.reportSlowPathCall(coldPathBegin, call); 910 993 } 911 994 … … 919 1002 JIT jit(vm); 920 1003 921 jit.tagReturnAddress(); 1004 if (!JITCode::useDataIC(JITType::BaselineJIT)) 1005 jit.tagReturnAddress(); 922 1006 923 1007 constexpr GPRReg bytecodeOffsetGPR = argumentGPR0; … … 936 1020 jit.prepareCallOperation(vm); 937 1021 938 // FIXME: Consider making this a tail call directly to the target operation instead 939 // of returning to the client to call it. 940 jit.ret(); 1022 if (JITCode::useDataIC(JITType::BaselineJIT)) 1023 jit.farJump(Address(argumentGPR1, StructureStubInfo::offsetOfSlowOperation()), OperationPtrTag); 1024 else 1025 jit.ret(); 941 1026 942 1027 LinkBuffer patchBuffer(jit, GLOBAL_THUNK_ID, LinkBuffer::Profile::ExtraCTIThunk); … … 957 1042 emitJumpSlowCaseIfNotJSCell(regT0, property); 958 1043 JITDelByValGenerator gen( 959 m_codeBlock, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), RegisterSet::stubUnavailableRegisters(),960 JSValueRegs(regT1), JSValueRegs(regT0), JSValueRegs(regT0), regT 2);1044 m_codeBlock, JITType::BaselineJIT, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), RegisterSet::stubUnavailableRegisters(), 1045 JSValueRegs(regT1), JSValueRegs(regT0), JSValueRegs(regT0), regT3, regT2); 961 1046 gen.generateFastPath(*this); 962 addSlowCase(gen.slowPathJump()); 1047 if (!JITCode::useDataIC(JITType::BaselineJIT)) 1048 addSlowCase(gen.slowPathJump()); 1049 else 1050 addSlowCase(); 963 1051 m_delByVals.append(gen); 964 1052 … … 1009 1097 emitNakedNearCall(vm.getCTIStub(slow_op_del_by_val_prepareCallGenerator).retaggedCode<NoPtrTag>()); 1010 1098 1011 Call call = appendCall(operationDeleteByValOptimize); 1099 Call call; 1100 if (JITCode::useDataIC(JITType::BaselineJIT)) 1101 gen.stubInfo()->m_slowOperation = operationDeleteByValOptimize; 1102 else 1103 call = appendCall(operationDeleteByValOptimize); 1012 1104 emitNakedNearCall(vm.getCTIStub(checkExceptionGenerator).retaggedCode<NoPtrTag>()); 1013 1105 static_assert(returnValueGPR == regT0); 1014 1106 #endif // ENABLE(EXTRA_CTI_THUNKS) 1015 1107 1016 gen.reportSlowPathCall(coldPathBegin, call);1017 1018 1108 boxBoolean(regT0, JSValueRegs(regT0)); 1019 1109 emitPutVirtualRegister(dst, JSValueRegs(regT0)); 1110 gen.reportSlowPathCall(coldPathBegin, call); 1020 1111 } 1021 1112 … … 1029 1120 JIT jit(vm); 1030 1121 1031 jit.tagReturnAddress(); 1122 if (!JITCode::useDataIC(JITType::BaselineJIT)) 1123 jit.tagReturnAddress(); 1032 1124 1033 1125 constexpr GPRReg bytecodeOffsetGPR = argumentGPR0; … … 1046 1138 jit.prepareCallOperation(vm); 1047 1139 1048 // FIXME: Consider making this a tail call directly to the target operation instead 1049 // of returning to the client to call it. 1050 jit.ret(); 1140 if (JITCode::useDataIC(JITType::BaselineJIT)) 1141 jit.farJump(Address(argumentGPR1, StructureStubInfo::offsetOfSlowOperation()), OperationPtrTag); 1142 else 1143 jit.ret(); 1051 1144 1052 1145 LinkBuffer patchBuffer(jit, GLOBAL_THUNK_ID, LinkBuffer::Profile::ExtraCTIThunk); … … 1069 1162 1070 1163 JITGetByIdGenerator gen( 1071 m_codeBlock, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), RegisterSet::stubUnavailableRegisters(),1072 CacheableIdentifier::createFromIdentifierOwnedByCodeBlock(m_codeBlock, *ident), JSValueRegs(regT0), resultRegs, AccessType::TryGetById);1164 m_codeBlock, JITType::BaselineJIT, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), RegisterSet::stubUnavailableRegisters(), 1165 CacheableIdentifier::createFromIdentifierOwnedByCodeBlock(m_codeBlock, *ident), JSValueRegs(regT0), resultRegs, regT1, AccessType::TryGetById); 1073 1166 gen.generateFastPath(*this); 1074 1167 addSlowCase(gen.slowPathJump()); … … 1111 1204 emitNakedNearCall(vm.getCTIStub(slow_op_get_by_id_prepareCallGenerator).retaggedCode<NoPtrTag>()); 1112 1205 1113 Call call = appendCall(operationTryGetByIdOptimize); 1206 Call call; 1207 if (JITCode::useDataIC(JITType::BaselineJIT)) 1208 gen.stubInfo()->m_slowOperation = operationTryGetByIdOptimize; 1209 else 1210 call = appendCall(operationTryGetByIdOptimize); 1114 1211 emitNakedNearCall(vm.getCTIStub(checkExceptionGenerator).retaggedCode<NoPtrTag>()); 1115 1212 … … 1134 1231 1135 1232 JITGetByIdGenerator gen( 1136 m_codeBlock, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), RegisterSet::stubUnavailableRegisters(),1137 CacheableIdentifier::createFromIdentifierOwnedByCodeBlock(m_codeBlock, *ident), JSValueRegs(regT0), resultRegs, AccessType::GetByIdDirect);1233 m_codeBlock, JITType::BaselineJIT, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), RegisterSet::stubUnavailableRegisters(), 1234 CacheableIdentifier::createFromIdentifierOwnedByCodeBlock(m_codeBlock, *ident), JSValueRegs(regT0), resultRegs, regT1, AccessType::GetByIdDirect); 1138 1235 gen.generateFastPath(*this); 1139 1236 addSlowCase(gen.slowPathJump()); … … 1177 1274 emitNakedNearCall(vm.getCTIStub(slow_op_get_by_id_prepareCallGenerator).retaggedCode<NoPtrTag>()); 1178 1275 1179 Call call = appendCall(operationGetByIdDirectOptimize); 1276 Call call; 1277 if (JITCode::useDataIC(JITType::BaselineJIT)) 1278 gen.stubInfo()->m_slowOperation = operationGetByIdDirectOptimize; 1279 else 1280 call = appendCall(operationGetByIdDirectOptimize); 1180 1281 emitNakedNearCall(vm.getCTIStub(checkExceptionGenerator).retaggedCode<NoPtrTag>()); 1181 1282 … … 1208 1309 1209 1310 JITGetByIdGenerator gen( 1210 m_codeBlock, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), RegisterSet::stubUnavailableRegisters(),1211 CacheableIdentifier::createFromIdentifierOwnedByCodeBlock(m_codeBlock, *ident), JSValueRegs(regT0), resultRegs, AccessType::GetById);1311 m_codeBlock, JITType::BaselineJIT, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), RegisterSet::stubUnavailableRegisters(), 1312 CacheableIdentifier::createFromIdentifierOwnedByCodeBlock(m_codeBlock, *ident), JSValueRegs(regT0), resultRegs, regT1, AccessType::GetById); 1212 1313 gen.generateFastPath(*this); 1213 1314 addSlowCase(gen.slowPathJump()); … … 1234 1335 1235 1336 JITGetByIdWithThisGenerator gen( 1236 m_codeBlock, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), RegisterSet::stubUnavailableRegisters(),1237 CacheableIdentifier::createFromIdentifierOwnedByCodeBlock(m_codeBlock, *ident), resultRegs, JSValueRegs(regT0), JSValueRegs(regT1) );1337 m_codeBlock, JITType::BaselineJIT, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), RegisterSet::stubUnavailableRegisters(), 1338 CacheableIdentifier::createFromIdentifierOwnedByCodeBlock(m_codeBlock, *ident), resultRegs, JSValueRegs(regT0), JSValueRegs(regT1), regT2); 1238 1339 gen.generateFastPath(*this); 1239 1340 addSlowCase(gen.slowPathJump()); … … 1276 1377 emitNakedNearCall(vm.getCTIStub(slow_op_get_by_id_prepareCallGenerator).retaggedCode<NoPtrTag>()); 1277 1378 1278 Call call = appendCall(operationGetByIdOptimize); 1379 Call call; 1380 if (JITCode::useDataIC(JITType::BaselineJIT)) 1381 gen.stubInfo()->m_slowOperation = operationGetByIdOptimize; 1382 else 1383 call = appendCall(operationGetByIdOptimize); 1279 1384 emitNakedNearCall(vm.getCTIStub(checkExceptionGenerator).retaggedCode<NoPtrTag>()); 1280 1385 … … 1295 1400 JIT jit(vm); 1296 1401 1297 jit.tagReturnAddress(); 1402 if (!JITCode::useDataIC(JITType::BaselineJIT)) 1403 jit.tagReturnAddress(); 1298 1404 1299 1405 constexpr GPRReg bytecodeOffsetGPR = argumentGPR2; … … 1312 1418 jit.prepareCallOperation(vm); 1313 1419 1314 // FIXME: Consider making this a tail call directly to the target operation instead 1315 // of returning to the client to call it. 1316 jit.ret(); 1420 if (JITCode::useDataIC(JITType::BaselineJIT)) 1421 jit.farJump(Address(argumentGPR1, StructureStubInfo::offsetOfSlowOperation()), OperationPtrTag); 1422 else 1423 jit.ret(); 1317 1424 1318 1425 LinkBuffer patchBuffer(jit, GLOBAL_THUNK_ID, LinkBuffer::Profile::ExtraCTIThunk); … … 1355 1462 emitNakedNearCall(vm.getCTIStub(slow_op_get_by_id_with_this_prepareCallGenerator).retaggedCode<NoPtrTag>()); 1356 1463 1357 Call call = appendCall(operationGetByIdWithThisOptimize); 1464 Call call; 1465 if (JITCode::useDataIC(JITType::BaselineJIT)) 1466 gen.stubInfo()->m_slowOperation = operationGetByIdWithThisOptimize; 1467 else 1468 call = appendCall(operationGetByIdWithThisOptimize); 1358 1469 emitNakedNearCall(vm.getCTIStub(checkExceptionGenerator).retaggedCode<NoPtrTag>()); 1359 1470 … … 1374 1485 JIT jit(vm); 1375 1486 1376 jit.tagReturnAddress(); 1487 if (!JITCode::useDataIC(JITType::BaselineJIT)) 1488 jit.tagReturnAddress(); 1377 1489 1378 1490 constexpr GPRReg bytecodeOffsetGPR = argumentGPR3; … … 1393 1505 jit.prepareCallOperation(vm); 1394 1506 1395 // FIXME: Consider making this a tail call directly to the target operation instead 1396 // of returning to the client to call it. 1397 jit.ret(); 1507 if (JITCode::useDataIC(JITType::BaselineJIT)) 1508 jit.farJump(Address(argumentGPR1, StructureStubInfo::offsetOfSlowOperation()), OperationPtrTag); 1509 else 1510 jit.ret(); 1398 1511 1399 1512 LinkBuffer patchBuffer(jit, GLOBAL_THUNK_ID, LinkBuffer::Profile::ExtraCTIThunk); … … 1419 1532 1420 1533 JITPutByIdGenerator gen( 1421 m_codeBlock, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), RegisterSet::stubUnavailableRegisters(),1534 m_codeBlock, JITType::BaselineJIT, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), RegisterSet::stubUnavailableRegisters(), 1422 1535 CacheableIdentifier::createFromIdentifierOwnedByCodeBlock(m_codeBlock, *ident), 1423 JSValueRegs(regT0), JSValueRegs(regT1), regT 2, ecmaMode(bytecode),1536 JSValueRegs(regT0), JSValueRegs(regT1), regT3, regT2, ecmaMode(bytecode), 1424 1537 direct ? PutKind::Direct : PutKind::NotDirect); 1425 1426 1538 gen.generateFastPath(*this); 1427 1539 addSlowCase(gen.slowPathJump()); … … 1466 1578 emitNakedNearCall(vm.getCTIStub(slow_op_put_by_id_prepareCallGenerator).retaggedCode<NoPtrTag>()); 1467 1579 1468 Call call = appendCall(gen.slowPathFunction()); 1580 Call call; 1581 if (JITCode::useDataIC(JITType::BaselineJIT)) 1582 gen.stubInfo()->m_slowOperation = gen.slowPathFunction(); 1583 else 1584 call = appendCall(gen.slowPathFunction()); 1469 1585 emitNakedNearCall(vm.getCTIStub(checkExceptionGenerator).retaggedCode<NoPtrTag>()); 1470 1586 #endif // ENABLE(EXTRA_CTI_THUNKS) … … 1482 1598 JIT jit(vm); 1483 1599 1484 jit.tagReturnAddress(); 1600 if (!JITCode::useDataIC(JITType::BaselineJIT)) 1601 jit.tagReturnAddress(); 1485 1602 1486 1603 constexpr GPRReg bytecodeOffsetGPR = argumentGPR2; … … 1501 1618 jit.prepareCallOperation(vm); 1502 1619 1503 // FIXME: Consider making this a tail call directly to the target operation instead 1504 // of returning to the client to call it. 1505 jit.ret(); 1620 if (JITCode::useDataIC(JITType::BaselineJIT)) 1621 jit.farJump(Address(argumentGPR1, StructureStubInfo::offsetOfSlowOperation()), OperationPtrTag); 1622 else 1623 jit.ret(); 1506 1624 1507 1625 LinkBuffer patchBuffer(jit, GLOBAL_THUNK_ID, LinkBuffer::Profile::ExtraCTIThunk); … … 1522 1640 1523 1641 JITInByIdGenerator gen( 1524 m_codeBlock, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), RegisterSet::stubUnavailableRegisters(),1525 CacheableIdentifier::createFromIdentifierOwnedByCodeBlock(m_codeBlock, *ident), JSValueRegs(regT0), JSValueRegs(regT0) );1642 m_codeBlock, JITType::BaselineJIT, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), RegisterSet::stubUnavailableRegisters(), 1643 CacheableIdentifier::createFromIdentifierOwnedByCodeBlock(m_codeBlock, *ident), JSValueRegs(regT0), JSValueRegs(regT0), regT1); 1526 1644 gen.generateFastPath(*this); 1527 1645 addSlowCase(gen.slowPathJump()); … … 1565 1683 emitNakedNearCall(vm.getCTIStub(slow_op_get_by_id_prepareCallGenerator).retaggedCode<NoPtrTag>()); 1566 1684 1567 Call call = appendCall(operationInByIdOptimize); 1685 Call call; 1686 if (JITCode::useDataIC(JITType::BaselineJIT)) 1687 gen.stubInfo()->m_slowOperation = operationInByIdOptimize; 1688 else 1689 call = appendCall(operationInByIdOptimize); 1568 1690 emitNakedNearCall(vm.getCTIStub(checkExceptionGenerator).retaggedCode<NoPtrTag>()); 1569 1691 … … 1589 1711 1590 1712 JITInByValGenerator gen( 1591 m_codeBlock, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), RegisterSet::stubUnavailableRegisters(),1592 JSValueRegs(regT0), JSValueRegs(regT1), JSValueRegs(regT0) );1713 m_codeBlock, JITType::BaselineJIT, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), RegisterSet::stubUnavailableRegisters(), 1714 JSValueRegs(regT0), JSValueRegs(regT1), JSValueRegs(regT0), regT2); 1593 1715 gen.generateFastPath(*this); 1594 addSlowCase(gen.slowPathJump()); 1716 if (!JITCode::useDataIC(JITType::BaselineJIT)) 1717 addSlowCase(gen.slowPathJump()); 1718 else 1719 addSlowCase(); 1595 1720 m_inByVals.append(gen); 1596 1721 … … 1635 1760 emitNakedNearCall(vm.getCTIStub(slow_op_get_by_val_prepareCallGenerator).retaggedCode<NoPtrTag>()); 1636 1761 1637 Call call = appendCall(operationInByValOptimize); 1762 Call call; 1763 if (JITCode::useDataIC(JITType::BaselineJIT)) 1764 gen.stubInfo()->m_slowOperation = operationInByValOptimize; 1765 else 1766 call = appendCall(operationInByValOptimize); 1638 1767 emitNakedNearCall(vm.getCTIStub(checkExceptionGenerator).retaggedCode<NoPtrTag>()); 1639 1768 … … 2825 2954 2826 2955 JITPutByIdGenerator gen( 2827 m_codeBlock, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), RegisterSet::stubUnavailableRegisters(), propertyName,2828 JSValueRegs::payloadOnly(regT0), JSValueRegs(regT3, regT2), regT1, ecmaMode(bytecode), putKind);2956 m_codeBlock, JITType::BaselineJIT, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), RegisterSet::stubUnavailableRegisters(), propertyName, 2957 JSValueRegs::payloadOnly(regT0), JSValueRegs(regT3, regT2), InvalidGPRReg, regT1, ecmaMode(bytecode), putKind); 2829 2958 gen.generateFastPath(*this); 2830 2959 doneCases.append(jump()); … … 2836 2965 emitLoadTag(base, regT1); 2837 2966 2838 Call call = callOperation(gen.slowPathFunction(), m_codeBlock->globalObject(), gen.stubInfo(), JSValueRegs(regT3, regT2), JSValueRegs(regT1, regT0), propertyName.rawBits()); 2967 Call call; 2968 if (JITCode::useDataIC(JITType::BaselineJIT)) { 2969 gen.stubInfo()->m_slowOperation = gen.slowPathFunction(); 2970 move(TrustedImmPtr(gen.stubInfo()), GPRInfo::nonArgGPR0); 2971 callOperation<decltype(gen.slowPathFunction())>(Address(GPRInfo::nonArgGPR0, StructureStubInfo::offsetOfSlowOperation()), m_codeBlock->globalObject(), GPRInfo::nonArgGPR0, JSValueRegs(regT3, regT2), JSValueRegs(regT1, regT0), propertyName.rawBits()); 2972 } else 2973 call = callOperation(gen.slowPathFunction(), m_codeBlock->globalObject(), gen.stubInfo(), JSValueRegs(regT3, regT2), JSValueRegs(regT1, regT0), propertyName.rawBits()); 2839 2974 gen.reportSlowPathCall(coldPathBegin, call); 2840 2975 doneCases.append(jump()); … … 2888 3023 switch (arrayMode) { 2889 3024 case JITInt32: 2890 slowCases = emitInt32PutByVal(bytecode, badType );3025 slowCases = emitInt32PutByVal(bytecode, badType, nullptr); 2891 3026 break; 2892 3027 case JITDouble: 2893 slowCases = emitDoublePutByVal(bytecode, badType );3028 slowCases = emitDoublePutByVal(bytecode, badType, nullptr); 2894 3029 break; 2895 3030 case JITContiguous: 2896 slowCases = emitContiguousPutByVal(bytecode, badType );3031 slowCases = emitContiguousPutByVal(bytecode, badType, nullptr); 2897 3032 needsLinkForWriteBarrier = true; 2898 3033 break; 2899 3034 case JITArrayStorage: 2900 slowCases = emitArrayStoragePutByVal(bytecode, badType );3035 slowCases = emitArrayStoragePutByVal(bytecode, badType, nullptr); 2901 3036 needsLinkForWriteBarrier = true; 2902 3037 break; … … 2904 3039 TypedArrayType type = typedArrayTypeForJITArrayMode(arrayMode); 2905 3040 if (isInt(type)) 2906 slowCases = emitIntTypedArrayPutByVal(bytecode, badType, type);3041 slowCases = emitIntTypedArrayPutByVal(bytecode, badType, nullptr, type); 2907 3042 else { 2908 3043 // FIXME: Optimize BigInt64Array / BigUint64Array in IC … … 2910 3045 // https://bugs.webkit.org/show_bug.cgi?id=221183 2911 3046 ASSERT(isFloat(type)); 2912 slowCases = emitFloatTypedArrayPutByVal(bytecode, badType, type);3047 slowCases = emitFloatTypedArrayPutByVal(bytecode, badType, nullptr, type); 2913 3048 } 2914 3049 break; … … 2937 3072 "Baseline put_by_val_direct stub for %s, return point %p", toCString(*m_codeBlock).data(), returnAddress.untaggedValue()); 2938 3073 } 2939 MacroAssembler::repatchJump(byValInfo->badTypeJump, CodeLocationLabel<JITStubRoutinePtrTag>(byValInfo->stubRoutine->code().code())); 2940 MacroAssembler::repatchCall(CodeLocationCall<ReturnAddressPtrTag>(MacroAssemblerCodePtr<ReturnAddressPtrTag>(returnAddress)), FunctionPtr<OperationPtrTag>(isDirect ? operationDirectPutByValGeneric : operationPutByValGeneric)); 3074 3075 if (JITCode::useDataIC(JITType::BaselineJIT)) { 3076 byValInfo->m_badTypeJumpTarget = CodeLocationLabel<JITStubRoutinePtrTag>(byValInfo->stubRoutine->code().code()); 3077 byValInfo->m_slowOperation = isDirect ? operationDirectPutByValGeneric : operationPutByValGeneric; 3078 } else { 3079 MacroAssembler::repatchJump(byValInfo->m_badTypeJump, CodeLocationLabel<JITStubRoutinePtrTag>(byValInfo->stubRoutine->code().code())); 3080 MacroAssembler::repatchCall(CodeLocationCall<ReturnAddressPtrTag>(MacroAssemblerCodePtr<ReturnAddressPtrTag>(returnAddress)), FunctionPtr<OperationPtrTag>(isDirect ? operationDirectPutByValGeneric : operationPutByValGeneric)); 3081 } 2941 3082 } 2942 3083 // This function is only consumed from another translation unit (JITOperations.cpp), … … 2977 3118 byValInfo->stubInfo = gen.stubInfo(); 2978 3119 2979 MacroAssembler::repatchJump(byValInfo->notIndexJump, CodeLocationLabel<JITStubRoutinePtrTag>(byValInfo->stubRoutine->code().code())); 2980 MacroAssembler::repatchCall(CodeLocationCall<ReturnAddressPtrTag>(MacroAssemblerCodePtr<ReturnAddressPtrTag>(returnAddress)), FunctionPtr<OperationPtrTag>(operationPutPrivateNameGeneric)); 3120 if (JITCode::useDataIC(JITType::BaselineJIT)) { 3121 byValInfo->m_notIndexJumpTarget = CodeLocationLabel<JITStubRoutinePtrTag>(byValInfo->stubRoutine->code().code()); 3122 byValInfo->m_slowOperation = operationPutPrivateNameGeneric; 3123 } else { 3124 MacroAssembler::repatchJump(byValInfo->m_notIndexJump, CodeLocationLabel<JITStubRoutinePtrTag>(byValInfo->stubRoutine->code().code())); 3125 MacroAssembler::repatchCall(CodeLocationCall<ReturnAddressPtrTag>(MacroAssemblerCodePtr<ReturnAddressPtrTag>(returnAddress)), FunctionPtr<OperationPtrTag>(operationPutPrivateNameGeneric)); 3126 } 2981 3127 } 2982 3128 … … 3015 3161 byValInfo->stubInfo = gen.stubInfo(); 3016 3162 3017 MacroAssembler::repatchJump(byValInfo->notIndexJump, CodeLocationLabel<JITStubRoutinePtrTag>(byValInfo->stubRoutine->code().code())); 3018 MacroAssembler::repatchCall(CodeLocationCall<ReturnAddressPtrTag>(MacroAssemblerCodePtr<ReturnAddressPtrTag>(returnAddress)), FunctionPtr<OperationPtrTag>(putKind == PutKind::Direct ? operationDirectPutByValGeneric : operationPutByValGeneric)); 3163 if (JITCode::useDataIC(JITType::BaselineJIT)) { 3164 byValInfo->m_notIndexJumpTarget = CodeLocationLabel<JITStubRoutinePtrTag>(byValInfo->stubRoutine->code().code()); 3165 byValInfo->m_slowOperation = putKind == PutKind::Direct ? operationDirectPutByValGeneric : operationPutByValGeneric; 3166 } else { 3167 MacroAssembler::repatchJump(byValInfo->m_notIndexJump, CodeLocationLabel<JITStubRoutinePtrTag>(byValInfo->stubRoutine->code().code())); 3168 MacroAssembler::repatchCall(CodeLocationCall<ReturnAddressPtrTag>(MacroAssemblerCodePtr<ReturnAddressPtrTag>(returnAddress)), FunctionPtr<OperationPtrTag>(putKind == PutKind::Direct ? operationDirectPutByValGeneric : operationPutByValGeneric)); 3169 } 3019 3170 } 3020 3171 // This function is only consumed from another translation unit (JITOperations.cpp), … … 3023 3174 template void JIT::privateCompilePutByValWithCachedId<OpPutByValDirect>(ByValInfo*, ReturnAddressPtr, PutKind, CacheableIdentifier); 3024 3175 3025 JIT::JumpList JIT::emitDoubleLoad(const Instruction*, PatchableJump& badType )3176 JIT::JumpList JIT::emitDoubleLoad(const Instruction*, PatchableJump& badType, ByValInfo* byValInfo) 3026 3177 { 3027 3178 #if USE(JSVALUE64) … … 3039 3190 JumpList slowCases; 3040 3191 3041 badType = patchableBranch32(NotEqual, indexing, TrustedImm32(DoubleShape)); 3192 if (JITCode::useDataIC(JITType::BaselineJIT)) { 3193 if (byValInfo) { 3194 auto isCorrectType = branch32(Equal, indexing, TrustedImm32(DoubleShape)); 3195 farJump(AbsoluteAddress(&byValInfo->m_badTypeJumpTarget), JITStubRoutinePtrTag); 3196 isCorrectType.link(this); 3197 } else 3198 badType = patchableBranch32(NotEqual, indexing, TrustedImm32(DoubleShape)); 3199 } else 3200 badType = patchableBranch32(NotEqual, indexing, TrustedImm32(DoubleShape)); 3201 3042 3202 loadPtr(Address(base, JSObject::butterflyOffset()), scratch); 3043 3203 slowCases.append(branch32(AboveOrEqual, property, Address(scratch, Butterfly::offsetOfPublicLength()))); … … 3048 3208 } 3049 3209 3050 JIT::JumpList JIT::emitContiguousLoad(const Instruction*, PatchableJump& badType, IndexingType expectedShape)3210 JIT::JumpList JIT::emitContiguousLoad(const Instruction*, PatchableJump& badType, ByValInfo* byValInfo, IndexingType expectedShape) 3051 3211 { 3052 3212 #if USE(JSVALUE64) … … 3066 3226 JumpList slowCases; 3067 3227 3068 badType = patchableBranch32(NotEqual, indexing, TrustedImm32(expectedShape)); 3228 if (JITCode::useDataIC(JITType::BaselineJIT)) { 3229 if (byValInfo) { 3230 auto isCorrectType = branch32(Equal, indexing, TrustedImm32(expectedShape)); 3231 farJump(AbsoluteAddress(&byValInfo->m_badTypeJumpTarget), JITStubRoutinePtrTag); 3232 isCorrectType.link(this); 3233 } else 3234 badType = patchableBranch32(NotEqual, indexing, TrustedImm32(expectedShape)); 3235 } else 3236 badType = patchableBranch32(NotEqual, indexing, TrustedImm32(expectedShape)); 3237 3069 3238 loadPtr(Address(base, JSObject::butterflyOffset()), scratch); 3070 3239 slowCases.append(branch32(AboveOrEqual, property, Address(scratch, Butterfly::offsetOfPublicLength()))); … … 3075 3244 } 3076 3245 3077 JIT::JumpList JIT::emitArrayStorageLoad(const Instruction*, PatchableJump& badType )3246 JIT::JumpList JIT::emitArrayStorageLoad(const Instruction*, PatchableJump& badType, ByValInfo* byValInfo) 3078 3247 { 3079 3248 #if USE(JSVALUE64) … … 3094 3263 3095 3264 add32(TrustedImm32(-ArrayStorageShape), indexing, scratch); 3096 badType = patchableBranch32(Above, scratch, TrustedImm32(SlowPutArrayStorageShape - ArrayStorageShape)); 3265 3266 if (JITCode::useDataIC(JITType::BaselineJIT)) { 3267 if (byValInfo) { 3268 auto isCorrectType = branch32(BelowOrEqual, scratch, TrustedImm32(SlowPutArrayStorageShape - ArrayStorageShape)); 3269 farJump(AbsoluteAddress(&byValInfo->m_badTypeJumpTarget), JITStubRoutinePtrTag); 3270 isCorrectType.link(this); 3271 } else 3272 badType = patchableBranch32(Above, scratch, TrustedImm32(SlowPutArrayStorageShape - ArrayStorageShape)); 3273 } else 3274 badType = patchableBranch32(Above, scratch, TrustedImm32(SlowPutArrayStorageShape - ArrayStorageShape)); 3097 3275 3098 3276 loadPtr(Address(base, JSObject::butterflyOffset()), scratch); … … 3106 3284 3107 3285 template<typename Op> 3108 JIT::JumpList JIT::emitIntTypedArrayPutByVal(Op bytecode, PatchableJump& badType, TypedArrayType type)3286 JIT::JumpList JIT::emitIntTypedArrayPutByVal(Op bytecode, PatchableJump& badType, ByValInfo* byValInfo, TypedArrayType type) 3109 3287 { 3110 3288 auto& metadata = bytecode.metadata(m_codeBlock); … … 3131 3309 3132 3310 load8(Address(base, JSCell::typeInfoTypeOffset()), earlyScratch); 3133 badType = patchableBranch32(NotEqual, earlyScratch, TrustedImm32(typeForTypedArrayType(type))); 3311 3312 if (JITCode::useDataIC(JITType::BaselineJIT)) { 3313 if (byValInfo) { 3314 auto isCorrectType = branch32(Equal, earlyScratch, TrustedImm32(typeForTypedArrayType(type))); 3315 farJump(AbsoluteAddress(&byValInfo->m_badTypeJumpTarget), JITStubRoutinePtrTag); 3316 isCorrectType.link(this); 3317 } else 3318 badType = patchableBranch32(NotEqual, earlyScratch, TrustedImm32(typeForTypedArrayType(type))); 3319 } else 3320 badType = patchableBranch32(NotEqual, earlyScratch, TrustedImm32(typeForTypedArrayType(type))); 3321 3134 3322 load32(Address(base, JSArrayBufferView::offsetOfLength()), lateScratch2); 3135 3323 Jump inBounds = branch32(Below, property, lateScratch2); … … 3182 3370 3183 3371 template<typename Op> 3184 JIT::JumpList JIT::emitFloatTypedArrayPutByVal(Op bytecode, PatchableJump& badType, TypedArrayType type)3372 JIT::JumpList JIT::emitFloatTypedArrayPutByVal(Op bytecode, PatchableJump& badType, ByValInfo* byValInfo, TypedArrayType type) 3185 3373 { 3186 3374 auto& metadata = bytecode.metadata(m_codeBlock); … … 3207 3395 3208 3396 load8(Address(base, JSCell::typeInfoTypeOffset()), earlyScratch); 3209 badType = patchableBranch32(NotEqual, earlyScratch, TrustedImm32(typeForTypedArrayType(type))); 3397 3398 if (JITCode::useDataIC(JITType::BaselineJIT)) { 3399 if (byValInfo) { 3400 auto isCorrectType = branch32(Equal, earlyScratch, TrustedImm32(typeForTypedArrayType(type))); 3401 farJump(AbsoluteAddress(&byValInfo->m_badTypeJumpTarget), JITStubRoutinePtrTag); 3402 isCorrectType.link(this); 3403 } else 3404 badType = patchableBranch32(NotEqual, earlyScratch, TrustedImm32(typeForTypedArrayType(type))); 3405 } else 3406 badType = patchableBranch32(NotEqual, earlyScratch, TrustedImm32(typeForTypedArrayType(type))); 3407 3210 3408 load32(Address(base, JSArrayBufferView::offsetOfLength()), lateScratch2); 3211 3409 Jump inBounds = branch32(Below, property, lateScratch2); -
trunk/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp
r278591 r278656 132 132 emitJumpSlowCaseIfNotJSCell(base, baseRegs.tagGPR()); 133 133 JITDelByIdGenerator gen( 134 m_codeBlock, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), RegisterSet::stubUnavailableRegisters(),134 m_codeBlock, JITType::BaselineJIT, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), RegisterSet::stubUnavailableRegisters(), 135 135 CacheableIdentifier::createFromIdentifierOwnedByCodeBlock(m_codeBlock, *ident), 136 baseRegs, resultRegs, regT4);136 baseRegs, resultRegs, InvalidGPRReg, regT4); 137 137 gen.generateFastPath(*this); 138 138 addSlowCase(gen.slowPathJump()); … … 167 167 168 168 JITDelByValGenerator gen( 169 m_codeBlock, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), RegisterSet::stubUnavailableRegisters(),170 baseRegs, propertyRegs, resultRegs, regT4);169 m_codeBlock, JITType::BaselineJIT, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), RegisterSet::stubUnavailableRegisters(), 170 baseRegs, propertyRegs, resultRegs, InvalidGPRReg, regT4); 171 171 172 172 gen.generateFastPath(*this); … … 258 258 259 259 JITGetByValGenerator gen( 260 m_codeBlock, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), AccessType::GetByVal, RegisterSet::stubUnavailableRegisters(),261 JSValueRegs::payloadOnly(regT0), JSValueRegs(regT3, regT2), resultRegs );260 m_codeBlock, JITType::BaselineJIT, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), AccessType::GetByVal, RegisterSet::stubUnavailableRegisters(), 261 JSValueRegs::payloadOnly(regT0), JSValueRegs(regT3, regT2), resultRegs, InvalidGPRReg); 262 262 if (isOperandConstantInt(property)) 263 263 gen.stubInfo()->propertyIsInt32 = true; … … 306 306 307 307 JITGetByValGenerator gen( 308 m_codeBlock, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), AccessType::GetPrivateName,309 RegisterSet::stubUnavailableRegisters(), baseGPR, propertyGPR, resultRegs );308 m_codeBlock, JITType::BaselineJIT, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), AccessType::GetPrivateName, 309 RegisterSet::stubUnavailableRegisters(), baseGPR, propertyGPR, resultRegs, InvalidGPRReg); 310 310 gen.generateFastPath(*this); 311 311 addSlowCase(gen.slowPathJump()); … … 394 394 395 395 JITPrivateBrandAccessGenerator gen( 396 m_codeBlock, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), AccessType::SetPrivateBrand, RegisterSet::stubUnavailableRegisters(),397 baseRegs, brandRegs );396 m_codeBlock, JITType::BaselineJIT, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), AccessType::SetPrivateBrand, RegisterSet::stubUnavailableRegisters(), 397 baseRegs, brandRegs, InvalidGPRReg); 398 398 gen.generateFastPath(*this); 399 399 addSlowCase(gen.slowPathJump()); … … 434 434 435 435 JITPrivateBrandAccessGenerator gen( 436 m_codeBlock, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), AccessType::CheckPrivateBrand, RegisterSet::stubUnavailableRegisters(),437 baseRegs, brandRegs );436 m_codeBlock, JITType::BaselineJIT, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), AccessType::CheckPrivateBrand, RegisterSet::stubUnavailableRegisters(), 437 baseRegs, brandRegs, InvalidGPRReg); 438 438 gen.generateFastPath(*this); 439 439 addSlowCase(gen.slowPathJump()); … … 487 487 switch (mode) { 488 488 case JITInt32: 489 slowCases = emitInt32PutByVal(bytecode, badType );489 slowCases = emitInt32PutByVal(bytecode, badType, byValInfo); 490 490 break; 491 491 case JITDouble: 492 slowCases = emitDoublePutByVal(bytecode, badType );492 slowCases = emitDoublePutByVal(bytecode, badType, byValInfo); 493 493 break; 494 494 case JITContiguous: 495 slowCases = emitContiguousPutByVal(bytecode, badType );495 slowCases = emitContiguousPutByVal(bytecode, badType, byValInfo); 496 496 break; 497 497 case JITArrayStorage: 498 slowCases = emitArrayStoragePutByVal(bytecode, badType );498 slowCases = emitArrayStoragePutByVal(bytecode, badType, byValInfo); 499 499 break; 500 500 default: … … 512 512 513 513 template <typename Op> 514 JIT::JumpList JIT::emitGenericContiguousPutByVal(Op bytecode, PatchableJump& badType, IndexingType indexingShape)514 JIT::JumpList JIT::emitGenericContiguousPutByVal(Op bytecode, PatchableJump& badType, ByValInfo* byValInfo, IndexingType indexingShape) 515 515 { 516 516 auto& metadata = bytecode.metadata(m_codeBlock); … … 521 521 JumpList slowCases; 522 522 523 UNUSED_PARAM(byValInfo); 523 524 badType = patchableBranch32(NotEqual, regT1, TrustedImm32(ContiguousShape)); 524 525 … … 573 574 574 575 template <typename Op> 575 JIT::JumpList JIT::emitArrayStoragePutByVal(Op bytecode, PatchableJump& badType )576 JIT::JumpList JIT::emitArrayStoragePutByVal(Op bytecode, PatchableJump& badType, ByValInfo* byValInfo) 576 577 { 577 578 auto& metadata = bytecode.metadata(m_codeBlock); … … 582 583 JumpList slowCases; 583 584 585 UNUSED_PARAM(byValInfo); 584 586 badType = patchableBranch32(NotEqual, regT1, TrustedImm32(ArrayStorageShape)); 585 587 … … 661 663 662 664 JITGetByIdGenerator gen( 663 m_codeBlock, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), RegisterSet::stubUnavailableRegisters(),664 CacheableIdentifier::createFromIdentifierOwnedByCodeBlock(m_codeBlock, *ident), JSValueRegs::payloadOnly(regT0), resultRegs, AccessType::TryGetById);665 m_codeBlock, JITType::BaselineJIT, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), RegisterSet::stubUnavailableRegisters(), 666 CacheableIdentifier::createFromIdentifierOwnedByCodeBlock(m_codeBlock, *ident), JSValueRegs::payloadOnly(regT0), resultRegs, InvalidGPRReg, AccessType::TryGetById); 665 667 gen.generateFastPath(*this); 666 668 addSlowCase(gen.slowPathJump()); … … 702 704 703 705 JITGetByIdGenerator gen( 704 m_codeBlock, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), RegisterSet::stubUnavailableRegisters(),705 CacheableIdentifier::createFromIdentifierOwnedByCodeBlock(m_codeBlock, *ident), JSValueRegs::payloadOnly(regT0), resultRegs, AccessType::GetByIdDirect);706 m_codeBlock, JITType::BaselineJIT, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), RegisterSet::stubUnavailableRegisters(), 707 CacheableIdentifier::createFromIdentifierOwnedByCodeBlock(m_codeBlock, *ident), JSValueRegs::payloadOnly(regT0), resultRegs, InvalidGPRReg, AccessType::GetByIdDirect); 706 708 gen.generateFastPath(*this); 707 709 addSlowCase(gen.slowPathJump()); … … 749 751 JSValueRegs resultRegs = JSValueRegs(regT1, regT0); 750 752 JITGetByIdGenerator gen( 751 m_codeBlock, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), RegisterSet::stubUnavailableRegisters(),752 CacheableIdentifier::createFromIdentifierOwnedByCodeBlock(m_codeBlock, *ident), JSValueRegs::payloadOnly(regT0), resultRegs, AccessType::GetById);753 m_codeBlock, JITType::BaselineJIT, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), RegisterSet::stubUnavailableRegisters(), 754 CacheableIdentifier::createFromIdentifierOwnedByCodeBlock(m_codeBlock, *ident), JSValueRegs::payloadOnly(regT0), resultRegs, InvalidGPRReg, AccessType::GetById); 753 755 gen.generateFastPath(*this); 754 756 addSlowCase(gen.slowPathJump()); … … 792 794 793 795 JITGetByIdWithThisGenerator gen( 794 m_codeBlock, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), RegisterSet::stubUnavailableRegisters(),795 CacheableIdentifier::createFromIdentifierOwnedByCodeBlock(m_codeBlock, *ident), resultRegs, JSValueRegs::payloadOnly(regT0), JSValueRegs(regT4, regT3) );796 m_codeBlock, JITType::BaselineJIT, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), RegisterSet::stubUnavailableRegisters(), 797 CacheableIdentifier::createFromIdentifierOwnedByCodeBlock(m_codeBlock, *ident), resultRegs, JSValueRegs::payloadOnly(regT0), JSValueRegs(regT4, regT3), InvalidGPRReg); 796 798 gen.generateFastPath(*this); 797 799 addSlowCase(gen.slowPathJump()); … … 836 838 837 839 JITPutByIdGenerator gen( 838 m_codeBlock, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), RegisterSet::stubUnavailableRegisters(),840 m_codeBlock, JITType::BaselineJIT, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), RegisterSet::stubUnavailableRegisters(), 839 841 CacheableIdentifier::createFromIdentifierOwnedByCodeBlock(m_codeBlock, *ident), 840 JSValueRegs::payloadOnly(regT0), JSValueRegs(regT3, regT2), 842 JSValueRegs::payloadOnly(regT0), JSValueRegs(regT3, regT2), InvalidGPRReg, 841 843 regT1, bytecode.m_flags.ecmaMode(), direct ? PutKind::Direct : PutKind::NotDirect); 842 844 … … 883 885 884 886 JITInByIdGenerator gen( 885 m_codeBlock, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), RegisterSet::stubUnavailableRegisters(),886 CacheableIdentifier::createFromIdentifierOwnedByCodeBlock(m_codeBlock, *ident), JSValueRegs::payloadOnly(regT0), JSValueRegs(regT1, regT0) );887 m_codeBlock, JITType::BaselineJIT, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), RegisterSet::stubUnavailableRegisters(), 888 CacheableIdentifier::createFromIdentifierOwnedByCodeBlock(m_codeBlock, *ident), JSValueRegs::payloadOnly(regT0), JSValueRegs(regT1, regT0), InvalidGPRReg); 887 889 gen.generateFastPath(*this); 888 890 addSlowCase(gen.slowPathJump()); … … 923 925 924 926 JITInByValGenerator gen( 925 m_codeBlock, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), RegisterSet::stubUnavailableRegisters(),926 JSValueRegs::payloadOnly(regT0), JSValueRegs(regT3, regT2), JSValueRegs(regT1, regT0) );927 m_codeBlock, JITType::BaselineJIT, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), RegisterSet::stubUnavailableRegisters(), 928 JSValueRegs::payloadOnly(regT0), JSValueRegs(regT3, regT2), JSValueRegs(regT1, regT0), InvalidGPRReg); 927 929 gen.generateFastPath(*this); 928 930 addSlowCase(gen.slowPathJump()); -
trunk/Source/JavaScriptCore/jit/JITStubRoutine.h
r277027 r278656 35 35 class JITStubRoutineSet; 36 36 class VM; 37 38 #if USE(JSVALUE64) 39 using StructureID = uint32_t; 40 #else 41 using StructureID = Structure*; 42 #endif 43 44 class AccessCase; 37 45 38 46 // This is a base-class for JIT stub routines, and also the class you want … … 104 112 MacroAssemblerCodeRef<JITStubRoutinePtrTag> m_code; 105 113 unsigned m_refCount; 114 mutable unsigned m_hash { 0 }; 106 115 }; 107 116 -
trunk/Source/JavaScriptCore/jit/PolymorphicCallStubRoutine.cpp
r277680 r278656 29 29 #if ENABLE(JIT) 30 30 31 #include "AccessCase.h" 31 32 #include "CallLinkInfo.h" 32 33 #include "CodeBlock.h" … … 68 69 CallLinkInfo& info, const Vector<PolymorphicCallCase>& cases, 69 70 UniqueArray<uint32_t>&& fastCounts) 70 : GCAwareJITStubRoutine(codeRef , vm)71 : GCAwareJITStubRoutine(codeRef) 71 72 , m_variants(cases.size()) 72 73 , m_fastCounts(WTFMove(fastCounts)) … … 81 82 } 82 83 WTF::storeStoreFence(); 84 makeGCAware(vm); 83 85 } 84 86 -
trunk/Source/JavaScriptCore/jit/Repatch.cpp
r278445 r278656 72 72 namespace JSC { 73 73 74 static FunctionPtr<CFunctionPtrTag> readPutICCallTarget(CodeBlock* codeBlock, CodeLocationCall<JSInternalPtrTag> call) 75 { 74 static FunctionPtr<CFunctionPtrTag> readPutICCallTarget(CodeBlock* codeBlock, StructureStubInfo& stubInfo) 75 { 76 if (codeBlock->useDataIC()) 77 return stubInfo.m_slowOperation.retagged<CFunctionPtrTag>(); 78 CodeLocationCall<JSInternalPtrTag> call = stubInfo.m_slowPathCallLocation; 76 79 #if ENABLE(FTL_JIT) 77 80 if (codeBlock->jitType() == JITType::FTLJIT) { … … 104 107 #endif // ENABLE(FTL_JIT) 105 108 MacroAssembler::repatchCall(call, newCalleeFunction.retagged<OperationPtrTag>()); 109 } 110 111 static void repatchSlowPathCall(CodeBlock* codeBlock, StructureStubInfo& stubInfo, FunctionPtr<CFunctionPtrTag> newCalleeFunction) 112 { 113 if (codeBlock->useDataIC()) { 114 stubInfo.m_slowOperation = newCalleeFunction.retagged<OperationPtrTag>(); 115 return; 116 } 117 ftlThunkAwareRepatchCall(codeBlock, stubInfo.m_slowPathCallLocation, newCalleeFunction); 106 118 } 107 119 … … 210 222 const bool isPrivate = kind == GetByKind::PrivateName || kind == GetByKind::PrivateNameById; 211 223 212 std::unique_ptr<AccessCase> newCase;224 RefPtr<AccessCase> newCase; 213 225 214 226 if (propertyName == vm.propertyNames->length) { … … 220 232 bool generatedCodeInline = InlineAccess::generateArrayLength(stubInfo, jsCast<JSArray*>(baseCell)); 221 233 if (generatedCodeInline) { 222 ftlThunkAwareRepatchCall(codeBlock, stubInfo.slowPathCallLocation, appropriateOptimizingGetByFunction(kind));234 repatchSlowPathCall(codeBlock, stubInfo, appropriateOptimizingGetByFunction(kind)); 223 235 stubInfo.initArrayLength(locker); 224 236 return RetryCacheLater; … … 228 240 newCase = AccessCase::create(vm, codeBlock, AccessCase::ArrayLength, propertyName); 229 241 } else if (isJSString(baseCell)) { 230 if (stubInfo.cacheType() == CacheType::Unset && InlineAccess::isCacheableStringLength(stubInfo)) { 242 if (stubInfo.cacheType() == CacheType::Unset 243 && InlineAccess::isCacheableStringLength(stubInfo)) { 231 244 bool generatedCodeInline = InlineAccess::generateStringLength(stubInfo); 232 245 if (generatedCodeInline) { 233 ftlThunkAwareRepatchCall(codeBlock, stubInfo.slowPathCallLocation, appropriateOptimizingGetByFunction(kind));246 repatchSlowPathCall(codeBlock, stubInfo, appropriateOptimizingGetByFunction(kind)); 234 247 stubInfo.initStringLength(locker); 235 248 return RetryCacheLater; … … 283 296 && !structure->needImpurePropertyWatchpoint() 284 297 && !loadTargetFromProxy) { 285 286 298 bool generatedCodeInline = InlineAccess::generateSelfPropertyAccess(stubInfo, structure, slot.cachedOffset()); 287 299 if (generatedCodeInline) { 288 300 LOG_IC((ICEvent::GetBySelfPatch, structure->classInfo(), Identifier::fromUid(vm, propertyName.uid()), slot.slotBase() == baseValue)); 289 301 structure->startWatchingPropertyForReplacements(vm, slot.cachedOffset()); 290 ftlThunkAwareRepatchCall(codeBlock, stubInfo.slowPathCallLocation, appropriateOptimizingGetByFunction(kind));302 repatchSlowPathCall(codeBlock, stubInfo, appropriateOptimizingGetByFunction(kind)); 291 303 stubInfo.initGetByIdSelf(locker, codeBlock, structure, slot.cachedOffset(), propertyName); 292 304 return RetryCacheLater; … … 426 438 427 439 RELEASE_ASSERT(result.code()); 428 InlineAccess::rewireStubAsJump(stubInfo, CodeLocationLabel<JITStubRoutinePtrTag>(result.code())); 440 switch (kind) { 441 case GetByKind::Normal: 442 case GetByKind::WithThis: 443 case GetByKind::Try: 444 case GetByKind::Direct: 445 case GetByKind::PrivateNameById: 446 InlineAccess::rewireStubAsJumpInAccess(codeBlock, stubInfo, CodeLocationLabel<JITStubRoutinePtrTag>(result.code())); 447 break; 448 case GetByKind::NormalByVal: 449 case GetByKind::PrivateName: 450 InlineAccess::rewireStubAsJumpInAccessNotUsingInlineAccess(codeBlock, stubInfo, CodeLocationLabel<JITStubRoutinePtrTag>(result.code())); 451 break; 452 } 453 429 454 } 430 455 } … … 440 465 441 466 if (tryCacheGetBy(globalObject, codeBlock, baseValue, propertyName, slot, stubInfo, kind) == GiveUpOnCache) 442 ftlThunkAwareRepatchCall(codeBlock, stubInfo.slowPathCallLocation, appropriateGetByFunction(kind));467 repatchSlowPathCall(codeBlock, stubInfo, appropriateGetByFunction(kind)); 443 468 } 444 469 … … 530 555 531 556 RELEASE_ASSERT(result.code()); 532 InlineAccess::rewireStubAsJump (stubInfo, CodeLocationLabel<JITStubRoutinePtrTag>(result.code()));557 InlineAccess::rewireStubAsJumpInAccessNotUsingInlineAccess(codeBlock, stubInfo, CodeLocationLabel<JITStubRoutinePtrTag>(result.code())); 533 558 } 534 559 } … … 541 566 { 542 567 if (tryCacheArrayGetByVal(globalObject, codeBlock, base, index, stubInfo) == GiveUpOnCache) 543 ftlThunkAwareRepatchCall(codeBlock, stubInfo.slowPathCallLocation, operationGetByValGeneric);568 repatchSlowPathCall(codeBlock, stubInfo, operationGetByValGeneric); 544 569 } 545 570 … … 637 662 return GiveUpOnCache; 638 663 639 std::unique_ptr<AccessCase> newCase;664 RefPtr<AccessCase> newCase; 640 665 641 666 if (slot.base() == baseValue && slot.isCacheablePut()) { … … 659 684 if (generatedCodeInline) { 660 685 LOG_IC((ICEvent::PutByIdSelfPatch, oldStructure->classInfo(), ident, slot.base() == baseValue)); 661 ftlThunkAwareRepatchCall(codeBlock, stubInfo.slowPathCallLocation, appropriateOptimizingPutByIdFunction(slot, putKind));686 repatchSlowPathCall(codeBlock, stubInfo, appropriateOptimizingPutByIdFunction(slot, putKind)); 662 687 stubInfo.initPutByIdReplace(locker, codeBlock, oldStructure, slot.cachedOffset(), propertyName); 663 688 return RetryCacheLater; … … 802 827 RELEASE_ASSERT(result.code()); 803 828 804 InlineAccess::rewireStubAsJump (stubInfo, CodeLocationLabel<JITStubRoutinePtrTag>(result.code()));829 InlineAccess::rewireStubAsJumpInAccess(codeBlock, stubInfo, CodeLocationLabel<JITStubRoutinePtrTag>(result.code())); 805 830 } 806 831 } … … 816 841 817 842 if (tryCachePutByID(globalObject, codeBlock, baseValue, oldStructure, propertyName, slot, stubInfo, putKind) == GiveUpOnCache) 818 ftlThunkAwareRepatchCall(codeBlock, stubInfo.slowPathCallLocation, appropriateGenericPutByIdFunction(slot, putKind));843 repatchSlowPathCall(codeBlock, stubInfo, appropriateGenericPutByIdFunction(slot, putKind)); 819 844 } 820 845 … … 847 872 return RetryCacheLater; 848 873 849 std::unique_ptr<AccessCase> newCase;874 RefPtr<AccessCase> newCase; 850 875 851 876 if (slot.isDeleteHit()) { … … 875 900 RELEASE_ASSERT(result.code()); 876 901 LOG_IC((ICEvent::DelByReplaceWithJump, oldStructure->classInfo(), Identifier::fromUid(vm, propertyName.uid()))); 877 InlineAccess::rewireStubAsJump (stubInfo, CodeLocationLabel<JITStubRoutinePtrTag>(result.code()));902 InlineAccess::rewireStubAsJumpInAccessNotUsingInlineAccess(codeBlock, stubInfo, CodeLocationLabel<JITStubRoutinePtrTag>(result.code())); 878 903 } 879 904 } … … 892 917 LOG_IC((ICEvent::DelByReplaceWithGeneric, baseValue.classInfoOrNull(globalObject->vm()), Identifier::fromUid(vm, propertyName.uid()))); 893 918 if (kind == DelByKind::Normal) 894 ftlThunkAwareRepatchCall(codeBlock, stubInfo.slowPathCallLocation, operationDeleteByIdGeneric);919 repatchSlowPathCall(codeBlock, stubInfo, operationDeleteByIdGeneric); 895 920 else 896 ftlThunkAwareRepatchCall(codeBlock, stubInfo.slowPathCallLocation, operationDeleteByValGeneric);921 repatchSlowPathCall(codeBlock, stubInfo, operationDeleteByValGeneric); 897 922 } 898 923 } … … 900 925 static InlineCacheAction tryCacheInBy( 901 926 JSGlobalObject* globalObject, CodeBlock* codeBlock, JSObject* base, CacheableIdentifier propertyName, 902 bool wasFound, const PropertySlot& slot, StructureStubInfo& stubInfo )927 bool wasFound, const PropertySlot& slot, StructureStubInfo& stubInfo, InByKind kind) 903 928 { 904 929 VM& vm = globalObject->vm(); … … 938 963 LOG_IC((ICEvent::InByIdSelfPatch, structure->classInfo(), ident, slot.slotBase() == base)); 939 964 structure->startWatchingPropertyForReplacements(vm, slot.cachedOffset()); 940 ftlThunkAwareRepatchCall(codeBlock, stubInfo.slowPathCallLocation, operationInByIdOptimize);965 repatchSlowPathCall(codeBlock, stubInfo, operationInByIdOptimize); 941 966 stubInfo.initInByIdSelf(locker, codeBlock, structure, slot.cachedOffset(), propertyName); 942 967 return RetryCacheLater; … … 985 1010 LOG_IC((ICEvent::InAddAccessCase, structure->classInfo(), ident, slot.slotBase() == base)); 986 1011 987 std::unique_ptr<AccessCase> newCase = AccessCase::create(1012 Ref<AccessCase> newCase = AccessCase::create( 988 1013 vm, codeBlock, wasFound ? AccessCase::InHit : AccessCase::InMiss, propertyName, wasFound ? slot.cachedOffset() : invalidOffset, structure, conditionSet, WTFMove(prototypeAccessChain)); 989 1014 … … 994 1019 995 1020 RELEASE_ASSERT(result.code()); 996 InlineAccess::rewireStubAsJump(stubInfo, CodeLocationLabel<JITStubRoutinePtrTag>(result.code())); 1021 1022 switch (kind) { 1023 case InByKind::Normal: 1024 InlineAccess::rewireStubAsJumpInAccess(codeBlock, stubInfo, CodeLocationLabel<JITStubRoutinePtrTag>(result.code())); 1025 break; 1026 case InByKind::NormalByVal: 1027 InlineAccess::rewireStubAsJumpInAccessNotUsingInlineAccess(codeBlock, stubInfo, CodeLocationLabel<JITStubRoutinePtrTag>(result.code())); 1028 break; 1029 } 997 1030 } 998 1031 } … … 1008 1041 VM& vm = globalObject->vm(); 1009 1042 1010 if (tryCacheInBy(globalObject, codeBlock, baseObject, propertyName, wasFound, slot, stubInfo ) == GiveUpOnCache) {1043 if (tryCacheInBy(globalObject, codeBlock, baseObject, propertyName, wasFound, slot, stubInfo, kind) == GiveUpOnCache) { 1011 1044 LOG_IC((ICEvent::InReplaceWithGeneric, baseObject->classInfo(globalObject->vm()), Identifier::fromUid(vm, propertyName.uid()))); 1012 1045 if (kind == InByKind::Normal) 1013 ftlThunkAwareRepatchCall(codeBlock, stubInfo.slowPathCallLocation, operationInByIdGeneric);1046 repatchSlowPathCall(codeBlock, stubInfo, operationInByIdGeneric); 1014 1047 else 1015 ftlThunkAwareRepatchCall(codeBlock, stubInfo.slowPathCallLocation, operationInByValGeneric);1048 repatchSlowPathCall(codeBlock, stubInfo, operationInByValGeneric); 1016 1049 } 1017 1050 } … … 1039 1072 LOG_IC((ICEvent::CheckPrivateBrandAddAccessCase, structure->classInfo(), ident, isBaseProperty)); 1040 1073 1041 std::unique_ptr<AccessCase> newCase = AccessCase::createCheckPrivateBrand(vm, codeBlock, brandID, structure);1074 Ref<AccessCase> newCase = AccessCase::createCheckPrivateBrand(vm, codeBlock, brandID, structure); 1042 1075 1043 1076 result = stubInfo.addAccessCase(locker, globalObject, codeBlock, ECMAMode::strict(), brandID, WTFMove(newCase)); … … 1047 1080 1048 1081 RELEASE_ASSERT(result.code()); 1049 InlineAccess::rewireStubAsJump (stubInfo, CodeLocationLabel<JITStubRoutinePtrTag>(result.code()));1082 InlineAccess::rewireStubAsJumpInAccessNotUsingInlineAccess(codeBlock, stubInfo, CodeLocationLabel<JITStubRoutinePtrTag>(result.code())); 1050 1083 } 1051 1084 } … … 1061 1094 1062 1095 if (tryCacheCheckPrivateBrand(globalObject, codeBlock, baseObject, brandID, stubInfo) == GiveUpOnCache) 1063 ftlThunkAwareRepatchCall(codeBlock, stubInfo.slowPathCallLocation, operationCheckPrivateBrandGeneric);1096 repatchSlowPathCall(codeBlock, stubInfo, operationCheckPrivateBrandGeneric); 1064 1097 } 1065 1098 … … 1098 1131 LOG_IC((ICEvent::SetPrivateBrandAddAccessCase, oldStructure->classInfo(), ident, isBaseProperty)); 1099 1132 1100 std::unique_ptr<AccessCase> newCase = AccessCase::createSetPrivateBrand(vm, codeBlock, brandID, oldStructure, newStructure);1133 Ref<AccessCase> newCase = AccessCase::createSetPrivateBrand(vm, codeBlock, brandID, oldStructure, newStructure); 1101 1134 1102 1135 result = stubInfo.addAccessCase(locker, globalObject, codeBlock, ECMAMode::strict(), brandID, WTFMove(newCase)); … … 1106 1139 1107 1140 RELEASE_ASSERT(result.code()); 1108 InlineAccess::rewireStubAsJump (stubInfo, CodeLocationLabel<JITStubRoutinePtrTag>(result.code()));1141 InlineAccess::rewireStubAsJumpInAccessNotUsingInlineAccess(codeBlock, stubInfo, CodeLocationLabel<JITStubRoutinePtrTag>(result.code())); 1109 1142 } 1110 1143 } … … 1120 1153 1121 1154 if (tryCacheSetPrivateBrand(globalObject, codeBlock, baseObject, oldStructure, brandID, stubInfo) == GiveUpOnCache) 1122 ftlThunkAwareRepatchCall(codeBlock, stubInfo.slowPathCallLocation, operationSetPrivateBrandGeneric);1155 repatchSlowPathCall(codeBlock, stubInfo, operationSetPrivateBrandGeneric); 1123 1156 } 1124 1157 … … 1140 1173 JSCell* value = valueValue.asCell(); 1141 1174 Structure* structure = value->structure(vm); 1142 std::unique_ptr<AccessCase> newCase;1175 RefPtr<AccessCase> newCase; 1143 1176 JSObject* prototype = jsDynamicCast<JSObject*>(vm, prototypeValue); 1144 1177 if (prototype) { … … 1174 1207 1175 1208 RELEASE_ASSERT(result.code()); 1176 1177 MacroAssembler::repatchJump( 1178 stubInfo.patchableJump(), 1179 CodeLocationLabel<JITStubRoutinePtrTag>(result.code())); 1209 InlineAccess::rewireStubAsJumpInAccessNotUsingInlineAccess(codeBlock, stubInfo, CodeLocationLabel<JITStubRoutinePtrTag>(result.code())); 1180 1210 } 1181 1211 } … … 1192 1222 SuperSamplerScope superSamplerScope(false); 1193 1223 if (tryCacheInstanceOf(globalObject, codeBlock, valueValue, prototypeValue, stubInfo, wasFound) == GiveUpOnCache) 1194 ftlThunkAwareRepatchCall(codeBlock, stubInfo.slowPathCallLocation, operationInstanceOfGeneric);1224 repatchSlowPathCall(codeBlock, stubInfo, operationInstanceOfGeneric); 1195 1225 } 1196 1226 … … 1209 1239 MacroAssemblerCodeRef<JITStubRoutinePtrTag> virtualThunk = virtualThunkFor(vm, callLinkInfo); 1210 1240 linkSlowPathTo(vm, callLinkInfo, virtualThunk); 1211 callLinkInfo.setSlowStub(GCAwareJITStubRoutine::create(v irtualThunk, vm));1241 callLinkInfo.setSlowStub(GCAwareJITStubRoutine::create(vm, virtualThunk)); 1212 1242 } 1213 1243 … … 1327 1357 MacroAssemblerCodeRef<JITStubRoutinePtrTag> virtualThunk = virtualThunkFor(vm, callLinkInfo); 1328 1358 revertCall(vm, callLinkInfo, virtualThunk); 1329 callLinkInfo.setSlowStub(GCAwareJITStubRoutine::create(v irtualThunk, vm));1359 callLinkInfo.setSlowStub(GCAwareJITStubRoutine::create(vm, virtualThunk)); 1330 1360 callLinkInfo.setClearedByVirtual(); 1331 1361 } … … 1648 1678 void resetGetBy(CodeBlock* codeBlock, StructureStubInfo& stubInfo, GetByKind kind) 1649 1679 { 1650 ftlThunkAwareRepatchCall(codeBlock, stubInfo.slowPathCallLocation, appropriateOptimizingGetByFunction(kind)); 1651 InlineAccess::rewireStubAsJump(stubInfo, stubInfo.slowPathStartLocation); 1680 repatchSlowPathCall(codeBlock, stubInfo, appropriateOptimizingGetByFunction(kind)); 1681 switch (kind) { 1682 case GetByKind::Normal: 1683 case GetByKind::WithThis: 1684 case GetByKind::Try: 1685 case GetByKind::Direct: 1686 case GetByKind::PrivateNameById: 1687 InlineAccess::resetStubAsJumpInAccess(codeBlock, stubInfo); 1688 break; 1689 case GetByKind::NormalByVal: 1690 case GetByKind::PrivateName: 1691 InlineAccess::resetStubAsJumpInAccessNotUsingInlineAccess(codeBlock, stubInfo); 1692 break; 1693 } 1652 1694 } 1653 1695 … … 1655 1697 { 1656 1698 using FunctionType = decltype(&operationPutByIdDirectStrictOptimize); 1657 FunctionType unoptimizedFunction = reinterpret_cast<FunctionType>(readPutICCallTarget(codeBlock, stubInfo .slowPathCallLocation).executableAddress());1699 FunctionType unoptimizedFunction = reinterpret_cast<FunctionType>(readPutICCallTarget(codeBlock, stubInfo).executableAddress()); 1658 1700 FunctionType optimizedFunction; 1659 1701 if (unoptimizedFunction == operationPutByIdStrict || unoptimizedFunction == operationPutByIdStrictOptimize) … … 1672 1714 } 1673 1715 1674 ftlThunkAwareRepatchCall(codeBlock, stubInfo.slowPathCallLocation, optimizedFunction);1675 InlineAccess::re wireStubAsJump(stubInfo, stubInfo.slowPathStartLocation);1716 repatchSlowPathCall(codeBlock, stubInfo, optimizedFunction); 1717 InlineAccess::resetStubAsJumpInAccess(codeBlock, stubInfo); 1676 1718 } 1677 1719 … … 1679 1721 { 1680 1722 if (kind == DelByKind::Normal) 1681 ftlThunkAwareRepatchCall(codeBlock, stubInfo.slowPathCallLocation, operationDeleteByIdOptimize);1723 repatchSlowPathCall(codeBlock, stubInfo, operationDeleteByIdOptimize); 1682 1724 else 1683 ftlThunkAwareRepatchCall(codeBlock, stubInfo.slowPathCallLocation, operationDeleteByValOptimize); 1684 InlineAccess::rewireStubAsJump(stubInfo, stubInfo.slowPathStartLocation); 1685 } 1686 1687 static void resetPatchableJump(StructureStubInfo& stubInfo) 1688 { 1689 MacroAssembler::repatchJump(stubInfo.patchableJump(), stubInfo.slowPathStartLocation); 1725 repatchSlowPathCall(codeBlock, stubInfo, operationDeleteByValOptimize); 1726 InlineAccess::resetStubAsJumpInAccessNotUsingInlineAccess(codeBlock, stubInfo); 1690 1727 } 1691 1728 1692 1729 void resetInBy(CodeBlock* codeBlock, StructureStubInfo& stubInfo, InByKind kind) 1693 1730 { 1694 if (kind == InByKind::Normal) 1695 ftlThunkAwareRepatchCall(codeBlock, stubInfo.slowPathCallLocation, operationInByIdOptimize); 1696 else 1697 ftlThunkAwareRepatchCall(codeBlock, stubInfo.slowPathCallLocation, operationInByValOptimize); 1698 InlineAccess::rewireStubAsJump(stubInfo, stubInfo.slowPathStartLocation); 1699 } 1700 1701 void resetInstanceOf(StructureStubInfo& stubInfo) 1702 { 1703 resetPatchableJump(stubInfo); 1731 switch (kind) { 1732 case InByKind::Normal: 1733 repatchSlowPathCall(codeBlock, stubInfo, operationInByIdOptimize); 1734 InlineAccess::resetStubAsJumpInAccess(codeBlock, stubInfo); 1735 break; 1736 case InByKind::NormalByVal: 1737 repatchSlowPathCall(codeBlock, stubInfo, operationInByValOptimize); 1738 InlineAccess::resetStubAsJumpInAccessNotUsingInlineAccess(codeBlock, stubInfo); 1739 break; 1740 } 1741 } 1742 1743 void resetInstanceOf(CodeBlock* codeBlock, StructureStubInfo& stubInfo) 1744 { 1745 repatchSlowPathCall(codeBlock, stubInfo, operationInstanceOfOptimize); 1746 InlineAccess::resetStubAsJumpInAccessNotUsingInlineAccess(codeBlock, stubInfo); 1704 1747 } 1705 1748 1706 1749 void resetCheckPrivateBrand(CodeBlock* codeBlock, StructureStubInfo& stubInfo) 1707 1750 { 1708 ftlThunkAwareRepatchCall(codeBlock, stubInfo.slowPathCallLocation, operationCheckPrivateBrandOptimize);1709 InlineAccess::re wireStubAsJump(stubInfo, stubInfo.slowPathStartLocation);1751 repatchSlowPathCall(codeBlock, stubInfo, operationCheckPrivateBrandOptimize); 1752 InlineAccess::resetStubAsJumpInAccessNotUsingInlineAccess(codeBlock, stubInfo); 1710 1753 } 1711 1754 1712 1755 void resetSetPrivateBrand(CodeBlock* codeBlock, StructureStubInfo& stubInfo) 1713 1756 { 1714 ftlThunkAwareRepatchCall(codeBlock, stubInfo.slowPathCallLocation, operationSetPrivateBrandOptimize);1715 InlineAccess::re wireStubAsJump(stubInfo, stubInfo.slowPathStartLocation);1757 repatchSlowPathCall(codeBlock, stubInfo, operationSetPrivateBrandOptimize); 1758 InlineAccess::resetStubAsJumpInAccessNotUsingInlineAccess(codeBlock, stubInfo); 1716 1759 } 1717 1760 -
trunk/Source/JavaScriptCore/jit/Repatch.h
r278445 r278656 71 71 void resetDelBy(CodeBlock*, StructureStubInfo&, DelByKind); 72 72 void resetInBy(CodeBlock*, StructureStubInfo&, InByKind); 73 void resetInstanceOf( StructureStubInfo&);73 void resetInstanceOf(CodeBlock*, StructureStubInfo&); 74 74 void resetCheckPrivateBrand(CodeBlock*, StructureStubInfo&); 75 75 void resetSetPrivateBrand(CodeBlock*, StructureStubInfo&); -
trunk/Source/JavaScriptCore/runtime/Options.cpp
r278340 r278656 433 433 Options::useConcurrentGC() = false; 434 434 #endif 435 436 if (!isARM64()) 437 Options::useDataIC() = false; 438 if (!Options::useDataIC()) 439 Options::useDataICInOptimizingJIT() = false; 435 440 436 441 // At initialization time, we may decide that useJIT should be false for any -
trunk/Source/JavaScriptCore/runtime/OptionsList.h
r278213 r278656 539 539 v(Bool, useTopLevelAwait, true, Normal, "allow the await keyword at the top level of a module.") \ 540 540 v(Bool, verboseExecutablePoolAllocation, false, Normal, nullptr) \ 541 v(Bool, useDataIC, isARM64(), Normal, nullptr) \ 542 v(Bool, useDataICInOptimizingJIT, false, Normal, nullptr) \ 541 543 542 544 -
trunk/Source/JavaScriptCore/runtime/StructureIDTable.h
r267192 r278656 37 37 38 38 #if USE(JSVALUE64) 39 typedef uint32_t StructureID;39 using StructureID = uint32_t; 40 40 41 41 inline StructureID nukedStructureIDBit() … … 59 59 } 60 60 #else // not USE(JSVALUE64) 61 typedef Structure* StructureID;61 using StructureID = Structure*; 62 62 63 63 inline StructureID nukedStructureIDBit() -
trunk/Source/JavaScriptCore/runtime/VM.cpp
r278213 r278656 30 30 #include "VM.h" 31 31 32 #include "AccessCase.h" 32 33 #include "AggregateError.h" 33 34 #include "ArgList.h" … … 568 569 getCTIInternalFunctionTrampolineFor(CodeForCall); 569 570 getCTIInternalFunctionTrampolineFor(CodeForConstruct); 571 m_sharedJITStubs = makeUnique<SharedJITStubSet>(); 570 572 } 571 573 #endif // ENABLE(JIT) … … 655 657 for (unsigned i = 0; i < m_scratchBuffers.size(); ++i) 656 658 VMMalloc::free(m_scratchBuffers[i]); 659 #endif 660 661 #if ENABLE(JIT) 662 m_sharedJITStubs = nullptr; 657 663 #endif 658 664 } -
trunk/Source/JavaScriptCore/runtime/VM.h
r278338 r278656 176 176 #endif 177 177 class ShadowChicken; 178 class SharedJITStubSet; 178 179 class ScriptExecutable; 179 180 class SourceProvider; … … 847 848 std::unique_ptr<JITThunks> jitStubs; 848 849 MacroAssemblerCodeRef<JITThunkPtrTag> getCTIStub(ThunkGenerator); 850 std::unique_ptr<SharedJITStubSet> m_sharedJITStubs; 849 851 850 852 #endif // ENABLE(JIT) … … 852 854 std::unique_ptr<FTL::Thunks> ftlThunks; 853 855 #endif 856 854 857 NativeExecutable* getHostFunction(NativeFunction, NativeFunction constructor, const String& name); 855 858 NativeExecutable* getHostFunction(NativeFunction, Intrinsic, NativeFunction constructor, const DOMJIT::Signature*, const String& name); -
trunk/Tools/ChangeLog
r278638 r278656 1 2021-06-08 Yusuke Suzuki <ysuzuki@apple.com> 2 3 [JSC] Use DataIC for AccessCase 4 https://bugs.webkit.org/show_bug.cgi?id=226072 5 6 Reviewed by Saam Barati and Filip Pizlo. 7 8 * Scripts/run-jsc-stress-tests: 9 1 10 2021-06-08 Dewei Zhu <dewei_zhu@apple.com> 2 11 -
trunk/Tools/Scripts/run-jsc-stress-tests
r278425 r278656 553 553 # NOTE: Tests rely on this using scribbleFreeCells. 554 554 NO_CJIT_OPTIONS = ["--useConcurrentJIT=false", "--thresholdForJITAfterWarmUp=100", "--scribbleFreeCells=true"] 555 B3O1_OPTIONS = ["--defaultB3OptLevel=1" ]555 B3O1_OPTIONS = ["--defaultB3OptLevel=1", "--useDataICInOptimizingJIT=1"] 556 556 B3O0_OPTIONS = ["--maxDFGNodesInBasicBlockForPreciseAnalysis=100", "--defaultB3OptLevel=0"] 557 557 FTL_OPTIONS = ["--useFTLJIT=true"] … … 1620 1620 1621 1621 def runNoisyTestNoCJITB3O1 1622 runNoisyTest("ftl-no-cjit ", "--validateBytecode=true", "--validateGraphAtEachPhase=true", *(FTL_OPTIONS + NO_CJIT_OPTIONS + B3O1_OPTIONS))1622 runNoisyTest("ftl-no-cjit-b3o1", "--validateBytecode=true", "--validateGraphAtEachPhase=true", *(FTL_OPTIONS + NO_CJIT_OPTIONS + B3O1_OPTIONS)) 1623 1623 end 1624 1624
Note:
See TracChangeset
for help on using the changeset viewer.