Changeset 228966 in webkit
- Timestamp:
- Feb 23, 2018 3:16:59 PM (6 years ago)
- Location:
- trunk
- Files:
-
- 1 added
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JSTests/ChangeLog
r228950 r228966 1 2018-02-23 Oleksandr Skachkov <gskachkov@gmail.com> 2 3 WebAssembly: cache memory address / size on instance 4 https://bugs.webkit.org/show_bug.cgi?id=177305 5 6 Reviewed by JF Bastien. 7 8 * wasm/function-tests/memory-reuse.js: Added. 9 (createWasmInstance): 10 (doCheckTrap): 11 (doMemoryGrow): 12 (doCheck): 13 (checkWasmInstancesWithSharedMemory): 14 1 15 2018-02-23 Yusuke Suzuki <utatane.tea@gmail.com> 2 16 -
trunk/Source/JavaScriptCore/ChangeLog
r228952 r228966 1 2018-02-23 Oleksandr Skachkov <gskachkov@gmail.com> 2 3 WebAssembly: cache memory address / size on instance 4 https://bugs.webkit.org/show_bug.cgi?id=177305 5 6 Reviewed by JF Bastien. 7 8 Cache memory address/size in wasm:Instance to avoid load wasm:Memory 9 object during access to memory and memory size property in JiT 10 11 * wasm/WasmB3IRGenerator.cpp: 12 (JSC::Wasm::B3IRGenerator::restoreWebAssemblyGlobalState): 13 (JSC::Wasm::B3IRGenerator::addCurrentMemory): 14 (JSC::Wasm::B3IRGenerator::addCallIndirect): 15 * wasm/WasmBinding.cpp: 16 (JSC::Wasm::wasmToWasm): 17 * wasm/WasmInstance.h: 18 (JSC::Wasm::Instance::cachedMemory const): 19 (JSC::Wasm::Instance::cachedMemorySize const): 20 (JSC::Wasm::Instance::createWeakPtr): 21 (JSC::Wasm::Instance::setMemory): 22 (JSC::Wasm::Instance::updateCachedMemory): 23 (JSC::Wasm::Instance::offsetOfCachedMemory): 24 (JSC::Wasm::Instance::offsetOfCachedMemorySize): 25 (JSC::Wasm::Instance::offsetOfCachedIndexingMask): 26 (JSC::Wasm::Instance::allocationSize): 27 * wasm/WasmMemory.cpp: 28 (JSC::Wasm::Memory::grow): 29 (JSC::Wasm::Memory::registerInstance): 30 * wasm/WasmMemory.h: 31 (JSC::Wasm::Memory::indexingMask): 32 * wasm/js/JSToWasm.cpp: 33 (JSC::Wasm::createJSToWasmWrapper): 34 * wasm/js/WebAssemblyModuleRecord.cpp: 35 (JSC::WebAssemblyModuleRecord::evaluate): 36 1 37 2018-02-23 Saam Barati <sbarati@apple.com> 2 38 -
trunk/Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp
r226615 r228966 486 486 patchpoint->setGenerator([pinnedRegs] (CCallHelpers& jit, const B3::StackmapGenerationParams& params) { 487 487 GPRReg baseMemory = pinnedRegs->baseMemoryPointer; 488 jit.loadPtr(CCallHelpers::Address(params[0].gpr(), Instance::offsetOfMemory()), baseMemory);489 488 const auto& sizeRegs = pinnedRegs->sizeRegisters; 490 489 ASSERT(sizeRegs.size() >= 1); 491 490 ASSERT(!sizeRegs[0].sizeOffset); // The following code assumes we start at 0, and calculates subsequent size registers relative to 0. 492 jit.loadPtr(CCallHelpers::Address( baseMemory, Memory::offsetOfSize()), sizeRegs[0].sizeRegister);493 jit.loadPtr(CCallHelpers::Address( baseMemory, Memory::offsetOfIndexingMask()), pinnedRegs->indexingMask);494 jit.loadPtr(CCallHelpers::Address( baseMemory, Memory::offsetOfMemory()), baseMemory);491 jit.loadPtr(CCallHelpers::Address(params[0].gpr(), Instance::offsetOfCachedMemorySize()), sizeRegs[0].sizeRegister); 492 jit.loadPtr(CCallHelpers::Address(params[0].gpr(), Instance::offsetOfCachedIndexingMask()), pinnedRegs->indexingMask); 493 jit.loadPtr(CCallHelpers::Address(params[0].gpr(), Instance::offsetOfCachedMemory()), baseMemory); 495 494 for (unsigned i = 1; i < sizeRegs.size(); ++i) 496 495 jit.add64(CCallHelpers::TrustedImm32(-sizeRegs[i].sizeOffset), sizeRegs[0].sizeRegister, sizeRegs[i].sizeRegister); … … 605 604 auto B3IRGenerator::addCurrentMemory(ExpressionType& result) -> PartialResult 606 605 { 607 Value* memoryObject = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, pointerType(), origin(), instanceValue(), safeCast<int32_t>(Instance::offsetOfMemory()));608 609 606 static_assert(sizeof(decltype(static_cast<Memory*>(nullptr)->size())) == sizeof(uint64_t), "codegen relies on this size"); 610 Value* size = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, Int64, origin(), memoryObject, safeCast<int32_t>(Memory::offsetOfSize()));611 607 Value* size = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, Int64, origin(), instanceValue(), safeCast<int32_t>(Instance::offsetOfCachedMemorySize())); 608 612 609 constexpr uint32_t shiftValue = 16; 613 610 static_assert(PageCount::pageSize == 1ull << shiftValue, "This must hold for the code below to be correct."); … … 1300 1297 jit.storePtr(baseMemory, CCallHelpers::Address(newContextInstance, Instance::offsetOfCachedStackLimit())); 1301 1298 jit.storeWasmContextInstance(newContextInstance); 1302 jit.loadPtr(CCallHelpers::Address(newContextInstance, Instance::offsetOfMemory()), baseMemory); // Memory*. 1299 ASSERT(sizeRegs[0].sizeRegister != baseMemory); 1300 // FIXME: We should support more than one memory size register 1301 // see: https://bugs.webkit.org/show_bug.cgi?id=162952 1303 1302 ASSERT(sizeRegs.size() == 1); 1304 ASSERT(sizeRegs[0].sizeRegister != baseMemory);1305 1303 ASSERT(sizeRegs[0].sizeRegister != newContextInstance); 1306 1304 ASSERT(!sizeRegs[0].sizeOffset); 1307 jit.loadPtr(CCallHelpers::Address( baseMemory, Memory::offsetOfIndexingMask()), pinnedRegs.indexingMask); // Indexing mask.1308 jit.loadPtr(CCallHelpers::Address( baseMemory, Memory::offsetOfSize()), sizeRegs[0].sizeRegister); // Memory size.1309 jit.loadPtr(CCallHelpers::Address( baseMemory, Memory::offsetOfMemory()), baseMemory); // Memory::void*.1305 jit.loadPtr(CCallHelpers::Address(newContextInstance, Instance::offsetOfCachedIndexingMask()), pinnedRegs.indexingMask); // Indexing mask. 1306 jit.loadPtr(CCallHelpers::Address(newContextInstance, Instance::offsetOfCachedMemorySize()), sizeRegs[0].sizeRegister); // Memory size. 1307 jit.loadPtr(CCallHelpers::Address(newContextInstance, Instance::offsetOfCachedMemory()), baseMemory); // Memory::void*. 1310 1308 }); 1311 1309 doContextSwitch->appendNewControlValue(m_proc, Jump, origin(), continuation); -
trunk/Source/JavaScriptCore/wasm/WasmBinding.cpp
r226461 r228966 65 65 // FIXME the following code assumes that all Wasm::Instance have the same pinned registers. https://bugs.webkit.org/show_bug.cgi?id=162952 66 66 // Set up the callee's baseMemory register as well as the memory size registers. 67 jit.loadPtr(JIT::Address(baseMemory, Instance::offsetOfMemory()), baseMemory); // Wasm::Memory*.68 67 ASSERT(!sizeRegs[0].sizeOffset); // The following code assumes we start at 0, and calculates subsequent size registers relative to 0. 69 jit.loadPtr( CCallHelpers::Address(baseMemory, Memory::offsetOfIndexingMask()), pinnedRegs.indexingMask); // Indexing mask.70 jit.loadPtr(JIT::Address(baseMemory, Wasm:: Memory::offsetOfSize()), sizeRegs[0].sizeRegister); // Memory size.71 jit.loadPtr(JIT::Address(baseMemory, Wasm:: Memory::offsetOfMemory()), baseMemory); // Wasm::Memory::void*.68 jit.loadPtr(JIT::Address(baseMemory, Wasm::Instance::offsetOfCachedIndexingMask()), pinnedRegs.indexingMask); // Indexing mask. 69 jit.loadPtr(JIT::Address(baseMemory, Wasm::Instance::offsetOfCachedMemorySize()), sizeRegs[0].sizeRegister); // Memory size. 70 jit.loadPtr(JIT::Address(baseMemory, Wasm::Instance::offsetOfCachedMemory()), baseMemory); // Wasm::Memory::void*. 72 71 for (unsigned i = 1; i < sizeRegs.size(); ++i) { 73 72 ASSERT(sizeRegs[i].sizeRegister != baseMemory); -
trunk/Source/JavaScriptCore/wasm/WasmInstance.h
r226920 r228966 66 66 Memory* memory() { return m_memory.get(); } 67 67 Table* table() { return m_table.get(); } 68 69 void setMemory(Ref<Memory>&& memory) { m_memory = WTFMove(memory); } 68 69 void* cachedMemory() const { return m_cachedMemory; } 70 size_t cachedMemorySize() const { return m_cachedMemorySize; } 71 72 WeakPtr<Instance> createWeakPtr() { return m_weakPtrFactory.createWeakPtr(*this); } 73 void setMemory(Ref<Memory>&& memory) 74 { 75 m_memory = WTFMove(memory); 76 m_memory.get()->registerInstance(this); 77 updateCachedMemory(); 78 } 79 void updateCachedMemory() 80 { 81 if (m_memory != nullptr) { 82 m_cachedMemory = memory()->memory(); 83 m_cachedMemorySize = memory()->size(); 84 m_cachedIndexingMask = memory()->indexingMask(); 85 } 86 } 70 87 void setTable(Ref<Table>&& table) { m_table = WTFMove(table); } 71 88 … … 79 96 static ptrdiff_t offsetOfGlobals() { return OBJECT_OFFSETOF(Instance, m_globals); } 80 97 static ptrdiff_t offsetOfTable() { return OBJECT_OFFSETOF(Instance, m_table); } 98 static ptrdiff_t offsetOfCachedMemory() { return OBJECT_OFFSETOF(Instance, m_cachedMemory); } 99 static ptrdiff_t offsetOfCachedMemorySize() { return OBJECT_OFFSETOF(Instance, m_cachedMemorySize); } 100 static ptrdiff_t offsetOfCachedIndexingMask() { return OBJECT_OFFSETOF(Instance, m_cachedIndexingMask); } 81 101 static ptrdiff_t offsetOfPointerToTopEntryFrame() { return OBJECT_OFFSETOF(Instance, m_pointerToTopEntryFrame); } 82 102 … … 127 147 return (offsetOfTail() + sizeof(ImportFunctionInfo) * numImportFunctions).unsafeGet(); 128 148 } 129 130 149 void* m_owner { nullptr }; // In a JS embedding, this is a JSWebAssemblyInstance*. 131 150 Context* m_context { nullptr }; 151 void* m_cachedMemory { nullptr }; 152 size_t m_cachedMemorySize { 0 }; 153 size_t m_cachedIndexingMask { 0 }; 132 154 Ref<Module> m_module; 133 155 RefPtr<CodeBlock> m_codeBlock; … … 139 161 void* m_cachedStackLimit { bitwise_cast<void*>(std::numeric_limits<uintptr_t>::max()) }; 140 162 StoreTopCallFrameCallback m_storeTopCallFrame; 163 WeakPtrFactory<Instance> m_weakPtrFactory; 141 164 unsigned m_numImportFunctions { 0 }; 142 165 }; -
trunk/Source/JavaScriptCore/wasm/WasmMemory.cpp
r227951 r228966 26 26 #include "config.h" 27 27 #include "WasmMemory.h" 28 #include "WasmInstance.h" 28 29 29 30 #if ENABLE(WEBASSEMBLY) … … 378 379 auto success = [&] () { 379 380 m_growSuccessCallback(GrowSuccessTag, oldPageCount, newPageCount); 381 // Update cache for instance 382 for (auto& instance : m_instances) { 383 if (instance.get() != nullptr) 384 instance.get()->updateCachedMemory(); 385 } 380 386 return oldPageCount; 381 387 }; … … 438 444 } 439 445 446 void Memory::registerInstance(Instance* instance) 447 { 448 size_t count = m_instances.size(); 449 for (size_t index = 0; index < count; index++) { 450 if (m_instances.at(index).get() == nullptr) { 451 m_instances.at(index) = instance->createWeakPtr(); 452 return; 453 } 454 } 455 m_instances.append(instance->createWeakPtr()); 456 } 457 440 458 void Memory::dump(PrintStream& out) const 441 459 { -
trunk/Source/JavaScriptCore/wasm/WasmMemory.h
r226461 r228966 35 35 #include <wtf/RefCounted.h> 36 36 #include <wtf/RefPtr.h> 37 #include <wtf/Vector.h> 38 #include <wtf/WeakPtr.h> 37 39 38 40 namespace WTF { … … 43 45 44 46 namespace Wasm { 47 48 class Instance; 45 49 46 50 class Memory : public RefCounted<Memory> { … … 67 71 void* memory() const { return m_memory; } 68 72 size_t size() const { return m_size; } 73 size_t indexingMask() { return m_indexingMask; } 69 74 PageCount sizeInPages() const { return PageCount::fromBytes(m_size); } 70 75 … … 81 86 }; 82 87 Expected<PageCount, GrowFailReason> grow(PageCount); 88 void registerInstance(Instance*); 83 89 84 90 void check() { ASSERT(!deletionHasBegun()); } … … 93 99 Memory(PageCount initial, PageCount maximum, WTF::Function<void(NotifyPressure)>&& notifyMemoryPressure, WTF::Function<void(SyncTryToReclaim)>&& syncTryToReclaimMemory, WTF::Function<void(GrowSuccess, PageCount, PageCount)>&& growSuccessCallback); 94 100 95 // FIXME: we cache these on the instances to avoid a load on instance->instance calls. This will require updating all the instances when grow is called. https://bugs.webkit.org/show_bug.cgi?id=17730596 101 void* m_memory { nullptr }; 97 102 size_t m_size { 0 }; … … 104 109 WTF::Function<void(SyncTryToReclaim)> m_syncTryToReclaimMemory; 105 110 WTF::Function<void(GrowSuccess, PageCount, PageCount)> m_growSuccessCallback; 111 Vector<WeakPtr<Instance>> m_instances; 106 112 }; 107 113 -
trunk/Source/JavaScriptCore/wasm/js/JSToWasm.cpp
r227527 r228966 176 176 GPRReg baseMemory = pinnedRegs.baseMemoryPointer; 177 177 178 if (!Context::useFastTLS()) 179 jit.loadPtr(CCallHelpers::Address(wasmContextInstanceGPR, Instance::offsetOfMemory()), baseMemory); 180 else { 178 if (Context::useFastTLS()) 181 179 jit.loadWasmContextInstance(baseMemory); 182 jit.loadPtr(CCallHelpers::Address(baseMemory, Instance::offsetOfMemory()), baseMemory); 183 } 184 180 181 GPRReg currentInstanceGPR = Context::useFastTLS() ? baseMemory : wasmContextInstanceGPR; 185 182 if (mode != MemoryMode::Signaling) { 186 jit.loadPtr(CCallHelpers::Address( baseMemory, Wasm::Memory::offsetOfIndexingMask()), pinnedRegs.indexingMask);183 jit.loadPtr(CCallHelpers::Address(currentInstanceGPR, Wasm::Instance::offsetOfCachedIndexingMask()), pinnedRegs.indexingMask); 187 184 const auto& sizeRegs = pinnedRegs.sizeRegisters; 188 185 ASSERT(sizeRegs.size() >= 1); 189 186 ASSERT(!sizeRegs[0].sizeOffset); // The following code assumes we start at 0, and calculates subsequent size registers relative to 0. 190 jit.loadPtr(CCallHelpers::Address( baseMemory, Wasm::Memory::offsetOfSize()), sizeRegs[0].sizeRegister);187 jit.loadPtr(CCallHelpers::Address(currentInstanceGPR, Wasm::Instance::offsetOfCachedMemorySize()), sizeRegs[0].sizeRegister); 191 188 for (unsigned i = 1; i < sizeRegs.size(); ++i) 192 189 jit.add64(CCallHelpers::TrustedImm32(-sizeRegs[i].sizeOffset), sizeRegs[0].sizeRegister, sizeRegs[i].sizeRegister); 193 190 } 194 191 195 jit.loadPtr(CCallHelpers::Address( baseMemory, Wasm::Memory::offsetOfMemory()), baseMemory);192 jit.loadPtr(CCallHelpers::Address(currentInstanceGPR, Wasm::Instance::offsetOfCachedMemory()), baseMemory); 196 193 } 197 194 -
trunk/Source/JavaScriptCore/wasm/js/WebAssemblyModuleRecord.cpp
r226920 r228966 224 224 225 225 const Vector<Wasm::Segment::Ptr>& data = moduleInformation.data; 226 JSWebAssemblyMemory* jsMemory = m_instance->memory(); 227 226 228 227 std::optional<JSValue> exception; 229 228 … … 251 250 252 251 auto forEachSegment = [&] (auto fn) { 253 uint8_t* memory = reinterpret_cast<uint8_t*>( jsMemory->memory().memory());254 uint64_t sizeInBytes = jsMemory->memory().size();252 uint8_t* memory = reinterpret_cast<uint8_t*>(m_instance->instance().cachedMemory()); 253 uint64_t sizeInBytes = m_instance->instance().cachedMemorySize(); 255 254 256 255 for (const Wasm::Segment::Ptr& segment : data) {
Note: See TracChangeset
for help on using the changeset viewer.