Changeset 243886 in webkit
- Timestamp:
- Apr 4, 2019, 11:54:16 AM (7 years ago)
- Location:
- trunk
- Files:
-
- 32 edited
- 4 copied
-
JSTests/ChangeLog (modified) (1 diff)
-
JSTests/wasm/function-tests/stack-trace.js (modified) (1 diff)
-
Source/JavaScriptCore/CMakeLists.txt (modified) (1 diff)
-
Source/JavaScriptCore/ChangeLog (modified) (1 diff)
-
Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (modified) (8 diffs)
-
Source/JavaScriptCore/Sources.txt (modified) (2 diffs)
-
Source/JavaScriptCore/assembler/MacroAssemblerCodeRef.h (modified) (2 diffs)
-
Source/JavaScriptCore/interpreter/Interpreter.cpp (modified) (2 diffs)
-
Source/JavaScriptCore/interpreter/StackVisitor.cpp (modified) (3 diffs)
-
Source/JavaScriptCore/interpreter/StackVisitor.h (modified) (1 diff)
-
Source/JavaScriptCore/jit/JITOperations.cpp (modified) (3 diffs)
-
Source/JavaScriptCore/jit/RegisterSet.cpp (modified) (2 diffs)
-
Source/JavaScriptCore/jit/RegisterSet.h (modified) (1 diff)
-
Source/JavaScriptCore/jit/Repatch.cpp (modified) (3 diffs)
-
Source/JavaScriptCore/jit/Repatch.h (modified) (1 diff)
-
Source/JavaScriptCore/runtime/JSFunction.cpp (modified) (2 diffs)
-
Source/JavaScriptCore/runtime/JSGlobalObject.cpp (modified) (2 diffs)
-
Source/JavaScriptCore/runtime/JSGlobalObject.h (modified) (2 diffs)
-
Source/JavaScriptCore/runtime/VM.cpp (modified) (3 diffs)
-
Source/JavaScriptCore/runtime/VM.h (modified) (2 diffs)
-
Source/JavaScriptCore/wasm/WasmAirIRGenerator.cpp (modified) (5 diffs)
-
Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp (modified) (5 diffs)
-
Source/JavaScriptCore/wasm/WasmBinding.cpp (modified) (2 diffs)
-
Source/JavaScriptCore/wasm/WasmContext.h (modified) (1 diff)
-
Source/JavaScriptCore/wasm/WasmContextInlines.h (modified) (1 diff)
-
Source/JavaScriptCore/wasm/WasmMemoryInformation.cpp (modified) (3 diffs)
-
Source/JavaScriptCore/wasm/WasmMemoryInformation.h (modified) (2 diffs)
-
Source/JavaScriptCore/wasm/WasmOMGPlan.cpp (modified) (1 diff)
-
Source/JavaScriptCore/wasm/js/JSToWasm.cpp (modified) (1 diff)
-
Source/JavaScriptCore/wasm/js/JSToWasmICCallee.cpp (copied) (copied from trunk/Source/JavaScriptCore/wasm/js/WebAssemblyPrototype.h ) (2 diffs)
-
Source/JavaScriptCore/wasm/js/JSToWasmICCallee.h (copied) (copied from trunk/Source/JavaScriptCore/wasm/WasmContext.h ) (2 diffs)
-
Source/JavaScriptCore/wasm/js/WebAssemblyFunction.cpp (modified) (3 diffs)
-
Source/JavaScriptCore/wasm/js/WebAssemblyFunction.h (modified) (4 diffs)
-
Source/JavaScriptCore/wasm/js/WebAssemblyFunctionHeapCellType.cpp (copied) (copied from trunk/Source/JavaScriptCore/wasm/WasmContextInlines.h ) (2 diffs)
-
Source/JavaScriptCore/wasm/js/WebAssemblyFunctionHeapCellType.h (copied) (copied from trunk/Source/JavaScriptCore/wasm/WasmContext.h ) (3 diffs)
-
Source/JavaScriptCore/wasm/js/WebAssemblyPrototype.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/JSTests/ChangeLog
r243875 r243886 1 2019-04-04 Saam barati <sbarati@apple.com> 2 3 Teach Call ICs how to call Wasm 4 https://bugs.webkit.org/show_bug.cgi?id=196387 5 6 Reviewed by Filip Pizlo. 7 8 * wasm/function-tests/stack-trace.js: 9 1 10 2019-04-04 Caio Lima <ticaiolima@gmail.com> 2 11 -
trunk/JSTests/wasm/function-tests/stack-trace.js
r225550 r243886 44 44 assert.truthy(stacktrace[0].indexOf("imp") !== -1); // the arrow function import named "imp". 45 45 assert.eq(stacktrace[1], "wasm-stub@[wasm code]"); // the wasm->js stub 46 assert.eq(stacktrace[2], "<?>.wasm-function[4]@[wasm code]"); 47 assert.eq(stacktrace[3], "<?>.wasm-function[2]@[wasm code]"); 48 assert.eq(stacktrace[4], "<?>.wasm-function[3]@[wasm code]"); 49 assert.eq(stacktrace[5], "<?>.wasm-function[1]@[wasm code]"); 50 assert.eq(stacktrace[6], "wasm-stub@[wasm code]"); // wasm entry 51 46 let found = false; 47 for (let i = 0; i < stacktrace.length; ++i) { 48 let str = stacktrace[i]; 49 if (str !== "<?>.wasm-function[4]@[wasm code]") 50 continue; 51 found = true; 52 assert.eq(stacktrace[i + 1], "<?>.wasm-function[2]@[wasm code]"); 53 assert.eq(stacktrace[i + 2], "<?>.wasm-function[3]@[wasm code]"); 54 assert.eq(stacktrace[i + 3], "<?>.wasm-function[1]@[wasm code]"); 55 } 56 assert.truthy(found); 52 57 stacktrace = null; 53 58 } -
trunk/Source/JavaScriptCore/CMakeLists.txt
r243833 r243886 101 101 102 102 wasm/js/JSWebAssembly.cpp 103 wasm/js/JSToWasmICCallee.cpp 103 104 wasm/js/WebAssemblyCompileErrorConstructor.cpp 104 105 wasm/js/WebAssemblyCompileErrorPrototype.cpp 106 wasm/js/WebAssemblyFunctionHeapCellType.cpp 105 107 wasm/js/WebAssemblyInstanceConstructor.cpp 106 108 wasm/js/WebAssemblyInstancePrototype.cpp -
trunk/Source/JavaScriptCore/ChangeLog
r243885 r243886 1 2019-04-04 Saam barati <sbarati@apple.com> 2 3 Teach Call ICs how to call Wasm 4 https://bugs.webkit.org/show_bug.cgi?id=196387 5 6 Reviewed by Filip Pizlo. 7 8 This patch teaches JS to call Wasm without going through the native thunk. 9 Currently, we emit a JIT "JS" callee stub which marshals arguments from 10 JS to Wasm. Like the native version of this, this thunk is responsible 11 for saving and restoring the VM's current Wasm context. Instead of emitting 12 an exception handler, we also teach the unwinder how to read the previous 13 wasm context to restore it as it unwindws past this frame. 14 15 This patch is straight forward, and leaves some areas for perf improvement: 16 - We can teach the DFG/FTL to directly use the Wasm calling convention when 17 it knows it's calling a single Wasm function. This way we don't shuffle 18 registers to the stack and then back into registers. 19 - We bail out to the slow path for mismatched arity. I opened a bug to fix 20 optimize arity check failures: https://bugs.webkit.org/show_bug.cgi?id=196564 21 - We bail out to the slow path Double JSValues flowing into i32 arguments. 22 We should teach this thunk how to do that conversion directly. 23 24 This patch also refactors the code to explicitly have a single pinned size register. 25 We used pretend in some places that we could have more than one pinned size register. 26 However, there was other code that just asserted the size was one. This patch just rips 27 out this code since we never moved to having more than one pinned size register. Doing 28 this refactoring cleans up the various places where we set up the size register. 29 30 This patch is a 50-60% progression on JetStream 2's richards-wasm. 31 32 * JavaScriptCore.xcodeproj/project.pbxproj: 33 * Sources.txt: 34 * assembler/MacroAssemblerCodeRef.h: 35 (JSC::MacroAssemblerCodeRef::operator=): 36 (JSC::MacroAssemblerCodeRef::MacroAssemblerCodeRef): 37 * interpreter/Interpreter.cpp: 38 (JSC::UnwindFunctor::operator() const): 39 (JSC::UnwindFunctor::copyCalleeSavesToEntryFrameCalleeSavesBuffer const): 40 * interpreter/StackVisitor.cpp: 41 (JSC::StackVisitor::Frame::calleeSaveRegistersForUnwinding): 42 (JSC::StackVisitor::Frame::calleeSaveRegisters): Deleted. 43 * interpreter/StackVisitor.h: 44 * jit/JITOperations.cpp: 45 * jit/RegisterSet.cpp: 46 (JSC::RegisterSet::runtimeTagRegisters): 47 (JSC::RegisterSet::specialRegisters): 48 (JSC::RegisterSet::runtimeRegisters): Deleted. 49 * jit/RegisterSet.h: 50 * jit/Repatch.cpp: 51 (JSC::linkPolymorphicCall): 52 * runtime/JSFunction.cpp: 53 (JSC::getCalculatedDisplayName): 54 * runtime/JSGlobalObject.cpp: 55 (JSC::JSGlobalObject::init): 56 (JSC::JSGlobalObject::visitChildren): 57 * runtime/JSGlobalObject.h: 58 (JSC::JSGlobalObject::jsToWasmICCalleeStructure const): 59 * runtime/VM.cpp: 60 (JSC::VM::VM): 61 * runtime/VM.h: 62 * wasm/WasmAirIRGenerator.cpp: 63 (JSC::Wasm::AirIRGenerator::AirIRGenerator): 64 (JSC::Wasm::AirIRGenerator::restoreWebAssemblyGlobalState): 65 (JSC::Wasm::AirIRGenerator::addCallIndirect): 66 * wasm/WasmB3IRGenerator.cpp: 67 (JSC::Wasm::B3IRGenerator::B3IRGenerator): 68 (JSC::Wasm::B3IRGenerator::restoreWebAssemblyGlobalState): 69 (JSC::Wasm::B3IRGenerator::addCallIndirect): 70 * wasm/WasmBinding.cpp: 71 (JSC::Wasm::wasmToWasm): 72 * wasm/WasmContext.h: 73 (JSC::Wasm::Context::pointerToInstance): 74 * wasm/WasmContextInlines.h: 75 (JSC::Wasm::Context::store): 76 * wasm/WasmMemoryInformation.cpp: 77 (JSC::Wasm::getPinnedRegisters): 78 (JSC::Wasm::PinnedRegisterInfo::get): 79 (JSC::Wasm::PinnedRegisterInfo::PinnedRegisterInfo): 80 * wasm/WasmMemoryInformation.h: 81 (JSC::Wasm::PinnedRegisterInfo::toSave const): 82 * wasm/WasmOMGPlan.cpp: 83 (JSC::Wasm::OMGPlan::work): 84 * wasm/js/JSToWasm.cpp: 85 (JSC::Wasm::createJSToWasmWrapper): 86 * wasm/js/JSToWasmICCallee.cpp: Added. 87 (JSC::JSToWasmICCallee::create): 88 (JSC::JSToWasmICCallee::createStructure): 89 (JSC::JSToWasmICCallee::visitChildren): 90 * wasm/js/JSToWasmICCallee.h: Added. 91 (JSC::JSToWasmICCallee::function): 92 (JSC::JSToWasmICCallee::JSToWasmICCallee): 93 * wasm/js/WebAssemblyFunction.cpp: 94 (JSC::WebAssemblyFunction::useTagRegisters const): 95 (JSC::WebAssemblyFunction::calleeSaves const): 96 (JSC::WebAssemblyFunction::usedCalleeSaveRegisters const): 97 (JSC::WebAssemblyFunction::previousInstanceOffset const): 98 (JSC::WebAssemblyFunction::previousInstance): 99 (JSC::WebAssemblyFunction::jsCallEntrypointSlow): 100 (JSC::WebAssemblyFunction::visitChildren): 101 (JSC::WebAssemblyFunction::destroy): 102 * wasm/js/WebAssemblyFunction.h: 103 * wasm/js/WebAssemblyFunctionHeapCellType.cpp: Added. 104 (JSC::WebAssemblyFunctionDestroyFunc::operator() const): 105 (JSC::WebAssemblyFunctionHeapCellType::WebAssemblyFunctionHeapCellType): 106 (JSC::WebAssemblyFunctionHeapCellType::~WebAssemblyFunctionHeapCellType): 107 (JSC::WebAssemblyFunctionHeapCellType::finishSweep): 108 (JSC::WebAssemblyFunctionHeapCellType::destroy): 109 * wasm/js/WebAssemblyFunctionHeapCellType.h: Added. 110 * wasm/js/WebAssemblyPrototype.h: 111 1 112 2019-04-04 Yusuke Suzuki <ysuzuki@apple.com> 2 113 -
trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
r243851 r243886 874 874 521131F71F82BF14007CCEEE /* PolyProtoAccessChain.h in Headers */ = {isa = PBXBuildFile; fileRef = 521131F61F82BF11007CCEEE /* PolyProtoAccessChain.h */; settings = {ATTRIBUTES = (Private, ); }; }; 875 875 521322461ECBCE8200F65615 /* WebAssemblyFunctionBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 521322441ECBCE8200F65615 /* WebAssemblyFunctionBase.h */; }; 876 523FD88E225566C9003B3DCC /* WebAssemblyFunctionHeapCellType.h in Headers */ = {isa = PBXBuildFile; fileRef = 523FD88C225566C3003B3DCC /* WebAssemblyFunctionHeapCellType.h */; }; 876 877 524E9D7322092B5200A6BEEE /* AirAllocateRegistersAndStackAndGenerateCode.h in Headers */ = {isa = PBXBuildFile; fileRef = 524E9D7222092B4600A6BEEE /* AirAllocateRegistersAndStackAndGenerateCode.h */; }; 877 878 5250D2D21E8DA05A0029A932 /* WasmThunks.h in Headers */ = {isa = PBXBuildFile; fileRef = 5250D2D01E8DA05A0029A932 /* WasmThunks.h */; settings = {ATTRIBUTES = (Private, ); }; }; … … 881 882 52678F911A04177C006A306D /* ControlFlowProfiler.h in Headers */ = {isa = PBXBuildFile; fileRef = 52678F901A04177C006A306D /* ControlFlowProfiler.h */; settings = {ATTRIBUTES = (Private, ); }; }; 882 883 526AC4B71E977C5D003500E1 /* WasmCodeBlock.h in Headers */ = {isa = PBXBuildFile; fileRef = 526AC4B51E977C5D003500E1 /* WasmCodeBlock.h */; settings = {ATTRIBUTES = (Private, ); }; }; 884 527CE35422555FE500C6F382 /* JSToWasmICCallee.h in Headers */ = {isa = PBXBuildFile; fileRef = 527CE35322555FDD00C6F382 /* JSToWasmICCallee.h */; }; 883 885 52847ADC21FFB8690061A9DB /* WasmAirIRGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = 52847ADA21FFB8630061A9DB /* WasmAirIRGenerator.h */; }; 884 886 52B310FB1974AE610080857C /* FunctionHasExecutedCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 52B310FA1974AE610080857C /* FunctionHasExecutedCache.h */; settings = {ATTRIBUTES = (Private, ); }; }; … … 3378 3380 521322431ECBCE8200F65615 /* WebAssemblyFunctionBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WebAssemblyFunctionBase.cpp; path = js/WebAssemblyFunctionBase.cpp; sourceTree = "<group>"; }; 3379 3381 521322441ECBCE8200F65615 /* WebAssemblyFunctionBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WebAssemblyFunctionBase.h; path = js/WebAssemblyFunctionBase.h; sourceTree = "<group>"; }; 3382 523FD88C225566C3003B3DCC /* WebAssemblyFunctionHeapCellType.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = WebAssemblyFunctionHeapCellType.h; path = js/WebAssemblyFunctionHeapCellType.h; sourceTree = "<group>"; }; 3383 523FD88D225566C4003B3DCC /* WebAssemblyFunctionHeapCellType.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = WebAssemblyFunctionHeapCellType.cpp; path = js/WebAssemblyFunctionHeapCellType.cpp; sourceTree = "<group>"; }; 3380 3384 524E9D7122092B4500A6BEEE /* AirAllocateRegistersAndStackAndGenerateCode.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = AirAllocateRegistersAndStackAndGenerateCode.cpp; path = b3/air/AirAllocateRegistersAndStackAndGenerateCode.cpp; sourceTree = "<group>"; }; 3381 3385 524E9D7222092B4600A6BEEE /* AirAllocateRegistersAndStackAndGenerateCode.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = AirAllocateRegistersAndStackAndGenerateCode.h; path = b3/air/AirAllocateRegistersAndStackAndGenerateCode.h; sourceTree = "<group>"; }; … … 3390 3394 526AC4B51E977C5D003500E1 /* WasmCodeBlock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmCodeBlock.h; sourceTree = "<group>"; }; 3391 3395 527773DD1AAF83AC00BDE7E8 /* RuntimeType.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RuntimeType.cpp; sourceTree = "<group>"; }; 3396 527CE35222555FDD00C6F382 /* JSToWasmICCallee.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = JSToWasmICCallee.cpp; path = js/JSToWasmICCallee.cpp; sourceTree = "<group>"; }; 3397 527CE35322555FDD00C6F382 /* JSToWasmICCallee.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = JSToWasmICCallee.h; path = js/JSToWasmICCallee.h; sourceTree = "<group>"; }; 3392 3398 52847AD921FFB8630061A9DB /* WasmAirIRGenerator.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WasmAirIRGenerator.cpp; sourceTree = "<group>"; }; 3393 3399 52847ADA21FFB8630061A9DB /* WasmAirIRGenerator.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WasmAirIRGenerator.h; sourceTree = "<group>"; }; … … 8269 8275 AD8DD6D01F6708A30004EB52 /* JSToWasm.cpp */, 8270 8276 AD8DD6CF1F67089F0004EB52 /* JSToWasm.h */, 8277 527CE35222555FDD00C6F382 /* JSToWasmICCallee.cpp */, 8278 527CE35322555FDD00C6F382 /* JSToWasmICCallee.h */, 8271 8279 ADD09AF21F624829001313C2 /* JSWebAssembly.cpp */, 8272 8280 ADD09AF31F62482E001313C2 /* JSWebAssembly.h */, … … 8298 8306 AD4937C91DDD27340077C807 /* WebAssemblyFunction.cpp */, 8299 8307 AD4937CA1DDD27340077C807 /* WebAssemblyFunction.h */, 8308 523FD88D225566C4003B3DCC /* WebAssemblyFunctionHeapCellType.cpp */, 8309 523FD88C225566C3003B3DCC /* WebAssemblyFunctionHeapCellType.h */, 8300 8310 521322431ECBCE8200F65615 /* WebAssemblyFunctionBase.cpp */, 8301 8311 521322441ECBCE8200F65615 /* WebAssemblyFunctionBase.h */, … … 8615 8625 DC69B99D1D15F914002E3C00 /* B3InferSwitches.h in Headers */, 8616 8626 0FEC85BA1BE1462F0080FF74 /* B3InsertionSet.h in Headers */, 8627 523FD88E225566C9003B3DCC /* WebAssemblyFunctionHeapCellType.h in Headers */, 8617 8628 0FEC85BB1BE1462F0080FF74 /* B3InsertionSetInlines.h in Headers */, 8618 8629 0FDF67D21D9C6D27001B9825 /* B3Kind.h in Headers */, … … 8807 8818 0FBB73BB1DEF8645002C009E /* DeleteAllCodeEffort.h in Headers */, 8808 8819 0F96303C1D4192CD005609D9 /* DestructionMode.h in Headers */, 8820 527CE35422555FE500C6F382 /* JSToWasmICCallee.h in Headers */, 8809 8821 A77A423E17A0BBFD00A8DB81 /* DFGAbstractHeap.h in Headers */, 8810 8822 A704D90317A0BAA8006BA554 /* DFGAbstractInterpreter.h in Headers */, -
trunk/Source/JavaScriptCore/Sources.txt
r243851 r243886 1015 1015 wasm/js/JSToWasm.cpp 1016 1016 wasm/js/JSToWasm.h 1017 wasm/js/JSToWasmICCallee.cpp 1017 1018 wasm/js/JSWebAssembly.cpp 1018 1019 wasm/js/JSWebAssemblyCodeBlock.cpp … … 1031 1032 wasm/js/WebAssemblyFunction.cpp 1032 1033 wasm/js/WebAssemblyFunctionBase.cpp 1034 wasm/js/WebAssemblyFunctionHeapCellType.cpp 1033 1035 wasm/js/WebAssemblyInstanceConstructor.cpp 1034 1036 wasm/js/WebAssemblyInstancePrototype.cpp -
trunk/Source/JavaScriptCore/assembler/MacroAssemblerCodeRef.h
r242100 r243886 381 381 ASSERT(m_codePtr); 382 382 } 383 384 template<PtrTag otherTag> 385 MacroAssemblerCodeRef& operator=(const MacroAssemblerCodeRef<otherTag>& otherCodeRef) 386 { 387 m_codePtr = MacroAssemblerCodePtr<tag>::createFromExecutableAddress(otherCodeRef.code().template retaggedExecutableAddress<tag>()); 388 m_executableMemory = otherCodeRef.m_executableMemory; 389 return *this; 390 } 383 391 384 392 // Use this only when you know that the codePtr refers to code that is … … 444 452 template<PtrTag otherTag> 445 453 MacroAssemblerCodeRef(const MacroAssemblerCodeRef<otherTag>& otherCodeRef) 446 : m_codePtr(MacroAssemblerCodePtr<tag>::createFromExecutableAddress(otherCodeRef.code().template retaggedExecutableAddress<tag>()))447 , m_executableMemory(otherCodeRef.m_executableMemory)448 {}454 { 455 *this = otherCodeRef; 456 } 449 457 450 458 MacroAssemblerCodePtr<tag> m_codePtr; -
trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp
r242636 r243886 550 550 } 551 551 552 #if ENABLE(WEBASSEMBLY) 553 if (visitor->callee().isCell()) { 554 if (auto* jsToWasmICCallee = jsDynamicCast<JSToWasmICCallee*>(m_vm, visitor->callee().asCell())) 555 m_vm.wasmContext.store(jsToWasmICCallee->function()->previousInstance(m_callFrame), m_vm.softStackLimit()); 556 } 557 #endif 558 552 559 notifyDebuggerOfUnwinding(m_vm, m_callFrame); 553 560 … … 565 572 { 566 573 #if !ENABLE(C_LOOP) && NUMBER_OF_CALLEE_SAVES_REGISTERS > 0 567 const RegisterAtOffsetList* currentCalleeSaves = visitor->calleeSaveRegisters();574 Optional<RegisterAtOffsetList> currentCalleeSaves = visitor->calleeSaveRegistersForUnwinding(); 568 575 569 576 if (!currentCalleeSaves) -
trunk/Source/JavaScriptCore/interpreter/StackVisitor.cpp
r243232 r243886 34 34 #include "WasmCallee.h" 35 35 #include "WasmIndexOrName.h" 36 #include "WebAssemblyFunction.h" 36 37 #include <wtf/text/StringBuilder.h> 37 38 … … 253 254 } 254 255 255 const RegisterAtOffsetList* StackVisitor::Frame::calleeSaveRegisters()256 Optional<RegisterAtOffsetList> StackVisitor::Frame::calleeSaveRegistersForUnwinding() 256 257 { 257 258 if (isInlinedFrame()) 258 return nullptr;259 return WTF::nullopt; 259 260 260 261 #if !ENABLE(C_LOOP) && NUMBER_OF_CALLEE_SAVES_REGISTERS > 0 … … 264 265 if (callee().isCell()) { 265 266 RELEASE_ASSERT(isWebAssemblyToJSCallee(callee().asCell())); 266 return nullptr;267 return WTF::nullopt; 267 268 } 268 269 Wasm::Callee* wasmCallee = callee().asWasmCallee(); 269 return wasmCallee->calleeSaveRegisters(); 270 return *wasmCallee->calleeSaveRegisters(); 271 } 272 273 if (callee().isCell()) { 274 if (auto* jsToWasmICCallee = jsDynamicCast<JSToWasmICCallee*>(*callee().asCell()->vm(), callee().asCell())) 275 return jsToWasmICCallee->function()->usedCalleeSaveRegisters(); 270 276 } 271 277 #endif // ENABLE(WEBASSEMBLY) 272 278 273 279 if (CodeBlock* codeBlock = this->codeBlock()) 274 return codeBlock->calleeSaveRegisters();280 return *codeBlock->calleeSaveRegisters(); 275 281 276 282 #endif // !ENABLE(C_LOOP) && NUMBER_OF_CALLEE_SAVES_REGISTERS > 0 277 283 278 return nullptr;284 return WTF::nullopt; 279 285 } 280 286 -
trunk/Source/JavaScriptCore/interpreter/StackVisitor.h
r243232 r243886 95 95 JS_EXPORT_PRIVATE void computeLineAndColumn(unsigned& line, unsigned& column) const; 96 96 97 const RegisterAtOffsetList* calleeSaveRegisters();97 Optional<RegisterAtOffsetList> calleeSaveRegistersForUnwinding(); 98 98 99 99 ClonedArguments* createArguments(); -
trunk/Source/JavaScriptCore/jit/JITOperations.cpp
r242991 r243886 77 77 #include "TypeProfilerLog.h" 78 78 #include "VMInlines.h" 79 #include "WebAssemblyFunction.h" 79 80 #include <wtf/InlineASM.h> 80 81 … … 1037 1038 MacroAssemblerCodePtr<JSEntryPtrTag> codePtr; 1038 1039 CodeBlock* codeBlock = nullptr; 1039 if (executable->isHostFunction()) 1040 codePtr = executable->entrypointFor(kind, MustCheckArity); 1041 else { 1040 if (executable->isHostFunction()) { 1041 codePtr = jsToWasmICCodePtr(*vm, kind, callee); 1042 if (!codePtr) 1043 codePtr = executable->entrypointFor(kind, MustCheckArity); 1044 } else { 1042 1045 FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable); 1043 1046 … … 1065 1068 codePtr = functionExecutable->entrypointFor(kind, arity); 1066 1069 } 1070 1067 1071 if (!callLinkInfo->seenOnce()) 1068 1072 callLinkInfo->setSeen(); -
trunk/Source/JavaScriptCore/jit/RegisterSet.cpp
r240432 r243886 59 59 } 60 60 61 RegisterSet RegisterSet::runtime Registers()61 RegisterSet RegisterSet::runtimeTagRegisters() 62 62 { 63 63 #if USE(JSVALUE64) … … 71 71 { 72 72 return RegisterSet( 73 stackRegisters(), reservedHardwareRegisters(), runtime Registers());73 stackRegisters(), reservedHardwareRegisters(), runtimeTagRegisters()); 74 74 } 75 75 -
trunk/Source/JavaScriptCore/jit/RegisterSet.h
r236381 r243886 51 51 JS_EXPORT_PRIVATE static RegisterSet stackRegisters(); 52 52 JS_EXPORT_PRIVATE static RegisterSet reservedHardwareRegisters(); 53 static RegisterSet runtime Registers();53 static RegisterSet runtimeTagRegisters(); 54 54 static RegisterSet specialRegisters(); // The union of stack, reserved hardware, and runtime registers. 55 55 JS_EXPORT_PRIVATE static RegisterSet calleeSaveRegisters(); -
trunk/Source/JavaScriptCore/jit/Repatch.cpp
r243626 r243886 976 976 list = stub->variants(); 977 977 else if (JSObject* oldCallee = callLinkInfo.callee()) 978 list = CallVariantList { CallVariant(oldCallee) };978 list = CallVariantList { CallVariant(oldCallee) }; 979 979 980 980 list = variantListWithVariant(list, newVariant); … … 1138 1138 if (variant.executable()) { 1139 1139 ASSERT(variant.executable()->hasJITCodeForCall()); 1140 codePtr = variant.executable()->generatedJITCodeForCall()->addressForCall(ArityCheckNotRequired); 1140 1141 codePtr = jsToWasmICCodePtr(vm, callLinkInfo.specializationKind(), variant.function()); 1142 if (!codePtr) 1143 codePtr = variant.executable()->generatedJITCodeForCall()->addressForCall(ArityCheckNotRequired); 1141 1144 } else { 1142 1145 ASSERT(variant.internalFunction()); … … 1278 1281 } 1279 1282 1283 MacroAssemblerCodePtr<JSEntryPtrTag> jsToWasmICCodePtr(VM& vm, CodeSpecializationKind kind, JSObject* callee) 1284 { 1285 #if ENABLE(WEBASSEMBLY) 1286 if (!callee) 1287 return nullptr; 1288 if (kind != CodeForCall) 1289 return nullptr; 1290 if (auto* wasmFunction = jsDynamicCast<WebAssemblyFunction*>(vm, callee)) 1291 return wasmFunction->jsCallEntrypoint(); 1292 #else 1293 UNUSED_PARAM(vm); 1294 UNUSED_PARAM(kind); 1295 UNUSED_PARAM(callee); 1296 #endif 1297 return nullptr; 1298 } 1299 1280 1300 } // namespace JSC 1281 1301 -
trunk/Source/JavaScriptCore/jit/Repatch.h
r232047 r243886 58 58 void resetInstanceOf(StructureStubInfo&); 59 59 void ftlThunkAwareRepatchCall(CodeBlock*, CodeLocationCall<JSInternalPtrTag>, FunctionPtr<CFunctionPtrTag> newCalleeFunction); 60 MacroAssemblerCodePtr<JSEntryPtrTag> jsToWasmICCodePtr(VM&, CodeSpecializationKind, JSObject* callee); 61 60 62 61 63 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/JSFunction.cpp
r242991 r243886 49 49 #include "PropertyNameArray.h" 50 50 #include "StackVisitor.h" 51 #include "WebAssemblyFunction.h" 51 52 52 53 namespace JSC { … … 628 629 String getCalculatedDisplayName(VM& vm, JSObject* object) 629 630 { 631 #if ENABLE(WEBASSEMBLY) 632 if (jsDynamicCast<JSToWasmICCallee*>(vm, object)) 633 return "wasm-stub"_s; 634 #endif 635 630 636 if (!jsDynamicCast<JSFunction*>(vm, object) && !jsDynamicCast<InternalFunction*>(vm, object)) 631 637 return emptyString(); 632 633 638 634 639 Structure* structure = object->structure(vm); -
trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
r243560 r243886 1054 1054 init.set(WebAssemblyFunction::createStructure(init.vm, init.owner, init.owner->m_functionPrototype.get())); 1055 1055 }); 1056 m_jsToWasmICCalleeStructure.initLater( 1057 [] (const Initializer<Structure>& init) { 1058 init.set(JSToWasmICCallee::createStructure(init.vm, init.owner, JSValue())); 1059 }); 1056 1060 m_webAssemblyWrapperFunctionStructure.initLater( 1057 1061 [] (const Initializer<Structure>& init) { … … 1752 1756 thisObject->m_webAssemblyModuleRecordStructure.visit(visitor); 1753 1757 thisObject->m_webAssemblyFunctionStructure.visit(visitor); 1758 thisObject->m_jsToWasmICCalleeStructure.visit(visitor); 1754 1759 thisObject->m_webAssemblyWrapperFunctionStructure.visit(visitor); 1755 1760 thisObject->m_webAssemblyToJSCalleeStructure.visit(visitor); -
trunk/Source/JavaScriptCore/runtime/JSGlobalObject.h
r243617 r243886 401 401 LazyProperty<JSGlobalObject, Structure> m_webAssemblyModuleRecordStructure; 402 402 LazyProperty<JSGlobalObject, Structure> m_webAssemblyFunctionStructure; 403 LazyProperty<JSGlobalObject, Structure> m_jsToWasmICCalleeStructure; 403 404 LazyProperty<JSGlobalObject, Structure> m_webAssemblyWrapperFunctionStructure; 404 405 LazyProperty<JSGlobalObject, Structure> m_webAssemblyToJSCalleeStructure; … … 765 766 Structure* webAssemblyModuleRecordStructure() const { return m_webAssemblyModuleRecordStructure.get(this); } 766 767 Structure* webAssemblyFunctionStructure() const { return m_webAssemblyFunctionStructure.get(this); } 768 Structure* jsToWasmICCalleeStructure() const { return m_jsToWasmICCalleeStructure.get(this); } 767 769 Structure* webAssemblyWrapperFunctionStructure() const { return m_webAssemblyWrapperFunctionStructure.get(this); } 768 770 Structure* webAssemblyToJSCalleeStructure() const { return m_webAssemblyToJSCalleeStructure.get(this); } -
trunk/Source/JavaScriptCore/runtime/VM.cpp
r243832 r243886 149 149 #include "WeakGCMapInlines.h" 150 150 #include "WebAssemblyFunction.h" 151 #include "WebAssemblyFunctionHeapCellType.h" 151 152 #include "WebAssemblyWrapperFunction.h" 152 153 #include <wtf/ProcessID.h> … … 281 282 #if ENABLE(WEBASSEMBLY) 282 283 , webAssemblyCodeBlockHeapCellType(std::make_unique<JSWebAssemblyCodeBlockHeapCellType>()) 284 , webAssemblyFunctionHeapCellType(std::make_unique<WebAssemblyFunctionHeapCellType>()) 283 285 #endif 284 286 , primitiveGigacageAuxiliarySpace("Primitive Gigacage Auxiliary", heap, auxiliaryHeapCellType.get(), primitiveGigacageAllocator.get()) … … 1265 1267 #if ENABLE(WEBASSEMBLY) 1266 1268 DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(webAssemblyCodeBlockSpace, webAssemblyCodeBlockHeapCellType.get(), JSWebAssemblyCodeBlock) 1267 DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(webAssemblyFunctionSpace, cellHeapCellType.get(), WebAssemblyFunction)1269 DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(webAssemblyFunctionSpace, webAssemblyFunctionHeapCellType.get(), WebAssemblyFunction) 1268 1270 DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(webAssemblyWrapperFunctionSpace, cellHeapCellType.get(), WebAssemblyWrapperFunction) 1269 1271 #endif -
trunk/Source/JavaScriptCore/runtime/VM.h
r243832 r243886 159 159 class Watchpoint; 160 160 class WatchpointSet; 161 class WebAssemblyFunctionHeapCellType; 161 162 162 163 #if ENABLE(FTL_JIT) … … 338 339 #if ENABLE(WEBASSEMBLY) 339 340 std::unique_ptr<JSWebAssemblyCodeBlockHeapCellType> webAssemblyCodeBlockHeapCellType; 341 std::unique_ptr<WebAssemblyFunctionHeapCellType> webAssemblyFunctionHeapCellType; 340 342 #endif 341 343 -
trunk/Source/JavaScriptCore/wasm/WasmAirIRGenerator.cpp
r243514 r243886 681 681 682 682 if (mode != MemoryMode::Signaling) { 683 ASSERT(!pinnedRegs.sizeRegisters[0].sizeOffset); 684 m_memorySizeGPR = pinnedRegs.sizeRegisters[0].sizeRegister; 685 for (const PinnedSizeRegisterInfo& regInfo : pinnedRegs.sizeRegisters) 686 m_code.pinRegister(regInfo.sizeRegister); 683 m_memorySizeGPR = pinnedRegs.sizeRegister; 684 m_code.pinRegister(m_memorySizeGPR); 687 685 } 688 686 … … 824 822 RegisterSet clobbers; 825 823 clobbers.set(pinnedRegs->baseMemoryPointer); 826 for (auto info : pinnedRegs->sizeRegisters) 827 clobbers.set(info.sizeRegister); 824 clobbers.set(pinnedRegs->sizeRegister); 828 825 829 826 auto* patchpoint = addPatchpoint(B3::Void); … … 835 832 836 833 patchpoint->setGenerator([pinnedRegs] (CCallHelpers& jit, const B3::StackmapGenerationParams& params) { 837 GPRReg baseMemory = pinnedRegs->baseMemoryPointer; 838 const auto& sizeRegs = pinnedRegs->sizeRegisters; 839 ASSERT(sizeRegs.size() >= 1); 840 ASSERT(!sizeRegs[0].sizeOffset); // The following code assumes we start at 0, and calculates subsequent size registers relative to 0. 841 jit.loadPtr(CCallHelpers::Address(params[0].gpr(), Instance::offsetOfCachedMemorySize()), sizeRegs[0].sizeRegister); 842 jit.loadPtr(CCallHelpers::Address(params[0].gpr(), Instance::offsetOfCachedMemory()), baseMemory); 843 for (unsigned i = 1; i < sizeRegs.size(); ++i) 844 jit.add64(CCallHelpers::TrustedImm32(-sizeRegs[i].sizeOffset), sizeRegs[0].sizeRegister, sizeRegs[i].sizeRegister); 834 jit.loadPtr(CCallHelpers::Address(params[0].gpr(), Instance::offsetOfCachedMemorySize()), pinnedRegs->sizeRegister); 835 jit.loadPtr(CCallHelpers::Address(params[0].gpr(), Instance::offsetOfCachedMemory()), pinnedRegs->baseMemoryPointer); 845 836 }); 846 837 … … 1856 1847 GPRReg oldContextInstance = params[1].gpr(); 1857 1848 const PinnedRegisterInfo& pinnedRegs = PinnedRegisterInfo::get(); 1858 const auto& sizeRegs = pinnedRegs.sizeRegisters;1859 1849 GPRReg baseMemory = pinnedRegs.baseMemoryPointer; 1860 1850 ASSERT(newContextInstance != baseMemory); … … 1862 1852 jit.storePtr(baseMemory, CCallHelpers::Address(newContextInstance, Instance::offsetOfCachedStackLimit())); 1863 1853 jit.storeWasmContextInstance(newContextInstance); 1864 ASSERT(sizeRegs[0].sizeRegister != baseMemory);1865 1854 // FIXME: We should support more than one memory size register 1866 1855 // see: https://bugs.webkit.org/show_bug.cgi?id=162952 1867 ASSERT(sizeRegs.size() == 1); 1868 ASSERT(sizeRegs[0].sizeRegister != newContextInstance); 1869 ASSERT(!sizeRegs[0].sizeOffset); 1870 jit.loadPtr(CCallHelpers::Address(newContextInstance, Instance::offsetOfCachedMemorySize()), sizeRegs[0].sizeRegister); // Memory size. 1856 ASSERT(pinnedRegs.sizeRegister != newContextInstance); 1857 jit.loadPtr(CCallHelpers::Address(newContextInstance, Instance::offsetOfCachedMemorySize()), pinnedRegs.sizeRegister); // Memory size. 1871 1858 jit.loadPtr(CCallHelpers::Address(newContextInstance, Instance::offsetOfCachedMemory()), baseMemory); // Memory::void*. 1872 1859 }); -
trunk/Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp
r243163 r243886 347 347 348 348 if (mode != MemoryMode::Signaling) { 349 ASSERT(!pinnedRegs.sizeRegisters[0].sizeOffset); 350 m_memorySizeGPR = pinnedRegs.sizeRegisters[0].sizeRegister; 351 for (const PinnedSizeRegisterInfo& regInfo : pinnedRegs.sizeRegisters) 352 m_proc.pinRegister(regInfo.sizeRegister); 349 m_memorySizeGPR = pinnedRegs.sizeRegister; 350 m_proc.pinRegister(m_memorySizeGPR); 353 351 } 354 352 … … 470 468 RegisterSet clobbers; 471 469 clobbers.set(pinnedRegs->baseMemoryPointer); 472 for (auto info : pinnedRegs->sizeRegisters) 473 clobbers.set(info.sizeRegister); 470 clobbers.set(pinnedRegs->sizeRegister); 474 471 475 472 B3::PatchpointValue* patchpoint = block->appendNew<B3::PatchpointValue>(proc, B3::Void, origin()); … … 484 481 patchpoint->setGenerator([pinnedRegs] (CCallHelpers& jit, const B3::StackmapGenerationParams& params) { 485 482 GPRReg baseMemory = pinnedRegs->baseMemoryPointer; 486 const auto& sizeRegs = pinnedRegs->sizeRegisters; 487 ASSERT(sizeRegs.size() >= 1); 488 ASSERT(!sizeRegs[0].sizeOffset); // The following code assumes we start at 0, and calculates subsequent size registers relative to 0. 489 jit.loadPtr(CCallHelpers::Address(params[0].gpr(), Instance::offsetOfCachedMemorySize()), sizeRegs[0].sizeRegister); 483 jit.loadPtr(CCallHelpers::Address(params[0].gpr(), Instance::offsetOfCachedMemorySize()), pinnedRegs->sizeRegister); 490 484 jit.loadPtr(CCallHelpers::Address(params[0].gpr(), Instance::offsetOfCachedMemory()), baseMemory); 491 for (unsigned i = 1; i < sizeRegs.size(); ++i)492 jit.add64(CCallHelpers::TrustedImm32(-sizeRegs[i].sizeOffset), sizeRegs[0].sizeRegister, sizeRegs[i].sizeRegister);493 485 }); 494 486 } … … 1283 1275 GPRReg oldContextInstance = params[1].gpr(); 1284 1276 const PinnedRegisterInfo& pinnedRegs = PinnedRegisterInfo::get(); 1285 const auto& sizeRegs = pinnedRegs.sizeRegisters;1286 1277 GPRReg baseMemory = pinnedRegs.baseMemoryPointer; 1287 1278 ASSERT(newContextInstance != baseMemory); … … 1289 1280 jit.storePtr(baseMemory, CCallHelpers::Address(newContextInstance, Instance::offsetOfCachedStackLimit())); 1290 1281 jit.storeWasmContextInstance(newContextInstance); 1291 ASSERT( sizeRegs[0].sizeRegister != baseMemory);1282 ASSERT(pinnedRegs.sizeRegister != baseMemory); 1292 1283 // FIXME: We should support more than one memory size register 1293 1284 // see: https://bugs.webkit.org/show_bug.cgi?id=162952 1294 ASSERT(sizeRegs.size() == 1); 1295 ASSERT(sizeRegs[0].sizeRegister != newContextInstance); 1296 ASSERT(!sizeRegs[0].sizeOffset); 1297 jit.loadPtr(CCallHelpers::Address(newContextInstance, Instance::offsetOfCachedMemorySize()), sizeRegs[0].sizeRegister); // Memory size. 1285 ASSERT(pinnedRegs.sizeRegister != newContextInstance); 1286 jit.loadPtr(CCallHelpers::Address(newContextInstance, Instance::offsetOfCachedMemorySize()), pinnedRegs.sizeRegister); // Memory size. 1298 1287 jit.loadPtr(CCallHelpers::Address(newContextInstance, Instance::offsetOfCachedMemory()), baseMemory); // Memory::void*. 1299 1288 }); -
trunk/Source/JavaScriptCore/wasm/WasmBinding.cpp
r242100 r243886 49 49 GPRReg baseMemory = pinnedRegs.baseMemoryPointer; 50 50 ASSERT(baseMemory != scratch); 51 const auto& sizeRegs = pinnedRegs.sizeRegisters; 52 ASSERT(sizeRegs.size() >= 1); 53 ASSERT(sizeRegs[0].sizeRegister != baseMemory); 54 ASSERT(sizeRegs[0].sizeRegister != scratch); 55 GPRReg sizeRegAsScratch = sizeRegs[0].sizeRegister; 51 ASSERT(pinnedRegs.sizeRegister != baseMemory); 52 ASSERT(pinnedRegs.sizeRegister != scratch); 53 GPRReg sizeRegAsScratch = pinnedRegs.sizeRegister; 56 54 57 55 // B3's call codegen ensures that the JSCell is a WebAssemblyFunction. … … 68 66 // FIXME the following code assumes that all Wasm::Instance have the same pinned registers. https://bugs.webkit.org/show_bug.cgi?id=162952 69 67 // Set up the callee's baseMemory register as well as the memory size registers. 70 ASSERT(!sizeRegs[0].sizeOffset); // The following code assumes we start at 0, and calculates subsequent size registers relative to 0. 71 jit.loadPtr(JIT::Address(baseMemory, Wasm::Instance::offsetOfCachedMemorySize()), sizeRegs[0].sizeRegister); // Memory size. 68 jit.loadPtr(JIT::Address(baseMemory, Wasm::Instance::offsetOfCachedMemorySize()), pinnedRegs.sizeRegister); // Memory size. 72 69 jit.loadPtr(JIT::Address(baseMemory, Wasm::Instance::offsetOfCachedMemory()), baseMemory); // Wasm::Memory::void*. 73 for (unsigned i = 1; i < sizeRegs.size(); ++i) {74 ASSERT(sizeRegs[i].sizeRegister != baseMemory);75 ASSERT(sizeRegs[i].sizeRegister != scratch);76 jit.add64(JIT::TrustedImm32(-sizeRegs[i].sizeOffset), sizeRegs[0].sizeRegister, sizeRegs[i].sizeRegister);77 }78 70 79 71 // Tail call into the callee WebAssembly function. -
trunk/Source/JavaScriptCore/wasm/WasmContext.h
r224020 r243886 33 33 34 34 struct Context { 35 Instance* instance { nullptr };36 37 35 Instance* load() const; 38 36 void store(Instance*, void* softStackLimit); 39 37 40 38 static bool useFastTLS(); 39 40 Instance** pointerToInstance() 41 { 42 ASSERT(!useFastTLS()); 43 return &instance; 44 } 45 46 private: 47 Instance* instance { nullptr }; 41 48 }; 42 49 -
trunk/Source/JavaScriptCore/wasm/WasmContextInlines.h
r235989 r243886 56 56 inline void Context::store(Instance* inst, void* softStackLimit) 57 57 { 58 if (inst) 59 inst->setCachedStackLimit(softStackLimit); 60 58 61 #if ENABLE(FAST_TLS_JIT) 59 62 if (useFastTLS()) 60 63 _pthread_setspecific_direct(WTF_WASM_CONTEXT_KEY, bitwise_cast<void*>(inst)); 64 else 61 65 #endif 62 instance = inst; 63 if (instance) 64 instance->setCachedStackLimit(softStackLimit); 66 instance = inst; 65 67 } 66 68 -
trunk/Source/JavaScriptCore/wasm/WasmMemoryInformation.cpp
r235989 r243886 45 45 if (!remainingPinnedRegisters || RegisterSet::stackRegisters().get(reg)) 46 46 return; 47 if (RegisterSet::runtimeTagRegisters().get(reg)) { 48 // Since we don't need to, we currently don't pick from the tag registers to allow 49 // JS->Wasm stubs to freely use these registers. 50 return; 51 } 47 52 --remainingPinnedRegisters; 48 53 registers.append(gpr); … … 56 61 static std::once_flag staticPinnedRegisterInfoFlag; 57 62 std::call_once(staticPinnedRegisterInfoFlag, [] () { 58 Vector<PinnedSizeRegisterInfo> sizeRegisters; 59 GPRReg baseMemoryPointer = InvalidGPRReg; 60 GPRReg wasmContextInstancePointer = InvalidGPRReg; 61 62 // FIXME: We should support more than one memory size register, and we should allow different 63 // WebAssembly.Instance to have different pins. Right now we take a vector with only one entry. 64 // If we have more than one size register, we can have one for each load size class. 65 // see: https://bugs.webkit.org/show_bug.cgi?id=162952 66 Vector<unsigned> pinnedSizes = { 0 }; 67 unsigned numberOfPinnedRegisters = pinnedSizes.size() + 1; 63 unsigned numberOfPinnedRegisters = 2; 68 64 if (!Context::useFastTLS()) 69 65 ++numberOfPinnedRegisters; 70 66 Vector<GPRReg> pinnedRegs = getPinnedRegisters(numberOfPinnedRegisters); 71 67 72 baseMemoryPointer = pinnedRegs.takeLast(); 68 GPRReg baseMemoryPointer = pinnedRegs.takeLast(); 69 GPRReg sizeRegister = pinnedRegs.takeLast(); 70 GPRReg wasmContextInstancePointer = InvalidGPRReg; 73 71 if (!Context::useFastTLS()) 74 72 wasmContextInstancePointer = pinnedRegs.takeLast(); 75 73 76 ASSERT(pinnedSizes.size() == pinnedRegs.size()); 77 for (unsigned i = 0; i < pinnedSizes.size(); ++i) 78 sizeRegisters.append({ pinnedRegs[i], pinnedSizes[i] }); 79 staticPinnedRegisterInfo.construct(WTFMove(sizeRegisters), baseMemoryPointer, wasmContextInstancePointer); 74 staticPinnedRegisterInfo.construct(sizeRegister, baseMemoryPointer, wasmContextInstancePointer); 80 75 }); 81 76 … … 83 78 } 84 79 85 PinnedRegisterInfo::PinnedRegisterInfo( Vector<PinnedSizeRegisterInfo>&& sizeRegisters, GPRReg baseMemoryPointer, GPRReg wasmContextInstancePointer)86 : sizeRegister s(WTFMove(sizeRegisters))80 PinnedRegisterInfo::PinnedRegisterInfo(GPRReg sizeRegister, GPRReg baseMemoryPointer, GPRReg wasmContextInstancePointer) 81 : sizeRegister(sizeRegister) 87 82 , baseMemoryPointer(baseMemoryPointer) 88 83 , wasmContextInstancePointer(wasmContextInstancePointer) -
trunk/Source/JavaScriptCore/wasm/WasmMemoryInformation.h
r237823 r243886 46 46 class PinnedRegisterInfo { 47 47 public: 48 PinnedRegisterInfo( Vector<PinnedSizeRegisterInfo>&&, GPRReg, GPRReg);48 PinnedRegisterInfo(GPRReg, GPRReg, GPRReg); 49 49 50 50 static const PinnedRegisterInfo& get(); … … 56 56 if (wasmContextInstancePointer != InvalidGPRReg) 57 57 result.set(wasmContextInstancePointer); 58 if (mode != MemoryMode::Signaling) { 59 for (const auto& info : sizeRegisters) 60 result.set(info.sizeRegister); 61 } 58 if (mode != MemoryMode::Signaling) 59 result.set(sizeRegister); 62 60 return result; 63 61 } 64 62 65 Vector<PinnedSizeRegisterInfo> sizeRegisters;63 GPRReg sizeRegister; 66 64 GPRReg baseMemoryPointer; 67 65 GPRReg wasmContextInstancePointer; -
trunk/Source/JavaScriptCore/wasm/WasmOMGPlan.cpp
r235786 r243886 139 139 LockHolder holder(m_codeBlock->m_lock); 140 140 141 auto repatchCalls = [&] (const Vector<UnlinkedWasmToWasmCall>& callsites) {141 auto repatchCalls = [&] (const Vector<UnlinkedWasmToWasmCall>& callsites) { 142 142 for (auto& call : callsites) { 143 143 dataLogLnIf(WasmOMGPlanInternal::verbose, "Considering repatching call at: ", RawPointer(call.callLocation.dataLocation()), " that targets ", call.functionIndexSpace); -
trunk/Source/JavaScriptCore/wasm/js/JSToWasm.cpp
r242123 r243886 214 214 215 215 GPRReg currentInstanceGPR = Context::useFastTLS() ? baseMemory : wasmContextInstanceGPR; 216 if (mode != MemoryMode::Signaling) { 217 const auto& sizeRegs = pinnedRegs.sizeRegisters; 218 ASSERT(sizeRegs.size() >= 1); 219 ASSERT(!sizeRegs[0].sizeOffset); // The following code assumes we start at 0, and calculates subsequent size registers relative to 0. 220 jit.loadPtr(CCallHelpers::Address(currentInstanceGPR, Wasm::Instance::offsetOfCachedMemorySize()), sizeRegs[0].sizeRegister); 221 for (unsigned i = 1; i < sizeRegs.size(); ++i) 222 jit.add64(CCallHelpers::TrustedImm32(-sizeRegs[i].sizeOffset), sizeRegs[0].sizeRegister, sizeRegs[i].sizeRegister); 223 } 216 if (mode != MemoryMode::Signaling) 217 jit.loadPtr(CCallHelpers::Address(currentInstanceGPR, Wasm::Instance::offsetOfCachedMemorySize()), pinnedRegs.sizeRegister); 224 218 225 219 jit.loadPtr(CCallHelpers::Address(currentInstanceGPR, Wasm::Instance::offsetOfCachedMemory()), baseMemory); -
trunk/Source/JavaScriptCore/wasm/js/JSToWasmICCallee.cpp
r243885 r243886 1 1 /* 2 * Copyright (C) 2016 Apple Inc. All rights reserved. 3 * Copyright (C) 2018 Oleksandr Skachkov <gskachkov@gmail.com>. 2 * Copyright (C) 2019 Apple Inc. All rights reserved. 4 3 * 5 4 * Redistribution and use in source and binary forms, with or without … … 25 24 */ 26 25 27 #pragma once 26 #include "config.h" 27 #include "JSToWasmICCallee.h" 28 28 29 29 #if ENABLE(WEBASSEMBLY) 30 30 31 #include "JSDestructibleObject.h" 32 #include "JSObject.h" 31 #include "WebAssemblyFunction.h" 33 32 34 33 namespace JSC { 35 34 36 class WebAssemblyPrototype final : public JSNonFinalObject { 37 public: 38 typedef JSNonFinalObject Base; 39 static const unsigned StructureFlags = Base::StructureFlags | HasStaticPropertyTable; 35 const ClassInfo JSToWasmICCallee::s_info = { "JSToWasmICCallee", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSToWasmICCallee) }; 40 36 41 static WebAssemblyPrototype* create(VM&, JSGlobalObject*, Structure*); 42 static Structure* createStructure(VM&, JSGlobalObject*, JSValue); 43 JS_EXPORT_PRIVATE static void webAssemblyModuleValidateAsync(ExecState*, JSPromiseDeferred*, Vector<uint8_t>&&); 44 JS_EXPORT_PRIVATE static void webAssemblyModuleInstantinateAsync(ExecState*, JSPromiseDeferred*, Vector<uint8_t>&&, JSObject*); 37 JSToWasmICCallee* JSToWasmICCallee::create(VM& vm, JSGlobalObject* globalObject, WebAssemblyFunction* function) 38 { 39 auto* structure = globalObject->jsToWasmICCalleeStructure(); 40 JSToWasmICCallee* result = new (NotNull, allocateCell<JSToWasmICCallee>(vm.heap)) JSToWasmICCallee(vm, globalObject, structure); 41 result->finishCreation(vm); 42 result->m_function.set(vm, result, function); 43 return result; 44 } 45 45 46 DECLARE_INFO; 46 Structure* JSToWasmICCallee::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype) 47 { 48 return Structure::create(vm, globalObject, prototype, TypeInfo(JSCalleeType, StructureFlags), info()); 49 } 47 50 48 static JSValue instantiate(ExecState*, JSPromiseDeferred*, const Identifier&, JSValue); 51 void JSToWasmICCallee::visitChildren(JSCell* cell, SlotVisitor& visitor) 52 { 53 JSToWasmICCallee* thisObject = jsCast<JSToWasmICCallee*>(cell); 54 ASSERT_GC_OBJECT_INHERITS(thisObject, info()); 49 55 50 protected: 51 void finishCreation(VM&, JSGlobalObject*); 52 53 private: 54 WebAssemblyPrototype(VM&, Structure*); 55 }; 56 57 EncodedJSValue JSC_HOST_CALL webAssemblyCompileStreamingInternal(ExecState*); 58 EncodedJSValue JSC_HOST_CALL webAssemblyInstantiateStreamingInternal(ExecState*); 56 Base::visitChildren(thisObject, visitor); 57 visitor.append(thisObject->m_function); 58 } 59 59 60 60 } // namespace JSC -
trunk/Source/JavaScriptCore/wasm/js/JSToWasmICCallee.h
r243885 r243886 1 1 /* 2 * Copyright (C) 201 7Apple Inc. All rights reserved.2 * Copyright (C) 2019 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 26 26 #pragma once 27 27 28 #include "JSCallee.h" 29 30 namespace JSC { 31 28 32 #if ENABLE(WEBASSEMBLY) 29 33 30 namespace JSC { namespace Wasm { 34 class WebAssemblyFunction; 31 35 32 class Instance; 36 class JSToWasmICCallee : public JSCallee { 37 using Base = JSCallee; 38 public: 39 DECLARE_INFO; 33 40 34 struct Context { 35 Instance* instance { nullptr };41 static JSToWasmICCallee* create(VM&, JSGlobalObject*, WebAssemblyFunction*); 42 static Structure* createStructure(VM&, JSGlobalObject*, JSValue); 36 43 37 Instance* load() const; 38 void store(Instance*, void* softStackLimit); 44 WebAssemblyFunction* function() { return m_function.get(); } 39 45 40 static bool useFastTLS(); 46 private: 47 JSToWasmICCallee(VM& vm, JSGlobalObject* globalObject, Structure* structure) 48 : Base(vm, globalObject, structure) 49 { } 50 static void visitChildren(JSCell*, SlotVisitor&); 51 52 WriteBarrier<WebAssemblyFunction> m_function; 41 53 }; 42 54 43 } } // namespace JSC::Wasm 55 #endif // ENABLE(WEBASSEMBLY) 44 56 45 #endif // ENABLE(WEBASSEMBLY) 57 } // namespace JSC -
trunk/Source/JavaScriptCore/wasm/js/WebAssemblyFunction.cpp
r243051 r243886 37 37 #include "JSWebAssemblyRuntimeError.h" 38 38 #include "LLIntThunks.h" 39 #include "LinkBuffer.h" 39 40 #include "ProtoCallFrame.h" 40 41 #include "VM.h" 41 42 #include "WasmCallee.h" 43 #include "WasmCallingConvention.h" 42 44 #include "WasmContextInlines.h" 43 45 #include "WasmFormat.h" 44 46 #include "WasmMemory.h" 47 #include "WasmMemoryInformation.h" 48 #include "WasmModuleInformation.h" 45 49 #include "WasmSignatureInlines.h" 46 50 #include <wtf/FastTLS.h> … … 149 153 } 150 154 155 bool WebAssemblyFunction::useTagRegisters() const 156 { 157 const auto& signature = Wasm::SignatureInformation::get(signatureIndex()); 158 return signature.argumentCount() || signature.returnType() != Wasm::Void; 159 } 160 161 RegisterSet WebAssemblyFunction::calleeSaves() const 162 { 163 RegisterSet toSave = Wasm::PinnedRegisterInfo::get().toSave(instance()->memoryMode()); 164 if (useTagRegisters()) { 165 RegisterSet tagRegisters = RegisterSet::runtimeTagRegisters(); 166 // We rely on these being disjoint sets. 167 #if !ASSERT_DISABLED 168 for (Reg reg : tagRegisters) 169 ASSERT(!toSave.contains(reg)); 170 #endif 171 toSave.merge(tagRegisters); 172 } 173 return toSave; 174 } 175 176 RegisterAtOffsetList WebAssemblyFunction::usedCalleeSaveRegisters() const 177 { 178 return RegisterAtOffsetList { calleeSaves(), RegisterAtOffsetList::OffsetBaseType::FramePointerBased }; 179 } 180 181 ptrdiff_t WebAssemblyFunction::previousInstanceOffset() const 182 { 183 ptrdiff_t result = calleeSaves().numberOfSetRegisters() * sizeof(CPURegister); 184 result = -result - sizeof(CPURegister); 185 #if !ASSERT_DISABLED 186 ptrdiff_t minOffset = 1; 187 for (const RegisterAtOffset& regAtOffset : usedCalleeSaveRegisters()) { 188 ptrdiff_t offset = regAtOffset.offset(); 189 ASSERT(offset < 0); 190 minOffset = std::min(offset, minOffset); 191 } 192 ASSERT(minOffset - static_cast<ptrdiff_t>(sizeof(CPURegister)) == result); 193 #endif 194 return result; 195 } 196 197 Wasm::Instance* WebAssemblyFunction::previousInstance(CallFrame* callFrame) 198 { 199 ASSERT(callFrame->callee().rawPtr() == m_jsToWasmICCallee.get()); 200 auto* result = *bitwise_cast<Wasm::Instance**>(bitwise_cast<char*>(callFrame) + previousInstanceOffset()); 201 return result; 202 } 203 204 MacroAssemblerCodePtr<JSEntryPtrTag> WebAssemblyFunction::jsCallEntrypointSlow() 205 { 206 VM& vm = *this->vm(); 207 CCallHelpers jit; 208 209 const auto& signature = Wasm::SignatureInformation::get(signatureIndex()); 210 const auto& pinnedRegs = Wasm::PinnedRegisterInfo::get(); 211 RegisterAtOffsetList registersToSpill = usedCalleeSaveRegisters(); 212 213 auto& moduleInformation = instance()->instance().module().moduleInformation(); 214 215 unsigned totalFrameSize = registersToSpill.size() * sizeof(CPURegister); 216 totalFrameSize += sizeof(CPURegister); // Slot for the VM's previous wasm instance. 217 totalFrameSize += Wasm::WasmCallingConvention::headerSizeInBytes(); 218 totalFrameSize -= sizeof(CallerFrameAndPC); 219 220 unsigned numGPRs = 0; 221 unsigned numFPRs = 0; 222 bool argumentsIncludeI64 = false; 223 for (unsigned i = 0; i < signature.argumentCount(); i++) { 224 switch (signature.argument(i)) { 225 case Wasm::I64: 226 argumentsIncludeI64 = true; 227 break; 228 case Wasm::I32: 229 if (numGPRs >= Wasm::wasmCallingConvention().m_gprArgs.size()) 230 totalFrameSize += sizeof(CPURegister); 231 ++numGPRs; 232 break; 233 case Wasm::F32: 234 case Wasm::F64: 235 if (numFPRs >= Wasm::wasmCallingConvention().m_fprArgs.size()) 236 totalFrameSize += sizeof(CPURegister); 237 ++numFPRs; 238 break; 239 default: 240 RELEASE_ASSERT_NOT_REACHED(); 241 } 242 } 243 244 if (argumentsIncludeI64) 245 return nullptr; 246 247 totalFrameSize = WTF::roundUpToMultipleOf(stackAlignmentBytes(), totalFrameSize); 248 249 jit.emitFunctionPrologue(); 250 jit.subPtr(MacroAssembler::TrustedImm32(totalFrameSize), MacroAssembler::stackPointerRegister); 251 jit.store64(CCallHelpers::TrustedImm64(0), CCallHelpers::addressFor(CallFrameSlot::codeBlock)); 252 253 for (const RegisterAtOffset& regAtOffset : registersToSpill) { 254 GPRReg reg = regAtOffset.reg().gpr(); 255 ptrdiff_t offset = regAtOffset.offset(); 256 jit.storePtr(reg, CCallHelpers::Address(GPRInfo::callFrameRegister, offset)); 257 } 258 259 GPRReg scratchGPR = Wasm::wasmCallingConventionAir().prologueScratch(1); 260 GPRReg scratch2GPR = Wasm::wasmCallingConventionAir().prologueScratch(0); 261 jit.loadPtr(vm.addressOfSoftStackLimit(), scratch2GPR); 262 263 CCallHelpers::JumpList slowPath; 264 slowPath.append(jit.branchPtr(CCallHelpers::Above, MacroAssembler::stackPointerRegister, GPRInfo::callFrameRegister)); 265 slowPath.append(jit.branchPtr(CCallHelpers::Below, MacroAssembler::stackPointerRegister, scratch2GPR)); 266 267 // Ensure: 268 // argCountPlusThis - 1 >= signature.argumentCount() 269 // argCountPlusThis >= signature.argumentCount() + 1 270 // FIXME: We should handle mismatched arity 271 // https://bugs.webkit.org/show_bug.cgi?id=196564 272 slowPath.append(jit.branch32(CCallHelpers::Below, 273 CCallHelpers::payloadFor(CallFrameSlot::argumentCount), CCallHelpers::TrustedImm32(signature.argumentCount() + 1))); 274 275 if (useTagRegisters()) 276 jit.emitMaterializeTagCheckRegisters(); 277 278 // First we do stack slots for FPRs so we can use FPR argument registers as scratch. 279 // After that, we handle FPR argument registers. 280 // We also handle all GPR types here as we have GPR scratch registers. 281 { 282 CCallHelpers::Address calleeFrame = CCallHelpers::Address(MacroAssembler::stackPointerRegister, -static_cast<ptrdiff_t>(sizeof(CallerFrameAndPC))); 283 numGPRs = 0; 284 numFPRs = 0; 285 FPRReg scratchFPR = Wasm::wasmCallingConvention().m_fprArgs[0].fpr(); 286 287 ptrdiff_t jsOffset = CallFrameSlot::firstArgument * sizeof(EncodedJSValue); 288 289 ptrdiff_t wasmOffset = CallFrame::headerSizeInRegisters * sizeof(CPURegister); 290 for (unsigned i = 0; i < signature.argumentCount(); i++) { 291 switch (signature.argument(i)) { 292 case Wasm::I32: 293 jit.load64(CCallHelpers::Address(GPRInfo::callFrameRegister, jsOffset), scratchGPR); 294 slowPath.append(jit.branchIfNotInt32(scratchGPR)); 295 if (numGPRs >= Wasm::wasmCallingConvention().m_gprArgs.size()) { 296 jit.store32(scratchGPR, calleeFrame.withOffset(wasmOffset)); 297 wasmOffset += sizeof(CPURegister); 298 } else { 299 jit.zeroExtend32ToPtr(scratchGPR, Wasm::wasmCallingConvention().m_gprArgs[numGPRs].gpr()); 300 ++numGPRs; 301 } 302 break; 303 case Wasm::F32: 304 case Wasm::F64: 305 if (numFPRs >= Wasm::wasmCallingConvention().m_fprArgs.size()) { 306 jit.load64(CCallHelpers::Address(GPRInfo::callFrameRegister, jsOffset), scratchGPR); 307 slowPath.append(jit.branchIfNotNumber(scratchGPR)); 308 auto isInt32 = jit.branchIfInt32(scratchGPR); 309 if (signature.argument(i) == Wasm::F32) { 310 jit.unboxDouble(scratchGPR, scratchGPR, scratchFPR); 311 jit.convertDoubleToFloat(scratchFPR, scratchFPR); 312 jit.storeFloat(scratchFPR, calleeFrame.withOffset(wasmOffset)); 313 } else { 314 jit.add64(GPRInfo::tagTypeNumberRegister, scratchGPR, scratchGPR); 315 jit.store64(scratchGPR, calleeFrame.withOffset(wasmOffset)); 316 } 317 auto done = jit.jump(); 318 319 isInt32.link(&jit); 320 if (signature.argument(i) == Wasm::F32) { 321 jit.convertInt32ToFloat(scratchGPR, scratchFPR); 322 jit.storeFloat(scratchFPR, calleeFrame.withOffset(wasmOffset)); 323 } else { 324 jit.convertInt32ToDouble(scratchGPR, scratchFPR); 325 jit.storeDouble(scratchFPR, calleeFrame.withOffset(wasmOffset)); 326 } 327 done.link(&jit); 328 329 wasmOffset += sizeof(CPURegister); 330 } else 331 ++numFPRs; 332 break; 333 default: 334 RELEASE_ASSERT_NOT_REACHED(); 335 } 336 337 jsOffset += sizeof(EncodedJSValue); 338 } 339 } 340 341 // Now handle FPR arguments in registers. 342 { 343 numFPRs = 0; 344 ptrdiff_t jsOffset = CallFrameSlot::firstArgument * sizeof(EncodedJSValue); 345 for (unsigned i = 0; i < signature.argumentCount(); i++) { 346 switch (signature.argument(i)) { 347 case Wasm::F32: 348 case Wasm::F64: 349 if (numFPRs < Wasm::wasmCallingConvention().m_fprArgs.size()) { 350 FPRReg argFPR = Wasm::wasmCallingConvention().m_fprArgs[numFPRs].fpr(); 351 jit.load64(CCallHelpers::Address(GPRInfo::callFrameRegister, jsOffset), scratchGPR); 352 slowPath.append(jit.branchIfNotNumber(scratchGPR)); 353 auto isInt32 = jit.branchIfInt32(scratchGPR); 354 jit.unboxDouble(scratchGPR, scratchGPR, argFPR); 355 if (signature.argument(i) == Wasm::F32) 356 jit.convertDoubleToFloat(argFPR, argFPR); 357 auto done = jit.jump(); 358 359 isInt32.link(&jit); 360 if (signature.argument(i) == Wasm::F32) 361 jit.convertInt32ToFloat(scratchGPR, argFPR); 362 else 363 jit.convertInt32ToDouble(scratchGPR, argFPR); 364 365 done.link(&jit); 366 ++numFPRs; 367 } 368 break; 369 default: 370 break; 371 } 372 373 jsOffset += sizeof(EncodedJSValue); 374 } 375 } 376 377 // At this point, we're committed to doing a fast call. 378 379 if (Wasm::Context::useFastTLS()) 380 jit.loadWasmContextInstance(scratchGPR); 381 else 382 jit.loadPtr(vm.wasmContext.pointerToInstance(), scratchGPR); 383 ptrdiff_t previousInstanceOffset = this->previousInstanceOffset(); 384 jit.storePtr(scratchGPR, CCallHelpers::Address(GPRInfo::callFrameRegister, previousInstanceOffset)); 385 386 jit.move(CCallHelpers::TrustedImmPtr(&instance()->instance()), scratchGPR); 387 if (Wasm::Context::useFastTLS()) 388 jit.storeWasmContextInstance(scratchGPR); 389 else { 390 jit.move(scratchGPR, pinnedRegs.wasmContextInstancePointer); 391 jit.storePtr(scratchGPR, vm.wasmContext.pointerToInstance()); 392 } 393 // This contains the cached stack limit still. 394 jit.storePtr(scratch2GPR, CCallHelpers::Address(scratchGPR, Wasm::Instance::offsetOfCachedStackLimit())); 395 396 if (!!moduleInformation.memory) { 397 GPRReg baseMemory = pinnedRegs.baseMemoryPointer; 398 399 if (instance()->memoryMode() != Wasm::MemoryMode::Signaling) { 400 ASSERT(pinnedRegs.sizeRegister != scratchGPR); 401 jit.loadPtr(CCallHelpers::Address(scratchGPR, Wasm::Instance::offsetOfCachedMemorySize()), pinnedRegs.sizeRegister); 402 } 403 404 jit.loadPtr(CCallHelpers::Address(scratchGPR, Wasm::Instance::offsetOfCachedMemory()), baseMemory); 405 } 406 407 // We use this callee to indicate how to unwind past these types of frames: 408 // 1. We need to know where to get callee saves. 409 // 2. We need to know to restore the previous wasm context. 410 if (!m_jsToWasmICCallee) 411 m_jsToWasmICCallee.set(vm, this, JSToWasmICCallee::create(vm, globalObject(), this)); 412 jit.storePtr(CCallHelpers::TrustedImmPtr(m_jsToWasmICCallee.get()), CCallHelpers::addressFor(CallFrameSlot::callee)); 413 414 { 415 // FIXME: Currently we just do an indirect jump. But we should teach the Module 416 // how to repatch us: 417 // https://bugs.webkit.org/show_bug.cgi?id=196570 418 jit.loadPtr(entrypointLoadLocation(), scratchGPR); 419 jit.call(scratchGPR, WasmEntryPtrTag); 420 } 421 422 ASSERT(!RegisterSet::runtimeTagRegisters().contains(GPRInfo::nonPreservedNonReturnGPR)); 423 jit.loadPtr(CCallHelpers::Address(GPRInfo::callFrameRegister, previousInstanceOffset), GPRInfo::nonPreservedNonReturnGPR); 424 if (Wasm::Context::useFastTLS()) 425 jit.storeWasmContextInstance(GPRInfo::nonPreservedNonReturnGPR); 426 else 427 jit.storePtr(GPRInfo::nonPreservedNonReturnGPR, vm.wasmContext.pointerToInstance()); 428 429 switch (signature.returnType()) { 430 case Wasm::Void: 431 jit.moveTrustedValue(jsUndefined(), JSValueRegs { GPRInfo::returnValueGPR }); 432 break; 433 case Wasm::I32: 434 jit.zeroExtend32ToPtr(GPRInfo::returnValueGPR, GPRInfo::returnValueGPR); 435 jit.boxInt32(GPRInfo::returnValueGPR, JSValueRegs { GPRInfo::returnValueGPR }); 436 break; 437 case Wasm::F32: 438 jit.convertFloatToDouble(FPRInfo::returnValueFPR, FPRInfo::returnValueFPR); 439 FALLTHROUGH; 440 case Wasm::F64: { 441 jit.moveTrustedValue(jsNumber(pureNaN()), JSValueRegs { GPRInfo::returnValueGPR }); 442 auto isNaN = jit.branchIfNaN(FPRInfo::returnValueFPR); 443 jit.boxDouble(FPRInfo::returnValueFPR, JSValueRegs { GPRInfo::returnValueGPR }); 444 isNaN.link(&jit); 445 break; 446 } 447 case Wasm::I64: 448 case Wasm::Func: 449 case Wasm::Anyfunc: 450 return nullptr; 451 default: 452 break; 453 } 454 455 auto emitRestoreCalleeSaves = [&] { 456 for (const RegisterAtOffset& regAtOffset : registersToSpill) { 457 GPRReg reg = regAtOffset.reg().gpr(); 458 ASSERT(reg != GPRInfo::returnValueGPR); 459 ptrdiff_t offset = regAtOffset.offset(); 460 jit.loadPtr(CCallHelpers::Address(GPRInfo::callFrameRegister, offset), reg); 461 } 462 }; 463 464 emitRestoreCalleeSaves(); 465 466 jit.emitFunctionEpilogue(); 467 jit.ret(); 468 469 slowPath.link(&jit); 470 emitRestoreCalleeSaves(); 471 jit.move(CCallHelpers::TrustedImmPtr(this), GPRInfo::regT0); 472 jit.emitFunctionEpilogue(); 473 auto jumpToHostCallThunk = jit.jump(); 474 475 LinkBuffer linkBuffer(jit, nullptr, JITCompilationCanFail); 476 if (UNLIKELY(linkBuffer.didFailToAllocate())) 477 return nullptr; 478 479 linkBuffer.link(jumpToHostCallThunk, CodeLocationLabel<JSEntryPtrTag>(executable()->entrypointFor(CodeForCall, MustCheckArity).executableAddress())); 480 m_jsCallEntrypoint = FINALIZE_CODE(linkBuffer, WasmEntryPtrTag, "JS->Wasm IC"); 481 return m_jsCallEntrypoint.code(); 482 } 483 151 484 WebAssemblyFunction* WebAssemblyFunction::create(VM& vm, JSGlobalObject* globalObject, Structure* structure, unsigned length, const String& name, JSWebAssemblyInstance* instance, Wasm::Callee& jsEntrypoint, Wasm::WasmToWasmImportableFunction::LoadLocation wasmToWasmEntrypointLoadLocation, Wasm::SignatureIndex signatureIndex) 152 485 { … … 170 503 { } 171 504 505 void WebAssemblyFunction::visitChildren(JSCell* cell, SlotVisitor& visitor) 506 { 507 WebAssemblyFunction* thisObject = jsCast<WebAssemblyFunction*>(cell); 508 ASSERT_GC_OBJECT_INHERITS(thisObject, info()); 509 510 Base::visitChildren(thisObject, visitor); 511 visitor.append(thisObject->m_jsToWasmICCallee); 512 } 513 514 void WebAssemblyFunction::destroy(JSCell* cell) 515 { 516 static_cast<WebAssemblyFunction*>(cell)->WebAssemblyFunction::~WebAssemblyFunction(); 517 } 518 172 519 } // namespace JSC 173 520 -
trunk/Source/JavaScriptCore/wasm/js/WebAssemblyFunction.h
r243051 r243886 28 28 #if ENABLE(WEBASSEMBLY) 29 29 30 #include "JSToWasmICCallee.h" 30 31 #include "MacroAssemblerCodeRef.h" 31 32 #include "WasmCallee.h" … … 49 50 50 51 const static unsigned StructureFlags = Base::StructureFlags; 52 53 static const bool needsDestruction = true; 54 static void destroy(JSCell*); 51 55 52 56 template<typename CellType, SubspaceAccess mode> … … 75 79 static ptrdiff_t offsetOfEntrypointLoadLocation() { return OBJECT_OFFSETOF(WebAssemblyFunction, m_importableFunction) + WasmToWasmImportableFunction::offsetOfEntrypointLoadLocation(); } 76 80 81 MacroAssemblerCodePtr<JSEntryPtrTag> jsCallEntrypoint() 82 { 83 if (m_jsCallEntrypoint) 84 return m_jsCallEntrypoint.code(); 85 return jsCallEntrypointSlow(); 86 } 87 88 RegisterAtOffsetList usedCalleeSaveRegisters() const; 89 Wasm::Instance* previousInstance(CallFrame*); 90 77 91 private: 92 static void visitChildren(JSCell*, SlotVisitor&); 78 93 WebAssemblyFunction(VM&, JSGlobalObject*, Structure*, Wasm::Callee& jsEntrypoint, WasmToWasmImportableFunction::LoadLocation entrypointLoadLocation, Wasm::SignatureIndex); 94 95 MacroAssemblerCodePtr<JSEntryPtrTag> jsCallEntrypointSlow(); 96 ptrdiff_t previousInstanceOffset() const; 97 bool useTagRegisters() const; 98 99 RegisterSet calleeSaves() const; 79 100 80 101 // It's safe to just hold the raw WasmToWasmImportableFunction/jsEntrypoint because we have a reference … … 83 104 MacroAssemblerCodePtr<WasmEntryPtrTag> m_jsEntrypoint; 84 105 WasmToWasmImportableFunction m_importableFunction; 106 WriteBarrier<JSToWasmICCallee> m_jsToWasmICCallee; 107 // Used for JS calling into Wasm. 108 MacroAssemblerCodeRef<JSEntryPtrTag> m_jsCallEntrypoint; 85 109 }; 86 110 -
trunk/Source/JavaScriptCore/wasm/js/WebAssemblyFunctionHeapCellType.cpp
r243885 r243886 1 1 /* 2 * Copyright (C) 201 7Apple Inc. All rights reserved.2 * Copyright (C) 2019 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 21 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 22 * (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. 24 24 */ 25 25 26 #pragma once 26 #include "config.h" 27 #include "WebAssemblyFunctionHeapCellType.h" 27 28 28 29 #if ENABLE(WEBASSEMBLY) 29 30 30 #include "Options.h" 31 #include "WasmContext.h" 32 #include "WasmInstance.h" 33 #include <mutex> 34 #include <wtf/FastTLS.h> 31 #include "JSCInlines.h" 32 #include "MarkedBlockInlines.h" 33 #include "WebAssemblyFunction.h" 35 34 36 namespace JSC { namespace Wasm {35 namespace JSC { 37 36 38 inline bool Context::useFastTLS() 37 struct WebAssemblyFunctionDestroyFunc { 38 ALWAYS_INLINE void operator()(VM&, JSCell* cell) const 39 { 40 static_assert(std::is_final<WebAssemblyFunction>::value, "Otherwise, this code would not be correct."); 41 WebAssemblyFunction::info()->methodTable.destroy(cell); 42 } 43 }; 44 45 WebAssemblyFunctionHeapCellType::WebAssemblyFunctionHeapCellType() 46 : HeapCellType(CellAttributes(NeedsDestruction, HeapCell::JSCell)) 39 47 { 40 #if ENABLE(FAST_TLS_JIT)41 return Options::useFastTLSForWasmContext();42 #else43 return false;44 #endif45 48 } 46 49 47 inline Instance* Context::load() const 50 WebAssemblyFunctionHeapCellType::~WebAssemblyFunctionHeapCellType() 48 51 { 49 #if ENABLE(FAST_TLS_JIT)50 if (useFastTLS())51 return bitwise_cast<Instance*>(_pthread_getspecific_direct(WTF_WASM_CONTEXT_KEY));52 #endif53 return instance;54 52 } 55 53 56 inline void Context::store(Instance* inst, void* softStackLimit)54 void WebAssemblyFunctionHeapCellType::finishSweep(MarkedBlock::Handle& handle, FreeList* freeList) 57 55 { 58 #if ENABLE(FAST_TLS_JIT) 59 if (useFastTLS()) 60 _pthread_setspecific_direct(WTF_WASM_CONTEXT_KEY, bitwise_cast<void*>(inst)); 61 #endif 62 instance = inst; 63 if (instance) 64 instance->setCachedStackLimit(softStackLimit); 56 handle.finishSweepKnowingHeapCellType(freeList, WebAssemblyFunctionDestroyFunc()); 65 57 } 66 58 67 } } // namespace JSC::Wasm 59 void WebAssemblyFunctionHeapCellType::destroy(VM& vm, JSCell* cell) 60 { 61 WebAssemblyFunctionDestroyFunc()(vm, cell); 62 } 63 64 } // namespace JSC 68 65 69 66 #endif // ENABLE(WEBASSEMBLY) -
trunk/Source/JavaScriptCore/wasm/js/WebAssemblyFunctionHeapCellType.h
r243885 r243886 1 1 /* 2 * Copyright (C) 201 7Apple Inc. All rights reserved.2 * Copyright (C) 2019 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 21 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 22 * (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. 24 24 */ 25 25 … … 28 28 #if ENABLE(WEBASSEMBLY) 29 29 30 namespace JSC { namespace Wasm { 30 #include "HeapCellType.h" 31 31 32 class Instance; 32 namespace JSC { 33 33 34 struct Context{35 Instance* instance { nullptr }; 36 37 Instance* load() const;38 void store(Instance*, void* softStackLimit);39 40 static bool useFastTLS();34 class WebAssemblyFunctionHeapCellType : public HeapCellType { 35 public: 36 WebAssemblyFunctionHeapCellType(); 37 virtual ~WebAssemblyFunctionHeapCellType(); 38 39 void finishSweep(MarkedBlock::Handle&, FreeList*) override; 40 void destroy(VM&, JSCell*) override; 41 41 }; 42 42 43 } } // namespace JSC::Wasm43 } // namespace JSC 44 44 45 45 #endif // ENABLE(WEBASSEMBLY) -
trunk/Source/JavaScriptCore/wasm/js/WebAssemblyPrototype.h
r231194 r243886 34 34 namespace JSC { 35 35 36 class JSPromiseDeferred; 37 36 38 class WebAssemblyPrototype final : public JSNonFinalObject { 37 39 public:
Note:
See TracChangeset
for help on using the changeset viewer.