WebAssembly: cache memory address / size on instance
https://bugs.webkit.org/show_bug.cgi?id=177305

Reviewed by JF Bastien.

JSTests:

* wasm/function-tests/memory-reuse.js: Added.
(createWasmInstance):
(doCheckTrap):
(doMemoryGrow):
(doCheck):
(checkWasmInstancesWithSharedMemory):

Source/JavaScriptCore:

Cache memory address/size in wasm:Instance to avoid load wasm:Memory
object during access to memory and memory size property in JiT

* wasm/WasmB3IRGenerator.cpp:
(JSC::Wasm::B3IRGenerator::restoreWebAssemblyGlobalState):
(JSC::Wasm::B3IRGenerator::addCurrentMemory):
(JSC::Wasm::B3IRGenerator::addCallIndirect):
* wasm/WasmBinding.cpp:
(JSC::Wasm::wasmToWasm):
* wasm/WasmInstance.h:
(JSC::Wasm::Instance::cachedMemory const):
(JSC::Wasm::Instance::cachedMemorySize const):
(JSC::Wasm::Instance::createWeakPtr):
(JSC::Wasm::Instance::setMemory):
(JSC::Wasm::Instance::updateCachedMemory):
(JSC::Wasm::Instance::offsetOfCachedMemory):
(JSC::Wasm::Instance::offsetOfCachedMemorySize):
(JSC::Wasm::Instance::offsetOfCachedIndexingMask):
(JSC::Wasm::Instance::allocationSize):
* wasm/WasmMemory.cpp:
(JSC::Wasm::Memory::grow):
(JSC::Wasm::Memory::registerInstance):
* wasm/WasmMemory.h:
(JSC::Wasm::Memory::indexingMask):
* wasm/js/JSToWasm.cpp:
(JSC::Wasm::createJSToWasmWrapper):
* wasm/js/WebAssemblyModuleRecord.cpp:
(JSC::WebAssemblyModuleRecord::evaluate):


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@228966 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/wasm/WasmInstance.h b/Source/JavaScriptCore/wasm/WasmInstance.h
index aa9f7cf..edd5a61 100644
--- a/Source/JavaScriptCore/wasm/WasmInstance.h
+++ b/Source/JavaScriptCore/wasm/WasmInstance.h
@@ -65,8 +65,25 @@
     CodeBlock* codeBlock() { return m_codeBlock.get(); }
     Memory* memory() { return m_memory.get(); }
     Table* table() { return m_table.get(); }
-    
-    void setMemory(Ref<Memory>&& memory) { m_memory = WTFMove(memory); }
+
+    void* cachedMemory() const { return m_cachedMemory; }
+    size_t cachedMemorySize() const { return m_cachedMemorySize; }
+
+    WeakPtr<Instance> createWeakPtr() { return m_weakPtrFactory.createWeakPtr(*this); }
+    void setMemory(Ref<Memory>&& memory)
+    {
+        m_memory = WTFMove(memory);
+        m_memory.get()->registerInstance(this);
+        updateCachedMemory();
+    }
+    void updateCachedMemory()
+    {
+        if (m_memory != nullptr) {
+            m_cachedMemory = memory()->memory();
+            m_cachedMemorySize = memory()->size();
+            m_cachedIndexingMask = memory()->indexingMask();
+        }
+    }
     void setTable(Ref<Table>&& table) { m_table = WTFMove(table); }
 
     int32_t loadI32Global(unsigned i) const { return m_globals.get()[i]; }
@@ -78,6 +95,9 @@
     static ptrdiff_t offsetOfMemory() { return OBJECT_OFFSETOF(Instance, m_memory); }
     static ptrdiff_t offsetOfGlobals() { return OBJECT_OFFSETOF(Instance, m_globals); }
     static ptrdiff_t offsetOfTable() { return OBJECT_OFFSETOF(Instance, m_table); }
+    static ptrdiff_t offsetOfCachedMemory() { return OBJECT_OFFSETOF(Instance, m_cachedMemory); }
+    static ptrdiff_t offsetOfCachedMemorySize() { return OBJECT_OFFSETOF(Instance, m_cachedMemorySize); }
+    static ptrdiff_t offsetOfCachedIndexingMask() { return OBJECT_OFFSETOF(Instance, m_cachedIndexingMask); }
     static ptrdiff_t offsetOfPointerToTopEntryFrame() { return OBJECT_OFFSETOF(Instance, m_pointerToTopEntryFrame); }
 
     static ptrdiff_t offsetOfPointerToActualStackLimit() { return OBJECT_OFFSETOF(Instance, m_pointerToActualStackLimit); }
@@ -126,9 +146,11 @@
     {
         return (offsetOfTail() + sizeof(ImportFunctionInfo) * numImportFunctions).unsafeGet();
     }
-
     void* m_owner { nullptr }; // In a JS embedding, this is a JSWebAssemblyInstance*.
     Context* m_context { nullptr };
+    void* m_cachedMemory { nullptr };
+    size_t m_cachedMemorySize { 0 };
+    size_t m_cachedIndexingMask { 0 };
     Ref<Module> m_module;
     RefPtr<CodeBlock> m_codeBlock;
     RefPtr<Memory> m_memory;
@@ -138,6 +160,7 @@
     void** m_pointerToActualStackLimit { nullptr };
     void* m_cachedStackLimit { bitwise_cast<void*>(std::numeric_limits<uintptr_t>::max()) };
     StoreTopCallFrameCallback m_storeTopCallFrame;
+    WeakPtrFactory<Instance> m_weakPtrFactory;
     unsigned m_numImportFunctions { 0 };
 };