Ignore:
Timestamp:
May 12, 2021, 12:11:25 PM (4 years ago)
Author:
[email protected]
Message:

Implement some common Baseline JIT slow paths using JIT thunks.
https://bugs.webkit.org/show_bug.cgi?id=225682

Reviewed by Filip Pizlo.

Source/JavaScriptCore:

This patch implements the following changes:

  1. Implement exception handling thunks:
    1. handleExceptionGenerator, which calls operationLookupExceptionHandler().
    2. handleExceptionWithCallFrameRollbackGenerator, which calls operationLookupExceptionHandlerFromCallerFrame().

All the JIT tiers were emitting their own copy of these routines to call these
operation, one per CodeBlock. We now emit 2 thunks for these and have all the
tiers just jump to them.

PolymorphicAccess also now uses the handleExceptionGenerator thunk.

DFG::JITCompiler::compileExceptionHandlers() has one small behavior difference
before it calls operationLookupExceptionHandlerFromCallerFrame(): it first
re-sets the top of stack for the function where we are about to throw a
StackOverflowError from. This re-setting of top of stack is useless because
we're imminently unwinding out of at least this frame for the StackOverflowError.
Hence, it is ok to use the handleExceptionWithCallFrameRollbackGenerator thunk
here as well. Note that no other tiers does this re-setting of top of stack.

FTLLowerDFGToB3 has one case using operationLookupExceptionHandlerFromCallerFrame()
which cannot be refactored to use these thunks because it does additional
work to throw a StackOverflowError. A different thunk will be needed. I left
it alone for now.

  1. Introduce JITThunks::existingCTIStub(ThunkGenerator, NoLockingNecessaryTag) so that a thunk can get a pointer to another thunk without locking the JITThunks lock. Otherwise, deadlock ensues.
  1. Change SlowPathCall to emit and use thunks instead of emitting a blob of code to call a slow path function for every bytecode in a CodeBlock.
  1. Introduce JITThunks::ctiSlowPathFunctionStub() to manage these SlowPathFunction thunks.
  1. Introduce JITThunks::preinitializeAggressiveCTIThunks() to initialize these thunks at VM initialization time. Pre-initializing them has multiple benefits:
    1. the thunks are not scattered through out JIT memory, thereby reducing fragmentation.
    2. we don't spend time at runtime compiling them when the user is interacting with the VM. Conceptually, these thunks can be VM independent and can be shared by VMs process-wide. However, it will require some additional work. For now, the thunks remain bound to a specific VM instance.

These changes are only enabled when ENABLE(EXTRA_CTI_THUNKS), which is currently
only available for ARM64 and non-Windows x86_64.

This patch has passed JSC tests on AS Mac.

With this patch, --dumpLinkBufferStats shows the following changes in emitted
JIT code size (using a single run of the CLI version of JetStream2 on AS Mac):

Base New Diff

BaselineJIT: 89089964 (84.962811 MB) 84624776 (80.704475 MB) 0.95x (reduction)

DFG: 39117360 (37.305222 MB) 36415264 (34.728302 MB) 0.93x (reduction)

Thunk: 23230968 (22.154778 MB) 23130336 (22.058807 MB) 1.00x

InlineCache: 22027416 (21.006981 MB) 21969728 (20.951965 MB) 1.00x

FTL: 6575772 (6.271145 MB) 6097336 (5.814873 MB) 0.93x (reduction)

Wasm: 2302724 (2.196049 MB) 2301956 (2.195316 MB) 1.00x

YarrJIT: 1538956 (1.467663 MB) 1522488 (1.451958 MB) 0.99x

CSSJIT: 0 0

Uncategorized: 0 0

  • CMakeLists.txt:
  • JavaScriptCore.xcodeproj/project.pbxproj:
  • Sources.txt:
  • bytecode/CodeBlock.h:

(JSC::CodeBlock::offsetOfInstructionsRawPointer):

  • bytecode/PolymorphicAccess.cpp:

(JSC::AccessGenerationState::emitExplicitExceptionHandler):

  • dfg/DFGJITCompiler.cpp:

(JSC::DFG::JITCompiler::compileExceptionHandlers):
(JSC::DFG::JITCompiler::link):

  • dfg/DFGJITCompiler.h:
  • ftl/FTLCompile.cpp:

(JSC::FTL::compile):

  • ftl/FTLLink.cpp:

(JSC::FTL::link):

  • jit/JIT.cpp:

(JSC::JIT::link):
(JSC::JIT::privateCompileExceptionHandlers):

  • jit/JIT.h:
  • jit/JITThunks.cpp:

(JSC::JITThunks::existingCTIStub):
(JSC::JITThunks::ctiSlowPathFunctionStub):
(JSC::JITThunks::preinitializeExtraCTIThunks):

  • jit/JITThunks.h:
  • jit/SlowPathCall.cpp: Added.

(JSC::JITSlowPathCall::call):
(JSC::JITSlowPathCall::generateThunk):

  • jit/SlowPathCall.h:
  • jit/ThunkGenerators.cpp:

(JSC::handleExceptionGenerator):
(JSC::handleExceptionWithCallFrameRollbackGenerator):
(JSC::popThunkStackPreservesAndHandleExceptionGenerator):

  • jit/ThunkGenerators.h:
  • runtime/CommonSlowPaths.h:
  • runtime/SlowPathFunction.h: Added.
  • runtime/VM.cpp:

(JSC::VM::VM):

Source/WTF:

Introduce ENABLE(EXTRA_CTI_THUNKS) flag to guard the use of these new thunks.
Currently, the thunks are 64-bit only, and only supported for ARM64 and non-Windows
X86_64. The reason it is not supported for Windows as well is because Windows
only has 4 argument registers. In this patch, the thunks do not use that many
registers yet, but there will be more thunks coming that will require the use
of up to 6 argument registers.

  • wtf/PlatformEnable.h:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ftl/FTLCompile.cpp

    r277305 r277383  
    4141#include "LinkBuffer.h"
    4242#include "PCToCodeOriginMap.h"
     43#include "ThunkGenerators.h"
    4344#include <wtf/RecursableLambda.h>
    4445
     
    126127    // Emit the exception handler.
    127128    *state.exceptionHandler = jit.label();
     129#if ENABLE(EXTRA_CTI_THUNKS)
     130    CCallHelpers::Jump handler = jit.jump();
     131    VM* vmPtr = &vm;
     132    jit.addLinkTask(
     133        [=] (LinkBuffer& linkBuffer) {
     134            linkBuffer.link(handler, CodeLocationLabel(vmPtr->getCTIStub(handleExceptionGenerator).retaggedCode<NoPtrTag>()));
     135        });
     136#else
    128137    jit.copyCalleeSavesToEntryFrameCalleeSavesBuffer(vm.topEntryFrame);
    129138    jit.move(MacroAssembler::TrustedImmPtr(&vm), GPRInfo::argumentGPR0);
     
    135144            linkBuffer.link(call, FunctionPtr<OperationPtrTag>(operationLookupExceptionHandler));
    136145        });
     146#endif // ENABLE(EXTRA_CTI_THUNKS)
    137147
    138148    state.finalizer->b3CodeLinkBuffer = makeUnique<LinkBuffer>(jit, codeBlock, LinkBuffer::Profile::FTL, JITCompilationCanFail);
Note: See TracChangeset for help on using the changeset viewer.