WebAssembly: unique function signatures
authorjfbastien@apple.com <jfbastien@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 20 Dec 2016 18:54:33 +0000 (18:54 +0000)
committerjfbastien@apple.com <jfbastien@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 20 Dec 2016 18:54:33 +0000 (18:54 +0000)
commit4d5da9ad8d4fd1ee6fe72810a095514d9ee80be9
tree7d651441c9e08f204c2bb14165d9f13d9e485859
parent721b4ca1660c1e83b7ded941b635c623175ccc32
WebAssembly: unique function signatures
https://bugs.webkit.org/show_bug.cgi?id=165957
<rdar://problem/29735737>

Reviewed by Saam Barati.

JSTests:

* wasm/function-tests/table-basic.js: FIXME is now addressed,
though instance to instance calls still need work which bug
#165282 will address
(i.assert.eq.foo):
* wasm/js-api/unique-signature.js: Added.
(CallIndirectWithDuplicateSignatures):

Source/JavaScriptCore:

Signatures in a Module's Type section can be duplicated, we
therefore need to unique them so that call_indirect only needs to
do a single integer compare to check that a callee's Signature is
the same as the Signature declared at the call site. Without
uniquing we'd either trap when duplicate Signatures are used, or
we'd need to do multiple comparisons. This patch makes that narrow
usecase function correctly.

There's further complication when calling from wasm to
wasm, in which case the Signatures must also match. Such
cross-instance calls will be improved in bug #165282, but this
patch sets the groundwork for it:

- Signatures are now owned by SignatureInformation which lives on
  VM, and is shared by all Modules.
- When parsing a Module, a Signature is created for every Type
  entry, and then uniqued by SignatureInformation's adopt
  method. Duplicate Signatures are dropped and the previous
  SignatureIndex is returned, new Signatures are adopted and a new
  SignatureIndex is created.
- The SignatureIndex values are monotonic. 0 is used to represent
  invalid indices, which trap. This can only occur through Table.
- SignatureInformation is used while generating code to map a
  SignatureIndex back to the Signature* when return / argument
  information is needed. This is a simple lookup into a Vector. It
  isn't used at runtime.
- These Signatures live forever on VM because the bookkeeping
  likely isn't worth it. We may want to empty things out if all
  Modules die, this is tracked in bug #166037.
- We can further improve things by bit-packing SignatureIndex with
  Code*, which is tracked by bug #165511.

* CMakeLists.txt:
* JavaScriptCore.xcodeproj/project.pbxproj:
* runtime/VM.h: wasm signatures are uniqued here, but aren't accessed frequently (only during parsing) so indirection is fine
* wasm/WasmB3IRGenerator.cpp: use SignatureIndex instead of Signature* when appropriate, and when still using Signature* do so with its new API
(JSC::Wasm::createJSToWasmWrapper):
(JSC::Wasm::parseAndCompile):
* wasm/WasmBinding.cpp:
(JSC::Wasm::importStubGenerator): use SignatureIndex
* wasm/WasmBinding.h:
* wasm/WasmCallingConvention.h:
(JSC::Wasm::CallingConvention::loadArguments):
* wasm/WasmFormat.cpp: drive-by move of alloc/free functions to the implementation file, allows the .h file to drop an FastMalloc.h
(JSC::Wasm::Segment::create):
(JSC::Wasm::Segment::destroy):
(JSC::Wasm::Segment::createPtr):
* wasm/WasmFormat.h: move Signature to its own file
(JSC::Wasm::CallableFunction::CallableFunction):
* wasm/WasmFunctionParser.h:
(JSC::Wasm::FunctionParser<Context>::FunctionParser):
* wasm/WasmModuleParser.cpp:
* wasm/WasmModuleParser.h:
(JSC::Wasm::ModuleParser::ModuleParser):
* wasm/WasmParser.h:
(JSC::Wasm::Parser<SuccessType>::Parser):
* wasm/WasmPlan.cpp:
(JSC::Wasm::Plan::parseAndValidateModule):
(JSC::Wasm::Plan::run):
* wasm/WasmSignature.cpp: Added.
(JSC::Wasm::Signature::dump):
(JSC::Wasm::Signature::hash):
(JSC::Wasm::Signature::create):
(JSC::Wasm::Signature::createInvalid):
(JSC::Wasm::Signature::destroy):
(JSC::Wasm::SignatureInformation::~SignatureInformation):
(JSC::Wasm::SignatureInformation::adopt):
(JSC::Wasm::SignatureInformation::get):
* wasm/WasmSignature.h: Added.
(JSC::Wasm::Signature::Signature):
(JSC::Wasm::Signature::storage):
(JSC::Wasm::Signature::allocatedSize):
(JSC::Wasm::Signature::returnType):
(JSC::Wasm::Signature::returnCount):
(JSC::Wasm::Signature::argumentCount):
(JSC::Wasm::Signature::argument):
(JSC::Wasm::Signature::operator==):
(JSC::Wasm::SignatureHash::empty):
(JSC::Wasm::SignatureHash::deleted):
(JSC::Wasm::SignatureHash::SignatureHash):
(JSC::Wasm::SignatureHash::operator==):
(JSC::Wasm::SignatureHash::equal):
(JSC::Wasm::SignatureHash::hash):
(JSC::Wasm::SignatureHash::isHashTableDeletedValue):
* wasm/WasmValidate.cpp:
(JSC::Wasm::validateFunction):
* wasm/WasmValidate.h:
* wasm/js/JSWebAssemblyInstance.cpp:
(JSC::JSWebAssemblyInstance::create):
* wasm/js/JSWebAssemblyModule.h:
(JSC::JSWebAssemblyModule::signatureForFunctionIndexSpace):
* wasm/js/JSWebAssemblyTable.cpp:
(JSC::JSWebAssemblyTable::JSWebAssemblyTable):
(JSC::JSWebAssemblyTable::clearFunction):
(JSC::JSWebAssemblyTable::setFunction):
* wasm/js/WebAssemblyFunction.cpp:
(JSC::callWebAssemblyFunction):
(JSC::WebAssemblyFunction::call):
(JSC::WebAssemblyFunction::create):
(JSC::WebAssemblyFunction::WebAssemblyFunction):
(JSC::WebAssemblyFunction::finishCreation):
* wasm/js/WebAssemblyFunction.h:
(JSC::WebAssemblyFunction::signatureIndex):
* wasm/js/WebAssemblyModuleRecord.cpp:
(JSC::WebAssemblyModuleRecord::link):
(JSC::WebAssemblyModuleRecord::evaluate):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@210026 268f45cc-cd09-0410-ab3c-d52691b4dbfc
28 files changed:
JSTests/ChangeLog
JSTests/wasm/function-tests/table-basic.js
JSTests/wasm/js-api/unique-signature.js [new file with mode: 0644]
Source/JavaScriptCore/CMakeLists.txt
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
Source/JavaScriptCore/runtime/VM.h
Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp
Source/JavaScriptCore/wasm/WasmBinding.cpp
Source/JavaScriptCore/wasm/WasmBinding.h
Source/JavaScriptCore/wasm/WasmCallingConvention.h
Source/JavaScriptCore/wasm/WasmFormat.cpp
Source/JavaScriptCore/wasm/WasmFormat.h
Source/JavaScriptCore/wasm/WasmFunctionParser.h
Source/JavaScriptCore/wasm/WasmModuleParser.cpp
Source/JavaScriptCore/wasm/WasmModuleParser.h
Source/JavaScriptCore/wasm/WasmParser.h
Source/JavaScriptCore/wasm/WasmPlan.cpp
Source/JavaScriptCore/wasm/WasmSignature.cpp [new file with mode: 0644]
Source/JavaScriptCore/wasm/WasmSignature.h [new file with mode: 0644]
Source/JavaScriptCore/wasm/WasmValidate.cpp
Source/JavaScriptCore/wasm/WasmValidate.h
Source/JavaScriptCore/wasm/js/JSWebAssemblyInstance.cpp
Source/JavaScriptCore/wasm/js/JSWebAssemblyModule.h
Source/JavaScriptCore/wasm/js/JSWebAssemblyTable.cpp
Source/JavaScriptCore/wasm/js/WebAssemblyFunction.cpp
Source/JavaScriptCore/wasm/js/WebAssemblyFunction.h
Source/JavaScriptCore/wasm/js/WebAssemblyModuleRecord.cpp