Changeset 277929 in webkit
- Timestamp:
- May 22, 2021, 11:23:48 PM (4 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r277928 r277929 1 2021-05-22 Mark Lam <mark.lam@apple.com> 2 3 Use singleton thunks for virtual calls. 4 https://bugs.webkit.org/show_bug.cgi?id=226149 5 rdar://problem/78357604 6 7 Reviewed by Yusuke Suzuki. 8 9 Change virtualThunkFor() to return 1 of 6 possible singleton thunks. 10 These thunks are cached via vm.jitStubs->ctiStubs(). 11 12 This change saves us ~16M of executable JIT memory (for the unique thunks) on a 13 single run of Speedometer2. On an M1 Mac, switching to singleton thunks here also 14 appears to be a 1.012x speed up on Speedometer2. Performance is neutral on 15 JetStream2. 16 17 * jit/JITThunks.cpp: 18 (JSC::JITThunks::ctiInternalFunctionCall): 19 (JSC::JITThunks::ctiInternalFunctionConstruct): 20 * jit/JITThunks.h: 21 * jit/ThunkGenerators.cpp: 22 (JSC::virtualThunkFor): 23 (JSC::virtualThunkForRegularCall): 24 (JSC::virtualThunkForRegularConstruct): 25 (JSC::virtualThunkForTailCall): 26 (JSC::virtualThunkForTailConstruct): 27 (JSC::virtualThunkForConstructCall): 28 (JSC::virtualThunkForConstructConstruct): 29 * runtime/VM.cpp: 30 (JSC::VM::getCTIInternalFunctionTrampolineFor): 31 * runtime/VM.h: 32 1 33 2021-05-22 Mark Lam <mark.lam@apple.com> 2 34 -
trunk/Source/JavaScriptCore/jit/JITThunks.cpp
r277920 r277929 118 118 } 119 119 120 MacroAssemblerCodePtr<JITThunkPtrTag> JITThunks::ctiInternalFunctionCall(VM& vm) 121 { 122 ASSERT(Options::useJIT()); 120 MacroAssemblerCodePtr<JITThunkPtrTag> JITThunks::ctiInternalFunctionCall(VM& vm, Optional<NoLockingNecessaryTag> noLockingNecessary) 121 { 122 ASSERT(Options::useJIT()); 123 if (noLockingNecessary) 124 return existingCTIStub(internalFunctionCallGenerator, NoLockingNecessary).code(); 123 125 return ctiStub(vm, internalFunctionCallGenerator).code(); 124 126 } 125 127 126 MacroAssemblerCodePtr<JITThunkPtrTag> JITThunks::ctiInternalFunctionConstruct(VM& vm) 127 { 128 ASSERT(Options::useJIT()); 128 MacroAssemblerCodePtr<JITThunkPtrTag> JITThunks::ctiInternalFunctionConstruct(VM& vm, Optional<NoLockingNecessaryTag> noLockingNecessary) 129 { 130 ASSERT(Options::useJIT()); 131 if (noLockingNecessary) 132 return existingCTIStub(internalFunctionConstructGenerator, NoLockingNecessary).code(); 129 133 return ctiStub(vm, internalFunctionConstructGenerator).code(); 130 134 } -
trunk/Source/JavaScriptCore/jit/JITThunks.h
r277882 r277929 60 60 MacroAssemblerCodePtr<JITThunkPtrTag> ctiNativeTailCall(VM&); 61 61 MacroAssemblerCodePtr<JITThunkPtrTag> ctiNativeTailCallWithoutSavedTags(VM&); 62 MacroAssemblerCodePtr<JITThunkPtrTag> ctiInternalFunctionCall(VM& );63 MacroAssemblerCodePtr<JITThunkPtrTag> ctiInternalFunctionConstruct(VM& );62 MacroAssemblerCodePtr<JITThunkPtrTag> ctiInternalFunctionCall(VM&, Optional<NoLockingNecessaryTag> = WTF::nullopt); 63 MacroAssemblerCodePtr<JITThunkPtrTag> ctiInternalFunctionConstruct(VM&, Optional<NoLockingNecessaryTag> = WTF::nullopt); 64 64 65 65 MacroAssemblerCodeRef<JITThunkPtrTag> ctiStub(VM&, ThunkGenerator); -
trunk/Source/JavaScriptCore/jit/ThunkGenerators.cpp
r277928 r277929 264 264 // virtual calls by using the shuffler. 265 265 // https://bugs.webkit.org/show_bug.cgi?id=148831 266 MacroAssemblerCodeRef<JITStubRoutinePtrTag> virtualThunkFor(VM& vm, CallLinkInfo& callLinkInfo)266 static MacroAssemblerCodeRef<JITThunkPtrTag> virtualThunkFor(VM& vm, CallMode mode, CodeSpecializationKind kind) 267 267 { 268 268 // The callee is in regT0 (for JSVALUE32_64, the tag is in regT1). … … 272 272 273 273 CCallHelpers jit; 274 274 275 bool isTailCall = mode == CallMode::Tail; 276 275 277 CCallHelpers::JumpList slowCase; 276 278 … … 285 287 286 288 #if USE(JSVALUE64) 287 if ( callLinkInfo.isTailCall()) {289 if (isTailCall) { 288 290 // Tail calls could have clobbered the GPRInfo::notCellMaskRegister because they 289 291 // restore callee saved registers before getthing here. So, let's materialize … … 304 306 hasExecutable.link(&jit); 305 307 jit.loadPtr( 306 CCallHelpers::Address( 307 GPRInfo::regT4, ExecutableBase::offsetOfJITCodeWithArityCheckFor( 308 callLinkInfo.specializationKind())), 308 CCallHelpers::Address(GPRInfo::regT4, ExecutableBase::offsetOfJITCodeWithArityCheckFor(kind)), 309 309 GPRInfo::regT4); 310 310 slowCase.append(jit.branchTestPtr(CCallHelpers::Zero, GPRInfo::regT4)); … … 316 316 JSInterfaceJIT::Label callCode(jit.label()); 317 317 emitPointerValidation(jit, GPRInfo::regT4, JSEntryPtrTag); 318 if ( callLinkInfo.isTailCall()) {318 if (isTailCall) { 319 319 jit.preserveReturnAddressAfterCall(GPRInfo::regT0); 320 320 jit.prepareForTailCallSlow(GPRInfo::regT4); … … 325 325 notJSFunction.link(&jit); 326 326 slowCase.append(jit.branchIfNotType(GPRInfo::regT0, InternalFunctionType)); 327 void* executableAddress = vm.getCTIInternalFunctionTrampolineFor( callLinkInfo.specializationKind()).executableAddress();327 void* executableAddress = vm.getCTIInternalFunctionTrampolineFor(kind, NoLockingNecessary).executableAddress(); 328 328 jit.move(CCallHelpers::TrustedImmPtr(executableAddress), GPRInfo::regT4); 329 329 jit.jump().linkTo(callCode, &jit); … … 336 336 LinkBuffer patchBuffer(jit, GLOBAL_THUNK_ID, LinkBuffer::Profile::VirtualThunk); 337 337 return FINALIZE_CODE( 338 patchBuffer, JIT StubRoutinePtrTag,338 patchBuffer, JITThunkPtrTag, 339 339 "Virtual %s slow path thunk", 340 callLinkInfo.callMode() == CallMode::Regular ? "call" : callLinkInfo.callMode() == CallMode::Tail ? "tail call" : "construct"); 340 mode == CallMode::Regular ? "call" : mode == CallMode::Tail ? "tail call" : "construct"); 341 } 342 343 static MacroAssemblerCodeRef<JITThunkPtrTag> virtualThunkForRegularCall(VM& vm) 344 { 345 return virtualThunkFor(vm, CallMode::Regular, CodeForCall); 346 } 347 348 static MacroAssemblerCodeRef<JITThunkPtrTag> virtualThunkForRegularConstruct(VM& vm) 349 { 350 return virtualThunkFor(vm, CallMode::Regular, CodeForConstruct); 351 } 352 353 static MacroAssemblerCodeRef<JITThunkPtrTag> virtualThunkForTailCall(VM& vm) 354 { 355 return virtualThunkFor(vm, CallMode::Tail, CodeForCall); 356 } 357 358 static MacroAssemblerCodeRef<JITThunkPtrTag> virtualThunkForTailConstruct(VM& vm) 359 { 360 return virtualThunkFor(vm, CallMode::Tail, CodeForConstruct); 361 } 362 363 static MacroAssemblerCodeRef<JITThunkPtrTag> virtualThunkForConstructCall(VM& vm) 364 { 365 return virtualThunkFor(vm, CallMode::Construct, CodeForCall); 366 } 367 368 static MacroAssemblerCodeRef<JITThunkPtrTag> virtualThunkForConstructConstruct(VM& vm) 369 { 370 return virtualThunkFor(vm, CallMode::Construct, CodeForConstruct); 371 } 372 373 MacroAssemblerCodeRef<JITStubRoutinePtrTag> virtualThunkFor(VM& vm, CallLinkInfo& callLinkInfo) 374 { 375 auto mode = callLinkInfo.callMode(); 376 auto kind = callLinkInfo.specializationKind(); 377 auto generator = [&] () -> ThunkGenerator { 378 switch (mode) { 379 case CallMode::Regular: 380 if (kind == CodeForCall) 381 return virtualThunkForRegularCall; 382 return virtualThunkForRegularConstruct; 383 case CallMode::Tail: 384 if (kind == CodeForCall) 385 return virtualThunkForTailCall; 386 return virtualThunkForTailConstruct; 387 case CallMode::Construct: 388 if (kind == CodeForCall) 389 return virtualThunkForConstructCall; 390 return virtualThunkForConstructConstruct; 391 } 392 }; 393 return vm.getCTIStub(generator()).retagged<JITStubRoutinePtrTag>(); 341 394 } 342 395 -
trunk/Source/JavaScriptCore/runtime/VM.cpp
r277909 r277929 889 889 } 890 890 891 MacroAssemblerCodePtr<JSEntryPtrTag> VM::getCTIInternalFunctionTrampolineFor(CodeSpecializationKind kind) 892 { 891 MacroAssemblerCodePtr<JSEntryPtrTag> VM::getCTIInternalFunctionTrampolineFor(CodeSpecializationKind kind, Optional<NoLockingNecessaryTag> noLockingNecessary) 892 { 893 UNUSED_PARAM(noLockingNecessary); 893 894 #if ENABLE(JIT) 894 895 if (Options::useJIT()) { 895 896 if (kind == CodeForCall) 896 return jitStubs->ctiInternalFunctionCall(*this ).retagged<JSEntryPtrTag>();897 return jitStubs->ctiInternalFunctionConstruct(*this ).retagged<JSEntryPtrTag>();897 return jitStubs->ctiInternalFunctionCall(*this, noLockingNecessary).retagged<JSEntryPtrTag>(); 898 return jitStubs->ctiInternalFunctionConstruct(*this, noLockingNecessary).retagged<JSEntryPtrTag>(); 898 899 } 899 900 #endif -
trunk/Source/JavaScriptCore/runtime/VM.h
r277094 r277929 852 852 NativeExecutable* getBoundFunction(bool isJSFunction, bool canConstruct); 853 853 854 MacroAssemblerCodePtr<JSEntryPtrTag> getCTIInternalFunctionTrampolineFor(CodeSpecializationKind );854 MacroAssemblerCodePtr<JSEntryPtrTag> getCTIInternalFunctionTrampolineFor(CodeSpecializationKind, Optional<NoLockingNecessaryTag> = WTF::nullopt); 855 855 856 856 static ptrdiff_t exceptionOffset()
Note:
See TracChangeset
for help on using the changeset viewer.