Skip to content

Commit

Permalink
[JSC] Avoid Vector allocation if possible for Types etc. in Wasm parsers
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=260061
rdar://113733001

Reviewed by Alex Christensen.

We should use Vector<Type, 16> to avoid frequent allocation and deallocation of memory.
And we also use uncheckedAppend for pre-allocated Vector.

* Source/JavaScriptCore/wasm/WasmBBQJIT.cpp:
(JSC::Wasm::BBQJIT::emitCCall):
* Source/JavaScriptCore/wasm/WasmFunctionIPIntMetadataGenerator.cpp:
(JSC::Wasm::FunctionIPIntMetadataGenerator::addReturnData):
* Source/JavaScriptCore/wasm/WasmFunctionIPIntMetadataGenerator.h:
* Source/JavaScriptCore/wasm/WasmIPIntGenerator.cpp:
(JSC::Wasm::IPIntGenerator::addEndToUnreachable):
(JSC::Wasm::IPIntGenerator::addCallCommonData):
* Source/JavaScriptCore/wasm/WasmSectionParser.cpp:
(JSC::Wasm::SectionParser::parseFunctionType):
* Source/JavaScriptCore/wasm/WasmTypeDefinition.cpp:
(JSC::Wasm::TypeDefinition::replacePlaceholders const):
(JSC::Wasm::TypeInformation::typeDefinitionForFunction):
* Source/JavaScriptCore/wasm/WasmTypeDefinition.h:
* Source/JavaScriptCore/wasm/js/WebAssemblyTagConstructor.cpp:
(JSC::JSC_DEFINE_HOST_FUNCTION):

Canonical link: https://commits.webkit.org/266812@main
  • Loading branch information
Constellation committed Aug 11, 2023
1 parent 55c3d00 commit 3dcbd27
Show file tree
Hide file tree
Showing 8 changed files with 25 additions and 23 deletions.
14 changes: 8 additions & 6 deletions Source/JavaScriptCore/wasm/WasmBBQJIT.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7794,10 +7794,11 @@ class BBQJIT {
void emitCCall(Func function, const Vector<Value, N>& arguments)
{
// Currently, we assume the Wasm calling convention is the same as the C calling convention
Vector<Type, 1> resultTypes;
Vector<Type> argumentTypes;
Vector<Type, 16> resultTypes;
Vector<Type, 16> argumentTypes;
argumentTypes.reserveInitialCapacity(arguments.size());
for (const Value& value : arguments)
argumentTypes.append(Type { value.type(), 0u });
argumentTypes.uncheckedAppend(Type { value.type(), 0u });
RefPtr<TypeDefinition> functionType = TypeInformation::typeDefinitionForFunction(resultTypes, argumentTypes);
CallInformation callInfo = wasmCallingConvention().callInformationFor(*functionType, CallRole::Caller);
Checked<int32_t> calleeStackSize = WTF::roundUpToMultipleOf(stackAlignmentBytes(), callInfo.headerAndArgumentStackSizeInBytes);
Expand All @@ -7822,10 +7823,11 @@ class BBQJIT {
ASSERT(result.isTemp());

// Currently, we assume the Wasm calling convention is the same as the C calling convention
Vector<Type, 1> resultTypes = { Type { result.type(), 0u } };
Vector<Type> argumentTypes;
Vector<Type, 16> resultTypes = { Type { result.type(), 0u } };
Vector<Type, 16> argumentTypes;
argumentTypes.reserveInitialCapacity(arguments.size());
for (const Value& value : arguments)
argumentTypes.append(Type { value.type(), 0u });
argumentTypes.uncheckedAppend(Type { value.type(), 0u });
RefPtr<TypeDefinition> functionType = TypeInformation::typeDefinitionForFunction(resultTypes, argumentTypes);
CallInformation callInfo = wasmCallingConvention().callInformationFor(*functionType, CallRole::Caller);
Checked<int32_t> calleeStackSize = WTF::roundUpToMultipleOf(stackAlignmentBytes(), callInfo.headerAndArgumentStackSizeInBytes);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ void FunctionIPIntMetadataGenerator::addLEB128ConstantAndLengthForType(Type type
ASSERT_NOT_IMPLEMENTED_YET();
}

void FunctionIPIntMetadataGenerator::addReturnData(const Vector<Type>& types)
void FunctionIPIntMetadataGenerator::addReturnData(const Vector<Type, 16>& types)
{
size_t size = m_metadata.size();
m_returnMetadata = size;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ class FunctionIPIntMetadataGenerator {
void addRawValue(uint64_t value);
void addLEB128ConstantInt32AndLength(uint32_t value, uint32_t length);
void addLEB128ConstantAndLengthForType(Type, uint64_t value, uint32_t length);
void addReturnData(const Vector<Type>& types);
void addReturnData(const Vector<Type, 16>& types);

uint32_t m_functionIndex;
bool m_tailCallClobbersInstance { false };
Expand Down
4 changes: 2 additions & 2 deletions Source/JavaScriptCore/wasm/WasmIPIntGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1160,7 +1160,7 @@ PartialResult WARN_UNUSED_RETURN IPIntGenerator::addEndToUnreachable(ControlEntr

// Metadata = round up 8 bytes, one for each
m_metadata->m_bytecodeLength = m_parser->offset();
Vector<Type> types(entry.controlData.branchTargetArity());
Vector<Type, 16> types(entry.controlData.branchTargetArity());
for (size_t i = 0; i < entry.controlData.branchTargetArity(); ++i)
types[i] = entry.controlData.branchTargetType(i);
m_metadata->addReturnData(types);
Expand Down Expand Up @@ -1226,7 +1226,7 @@ void IPIntGenerator::addCallCommonData(const FunctionSignature& signature)
WRITE_TO_METADATA(extraMetadata + 6 + i * 2, locations[i], uint16_t);

// Returns
Vector<Type> returns(signature.returnCount());
Vector<Type, 16> returns(signature.returnCount());
for (size_t i = 0; i < signature.returnCount(); ++i)
returns[i] = signature.returnType(i);
m_metadata->addReturnData(returns);
Expand Down
8 changes: 4 additions & 4 deletions Source/JavaScriptCore/wasm/WasmSectionParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -779,25 +779,25 @@ auto SectionParser::parseFunctionType(uint32_t position, RefPtr<TypeDefinition>&
uint32_t argumentCount;
WASM_PARSER_FAIL_IF(!parseVarUInt32(argumentCount), "can't get Type's argument count at index ", position);
WASM_PARSER_FAIL_IF(argumentCount > maxFunctionParams, "argument count of Type at index ", position, " is too big ", argumentCount, " maximum ", maxFunctionParams);
Vector<Type> argumentTypes;
Vector<Type, 16> argumentTypes;
WASM_PARSER_FAIL_IF(!argumentTypes.tryReserveCapacity(argumentCount), "can't allocate enough memory for Type section's ", position, "th signature");

for (unsigned i = 0; i < argumentCount; ++i) {
Type argumentType;
WASM_PARSER_FAIL_IF(!parseValueType(m_info, argumentType), "can't get ", i, "th argument Type");
argumentTypes.append(argumentType);
argumentTypes.uncheckedAppend(argumentType);
}

uint32_t returnCount;
WASM_PARSER_FAIL_IF(!parseVarUInt32(returnCount), "can't get Type's return count at index ", position);
WASM_PARSER_FAIL_IF(returnCount > maxFunctionReturns, "return count of Type at index ", position, " is too big ", returnCount, " maximum ", maxFunctionReturns);

Vector<Type, 1> returnTypes;
Vector<Type, 16> returnTypes;
WASM_PARSER_FAIL_IF(!returnTypes.tryReserveCapacity(returnCount), "can't allocate enough memory for Type section's ", position, "th signature");
for (unsigned i = 0; i < returnCount; ++i) {
Type value;
WASM_PARSER_FAIL_IF(!parseValueType(m_info, value), "can't get ", i, "th Type's return value");
returnTypes.append(value);
returnTypes.uncheckedAppend(value);
}

functionSignature = TypeInformation::typeDefinitionForFunction(returnTypes, argumentTypes);
Expand Down
14 changes: 7 additions & 7 deletions Source/JavaScriptCore/wasm/WasmTypeDefinition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -423,10 +423,10 @@ const TypeDefinition& TypeDefinition::replacePlaceholders(TypeIndex projectee) c
{
if (is<FunctionSignature>()) {
const FunctionSignature* func = as<FunctionSignature>();
Vector<Type> newArguments;
Vector<Type, 1> newReturns;
newArguments.tryReserveCapacity(func->argumentCount());
newReturns.tryReserveCapacity(func->returnCount());
Vector<Type, 16> newArguments;
Vector<Type, 16> newReturns;
newArguments.reserveInitialCapacity(func->argumentCount());
newReturns.reserveInitialCapacity(func->returnCount());
for (unsigned i = 0; i < func->argumentCount(); ++i)
newArguments.uncheckedAppend(substitute(func->argumentType(i), projectee));
for (unsigned i = 0; i < func->returnCount(); ++i)
Expand Down Expand Up @@ -585,8 +585,8 @@ const TypeDefinition& TypeInformation::signatureForLLIntBuiltin(LLIntBuiltin bui
}

struct FunctionParameterTypes {
const Vector<Type, 1>& returnTypes;
const Vector<Type>& argumentTypes;
const Vector<Type, 16>& returnTypes;
const Vector<Type, 16>& argumentTypes;

static unsigned hash(const FunctionParameterTypes& params)
{
Expand Down Expand Up @@ -869,7 +869,7 @@ TypeInformation::TypeInformation()
m_Anyref_Externref = m_typeSet.template add<FunctionParameterTypes>(FunctionParameterTypes { { anyrefType() }, { externrefType() } }).iterator->key;
}

RefPtr<TypeDefinition> TypeInformation::typeDefinitionForFunction(const Vector<Type, 1>& results, const Vector<Type>& args)
RefPtr<TypeDefinition> TypeInformation::typeDefinitionForFunction(const Vector<Type, 16>& results, const Vector<Type, 16>& args)
{
if constexpr (ASSERT_ENABLED) {
ASSERT(!results.contains(Wasm::Types::Void));
Expand Down
2 changes: 1 addition & 1 deletion Source/JavaScriptCore/wasm/WasmTypeDefinition.h
Original file line number Diff line number Diff line change
Expand Up @@ -865,7 +865,7 @@ class TypeInformation {

static const TypeDefinition& signatureForLLIntBuiltin(LLIntBuiltin);

static RefPtr<TypeDefinition> typeDefinitionForFunction(const Vector<Type, 1>& returnTypes, const Vector<Type>& argumentTypes);
static RefPtr<TypeDefinition> typeDefinitionForFunction(const Vector<Type, 16>& returnTypes, const Vector<Type, 16>& argumentTypes);
static RefPtr<TypeDefinition> typeDefinitionForStruct(const Vector<FieldType>& fields);
static RefPtr<TypeDefinition> typeDefinitionForArray(FieldType);
static RefPtr<TypeDefinition> typeDefinitionForRecursionGroup(const Vector<TypeIndex>& types);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ JSC_DEFINE_HOST_FUNCTION(constructJSWebAssemblyTag, (JSGlobalObject* globalObjec
if (!signatureObject.isObject())
return throwVMTypeError(globalObject, scope, "WebAssembly.Tag constructor expects a tag type with the 'parameters' property."_s);

Vector<Wasm::Type> parameters;
Vector<Wasm::Type, 16> parameters;
forEachInIterable(globalObject, signatureObject, [&] (auto& vm, auto* globalObject, JSValue nextType) -> void {
auto scope = DECLARE_THROW_SCOPE(vm);

Expand Down

0 comments on commit 3dcbd27

Please sign in to comment.