Commit 9566a6e3 authored by Manos Koukoutos's avatar Manos Koukoutos Committed by V8 LUCI CQ

[wasm] Small refactoring for module types

Changes:
- Introduce {TypeDefinition} for wasm modules.
- Introduce an enum {TypeDefinition::Kind} to represent the three
  different definition types.
- Collapse the {types}, {type_kinds} and {supertypes} vectors into a
  single vector of {TypeDefinition}s.
- Use {TypeDefinition} in WasmModuleBuilder.
- Drive-by: Remove {kNullIndex} in WasmModuleBuilder.
- Drive-by: Tidy-up wasm-module.h.

Change-Id: I97c2c268bcad745176243c693cf169bfa5714f94
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3416233Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Commit-Queue: Manos Koukoutos <manoskouk@chromium.org>
Cr-Commit-Position: refs/heads/main@{#78813}
parent 36707481
...@@ -666,16 +666,16 @@ class ModuleDecoderImpl : public Decoder { ...@@ -666,16 +666,16 @@ class ModuleDecoderImpl : public Decoder {
errorf("type %d: cyclic inheritance", i); errorf("type %d: cyclic inheritance", i);
continue; continue;
} }
switch (module_->type_kinds[i]) { switch (module_->types[i].kind) {
case kWasmStructTypeCode: case TypeDefinition::kStruct:
if (!module->has_struct(explicit_super)) break; if (!module->has_struct(explicit_super)) break;
if (!StructIsSubtypeOf(i, explicit_super, module, module)) break; if (!StructIsSubtypeOf(i, explicit_super, module, module)) break;
continue; continue;
case kWasmArrayTypeCode: case TypeDefinition::kArray:
if (!module->has_array(explicit_super)) break; if (!module->has_array(explicit_super)) break;
if (!ArrayIsSubtypeOf(i, explicit_super, module, module)) break; if (!ArrayIsSubtypeOf(i, explicit_super, module, module)) break;
continue; continue;
case kWasmFunctionTypeCode: case TypeDefinition::kFunction:
if (!module->has_signature(explicit_super)) break; if (!module->has_signature(explicit_super)) break;
if (!FunctionIsSubtypeOf(i, explicit_super, module, module)) break; if (!FunctionIsSubtypeOf(i, explicit_super, module, module)) break;
continue; continue;
......
...@@ -230,14 +230,14 @@ void CreateMapForType(Isolate* isolate, const WasmModule* module, ...@@ -230,14 +230,14 @@ void CreateMapForType(Isolate* isolate, const WasmModule* module,
rtt_parent = handle(Map::cast(maps->get(supertype)), isolate); rtt_parent = handle(Map::cast(maps->get(supertype)), isolate);
} }
Handle<Map> map; Handle<Map> map;
switch (module->type_kinds[type_index]) { switch (module->types[type_index].kind) {
case kWasmStructTypeCode: case TypeDefinition::kStruct:
map = CreateStructMap(isolate, module, type_index, rtt_parent, instance); map = CreateStructMap(isolate, module, type_index, rtt_parent, instance);
break; break;
case kWasmArrayTypeCode: case TypeDefinition::kArray:
map = CreateArrayMap(isolate, module, type_index, rtt_parent, instance); map = CreateArrayMap(isolate, module, type_index, rtt_parent, instance);
break; break;
case kWasmFunctionTypeCode: case TypeDefinition::kFunction:
// TODO(7748): Create funcref RTTs lazily? // TODO(7748): Create funcref RTTs lazily?
// TODO(7748): Canonicalize function maps (cross-module)? // TODO(7748): Canonicalize function maps (cross-module)?
map = CreateFuncRefMap(isolate, module, rtt_parent, instance); map = CreateFuncRefMap(isolate, module, rtt_parent, instance);
...@@ -711,8 +711,8 @@ MaybeHandle<WasmInstanceObject> InstanceBuilder::Build() { ...@@ -711,8 +711,8 @@ MaybeHandle<WasmInstanceObject> InstanceBuilder::Build() {
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
if (enabled_.has_gc()) { if (enabled_.has_gc()) {
Handle<FixedArray> maps = isolate_->factory()->NewFixedArray( Handle<FixedArray> maps = isolate_->factory()->NewFixedArray(
static_cast<int>(module_->type_kinds.size())); static_cast<int>(module_->types.size()));
for (uint32_t index = 0; index < module_->type_kinds.size(); index++) { for (uint32_t index = 0; index < module_->types.size(); index++) {
CreateMapForType(isolate_, module_, index, instance, maps); CreateMapForType(isolate_, module_, index, instance, maps);
} }
instance->set_managed_object_maps(*maps); instance->set_managed_object_maps(*maps);
......
...@@ -58,7 +58,7 @@ void WasmFunctionBuilder::EmitI32V(int32_t val) { body_.write_i32v(val); } ...@@ -58,7 +58,7 @@ void WasmFunctionBuilder::EmitI32V(int32_t val) { body_.write_i32v(val); }
void WasmFunctionBuilder::EmitU32V(uint32_t val) { body_.write_u32v(val); } void WasmFunctionBuilder::EmitU32V(uint32_t val) { body_.write_u32v(val); }
void WasmFunctionBuilder::SetSignature(FunctionSig* sig) { void WasmFunctionBuilder::SetSignature(const FunctionSig* sig) {
DCHECK(!locals_.has_sig()); DCHECK(!locals_.has_sig());
locals_.set_sig(sig); locals_.set_sig(sig);
signature_index_ = builder_->AddSignature(sig); signature_index_ = builder_->AddSignature(sig);
...@@ -274,7 +274,7 @@ WasmModuleBuilder::WasmModuleBuilder(Zone* zone) ...@@ -274,7 +274,7 @@ WasmModuleBuilder::WasmModuleBuilder(Zone* zone)
has_max_memory_size_(false), has_max_memory_size_(false),
has_shared_memory_(false) {} has_shared_memory_(false) {}
WasmFunctionBuilder* WasmModuleBuilder::AddFunction(FunctionSig* sig) { WasmFunctionBuilder* WasmModuleBuilder::AddFunction(const FunctionSig* sig) {
functions_.push_back(zone_->New<WasmFunctionBuilder>(this)); functions_.push_back(zone_->New<WasmFunctionBuilder>(this));
// Add the signature if one was provided here. // Add the signature if one was provided here.
if (sig) functions_.back()->SetSignature(sig); if (sig) functions_.back()->SetSignature(sig);
...@@ -290,21 +290,22 @@ void WasmModuleBuilder::AddDataSegment(const byte* data, uint32_t size, ...@@ -290,21 +290,22 @@ void WasmModuleBuilder::AddDataSegment(const byte* data, uint32_t size,
} }
} }
uint32_t WasmModuleBuilder::ForceAddSignature(FunctionSig* sig, uint32_t WasmModuleBuilder::ForceAddSignature(const FunctionSig* sig,
uint32_t supertype) { uint32_t supertype) {
uint32_t index = static_cast<uint32_t>(types_.size()); uint32_t index = static_cast<uint32_t>(types_.size());
signature_map_.emplace(*sig, index); signature_map_.emplace(*sig, index);
types_.push_back(Type(sig, supertype)); types_.emplace_back(sig, supertype);
return index; return index;
} }
uint32_t WasmModuleBuilder::AddSignature(FunctionSig* sig, uint32_t supertype) { uint32_t WasmModuleBuilder::AddSignature(const FunctionSig* sig,
uint32_t supertype) {
auto sig_entry = signature_map_.find(*sig); auto sig_entry = signature_map_.find(*sig);
if (sig_entry != signature_map_.end()) return sig_entry->second; if (sig_entry != signature_map_.end()) return sig_entry->second;
return ForceAddSignature(sig, supertype); return ForceAddSignature(sig, supertype);
} }
uint32_t WasmModuleBuilder::AddException(FunctionSig* type) { uint32_t WasmModuleBuilder::AddException(const FunctionSig* type) {
DCHECK_EQ(0, type->return_count()); DCHECK_EQ(0, type->return_count());
int type_index = AddSignature(type); int type_index = AddSignature(type);
uint32_t except_index = static_cast<uint32_t>(exceptions_.size()); uint32_t except_index = static_cast<uint32_t>(exceptions_.size());
...@@ -315,20 +316,16 @@ uint32_t WasmModuleBuilder::AddException(FunctionSig* type) { ...@@ -315,20 +316,16 @@ uint32_t WasmModuleBuilder::AddException(FunctionSig* type) {
uint32_t WasmModuleBuilder::AddStructType(StructType* type, uint32_t WasmModuleBuilder::AddStructType(StructType* type,
uint32_t supertype) { uint32_t supertype) {
uint32_t index = static_cast<uint32_t>(types_.size()); uint32_t index = static_cast<uint32_t>(types_.size());
types_.push_back(Type(type, supertype)); types_.emplace_back(type, supertype);
return index; return index;
} }
uint32_t WasmModuleBuilder::AddArrayType(ArrayType* type, uint32_t supertype) { uint32_t WasmModuleBuilder::AddArrayType(ArrayType* type, uint32_t supertype) {
uint32_t index = static_cast<uint32_t>(types_.size()); uint32_t index = static_cast<uint32_t>(types_.size());
types_.push_back(Type(type, supertype)); types_.emplace_back(type, supertype);
return index; return index;
} }
// static
const uint32_t WasmModuleBuilder::kNullIndex =
std::numeric_limits<uint32_t>::max();
uint32_t WasmModuleBuilder::IncreaseTableMinSize(uint32_t table_index, uint32_t WasmModuleBuilder::IncreaseTableMinSize(uint32_t table_index,
uint32_t count) { uint32_t count) {
DCHECK_LT(table_index, tables_.size()); DCHECK_LT(table_index, tables_.size());
...@@ -600,11 +597,11 @@ void WasmModuleBuilder::WriteTo(ZoneBuffer* buffer) const { ...@@ -600,11 +597,11 @@ void WasmModuleBuilder::WriteTo(ZoneBuffer* buffer) const {
size_t start = EmitSection(kTypeSectionCode, buffer); size_t start = EmitSection(kTypeSectionCode, buffer);
buffer->write_size(types_.size()); buffer->write_size(types_.size());
for (const Type& type : types_) { for (const TypeDefinition& type : types_) {
bool has_super = type.supertype != kNoSuperType; bool has_super = type.supertype != kNoSuperType;
switch (type.kind) { switch (type.kind) {
case Type::kFunctionSig: { case TypeDefinition::kFunction: {
FunctionSig* sig = type.sig; const FunctionSig* sig = type.function_sig;
buffer->write_u8(has_super ? kWasmFunctionSubtypeCode buffer->write_u8(has_super ? kWasmFunctionSubtypeCode
: kWasmFunctionTypeCode); : kWasmFunctionTypeCode);
buffer->write_size(sig->parameter_count()); buffer->write_size(sig->parameter_count());
...@@ -622,8 +619,8 @@ void WasmModuleBuilder::WriteTo(ZoneBuffer* buffer) const { ...@@ -622,8 +619,8 @@ void WasmModuleBuilder::WriteTo(ZoneBuffer* buffer) const {
} }
break; break;
} }
case Type::kStructType: { case TypeDefinition::kStruct: {
StructType* struct_type = type.struct_type; const StructType* struct_type = type.struct_type;
buffer->write_u8(has_super ? kWasmStructSubtypeCode buffer->write_u8(has_super ? kWasmStructSubtypeCode
: kWasmStructTypeCode); : kWasmStructTypeCode);
buffer->write_size(struct_type->field_count()); buffer->write_size(struct_type->field_count());
...@@ -638,8 +635,8 @@ void WasmModuleBuilder::WriteTo(ZoneBuffer* buffer) const { ...@@ -638,8 +635,8 @@ void WasmModuleBuilder::WriteTo(ZoneBuffer* buffer) const {
} }
break; break;
} }
case Type::kArrayType: { case TypeDefinition::kArray: {
ArrayType* array_type = type.array_type; const ArrayType* array_type = type.array_type;
buffer->write_u8(has_super ? kWasmArraySubtypeCode buffer->write_u8(has_super ? kWasmArraySubtypeCode
: kWasmArrayTypeCode); : kWasmArrayTypeCode);
WriteValueType(buffer, array_type->element_type()); WriteValueType(buffer, array_type->element_type());
......
...@@ -166,7 +166,7 @@ class WasmModuleBuilder; ...@@ -166,7 +166,7 @@ class WasmModuleBuilder;
class V8_EXPORT_PRIVATE WasmFunctionBuilder : public ZoneObject { class V8_EXPORT_PRIVATE WasmFunctionBuilder : public ZoneObject {
public: public:
// Building methods. // Building methods.
void SetSignature(FunctionSig* sig); void SetSignature(const FunctionSig* sig);
uint32_t AddLocal(ValueType type); uint32_t AddLocal(ValueType type);
void EmitByte(byte b); void EmitByte(byte b);
void EmitI32V(int32_t val); void EmitI32V(int32_t val);
...@@ -208,7 +208,7 @@ class V8_EXPORT_PRIVATE WasmFunctionBuilder : public ZoneObject { ...@@ -208,7 +208,7 @@ class V8_EXPORT_PRIVATE WasmFunctionBuilder : public ZoneObject {
WasmModuleBuilder* builder() const { return builder_; } WasmModuleBuilder* builder() const { return builder_; }
uint32_t func_index() { return func_index_; } uint32_t func_index() { return func_index_; }
uint32_t sig_index() { return signature_index_; } uint32_t sig_index() { return signature_index_; }
inline FunctionSig* signature(); inline const FunctionSig* signature();
private: private:
explicit WasmFunctionBuilder(WasmModuleBuilder* builder); explicit WasmFunctionBuilder(WasmModuleBuilder* builder);
...@@ -311,7 +311,7 @@ class V8_EXPORT_PRIVATE WasmModuleBuilder : public ZoneObject { ...@@ -311,7 +311,7 @@ class V8_EXPORT_PRIVATE WasmModuleBuilder : public ZoneObject {
// Building methods. // Building methods.
uint32_t AddImport(base::Vector<const char> name, FunctionSig* sig, uint32_t AddImport(base::Vector<const char> name, FunctionSig* sig,
base::Vector<const char> module = {}); base::Vector<const char> module = {});
WasmFunctionBuilder* AddFunction(FunctionSig* sig = nullptr); WasmFunctionBuilder* AddFunction(const FunctionSig* sig = nullptr);
uint32_t AddGlobal(ValueType type, bool mutability = true, uint32_t AddGlobal(ValueType type, bool mutability = true,
WasmInitExpr init = WasmInitExpr()); WasmInitExpr init = WasmInitExpr());
uint32_t AddGlobalImport(base::Vector<const char> name, ValueType type, uint32_t AddGlobalImport(base::Vector<const char> name, ValueType type,
...@@ -332,11 +332,12 @@ class V8_EXPORT_PRIVATE WasmModuleBuilder : public ZoneObject { ...@@ -332,11 +332,12 @@ class V8_EXPORT_PRIVATE WasmModuleBuilder : public ZoneObject {
// exceeded. // exceeded.
uint32_t IncreaseTableMinSize(uint32_t table_index, uint32_t count); uint32_t IncreaseTableMinSize(uint32_t table_index, uint32_t count);
// Adds the signature to the module if it does not already exist. // Adds the signature to the module if it does not already exist.
uint32_t AddSignature(FunctionSig* sig, uint32_t supertype = kNoSuperType); uint32_t AddSignature(const FunctionSig* sig,
uint32_t supertype = kNoSuperType);
// Does not deduplicate function signatures. // Does not deduplicate function signatures.
uint32_t ForceAddSignature(FunctionSig* sig, uint32_t ForceAddSignature(const FunctionSig* sig,
uint32_t supertype = kNoSuperType); uint32_t supertype = kNoSuperType);
uint32_t AddException(FunctionSig* type); uint32_t AddException(const FunctionSig* type);
uint32_t AddStructType(StructType* type, uint32_t supertype = kNoSuperType); uint32_t AddStructType(StructType* type, uint32_t supertype = kNoSuperType);
uint32_t AddArrayType(ArrayType* type, uint32_t supertype = kNoSuperType); uint32_t AddArrayType(ArrayType* type, uint32_t supertype = kNoSuperType);
uint32_t AddTable(ValueType type, uint32_t min_size); uint32_t AddTable(ValueType type, uint32_t min_size);
...@@ -365,25 +366,27 @@ class V8_EXPORT_PRIVATE WasmModuleBuilder : public ZoneObject { ...@@ -365,25 +366,27 @@ class V8_EXPORT_PRIVATE WasmModuleBuilder : public ZoneObject {
ValueType GetTableType(uint32_t index) { return tables_[index].type; } ValueType GetTableType(uint32_t index) { return tables_[index].type; }
bool IsSignature(uint32_t index) { bool IsSignature(uint32_t index) {
return types_[index].kind == Type::kFunctionSig; return types_[index].kind == TypeDefinition::kFunction;
} }
FunctionSig* GetSignature(uint32_t index) { const FunctionSig* GetSignature(uint32_t index) {
DCHECK(types_[index].kind == Type::kFunctionSig); DCHECK(types_[index].kind == TypeDefinition::kFunction);
return types_[index].sig; return types_[index].function_sig;
} }
bool IsStructType(uint32_t index) { bool IsStructType(uint32_t index) {
return types_[index].kind == Type::kStructType; return types_[index].kind == TypeDefinition::kStruct;
} }
StructType* GetStructType(uint32_t index) { const StructType* GetStructType(uint32_t index) {
return types_[index].struct_type; return types_[index].struct_type;
} }
bool IsArrayType(uint32_t index) { bool IsArrayType(uint32_t index) {
return types_[index].kind == Type::kArrayType; return types_[index].kind == TypeDefinition::kArray;
}
const ArrayType* GetArrayType(uint32_t index) {
return types_[index].array_type;
} }
ArrayType* GetArrayType(uint32_t index) { return types_[index].array_type; }
WasmFunctionBuilder* GetFunction(uint32_t index) { return functions_[index]; } WasmFunctionBuilder* GetFunction(uint32_t index) { return functions_[index]; }
int NumExceptions() { return static_cast<int>(exceptions_.size()); } int NumExceptions() { return static_cast<int>(exceptions_.size()); }
...@@ -394,30 +397,11 @@ class V8_EXPORT_PRIVATE WasmModuleBuilder : public ZoneObject { ...@@ -394,30 +397,11 @@ class V8_EXPORT_PRIVATE WasmModuleBuilder : public ZoneObject {
int NumFunctions() { return static_cast<int>(functions_.size()); } int NumFunctions() { return static_cast<int>(functions_.size()); }
FunctionSig* GetExceptionType(int index) { const FunctionSig* GetExceptionType(int index) {
return types_[exceptions_[index]].sig; return types_[exceptions_[index]].function_sig;
} }
static const uint32_t kNullIndex;
private: private:
struct Type {
enum Kind { kFunctionSig, kStructType, kArrayType };
explicit Type(FunctionSig* signature, uint32_t supertype)
: kind(kFunctionSig), supertype(supertype), sig(signature) {}
explicit Type(StructType* struct_type, uint32_t supertype)
: kind(kStructType), supertype(supertype), struct_type(struct_type) {}
explicit Type(ArrayType* array_type, uint32_t supertype)
: kind(kArrayType), supertype(supertype), array_type(array_type) {}
Kind kind;
uint32_t supertype;
union {
FunctionSig* sig;
StructType* struct_type;
ArrayType* array_type;
};
};
struct WasmFunctionImport { struct WasmFunctionImport {
base::Vector<const char> module; base::Vector<const char> module;
base::Vector<const char> name; base::Vector<const char> name;
...@@ -460,7 +444,7 @@ class V8_EXPORT_PRIVATE WasmModuleBuilder : public ZoneObject { ...@@ -460,7 +444,7 @@ class V8_EXPORT_PRIVATE WasmModuleBuilder : public ZoneObject {
friend class WasmFunctionBuilder; friend class WasmFunctionBuilder;
Zone* zone_; Zone* zone_;
ZoneVector<Type> types_; ZoneVector<TypeDefinition> types_;
ZoneVector<WasmFunctionImport> function_imports_; ZoneVector<WasmFunctionImport> function_imports_;
ZoneVector<WasmGlobalImport> global_imports_; ZoneVector<WasmGlobalImport> global_imports_;
ZoneVector<WasmExport> exports_; ZoneVector<WasmExport> exports_;
...@@ -482,8 +466,8 @@ class V8_EXPORT_PRIVATE WasmModuleBuilder : public ZoneObject { ...@@ -482,8 +466,8 @@ class V8_EXPORT_PRIVATE WasmModuleBuilder : public ZoneObject {
#endif #endif
}; };
FunctionSig* WasmFunctionBuilder::signature() { const FunctionSig* WasmFunctionBuilder::signature() {
return builder_->types_[signature_index_].sig; return builder_->types_[signature_index_].function_sig;
} }
} // namespace wasm } // namespace wasm
......
...@@ -629,7 +629,7 @@ size_t EstimateStoredSize(const WasmModule* module) { ...@@ -629,7 +629,7 @@ size_t EstimateStoredSize(const WasmModule* module) {
return sizeof(WasmModule) + VectorSize(module->globals) + return sizeof(WasmModule) + VectorSize(module->globals) +
(module->signature_zone ? module->signature_zone->allocation_size() (module->signature_zone ? module->signature_zone->allocation_size()
: 0) + : 0) +
VectorSize(module->types) + VectorSize(module->type_kinds) + VectorSize(module->types) +
VectorSize(module->canonicalized_type_ids) + VectorSize(module->canonicalized_type_ids) +
VectorSize(module->functions) + VectorSize(module->data_segments) + VectorSize(module->functions) + VectorSize(module->data_segments) +
VectorSize(module->tables) + VectorSize(module->import_table) + VectorSize(module->tables) + VectorSize(module->import_table) +
......
...@@ -345,14 +345,22 @@ class V8_EXPORT_PRIVATE AsmJsOffsetInformation { ...@@ -345,14 +345,22 @@ class V8_EXPORT_PRIVATE AsmJsOffsetInformation {
}; };
struct TypeDefinition { struct TypeDefinition {
explicit TypeDefinition(const FunctionSig* sig) : function_sig(sig) {} enum Kind { kFunction, kStruct, kArray };
explicit TypeDefinition(const StructType* type) : struct_type(type) {}
explicit TypeDefinition(const ArrayType* type) : array_type(type) {} TypeDefinition(const FunctionSig* sig, uint32_t supertype)
: function_sig(sig), supertype(supertype), kind(kFunction) {}
TypeDefinition(const StructType* type, uint32_t supertype)
: struct_type(type), supertype(supertype), kind(kStruct) {}
TypeDefinition(const ArrayType* type, uint32_t supertype)
: array_type(type), supertype(supertype), kind(kArray) {}
union { union {
const FunctionSig* function_sig; const FunctionSig* function_sig;
const StructType* struct_type; const StructType* struct_type;
const ArrayType* array_type; const ArrayType* array_type;
}; };
uint32_t supertype;
Kind kind;
}; };
struct V8_EXPORT_PRIVATE WasmDebugSymbols { struct V8_EXPORT_PRIVATE WasmDebugSymbols {
...@@ -379,9 +387,9 @@ struct TypeFeedbackStorage { ...@@ -379,9 +387,9 @@ struct TypeFeedbackStorage {
struct WasmTable; struct WasmTable;
// End of a chain of explicit supertypes. // End of a chain of explicit supertypes.
constexpr uint32_t kGenericSuperType = 0xFFFFFFFE; constexpr uint32_t kGenericSuperType = std::numeric_limits<uint32_t>::max() - 1;
// Used for types that have no explicit supertype. // Used for types that have no explicit supertype.
constexpr uint32_t kNoSuperType = 0xFFFFFFFF; constexpr uint32_t kNoSuperType = std::numeric_limits<uint32_t>::max();
// Static representation of a module. // Static representation of a module.
struct V8_EXPORT_PRIVATE WasmModule { struct V8_EXPORT_PRIVATE WasmModule {
...@@ -395,7 +403,6 @@ struct V8_EXPORT_PRIVATE WasmModule { ...@@ -395,7 +403,6 @@ struct V8_EXPORT_PRIVATE WasmModule {
bool mem_export = false; // true if the memory is exported bool mem_export = false; // true if the memory is exported
int start_function_index = -1; // start function, >= 0 if any int start_function_index = -1; // start function, >= 0 if any
std::vector<WasmGlobal> globals;
// Size of the buffer required for all globals that are not imported and // Size of the buffer required for all globals that are not imported and
// mutable. // mutable.
uint32_t untagged_globals_buffer_size = 0; uint32_t untagged_globals_buffer_size = 0;
...@@ -410,26 +417,17 @@ struct V8_EXPORT_PRIVATE WasmModule { ...@@ -410,26 +417,17 @@ struct V8_EXPORT_PRIVATE WasmModule {
// ID and length). // ID and length).
WireBytesRef code = {0, 0}; WireBytesRef code = {0, 0};
WireBytesRef name = {0, 0}; WireBytesRef name = {0, 0};
std::vector<TypeDefinition> types; // by type index
std::vector<uint8_t> type_kinds; // by type index
std::vector<uint32_t> supertypes; // by type index
// Map from each type index to the index of its corresponding canonical index.
// Canonical indices do not correspond to types.
// Note: right now, only functions are canonicalized, and arrays and structs
// map to 0.
std::vector<uint32_t> canonicalized_type_ids;
bool has_type(uint32_t index) const { return index < types.size(); } bool has_type(uint32_t index) const { return index < types.size(); }
void add_signature(const FunctionSig* sig, uint32_t supertype) { void add_signature(const FunctionSig* sig, uint32_t supertype) {
types.push_back(TypeDefinition(sig)); types.push_back(TypeDefinition(sig, supertype));
type_kinds.push_back(kWasmFunctionTypeCode);
supertypes.push_back(supertype);
uint32_t canonical_id = sig ? signature_map.FindOrInsert(*sig) : 0; uint32_t canonical_id = sig ? signature_map.FindOrInsert(*sig) : 0;
canonicalized_type_ids.push_back(canonical_id); canonicalized_type_ids.push_back(canonical_id);
} }
bool has_signature(uint32_t index) const { bool has_signature(uint32_t index) const {
return index < types.size() && type_kinds[index] == kWasmFunctionTypeCode; return index < types.size() &&
types[index].kind == TypeDefinition::kFunction;
} }
const FunctionSig* signature(uint32_t index) const { const FunctionSig* signature(uint32_t index) const {
DCHECK(has_signature(index)); DCHECK(has_signature(index));
...@@ -437,14 +435,12 @@ struct V8_EXPORT_PRIVATE WasmModule { ...@@ -437,14 +435,12 @@ struct V8_EXPORT_PRIVATE WasmModule {
} }
void add_struct_type(const StructType* type, uint32_t supertype) { void add_struct_type(const StructType* type, uint32_t supertype) {
types.push_back(TypeDefinition(type)); types.push_back(TypeDefinition(type, supertype));
type_kinds.push_back(kWasmStructTypeCode);
supertypes.push_back(supertype);
// No canonicalization for structs. // No canonicalization for structs.
canonicalized_type_ids.push_back(0); canonicalized_type_ids.push_back(0);
} }
bool has_struct(uint32_t index) const { bool has_struct(uint32_t index) const {
return index < types.size() && type_kinds[index] == kWasmStructTypeCode; return index < types.size() && types[index].kind == TypeDefinition::kStruct;
} }
const StructType* struct_type(uint32_t index) const { const StructType* struct_type(uint32_t index) const {
DCHECK(has_struct(index)); DCHECK(has_struct(index));
...@@ -452,14 +448,12 @@ struct V8_EXPORT_PRIVATE WasmModule { ...@@ -452,14 +448,12 @@ struct V8_EXPORT_PRIVATE WasmModule {
} }
void add_array_type(const ArrayType* type, uint32_t supertype) { void add_array_type(const ArrayType* type, uint32_t supertype) {
types.push_back(TypeDefinition(type)); types.push_back(TypeDefinition(type, supertype));
type_kinds.push_back(kWasmArrayTypeCode);
supertypes.push_back(supertype);
// No canonicalization for arrays. // No canonicalization for arrays.
canonicalized_type_ids.push_back(0); canonicalized_type_ids.push_back(0);
} }
bool has_array(uint32_t index) const { bool has_array(uint32_t index) const {
return index < types.size() && type_kinds[index] == kWasmArrayTypeCode; return index < types.size() && types[index].kind == TypeDefinition::kArray;
} }
const ArrayType* array_type(uint32_t index) const { const ArrayType* array_type(uint32_t index) const {
DCHECK(has_array(index)); DCHECK(has_array(index));
...@@ -467,14 +461,23 @@ struct V8_EXPORT_PRIVATE WasmModule { ...@@ -467,14 +461,23 @@ struct V8_EXPORT_PRIVATE WasmModule {
} }
uint32_t supertype(uint32_t index) const { uint32_t supertype(uint32_t index) const {
DCHECK(index < supertypes.size()); DCHECK(index < types.size());
return supertypes[index]; return types[index].supertype;
} }
bool has_supertype(uint32_t index) const { bool has_supertype(uint32_t index) const {
return supertype(index) != kNoSuperType; return supertype(index) != kNoSuperType;
} }
std::vector<TypeDefinition> types; // by type index
// Map from each type index to the index of its corresponding canonical index.
// Canonical indices do not correspond to types.
// Note: right now, only functions are canonicalized, and arrays and structs
// map to 0.
std::vector<uint32_t> canonicalized_type_ids;
// Canonicalizing map for signature indexes.
SignatureMap signature_map;
std::vector<WasmFunction> functions; std::vector<WasmFunction> functions;
std::vector<WasmGlobal> globals;
std::vector<WasmDataSegment> data_segments; std::vector<WasmDataSegment> data_segments;
std::vector<WasmTable> tables; std::vector<WasmTable> tables;
std::vector<WasmImport> import_table; std::vector<WasmImport> import_table;
...@@ -483,9 +486,6 @@ struct V8_EXPORT_PRIVATE WasmModule { ...@@ -483,9 +486,6 @@ struct V8_EXPORT_PRIVATE WasmModule {
std::vector<WasmElemSegment> elem_segments; std::vector<WasmElemSegment> elem_segments;
std::vector<WasmCompilationHint> compilation_hints; std::vector<WasmCompilationHint> compilation_hints;
BranchHintInfo branch_hints; BranchHintInfo branch_hints;
SignatureMap signature_map; // canonicalizing map for signature indexes.
// Entries in this storage are short-lived: when tier-up of a function is
// scheduled, an entry is placed; the Turbofan graph builder consumes it.
mutable TypeFeedbackStorage type_feedback; mutable TypeFeedbackStorage type_feedback;
ModuleOrigin origin = kWasmOrigin; // origin of the module ModuleOrigin origin = kWasmOrigin; // origin of the module
......
...@@ -202,9 +202,9 @@ V8_INLINE bool EquivalentIndices(uint32_t index1, uint32_t index2, ...@@ -202,9 +202,9 @@ V8_INLINE bool EquivalentIndices(uint32_t index1, uint32_t index2,
const WasmModule* module1, const WasmModule* module1,
const WasmModule* module2) { const WasmModule* module2) {
DCHECK(index1 != index2 || module1 != module2); DCHECK(index1 != index2 || module1 != module2);
uint8_t kind1 = module1->type_kinds[index1]; TypeDefinition::Kind kind1 = module1->types[index1].kind;
if (kind1 != module2->type_kinds[index2]) return false; if (kind1 != module2->types[index2].kind) return false;
base::RecursiveMutexGuard type_cache_access( base::RecursiveMutexGuard type_cache_access(
TypeJudgementCache::instance()->type_cache_mutex()); TypeJudgementCache::instance()->type_cache_mutex());
...@@ -213,12 +213,12 @@ V8_INLINE bool EquivalentIndices(uint32_t index1, uint32_t index2, ...@@ -213,12 +213,12 @@ V8_INLINE bool EquivalentIndices(uint32_t index1, uint32_t index2,
return true; return true;
} }
if (kind1 == kWasmStructTypeCode) { if (kind1 == TypeDefinition::kStruct) {
return StructEquivalentIndices(index1, index2, module1, module2); return StructEquivalentIndices(index1, index2, module1, module2);
} else if (kind1 == kWasmArrayTypeCode) { } else if (kind1 == TypeDefinition::kArray) {
return ArrayEquivalentIndices(index1, index2, module1, module2); return ArrayEquivalentIndices(index1, index2, module1, module2);
} else { } else {
DCHECK_EQ(kind1, kWasmFunctionTypeCode); DCHECK_EQ(kind1, TypeDefinition::kFunction);
return FunctionEquivalentIndices(index1, index2, module1, module2); return FunctionEquivalentIndices(index1, index2, module1, module2);
} }
} }
...@@ -426,9 +426,9 @@ V8_NOINLINE V8_EXPORT_PRIVATE bool IsSubtypeOfImpl( ...@@ -426,9 +426,9 @@ V8_NOINLINE V8_EXPORT_PRIVATE bool IsSubtypeOfImpl(
// equality; here we catch (ref $x) being a subtype of (ref null $x). // equality; here we catch (ref $x) being a subtype of (ref null $x).
if (sub_module == super_module && sub_index == super_index) return true; if (sub_module == super_module && sub_index == super_index) return true;
uint8_t sub_kind = sub_module->type_kinds[sub_index]; TypeDefinition::Kind sub_kind = sub_module->types[sub_index].kind;
if (sub_kind != super_module->type_kinds[super_index]) return false; if (sub_kind != super_module->types[super_index].kind) return false;
// Types with explicit supertypes just check those. // Types with explicit supertypes just check those.
if (sub_module->has_supertype(sub_index)) { if (sub_module->has_supertype(sub_index)) {
...@@ -460,14 +460,15 @@ V8_NOINLINE V8_EXPORT_PRIVATE bool IsSubtypeOfImpl( ...@@ -460,14 +460,15 @@ V8_NOINLINE V8_EXPORT_PRIVATE bool IsSubtypeOfImpl(
return true; return true;
} }
if (sub_kind == kWasmStructTypeCode) { switch (sub_kind) {
return StructIsSubtypeOf(sub_index, super_index, sub_module, super_module); case TypeDefinition::kStruct:
} else if (sub_kind == kWasmArrayTypeCode) { return StructIsSubtypeOf(sub_index, super_index, sub_module,
return ArrayIsSubtypeOf(sub_index, super_index, sub_module, super_module);
} else {
DCHECK_EQ(sub_kind, kWasmFunctionTypeCode);
return FunctionIsSubtypeOf(sub_index, super_index, sub_module,
super_module); super_module);
case TypeDefinition::kArray:
return ArrayIsSubtypeOf(sub_index, super_index, sub_module, super_module);
case TypeDefinition::kFunction:
return FunctionIsSubtypeOf(sub_index, super_index, sub_module,
super_module);
} }
} }
......
...@@ -410,13 +410,11 @@ void TestTableInitElems(TestExecutionTier execution_tier, int table_index) { ...@@ -410,13 +410,11 @@ void TestTableInitElems(TestExecutionTier execution_tier, int table_index) {
function_indexes.push_back(fn.function_index()); function_indexes.push_back(fn.function_index());
} }
// Passive element segment has [f0, f1, f2, f3, f4, null].
function_indexes.push_back(WasmModuleBuilder::kNullIndex);
// Add 10 function tables, even though we only test one table. // Add 10 function tables, even though we only test one table.
for (int i = 0; i < 10; ++i) { for (int i = 0; i < 10; ++i) {
r.builder().AddIndirectFunctionTable(nullptr, kTableSize); r.builder().AddIndirectFunctionTable(nullptr, kTableSize);
} }
// Passive element segment has [f0, f1, f2, f3, f4].
r.builder().AddPassiveElementSegment(function_indexes); r.builder().AddPassiveElementSegment(function_indexes);
WasmFunctionCompiler& call = r.NewFunction(sigs.i_i(), "call"); WasmFunctionCompiler& call = r.NewFunction(sigs.i_i(), "call");
......
...@@ -622,7 +622,7 @@ class WasmGenerator { ...@@ -622,7 +622,7 @@ class WasmGenerator {
uint8_t random_byte = data->get<uint8_t>(); uint8_t random_byte = data->get<uint8_t>();
int func_index = random_byte % functions_.size(); int func_index = random_byte % functions_.size();
uint32_t sig_index = functions_[func_index]; uint32_t sig_index = functions_[func_index];
FunctionSig* sig = builder_->builder()->GetSignature(sig_index); const FunctionSig* sig = builder_->builder()->GetSignature(sig_index);
// Generate arguments. // Generate arguments.
for (size_t i = 0; i < sig->parameter_count(); ++i) { for (size_t i = 0; i < sig->parameter_count(); ++i) {
Generate(sig->GetParam(i), data); Generate(sig->GetParam(i), data);
...@@ -808,7 +808,8 @@ class WasmGenerator { ...@@ -808,7 +808,8 @@ class WasmGenerator {
control_depth - catch_blocks_[catch_index]); control_depth - catch_blocks_[catch_index]);
} else { } else {
int tag = data->get<uint8_t>() % builder_->builder()->NumExceptions(); int tag = data->get<uint8_t>() % builder_->builder()->NumExceptions();
FunctionSig* exception_sig = builder_->builder()->GetExceptionType(tag); const FunctionSig* exception_sig =
builder_->builder()->GetExceptionType(tag);
base::Vector<const ValueType> exception_types( base::Vector<const ValueType> exception_types(
exception_sig->parameters().begin(), exception_sig->parameters().begin(),
exception_sig->parameter_count()); exception_sig->parameter_count());
...@@ -853,7 +854,7 @@ class WasmGenerator { ...@@ -853,7 +854,7 @@ class WasmGenerator {
bool new_default = data->get<bool>(); bool new_default = data->get<bool>();
if (builder_->builder()->IsStructType(index)) { if (builder_->builder()->IsStructType(index)) {
StructType* struct_gen = builder_->builder()->GetStructType(index); const StructType* struct_gen = builder_->builder()->GetStructType(index);
int field_count = struct_gen->field_count(); int field_count = struct_gen->field_count();
bool can_be_defaultable = false; bool can_be_defaultable = false;
...@@ -1143,7 +1144,7 @@ class WasmGenerator { ...@@ -1143,7 +1144,7 @@ class WasmGenerator {
if (num_structs_ > 0) { if (num_structs_ > 0) {
int struct_index = data->get<uint8_t>() % num_structs_; int struct_index = data->get<uint8_t>() % num_structs_;
DCHECK(builder->IsStructType(struct_index)); DCHECK(builder->IsStructType(struct_index));
StructType* struct_type = builder->GetStructType(struct_index); const StructType* struct_type = builder->GetStructType(struct_index);
ZoneVector<uint32_t> field_indices(builder->zone()); ZoneVector<uint32_t> field_indices(builder->zone());
for (uint32_t i = 0; i < struct_type->field_count(); i++) { for (uint32_t i = 0; i < struct_type->field_count(); i++) {
if (struct_type->mutability(i)) { if (struct_type->mutability(i)) {
...@@ -1253,7 +1254,7 @@ class WasmGenerator { ...@@ -1253,7 +1254,7 @@ class WasmGenerator {
num_structs_(num_structs), num_structs_(num_structs),
num_arrays_(num_arrays), num_arrays_(num_arrays),
liftoff_as_reference_(liftoff_as_reference) { liftoff_as_reference_(liftoff_as_reference) {
FunctionSig* sig = fn->signature(); const FunctionSig* sig = fn->signature();
blocks_.emplace_back(); blocks_.emplace_back();
for (size_t i = 0; i < sig->return_count(); ++i) { for (size_t i = 0; i < sig->return_count(); ++i) {
blocks_.back().push_back(sig->GetReturn(i)); blocks_.back().push_back(sig->GetReturn(i));
...@@ -2508,7 +2509,7 @@ class WasmCompileFuzzer : public WasmExecutionFuzzer { ...@@ -2508,7 +2509,7 @@ class WasmCompileFuzzer : public WasmExecutionFuzzer {
// have typed-function tables. // have typed-function tables.
std::vector<WasmFunctionBuilder*> functions; std::vector<WasmFunctionBuilder*> functions;
for (int i = 0; i < num_functions; ++i) { for (int i = 0; i < num_functions; ++i) {
FunctionSig* sig = builder.GetSignature(function_signatures[i]); const FunctionSig* sig = builder.GetSignature(function_signatures[i]);
functions.push_back(builder.AddFunction(sig)); functions.push_back(builder.AddFunction(sig));
} }
...@@ -2576,7 +2577,7 @@ class WasmCompileFuzzer : public WasmExecutionFuzzer { ...@@ -2576,7 +2577,7 @@ class WasmCompileFuzzer : public WasmExecutionFuzzer {
WasmGenerator gen(f, function_signatures, globals, mutable_globals, WasmGenerator gen(f, function_signatures, globals, mutable_globals,
num_structs, num_arrays, &function_range, num_structs, num_arrays, &function_range,
liftoff_as_reference); liftoff_as_reference);
FunctionSig* sig = f->signature(); const FunctionSig* sig = f->signature();
base::Vector<const ValueType> return_types(sig->returns().begin(), base::Vector<const ValueType> return_types(sig->returns().begin(),
sig->return_count()); sig->return_count());
gen.Generate(return_types, &function_range); gen.Generate(return_types, &function_range);
......
...@@ -623,13 +623,6 @@ void GenerateTestCase(Isolate* isolate, ModuleWireBytes wire_bytes, ...@@ -623,13 +623,6 @@ void GenerateTestCase(Isolate* isolate, ModuleWireBytes wire_bytes,
os << ");\n"; os << ");\n";
} }
#if DEBUG
for (uint8_t kind : module->type_kinds) {
DCHECK(kWasmArrayTypeCode == kind || kWasmStructTypeCode == kind ||
kWasmFunctionTypeCode == kind);
}
#endif
for (int i = 0; i < static_cast<int>(module->types.size()); i++) { for (int i = 0; i < static_cast<int>(module->types.size()); i++) {
if (module->has_struct(i)) { if (module->has_struct(i)) {
const StructType* struct_type = module->types[i].struct_type; const StructType* struct_type = module->types[i].struct_type;
......
...@@ -136,13 +136,13 @@ class TestModuleBuilder { ...@@ -136,13 +136,13 @@ class TestModuleBuilder {
type_builder.AddField(field.first, field.second); type_builder.AddField(field.first, field.second);
} }
mod.add_struct_type(type_builder.Build(), supertype); mod.add_struct_type(type_builder.Build(), supertype);
return static_cast<byte>(mod.type_kinds.size() - 1); return static_cast<byte>(mod.types.size() - 1);
} }
byte AddArray(ValueType type, bool mutability) { byte AddArray(ValueType type, bool mutability) {
ArrayType* array = mod.signature_zone->New<ArrayType>(type, mutability); ArrayType* array = mod.signature_zone->New<ArrayType>(type, mutability);
mod.add_array_type(array, kNoSuperType); mod.add_array_type(array, kNoSuperType);
return static_cast<byte>(mod.type_kinds.size() - 1); return static_cast<byte>(mod.types.size() - 1);
} }
void InitializeMemory(MemoryType mem_type = kMemory32) { void InitializeMemory(MemoryType mem_type = kMemory32) {
......
...@@ -1634,7 +1634,6 @@ TEST_F(WasmModuleVerifyTest, CanonicalTypeIds) { ...@@ -1634,7 +1634,6 @@ TEST_F(WasmModuleVerifyTest, CanonicalTypeIds) {
const WasmModule* module = result.value().get(); const WasmModule* module = result.value().get();
EXPECT_EQ(5u, module->types.size()); EXPECT_EQ(5u, module->types.size());
EXPECT_EQ(5u, module->type_kinds.size());
EXPECT_EQ(5u, module->canonicalized_type_ids.size()); EXPECT_EQ(5u, module->canonicalized_type_ids.size());
EXPECT_EQ(2u, module->signature_map.size()); EXPECT_EQ(2u, module->signature_map.size());
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment