Ignore:
Timestamp:
Mar 24, 2017, 4:25:16 PM (8 years ago)
Author:
[email protected]
Message:

WebAssembly: store state in TLS instead of on VM
https://bugs.webkit.org/show_bug.cgi?id=169611

Reviewed by Filip Pizlo.

Source/JavaScriptCore:

Using thread-local storage instead of VM makes code more position
independent. We used to store the WebAssembly top Instance (the
latest one in the call stack) on VM, now we instead store it in
TLS. This top Instance is used to access a bunch of state such as
Memory location, size, table (for call_indirect), etc.

Instead of calling it "top", which is confusing, we now just call
it WasmContext.

Making the code PIC means future patches will be able to
postMessage and structured clone into IDB without having to
recompile the code. This wasn't possible before because we
hard-coded the address of VM at compilation time. That doesn't
work between workers, and doesn't work across reloads (which IDB
is intended to do).

It'll also potentially make code faster once we start tuning
what's in TLS, what's in which of the 4 free slots, and what's in
pinned registers. I'm leaving this tuning for later because
there's lower lying fruit for us to pick.

  • CMakeLists.txt:
  • JavaScriptCore.xcodeproj/project.pbxproj:
  • assembler/AbstractMacroAssembler.h:
  • assembler/AllowMacroScratchRegisterUsageIf.h: Copied from assembler/AllowMacroScratchRegisterUsage.h.

(JSC::AllowMacroScratchRegisterUsageIf::AllowMacroScratchRegisterUsageIf):
(JSC::AllowMacroScratchRegisterUsageIf::~AllowMacroScratchRegisterUsageIf):

  • assembler/MacroAssembler.h:

(JSC::MacroAssembler::storeToTLSPtr): we previously didn't have
the code required to store to TLS, only to load

  • assembler/MacroAssemblerARM64.h:

(JSC::MacroAssemblerARM64::loadFromTLSPtrNeedsMacroScratchRegister):
(JSC::MacroAssemblerARM64::storeToTLS32):
(JSC::MacroAssemblerARM64::storeToTLS64):
(JSC::MacroAssemblerARM64::storeToTLSPtrNeedsMacroScratchRegister):

  • assembler/MacroAssemblerX86Common.h:

(JSC::MacroAssemblerX86Common::loadFromTLSPtrNeedsMacroScratchRegister):
(JSC::MacroAssemblerX86Common::storeToTLS32):
(JSC::MacroAssemblerX86Common::storeToTLSPtrNeedsMacroScratchRegister):

  • assembler/MacroAssemblerX86_64.h:

(JSC::MacroAssemblerX86_64::loadFromTLS64): was loading 32-bit instead of 64-bit
(JSC::MacroAssemblerX86_64::storeToTLS64):

  • assembler/X86Assembler.h:

(JSC::X86Assembler::movl_rm):
(JSC::X86Assembler::movq_rm):

  • b3/testb3.cpp:

(JSC::B3::testFastTLSLoad):
(JSC::B3::testFastTLSStore):
(JSC::B3::run):

  • jit/AssemblyHelpers.h:

(JSC::AssemblyHelpers::loadWasmContext):
(JSC::AssemblyHelpers::storeWasmContext):
(JSC::AssemblyHelpers::loadWasmContextNeedsMacroScratchRegister):
(JSC::AssemblyHelpers::storeWasmContextNeedsMacroScratchRegister):

  • jit/Repatch.cpp:

(JSC::webAssemblyOwner):

  • jit/ThunkGenerators.cpp:

(JSC::throwExceptionFromWasmThunkGenerator):

  • runtime/Options.h:
  • runtime/VM.cpp:

(JSC::VM::VM):

  • runtime/VM.h:
  • wasm/WasmB3IRGenerator.cpp:

(JSC::Wasm::loadWasmContext):
(JSC::Wasm::storeWasmContext):
(JSC::Wasm::B3IRGenerator::B3IRGenerator):
(JSC::Wasm::getMemoryBaseAndSize):
(JSC::Wasm::restoreWebAssemblyGlobalState):
(JSC::Wasm::createJSToWasmWrapper):
(JSC::Wasm::parseAndCompile):

  • wasm/WasmBinding.cpp:

(JSC::Wasm::materializeImportJSCell):
(JSC::Wasm::wasmToJs):
(JSC::Wasm::wasmToWasm):

  • wasm/WasmContext.cpp: Added.

(JSC::loadWasmContext):
(JSC::storeWasmContext):

  • wasm/WasmContext.h: Added. Replaces "top" JSWebAssemblyInstance.
  • wasm/js/WebAssemblyFunction.cpp:

(JSC::callWebAssemblyFunction):

  • wasm/js/WebAssemblyInstanceConstructor.h:

Source/WTF:

  • wtf/FastTLS.h: reserve one key for WebAssembly, delete a bunch

of dead code which clang couldn't compile (it's valid GCC assembly
which LLVM dislikes).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/b3/testb3.cpp

    r213753 r214384  
    1521215212}
    1521315213
    15214 void testFastTLS()
     15214void testFastTLSLoad()
    1521515215{
    1521615216#if ENABLE(FAST_TLS_JIT)
     
    1522715227            jit.loadFromTLSPtr(fastTLSOffsetForKey(WTF_TESTING_KEY), params[0].gpr());
    1522815228        });
    15229    
     15229
    1523015230    root->appendNew<Value>(proc, Return, Origin(), patchpoint);
    1523115231   
    1523215232    CHECK_EQ(compileAndRun<uintptr_t>(proc), static_cast<uintptr_t>(0xbeef));
     15233#endif
     15234}
     15235
     15236void testFastTLSStore()
     15237{
     15238#if ENABLE(FAST_TLS_JIT)
     15239    Procedure proc;
     15240    BasicBlock* root = proc.addBlock();
     15241
     15242    PatchpointValue* patchpoint = root->appendNew<PatchpointValue>(proc, Void, Origin());
     15243    patchpoint->clobber(RegisterSet::macroScratchRegisters());
     15244    patchpoint->numGPScratchRegisters = 1;
     15245    patchpoint->setGenerator(
     15246        [&] (CCallHelpers& jit, const StackmapGenerationParams& params) {
     15247            AllowMacroScratchRegisterUsage allowScratch(jit);
     15248            GPRReg scratch = params.gpScratch(0);
     15249            jit.move(CCallHelpers::TrustedImm32(0xdead), scratch);
     15250            jit.storeToTLSPtr(scratch, fastTLSOffsetForKey(WTF_TESTING_KEY));
     15251        });
     15252
     15253    root->appendNewControlValue(proc, Return, Origin());
     15254
     15255    compileAndRun<void>(proc);
     15256    CHECK_EQ(bitwise_cast<uintptr_t>(_pthread_getspecific_direct(WTF_TESTING_KEY)), static_cast<uintptr_t>(0xdead));
    1523315257#endif
    1523415258}
     
    1676116785    RUN(testWasmAddress());
    1676216786   
    16763     RUN(testFastTLS());
     16787    RUN(testFastTLSLoad());
     16788    RUN(testFastTLSStore());
    1676416789
    1676516790    if (isX86()) {
Note: See TracChangeset for help on using the changeset viewer.