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).

Location:
trunk/Source/JavaScriptCore/assembler
Files:
6 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h

    r213714 r214384  
    11091109
    11101110    friend class AllowMacroScratchRegisterUsage;
     1111    friend class AllowMacroScratchRegisterUsageIf;
    11111112    friend class DisallowMacroScratchRegisterUsage;
    11121113    unsigned m_tempRegistersValidBits;
  • trunk/Source/JavaScriptCore/assembler/AllowMacroScratchRegisterUsageIf.h

    r214383 r214384  
    11/*
    2  * Copyright (C) 2016 Apple Inc. All rights reserved.
     2 * Copyright (C) 2017 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2121 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    2222 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
    2424 */
    2525
    2626#pragma once
    2727
    28 #if ENABLE(WEBASSEMBLY)
     28#if ENABLE(ASSEMBLER)
    2929
    30 #include "InternalFunction.h"
    31 #include "JSObject.h"
     30#include "MacroAssembler.h"
    3231
    3332namespace JSC {
    3433
    35 class JSWebAssemblyModule;
    36 class WebAssemblyInstancePrototype;
     34class AllowMacroScratchRegisterUsageIf {
     35public:
     36    AllowMacroScratchRegisterUsageIf(MacroAssembler& masm, bool allowIfTrue)
     37        : m_masm(masm)
     38        , m_allowIfTrue(allowIfTrue)
     39        , m_oldValueOfAllowScratchRegister(masm.m_allowScratchRegister)
     40    {
     41        if (m_allowIfTrue)
     42            masm.m_allowScratchRegister = true;
     43    }
    3744
    38 class WebAssemblyInstanceConstructor : public InternalFunction {
    39 public:
    40     typedef InternalFunction Base;
    41     static const unsigned StructureFlags = Base::StructureFlags | HasStaticPropertyTable;
    42 
    43     static WebAssemblyInstanceConstructor* create(VM&, Structure*, WebAssemblyInstancePrototype*);
    44     static Structure* createStructure(VM&, JSGlobalObject*, JSValue);
    45 
    46     DECLARE_INFO;
    47 
    48     static JSWebAssemblyInstance* createInstance(ExecState*, JSWebAssemblyModule*, JSObject* importObject, Structure*);
    49 
    50 protected:
    51     void finishCreation(VM&, WebAssemblyInstancePrototype*);
     45    ~AllowMacroScratchRegisterUsageIf()
     46    {
     47        if (m_allowIfTrue)
     48            m_masm.m_allowScratchRegister = m_oldValueOfAllowScratchRegister;
     49    }
    5250
    5351private:
    54     WebAssemblyInstanceConstructor(VM&, Structure*);
    55     static ConstructType getConstructData(JSCell*, ConstructData&);
    56     static CallType getCallData(JSCell*, CallData&);
    57     static void visitChildren(JSCell*, SlotVisitor&);
     52    MacroAssembler& m_masm;
     53    bool m_allowIfTrue;
     54    bool m_oldValueOfAllowScratchRegister;
    5855};
    5956
    6057} // namespace JSC
    6158
    62 #endif // ENABLE(WEBASSEMBLY)
     59#endif // ENABLE(ASSEMBLER)
  • trunk/Source/JavaScriptCore/assembler/MacroAssembler.h

    r214213 r214384  
    658658        loadFromTLS32(offset, dst);
    659659    }
     660
     661    void storeToTLSPtr(RegisterID src, uint32_t offset)
     662    {
     663        storeToTLS32(src, offset);
     664    }
    660665#endif
    661666
     
    971976    {
    972977        loadFromTLS64(offset, dst);
     978    }
     979    void storeToTLSPtr(RegisterID src, uint32_t offset)
     980    {
     981        storeToTLS64(src, offset);
    973982    }
    974983#endif
  • trunk/Source/JavaScriptCore/assembler/MacroAssemblerARM64.h

    r213753 r214384  
    36013601#if ENABLE(FAST_TLS_JIT)
    36023602    // This will use scratch registers if the offset is not legal.
    3603    
     3603
    36043604    void loadFromTLS32(uint32_t offset, RegisterID dst)
    36053605    {
     
    36143614        and64(TrustedImm32(~7), dst);
    36153615        load64(Address(dst, offset), dst);
     3616    }
     3617
     3618    static bool loadFromTLSPtrNeedsMacroScratchRegister()
     3619    {
     3620        return true;
     3621    }
     3622
     3623    void storeToTLS32(RegisterID src, uint32_t offset)
     3624    {
     3625        RegisterID tmp = getCachedDataTempRegisterIDAndInvalidate();
     3626        ASSERT(src != tmp);
     3627        m_assembler.mrs_TPIDRRO_EL0(tmp);
     3628        and64(TrustedImm32(~7), tmp);
     3629        store32(src, Address(tmp, offset));
     3630    }
     3631   
     3632    void storeToTLS64(RegisterID src, uint32_t offset)
     3633    {
     3634        RegisterID tmp = getCachedDataTempRegisterIDAndInvalidate();
     3635        ASSERT(src != tmp);
     3636        m_assembler.mrs_TPIDRRO_EL0(tmp);
     3637        and64(TrustedImm32(~7), tmp);
     3638        store64(src, Address(tmp, offset));
     3639    }
     3640
     3641    static bool storeToTLSPtrNeedsMacroScratchRegister()
     3642    {
     3643        return true;
    36163644    }
    36173645#endif // ENABLE(FAST_TLS_JIT)
  • trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h

    r213753 r214384  
    38643864        m_assembler.gs();
    38653865        m_assembler.movl_mr(offset, dst);
     3866    }
     3867
     3868
     3869    static bool loadFromTLSPtrNeedsMacroScratchRegister()
     3870    {
     3871        return false;
     3872    }
     3873
     3874    void storeToTLS32(RegisterID src, uint32_t offset)
     3875    {
     3876        m_assembler.gs();
     3877        m_assembler.movl_rm(src, offset);
     3878    }
     3879
     3880    static bool storeToTLSPtrNeedsMacroScratchRegister()
     3881    {
     3882        return false;
    38663883    }
    38673884#endif
  • trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h

    r213753 r214384  
    17061706    {
    17071707        m_assembler.gs();
    1708         m_assembler.movl_mr(offset, dst);
     1708        m_assembler.movq_mr(offset, dst);
     1709    }
     1710
     1711    void storeToTLS64(RegisterID src, uint32_t offset)
     1712    {
     1713        m_assembler.gs();
     1714        m_assembler.movq_rm(src, offset);
    17091715    }
    17101716#endif
  • trunk/Source/JavaScriptCore/assembler/X86Assembler.h

    r213753 r214384  
    23612361    }
    23622362
     2363    void movl_rm(RegisterID src, uint32_t addr)
     2364    {
     2365        m_formatter.oneByteOpAddr(OP_MOV_EvGv, src, addr);
     2366    }
     2367
    23632368#if CPU(X86_64)
    23642369    void movq_rr(RegisterID src, RegisterID dst)
     
    23802385    {
    23812386        m_formatter.oneByteOp64(OP_MOV_EvGv, src, base, index, scale, offset);
     2387    }
     2388
     2389    void movq_rm(RegisterID src, int offset)
     2390    {
     2391        m_formatter.oneByteOp64Addr(OP_MOV_EvGv, src, offset);
    23822392    }
    23832393
Note: See TracChangeset for help on using the changeset viewer.