Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (235785 => 235786)
--- trunk/Source/_javascript_Core/ChangeLog 2018-09-07 16:57:03 UTC (rev 235785)
+++ trunk/Source/_javascript_Core/ChangeLog 2018-09-07 17:29:04 UTC (rev 235786)
@@ -1,5 +1,67 @@
2018-09-07 Yusuke Suzuki <[email protected]>
+ [WebAssembly] Optimize JS to Wasm call by using pointer of Signature as SignatureIndex
+ https://bugs.webkit.org/show_bug.cgi?id=189401
+
+ Reviewed by Mark Lam.
+
+ SignatureInformation is a global repository for Signature to make Signature atomic.
+ It takes Ref<Signature>&& and generates SignatureIndex. And we get const Signature&
+ by using this SignatureIndex. However, converting SignatureIndex to const Signature&
+ always looks up a hash table. This is costly since JS to Wasm calls always use
+ Signature& to check types of arguments.
+
+ Instead of using this hash table, this patch uses a pointer of Signature as SignatureIndex.
+ This allows us to convert SignatureIndex to Signature by just casting it.
+
+ We also optimize SignatureInformation::singleton by making an accessor function inlined.
+ And we move ProtoCallFrame::init to the header since it's just setting values.
+
+ This change significantly optimizes JS to wasm calls (1e7 times) from 600ms to 320ms.
+
+ In the future, we can remove SignatureIndex by directly handling Ref<Signature>: adding
+ deref() of Signature which unregisters itself from SignatureInformation carefully. Or we can
+ make SignatureIndex uint32_t by introducing a mechanism similar to StructureID.
+
+ * _javascript_Core.xcodeproj/project.pbxproj:
+ * Sources.txt:
+ * interpreter/ProtoCallFrame.h:
+ (JSC::ProtoCallFrame::init):
+ * wasm/WasmB3IRGenerator.cpp:
+ (JSC::Wasm::B3IRGenerator::addCallIndirect):
+ * wasm/WasmBBQPlan.cpp:
+ * wasm/WasmFormat.h:
+ (JSC::Wasm::WasmToWasmImportableFunction::offsetOfSignatureIndex):
+ * wasm/WasmFunctionParser.h:
+ * wasm/WasmModule.h:
+ * wasm/WasmOMGPlan.cpp:
+ * wasm/WasmSectionParser.cpp:
+ (JSC::Wasm::SectionParser::parseType):
+ * wasm/WasmSignature.cpp:
+ (JSC::Wasm::SignatureInformation::adopt):
+ (JSC::Wasm::SignatureInformation::tryCleanup):
+ (JSC::Wasm::SignatureInformation::singleton): Deleted.
+ (JSC::Wasm::SignatureInformation::get): Deleted.
+ * wasm/WasmSignature.h:
+ (JSC::Wasm::Signature::index const):
+ (JSC::Wasm::SignatureHash::SignatureHash):
+ (JSC::Wasm::SignatureHash::hash):
+ (JSC::Wasm::SignatureHash::isHashTableDeletedValue const):
+ (JSC::Wasm::SignatureHash::empty): Deleted.
+ (JSC::Wasm::SignatureHash::deleted): Deleted.
+ * wasm/WasmSignatureInlines.h: Renamed from Source/_javascript_Core/interpreter/ProtoCallFrame.cpp.
+ (JSC::Wasm::SignatureInformation::singleton):
+ (JSC::Wasm::SignatureInformation::get):
+ * wasm/js/JSToWasm.cpp:
+ * wasm/js/JSWebAssemblyModule.h:
+ * wasm/js/WasmToJS.cpp:
+ (JSC::Wasm::wasmToJS):
+ * wasm/js/WebAssemblyFunction.cpp:
+ * wasm/js/WebAssemblyModuleRecord.cpp:
+ * wasm/js/WebAssemblyWrapperFunction.cpp:
+
+2018-09-07 Yusuke Suzuki <[email protected]>
+
[JSC] Put .throwStackOverflow code after the fast path in LLInt doVMEntry
https://bugs.webkit.org/show_bug.cgi?id=189410
Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (235785 => 235786)
--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2018-09-07 16:57:03 UTC (rev 235785)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2018-09-07 17:29:04 UTC (rev 235786)
@@ -1536,6 +1536,7 @@
AD5C36EC1F75AD7C000BCAAF /* WasmToJS.h in Headers */ = {isa = PBXBuildFile; fileRef = ADD09AEE1F5F623F001313C2 /* WasmToJS.h */; settings = {ATTRIBUTES = (Private, ); }; };
AD5C36EF1F7A263A000BCAAF /* WasmMemoryMode.h in Headers */ = {isa = PBXBuildFile; fileRef = AD5C36EE1F7A2629000BCAAF /* WasmMemoryMode.h */; settings = {ATTRIBUTES = (Private, ); }; };
AD7438C01E0457A400FD0C2A /* WasmSignature.h in Headers */ = {isa = PBXBuildFile; fileRef = AD7438BF1E04579200FD0C2A /* WasmSignature.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 4BAA07CEB81F49A296E02203 /* WasmSignatureInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 30A5F403F11C4F599CD596D5 /* WasmSignatureInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
AD7B4B2E1FA3E29800C9DF79 /* WasmNameSection.h in Headers */ = {isa = PBXBuildFile; fileRef = AD7B4B2D1FA3E28600C9DF79 /* WasmNameSection.h */; settings = {ATTRIBUTES = (Private, ); }; };
AD86A93E1AA4D88D002FE77F /* WeakGCMapInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = AD86A93D1AA4D87C002FE77F /* WeakGCMapInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
AD8FF3981EB5BDB20087FF82 /* WasmIndexOrName.h in Headers */ = {isa = PBXBuildFile; fileRef = AD8FF3951EB5BD850087FF82 /* WasmIndexOrName.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -3599,7 +3600,6 @@
65EA73620BAE35D1001BB560 /* CommonIdentifiers.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CommonIdentifiers.cpp; sourceTree = "<group>"; };
65EA73630BAE35D1001BB560 /* CommonIdentifiers.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CommonIdentifiers.h; sourceTree = "<group>"; };
65FB5115184EE8F800C12B70 /* ProtoCallFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProtoCallFrame.h; sourceTree = "<group>"; };
- 65FB5116184EE9BC00C12B70 /* ProtoCallFrame.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ProtoCallFrame.cpp; sourceTree = "<group>"; };
6A38CFA71E32B58B0060206F /* AsyncStackTrace.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AsyncStackTrace.cpp; sourceTree = "<group>"; };
6A38CFA81E32B58B0060206F /* AsyncStackTrace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AsyncStackTrace.h; sourceTree = "<group>"; };
6AD2CB4C19B9140100065719 /* DebuggerEvalEnabler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DebuggerEvalEnabler.h; sourceTree = "<group>"; };
@@ -4364,6 +4364,7 @@
AD5C36F01F7A26BF000BCAAF /* WasmMemoryMode.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WasmMemoryMode.cpp; sourceTree = "<group>"; };
AD7438BE1E04579200FD0C2A /* WasmSignature.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WasmSignature.cpp; sourceTree = "<group>"; };
AD7438BF1E04579200FD0C2A /* WasmSignature.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmSignature.h; sourceTree = "<group>"; };
+ 30A5F403F11C4F599CD596D5 /* WasmSignatureInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmSignatureInlines.h; sourceTree = "<group>"; };
AD7B4B2D1FA3E28600C9DF79 /* WasmNameSection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmNameSection.h; sourceTree = "<group>"; };
AD86A93D1AA4D87C002FE77F /* WeakGCMapInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeakGCMapInlines.h; sourceTree = "<group>"; };
AD8DD6CF1F67089F0004EB52 /* JSToWasm.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = JSToWasm.h; path = js/JSToWasm.h; sourceTree = "<group>"; };
@@ -5508,8 +5509,8 @@
796DAA2A1E89CCD6005DF24A /* CalleeBits.h */,
1429D8DB0ED2205B00B89619 /* CallFrame.cpp */,
1429D8DC0ED2205B00B89619 /* CallFrame.h */,
+ A7F869EC0F95C2EC00558697 /* CallFrameClosure.h */,
FEA3BBA7212B655800E93AD1 /* CallFrameInlines.h */,
- A7F869EC0F95C2EC00558697 /* CallFrameClosure.h */,
1429D85B0ED218E900B89619 /* CLoopStack.cpp */,
14D792640DAA03FB001A9F05 /* CLoopStack.h */,
A7C1EAEB17987AB600299DB2 /* CLoopStackInlines.h */,
@@ -5518,7 +5519,6 @@
1429D7D30ED2128200B89619 /* Interpreter.cpp */,
1429D77B0ED20D7300B89619 /* Interpreter.h */,
E39D9D841D39000600667282 /* InterpreterInlines.h */,
- 65FB5116184EE9BC00C12B70 /* ProtoCallFrame.cpp */,
65FB5115184EE8F800C12B70 /* ProtoCallFrame.h */,
149B24FF0D8AF6D1009CB8C7 /* Register.h */,
DC17E8131C9C7FD4008A6AB3 /* ShadowChicken.cpp */,
@@ -6362,6 +6362,7 @@
53F40E841D58F9770099A1B6 /* WasmSections.h */,
AD7438BE1E04579200FD0C2A /* WasmSignature.cpp */,
AD7438BF1E04579200FD0C2A /* WasmSignature.h */,
+ 30A5F403F11C4F599CD596D5 /* WasmSignatureInlines.h */,
E3A0531921342B670022EC14 /* WasmStreamingParser.cpp */,
E3A0531621342B660022EC14 /* WasmStreamingParser.h */,
AD5C36E31F69EC8B000BCAAF /* WasmTable.cpp */,
@@ -8444,7 +8445,6 @@
99DA00A31BD5993100F4575C /* builtins_generator.py in Headers */,
99DA00A41BD5993100F4575C /* builtins_model.py in Headers */,
99DA00A51BD5993100F4575C /* builtins_templates.py in Headers */,
- FEA3BBA8212B655900E93AD1 /* CallFrameInlines.h in Headers */,
41DEA1321B9F3163006D65DD /* BuiltinUtils.h in Headers */,
9E72940B190F0514001A91B5 /* BundlePath.h in Headers */,
0FB7F39715ED8E4600F167B2 /* Butterfly.h in Headers */,
@@ -8469,6 +8469,7 @@
0F64B27A1A7957B2006E4E66 /* CallEdge.h in Headers */,
796DAA2B1E89CCD6005DF24A /* CalleeBits.h in Headers */,
1429D8DE0ED2205B00B89619 /* CallFrame.h in Headers */,
+ FEA3BBA8212B655900E93AD1 /* CallFrameInlines.h in Headers */,
62EC9BB71B7EB07C00303AD1 /* CallFrameShuffleData.h in Headers */,
62D755D71B84FB4A001801FA /* CallFrameShuffler.h in Headers */,
0F0B83B114BCF71800885B4F /* CallLinkInfo.h in Headers */,
@@ -8759,6 +8760,7 @@
A70447EE17A0BD7000F5898E /* DumpContext.h in Headers */,
FE318FE01CAC982F00DFCC54 /* ECMAScriptSpecInternalFunctions.h in Headers */,
2A83638618D7D0EE0000EBCC /* EdenGCActivityCallback.h in Headers */,
+ FE086BCA2123DEFB003F2929 /* EntryFrame.h in Headers */,
2AD2EDFB19799E38004D6478 /* EnumerationMode.h in Headers */,
BC3046070E1F497F003232CF /* Error.h in Headers */,
BC02E90D0E1839DB000F9297 /* ErrorConstructor.h in Headers */,
@@ -9095,7 +9097,6 @@
978801411471AD920041B016 /* JSDateMath.h in Headers */,
C2A7F688160432D400F76B98 /* JSDestructibleObject.h in Headers */,
0F7DF13C1E2971130095951B /* JSDestructibleObjectHeapCellType.h in Headers */,
- FE086BCA2123DEFB003F2929 /* EntryFrame.h in Headers */,
FE384EE61ADDB7AD0055DE2C /* JSDollarVM.h in Headers */,
86E3C614167BABD7006D760A /* JSExport.h in Headers */,
A7B4ACAF1484C9CE00B38A36 /* JSExportMacros.h in Headers */,
@@ -9622,6 +9623,7 @@
E3A0531C21342B680022EC14 /* WasmSectionParser.h in Headers */,
53F40E851D58F9770099A1B6 /* WasmSections.h in Headers */,
AD7438C01E0457A400FD0C2A /* WasmSignature.h in Headers */,
+ 4BAA07CEB81F49A296E02203 /* WasmSignatureInlines.h in Headers */,
E3A0531A21342B680022EC14 /* WasmStreamingParser.h in Headers */,
AD5C36E61F69EC91000BCAAF /* WasmTable.h in Headers */,
5250D2D21E8DA05A0029A932 /* WasmThunks.h in Headers */,
Modified: trunk/Source/_javascript_Core/Sources.txt (235785 => 235786)
--- trunk/Source/_javascript_Core/Sources.txt 2018-09-07 16:57:03 UTC (rev 235785)
+++ trunk/Source/_javascript_Core/Sources.txt 2018-09-07 17:29:04 UTC (rev 235786)
@@ -587,7 +587,6 @@
interpreter/CLoopStack.cpp
interpreter/CallFrame.cpp
interpreter/Interpreter.cpp
-interpreter/ProtoCallFrame.cpp
interpreter/ShadowChicken.cpp
interpreter/StackVisitor.cpp
Deleted: trunk/Source/_javascript_Core/interpreter/ProtoCallFrame.cpp (235785 => 235786)
--- trunk/Source/_javascript_Core/interpreter/ProtoCallFrame.cpp 2018-09-07 16:57:03 UTC (rev 235785)
+++ trunk/Source/_javascript_Core/interpreter/ProtoCallFrame.cpp 2018-09-07 17:29:04 UTC (rev 235786)
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2013-2018 Apple Inc. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "ProtoCallFrame.h"
-
-#include "CodeBlock.h"
-#include "JSCInlines.h"
-#include "StackAlignment.h"
-
-namespace JSC {
-
-void ProtoCallFrame::init(CodeBlock* codeBlock, JSObject* callee, JSValue thisValue, int argCountIncludingThis, JSValue* otherArgs)
-{
- this->args = otherArgs;
- this->setCodeBlock(codeBlock);
- this->setCallee(callee);
- this->setArgumentCountIncludingThis(argCountIncludingThis);
- if (codeBlock && argCountIncludingThis < codeBlock->numParameters())
- this->hasArityMismatch = true;
- else
- this->hasArityMismatch = false;
-
- // Round up argCountIncludingThis to keep the stack frame size aligned.
- size_t paddedArgsCount = roundArgumentCountToAlignFrame(argCountIncludingThis);
- this->setPaddedArgCount(paddedArgsCount);
- this->clearCurrentVPC();
- this->setThisValue(thisValue);
-}
-
-} // namespace JSC
Modified: trunk/Source/_javascript_Core/interpreter/ProtoCallFrame.h (235785 => 235786)
--- trunk/Source/_javascript_Core/interpreter/ProtoCallFrame.h 2018-09-07 16:57:03 UTC (rev 235785)
+++ trunk/Source/_javascript_Core/interpreter/ProtoCallFrame.h 2018-09-07 17:29:04 UTC (rev 235786)
@@ -25,7 +25,9 @@
#pragma once
+#include "CodeBlock.h"
#include "Register.h"
+#include "StackAlignment.h"
#include <wtf/ForbidHeapAllocation.h>
namespace JSC {
@@ -73,4 +75,22 @@
}
};
+inline void ProtoCallFrame::init(CodeBlock* codeBlock, JSObject* callee, JSValue thisValue, int argCountIncludingThis, JSValue* otherArgs)
+{
+ this->args = otherArgs;
+ this->setCodeBlock(codeBlock);
+ this->setCallee(callee);
+ this->setArgumentCountIncludingThis(argCountIncludingThis);
+ if (codeBlock && argCountIncludingThis < codeBlock->numParameters())
+ this->hasArityMismatch = true;
+ else
+ this->hasArityMismatch = false;
+
+ // Round up argCountIncludingThis to keep the stack frame size aligned.
+ size_t paddedArgsCount = roundArgumentCountToAlignFrame(argCountIncludingThis);
+ this->setPaddedArgCount(paddedArgsCount);
+ this->clearCurrentVPC();
+ this->setThisValue(thisValue);
+}
+
} // namespace JSC
Modified: trunk/Source/_javascript_Core/wasm/WasmB3IRGenerator.cpp (235785 => 235786)
--- trunk/Source/_javascript_Core/wasm/WasmB3IRGenerator.cpp 2018-09-07 16:57:03 UTC (rev 235785)
+++ trunk/Source/_javascript_Core/wasm/WasmB3IRGenerator.cpp 2018-09-07 17:29:04 UTC (rev 235786)
@@ -59,6 +59,7 @@
#include "WasmMemory.h"
#include "WasmOMGPlan.h"
#include "WasmOpcodeOrigin.h"
+#include "WasmSignatureInlines.h"
#include "WasmThunks.h"
#include <limits>
#include <wtf/Optional.h>
@@ -1229,13 +1230,13 @@
// Check that the WasmToWasmImportableFunction is initialized. We trap if it isn't. An "invalid" SignatureIndex indicates it's not initialized.
// FIXME: when we have trap handlers, we can just let the call fail because Signature::invalidIndex is 0. https://bugs.webkit.org/show_bug.cgi?id=177210
- static_assert(sizeof(WasmToWasmImportableFunction::signatureIndex) == sizeof(uint32_t), "Load codegen assumes i32");
- ExpressionType calleeSignatureIndex = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, Int32, origin(), callableFunction, safeCast<int32_t>(OBJECT_OFFSETOF(WasmToWasmImportableFunction, signatureIndex)));
+ static_assert(sizeof(WasmToWasmImportableFunction::signatureIndex) == sizeof(uint64_t), "Load codegen assumes i64");
+ ExpressionType calleeSignatureIndex = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, Int64, origin(), callableFunction, safeCast<int32_t>(WasmToWasmImportableFunction::offsetOfSignatureIndex()));
{
CheckValue* check = m_currentBlock->appendNew<CheckValue>(m_proc, Check, origin(),
m_currentBlock->appendNew<Value>(m_proc, Equal, origin(),
calleeSignatureIndex,
- m_currentBlock->appendNew<Const32Value>(m_proc, origin(), Signature::invalidIndex)));
+ m_currentBlock->appendNew<Const64Value>(m_proc, origin(), Signature::invalidIndex)));
check->setGenerator([=] (CCallHelpers& jit, const B3::StackmapGenerationParams&) {
this->emitExceptionCheck(jit, ExceptionType::NullTableEntry);
@@ -1244,7 +1245,7 @@
// Check the signature matches the value we expect.
{
- ExpressionType expectedSignatureIndex = m_currentBlock->appendNew<Const32Value>(m_proc, origin(), SignatureInformation::get(signature));
+ ExpressionType expectedSignatureIndex = m_currentBlock->appendNew<Const64Value>(m_proc, origin(), SignatureInformation::get(signature));
CheckValue* check = m_currentBlock->appendNew<CheckValue>(m_proc, Check, origin(),
m_currentBlock->appendNew<Value>(m_proc, NotEqual, origin(), calleeSignatureIndex, expectedSignatureIndex));
Modified: trunk/Source/_javascript_Core/wasm/WasmBBQPlan.cpp (235785 => 235786)
--- trunk/Source/_javascript_Core/wasm/WasmBBQPlan.cpp 2018-09-07 16:57:03 UTC (rev 235785)
+++ trunk/Source/_javascript_Core/wasm/WasmBBQPlan.cpp 2018-09-07 17:29:04 UTC (rev 235786)
@@ -36,6 +36,7 @@
#include "WasmFaultSignalHandler.h"
#include "WasmMemory.h"
#include "WasmModuleParser.h"
+#include "WasmSignatureInlines.h"
#include "WasmTierUpCount.h"
#include "WasmValidate.h"
#include <wtf/DataLog.h>
Modified: trunk/Source/_javascript_Core/wasm/WasmFormat.h (235785 => 235786)
--- trunk/Source/_javascript_Core/wasm/WasmFormat.h 2018-09-07 16:57:03 UTC (rev 235785)
+++ trunk/Source/_javascript_Core/wasm/WasmFormat.h 2018-09-07 17:29:04 UTC (rev 235786)
@@ -276,6 +276,7 @@
// meant as fast lookup tables for these opcodes and do not own code.
struct WasmToWasmImportableFunction {
using LoadLocation = MacroAssemblerCodePtr<WasmEntryPtrTag>*;
+ static ptrdiff_t offsetOfSignatureIndex() { return OBJECT_OFFSETOF(WasmToWasmImportableFunction, signatureIndex); }
static ptrdiff_t offsetOfEntrypointLoadLocation() { return OBJECT_OFFSETOF(WasmToWasmImportableFunction, entrypointLoadLocation); }
// FIXME: Pack signature index and code pointer into one 64-bit value. See <https://bugs.webkit.org/show_bug.cgi?id=165511>.
Modified: trunk/Source/_javascript_Core/wasm/WasmFunctionParser.h (235785 => 235786)
--- trunk/Source/_javascript_Core/wasm/WasmFunctionParser.h 2018-09-07 16:57:03 UTC (rev 235785)
+++ trunk/Source/_javascript_Core/wasm/WasmFunctionParser.h 2018-09-07 17:29:04 UTC (rev 235786)
@@ -28,6 +28,7 @@
#if ENABLE(WEBASSEMBLY)
#include "WasmParser.h"
+#include "WasmSignatureInlines.h"
#include <wtf/DataLog.h>
namespace JSC { namespace Wasm {
Modified: trunk/Source/_javascript_Core/wasm/WasmModule.h (235785 => 235786)
--- trunk/Source/_javascript_Core/wasm/WasmModule.h 2018-09-07 16:57:03 UTC (rev 235785)
+++ trunk/Source/_javascript_Core/wasm/WasmModule.h 2018-09-07 17:29:04 UTC (rev 235786)
@@ -41,7 +41,7 @@
struct ModuleInformation;
class Plan;
-using SignatureIndex = uint32_t;
+using SignatureIndex = uint64_t;
class Module : public ThreadSafeRefCounted<Module> {
public:
Modified: trunk/Source/_javascript_Core/wasm/WasmOMGPlan.cpp (235785 => 235786)
--- trunk/Source/_javascript_Core/wasm/WasmOMGPlan.cpp 2018-09-07 16:57:03 UTC (rev 235785)
+++ trunk/Source/_javascript_Core/wasm/WasmOMGPlan.cpp 2018-09-07 17:29:04 UTC (rev 235786)
@@ -39,6 +39,7 @@
#include "WasmMachineThreads.h"
#include "WasmMemory.h"
#include "WasmNameSection.h"
+#include "WasmSignatureInlines.h"
#include "WasmValidate.h"
#include "WasmWorklist.h"
#include <wtf/DataLog.h>
Modified: trunk/Source/_javascript_Core/wasm/WasmSectionParser.cpp (235785 => 235786)
--- trunk/Source/_javascript_Core/wasm/WasmSectionParser.cpp 2018-09-07 16:57:03 UTC (rev 235785)
+++ trunk/Source/_javascript_Core/wasm/WasmSectionParser.cpp 2018-09-07 17:29:04 UTC (rev 235786)
@@ -34,6 +34,7 @@
#include "WasmNameSectionParser.h"
#include "WasmOps.h"
#include "WasmSections.h"
+#include "WasmSignatureInlines.h"
namespace JSC { namespace Wasm {
@@ -75,8 +76,7 @@
returnType = Type::Void;
signature->returnType() = returnType;
- std::pair<SignatureIndex, Ref<Signature>> result = SignatureInformation::adopt(WTFMove(signature));
- m_info->usedSignatures.uncheckedAppend(WTFMove(result.second));
+ m_info->usedSignatures.uncheckedAppend(SignatureInformation::adopt(WTFMove(signature)));
}
return { };
}
Modified: trunk/Source/_javascript_Core/wasm/WasmSignature.cpp (235785 => 235786)
--- trunk/Source/_javascript_Core/wasm/WasmSignature.cpp 2018-09-07 16:57:03 UTC (rev 235785)
+++ trunk/Source/_javascript_Core/wasm/WasmSignature.cpp 2018-09-07 17:29:04 UTC (rev 235786)
@@ -41,6 +41,9 @@
}
}
+SignatureInformation* SignatureInformation::theOne { nullptr };
+std::once_flag SignatureInformation::signatureInformationFlag;
+
String Signature::toString() const
{
String result(makeString(returnType()));
@@ -83,85 +86,33 @@
{
}
-SignatureInformation& SignatureInformation::singleton()
+Ref<Signature> SignatureInformation::adopt(Ref<Signature>&& signature)
{
- static SignatureInformation* theOne;
- static std::once_flag signatureInformationFlag;
- std::call_once(signatureInformationFlag, [] () {
- theOne = new SignatureInformation;
- });
-
- return *theOne;
-}
-
-std::pair<SignatureIndex, Ref<Signature>> SignatureInformation::adopt(Ref<Signature>&& signature)
-{
SignatureInformation& info = singleton();
LockHolder lock(info.m_lock);
- SignatureIndex nextValue = info.m_nextIndex;
- auto addResult = info.m_signatureMap.add(SignatureHash { signature.ptr() }, nextValue);
+ SignatureIndex nextValue = signature->index();
+ auto addResult = info.m_signatureSet.add(SignatureHash { signature.copyRef() });
if (addResult.isNewEntry) {
- ++info.m_nextIndex;
- RELEASE_ASSERT(info.m_nextIndex > nextValue); // crash on overflow.
- ASSERT(nextValue == addResult.iterator->value);
if (WasmSignatureInternal::verbose)
- dataLogLn("Adopt new signature ", signature.get(), " with index ", addResult.iterator->value, " hash: ", signature->hash());
-
- auto addResult = info.m_indexMap.add(nextValue, signature.copyRef());
- RELEASE_ASSERT(addResult.isNewEntry);
- ASSERT(info.m_indexMap.size() == info.m_signatureMap.size());
- return std::make_pair(nextValue, WTFMove(signature));
+ dataLogLn("Adopt new signature ", signature.get(), " with index ", nextValue, " hash: ", signature->hash());
+ return WTFMove(signature);
}
+ nextValue = addResult.iterator->key->index();
if (WasmSignatureInternal::verbose)
- dataLogLn("Existing signature ", signature.get(), " with index ", addResult.iterator->value, " hash: ", signature->hash());
- ASSERT(addResult.iterator->value != Signature::invalidIndex);
- ASSERT(info.m_indexMap.contains(addResult.iterator->value));
- return std::make_pair(addResult.iterator->value, Ref<Signature>(*info.m_indexMap.get(addResult.iterator->value)));
+ dataLogLn("Existing signature ", signature.get(), " with index ", nextValue, " hash: ", signature->hash());
+ return Ref<Signature>(*addResult.iterator->key);
}
-const Signature& SignatureInformation::get(SignatureIndex index)
-{
- ASSERT(index != Signature::invalidIndex);
- SignatureInformation& info = singleton();
- LockHolder lock(info.m_lock);
-
- return *info.m_indexMap.get(index);
-}
-
-SignatureIndex SignatureInformation::get(const Signature& signature)
-{
- SignatureInformation& info = singleton();
- LockHolder lock(info.m_lock);
-
- auto result = info.m_signatureMap.get(SignatureHash { &signature });
- ASSERT(result != Signature::invalidIndex);
- return result;
-}
-
void SignatureInformation::tryCleanup()
{
SignatureInformation& info = singleton();
LockHolder lock(info.m_lock);
- Vector<std::pair<SignatureIndex, Signature*>> toRemove;
- for (const auto& pair : info.m_indexMap) {
- const Ref<Signature>& signature = pair.value;
- if (signature->refCount() == 1) {
- // We're the only owner.
- toRemove.append(std::make_pair(pair.key, signature.ptr()));
- }
- }
- for (const auto& pair : toRemove) {
- bool removed = info.m_signatureMap.remove(SignatureHash { pair.second });
- ASSERT_UNUSED(removed, removed);
- removed = info.m_indexMap.remove(pair.first);
- ASSERT_UNUSED(removed, removed);
- }
- if (info.m_signatureMap.isEmpty()) {
- ASSERT(info.m_indexMap.isEmpty());
- info.m_nextIndex = Signature::firstValidIndex;
- }
+ info.m_signatureSet.removeIf([&] (auto& hash) {
+ const auto& signature = hash.key;
+ return signature->refCount() == 1;
+ });
}
} } // namespace JSC::Wasm
Modified: trunk/Source/_javascript_Core/wasm/WasmSignature.h (235785 => 235786)
--- trunk/Source/_javascript_Core/wasm/WasmSignature.h 2018-09-07 16:57:03 UTC (rev 235785)
+++ trunk/Source/_javascript_Core/wasm/WasmSignature.h 2018-09-07 17:29:04 UTC (rev 235786)
@@ -33,6 +33,7 @@
#include <cstring>
#include <wtf/CheckedArithmetic.h>
#include <wtf/HashMap.h>
+#include <wtf/HashSet.h>
#include <wtf/HashTraits.h>
#include <wtf/StdLibExtras.h>
#include <wtf/ThreadSafeRefCounted.h>
@@ -47,7 +48,7 @@
namespace Wasm {
using SignatureArgCount = uint32_t;
-using SignatureIndex = uint32_t;
+using SignatureIndex = uint64_t;
class Signature : public ThreadSafeRefCounted<Signature> {
WTF_MAKE_FAST_ALLOCATED;
@@ -81,6 +82,7 @@
return *storage(returnCount() + i);
}
Type argument(SignatureArgCount i) const { return const_cast<Signature*>(this)->argument(i); }
+ SignatureIndex index() const { return bitwise_cast<SignatureIndex>(this); }
WTF::String toString() const;
void dump(WTF::PrintStream& out) const;
@@ -102,7 +104,6 @@
// Signatures are uniqued and, for call_indirect, validated at runtime. Tables can create invalid SignatureIndex values which cause call_indirect to fail. We use 0 as the invalidIndex so that the codegen can easily test for it and trap, and we add a token invalid entry in SignatureInformation.
static const constexpr SignatureIndex invalidIndex = 0;
- static const constexpr SignatureIndex firstValidIndex = invalidIndex + 1;
private:
friend class SignatureInformation;
@@ -111,28 +112,21 @@
};
struct SignatureHash {
- const Signature* key;
- static const Signature* empty() { return nullptr; }
- static const Signature* deleted() { return reinterpret_cast<const Signature*>(1); }
- SignatureHash()
- : key(empty())
+ RefPtr<Signature> key { nullptr };
+ SignatureHash() = default;
+ explicit SignatureHash(Ref<Signature>&& key)
+ : key(WTFMove(key))
{
}
- explicit SignatureHash(const Signature* key)
- : key(key)
- {
- ASSERT(key != empty());
- ASSERT(key != deleted());
- }
explicit SignatureHash(WTF::HashTableDeletedValueType)
- : key(deleted())
+ : key(WTF::HashTableDeletedValue)
{
}
bool operator==(const SignatureHash& rhs) const { return equal(*this, rhs); }
static bool equal(const SignatureHash& lhs, const SignatureHash& rhs) { return lhs.key == rhs.key || (lhs.key && rhs.key && *lhs.key == *rhs.key); }
- static unsigned hash(const SignatureHash& signature) { return signature.key->hash(); }
+ static unsigned hash(const SignatureHash& signature) { return signature.key ? signature.key->hash() : 0; }
static const bool safeToCompareToEmptyOrDeleted = false;
- bool isHashTableDeletedValue() const { return key == deleted(); }
+ bool isHashTableDeletedValue() const { return key.isHashTableDeletedValue(); }
};
} } // namespace JSC::Wasm
@@ -165,16 +159,17 @@
public:
static SignatureInformation& singleton();
- static std::pair<SignatureIndex, Ref<Signature>> WARN_UNUSED_RETURN adopt(Ref<Signature>&&);
+ static Ref<Signature> WARN_UNUSED_RETURN adopt(Ref<Signature>&&);
static const Signature& WARN_UNUSED_RETURN get(SignatureIndex);
static SignatureIndex WARN_UNUSED_RETURN get(const Signature&);
static void tryCleanup();
private:
- HashMap<Wasm::SignatureHash, Wasm::SignatureIndex> m_signatureMap;
- HashMap<Wasm::SignatureIndex, Ref<Signature>> m_indexMap;
- SignatureIndex m_nextIndex { Signature::firstValidIndex };
+ HashSet<Wasm::SignatureHash> m_signatureSet;
Lock m_lock;
+
+ JS_EXPORT_PRIVATE static SignatureInformation* theOne;
+ JS_EXPORT_PRIVATE static std::once_flag signatureInformationFlag;
};
} } // namespace JSC::Wasm
Copied: trunk/Source/_javascript_Core/wasm/WasmSignatureInlines.h (from rev 235785, trunk/Source/_javascript_Core/interpreter/ProtoCallFrame.cpp) (0 => 235786)
--- trunk/Source/_javascript_Core/wasm/WasmSignatureInlines.h (rev 0)
+++ trunk/Source/_javascript_Core/wasm/WasmSignatureInlines.h 2018-09-07 17:29:04 UTC (rev 235786)
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2016-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2018 Yusuke Suzuki <[email protected]>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(WEBASSEMBLY)
+
+#include "WasmSignature.h"
+
+namespace JSC { namespace Wasm {
+
+inline SignatureInformation& SignatureInformation::singleton()
+{
+ std::call_once(signatureInformationFlag, [] () {
+ theOne = new SignatureInformation;
+ });
+ return *theOne;
+}
+
+inline const Signature& SignatureInformation::get(SignatureIndex index)
+{
+ ASSERT(index != Signature::invalidIndex);
+ return *bitwise_cast<const Signature*>(index);
+}
+
+inline SignatureIndex SignatureInformation::get(const Signature& signature)
+{
+ if (!ASSERT_DISABLED) {
+ SignatureInformation& info = singleton();
+ auto locker = holdLock(info.m_lock);
+ ASSERT_UNUSED(info, info.m_signatureSet.contains(SignatureHash { makeRef(const_cast<Signature&>(signature)) }));
+ }
+ return bitwise_cast<SignatureIndex>(&signature);
+}
+
+} } // namespace JSC::Wasm
+
+#endif // ENABLE(WEBASSEMBLY)
Modified: trunk/Source/_javascript_Core/wasm/js/JSToWasm.cpp (235785 => 235786)
--- trunk/Source/_javascript_Core/wasm/js/JSToWasm.cpp 2018-09-07 16:57:03 UTC (rev 235785)
+++ trunk/Source/_javascript_Core/wasm/js/JSToWasm.cpp 2018-09-07 17:29:04 UTC (rev 235786)
@@ -31,6 +31,7 @@
#include "CCallHelpers.h"
#include "JSWebAssemblyInstance.h"
#include "WasmCallingConvention.h"
+#include "WasmSignatureInlines.h"
namespace JSC { namespace Wasm {
Modified: trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyModule.h (235785 => 235786)
--- trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyModule.h 2018-09-07 16:57:03 UTC (rev 235785)
+++ trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyModule.h 2018-09-07 17:29:04 UTC (rev 235786)
@@ -43,7 +43,7 @@
class Module;
struct ModuleInformation;
class Plan;
-using SignatureIndex = uint32_t;
+using SignatureIndex = uint64_t;
}
class SymbolTable;
Modified: trunk/Source/_javascript_Core/wasm/js/WasmToJS.cpp (235785 => 235786)
--- trunk/Source/_javascript_Core/wasm/js/WasmToJS.cpp 2018-09-07 16:57:03 UTC (rev 235785)
+++ trunk/Source/_javascript_Core/wasm/js/WasmToJS.cpp 2018-09-07 17:29:04 UTC (rev 235786)
@@ -41,6 +41,7 @@
#include "WasmContext.h"
#include "WasmExceptionType.h"
#include "WasmInstance.h"
+#include "WasmSignatureInlines.h"
namespace JSC { namespace Wasm {
@@ -301,7 +302,8 @@
jit.move(CCallHelpers::TrustedImm32(0), GPRInfo::argumentGPR3);
static_assert(GPRInfo::numberOfArgumentRegisters >= 4, "We rely on this with the call below.");
- jit.setupArguments<decltype(callFunc)>(GPRInfo::argumentGPR1, CCallHelpers::TrustedImm32(signatureIndex), CCallHelpers::TrustedImmPtr(buffer));
+ static_assert(sizeof(SignatureIndex) == sizeof(uint64_t), "Following code assumes SignatureIndex is 64bit.");
+ jit.setupArguments<decltype(callFunc)>(GPRInfo::argumentGPR1, CCallHelpers::TrustedImm64(signatureIndex), CCallHelpers::TrustedImmPtr(buffer));
auto call = jit.call(OperationPtrTag);
auto noException = jit.emitExceptionCheck(*vm, AssemblyHelpers::InvertedExceptionCheck);
Modified: trunk/Source/_javascript_Core/wasm/js/WebAssemblyFunction.cpp (235785 => 235786)
--- trunk/Source/_javascript_Core/wasm/js/WebAssemblyFunction.cpp 2018-09-07 16:57:03 UTC (rev 235785)
+++ trunk/Source/_javascript_Core/wasm/js/WebAssemblyFunction.cpp 2018-09-07 17:29:04 UTC (rev 235786)
@@ -42,6 +42,7 @@
#include "WasmContext.h"
#include "WasmFormat.h"
#include "WasmMemory.h"
+#include "WasmSignatureInlines.h"
#include <wtf/FastTLS.h>
#include <wtf/SystemTracing.h>
Modified: trunk/Source/_javascript_Core/wasm/js/WebAssemblyModuleRecord.cpp (235785 => 235786)
--- trunk/Source/_javascript_Core/wasm/js/WebAssemblyModuleRecord.cpp 2018-09-07 16:57:03 UTC (rev 235785)
+++ trunk/Source/_javascript_Core/wasm/js/WebAssemblyModuleRecord.cpp 2018-09-07 17:29:04 UTC (rev 235786)
@@ -37,7 +37,7 @@
#include "JSWebAssemblyLinkError.h"
#include "JSWebAssemblyModule.h"
#include "ProtoCallFrame.h"
-#include "WasmSignature.h"
+#include "WasmSignatureInlines.h"
#include "WebAssemblyFunction.h"
#include <limits>
Modified: trunk/Source/_javascript_Core/wasm/js/WebAssemblyWrapperFunction.cpp (235785 => 235786)
--- trunk/Source/_javascript_Core/wasm/js/WebAssemblyWrapperFunction.cpp 2018-09-07 16:57:03 UTC (rev 235785)
+++ trunk/Source/_javascript_Core/wasm/js/WebAssemblyWrapperFunction.cpp 2018-09-07 17:29:04 UTC (rev 235786)
@@ -32,6 +32,7 @@
#include "FunctionPrototype.h"
#include "JSCInlines.h"
#include "JSWebAssemblyInstance.h"
+#include "WasmSignatureInlines.h"
namespace JSC {