зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1790626 - wasm: Manually serialize/deserialize PackedType to prepare for it not being POD. r=yury
PackedType will store a pointer to *TypeDef in a later commit, making it non-cacheable POD. We therefore need to specially handle it in serialization. This commit starts preparing for that. Differential Revision: https://phabricator.services.mozilla.com/D157386
This commit is contained in:
Родитель
99578d6774
Коммит
17d79988c0
|
@ -614,9 +614,6 @@ struct TableDesc {
|
||||||
uint32_t initialLength;
|
uint32_t initialLength;
|
||||||
Maybe<uint32_t> maximumLength;
|
Maybe<uint32_t> maximumLength;
|
||||||
|
|
||||||
WASM_CHECK_CACHEABLE_POD(elemType, isImportedOrExported, isAsmJS,
|
|
||||||
globalDataOffset, initialLength, maximumLength);
|
|
||||||
|
|
||||||
TableDesc() = default;
|
TableDesc() = default;
|
||||||
TableDesc(RefType elemType, uint32_t initialLength,
|
TableDesc(RefType elemType, uint32_t initialLength,
|
||||||
Maybe<uint32_t> maximumLength, bool isAsmJS,
|
Maybe<uint32_t> maximumLength, bool isAsmJS,
|
||||||
|
@ -629,8 +626,6 @@ struct TableDesc {
|
||||||
maximumLength(maximumLength) {}
|
maximumLength(maximumLength) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
WASM_DECLARE_CACHEABLE_POD(TableDesc);
|
|
||||||
|
|
||||||
using TableDescVector = Vector<TableDesc, 0, SystemAllocPolicy>;
|
using TableDescVector = Vector<TableDesc, 0, SystemAllocPolicy>;
|
||||||
|
|
||||||
} // namespace wasm
|
} // namespace wasm
|
||||||
|
|
|
@ -412,16 +412,56 @@ CoderResult CodeShareableBytes(Coder<mode>& coder,
|
||||||
return CodePodVector(coder, &item->bytes);
|
return CodePodVector(coder, &item->bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WasmValType.h
|
||||||
|
|
||||||
|
template <CoderMode mode>
|
||||||
|
CoderResult CodeValType(Coder<mode>& coder, CoderArg<mode, ValType> item) {
|
||||||
|
if constexpr (mode == MODE_DECODE) {
|
||||||
|
return coder.readBytes((void*)item, sizeof(ValType));
|
||||||
|
} else {
|
||||||
|
return coder.writeBytes((const void*)item, sizeof(ValType));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CoderResult CodeFieldType(Coder<MODE_DECODE>& coder, FieldType* item) {
|
||||||
|
return coder.readBytes((void*)item, sizeof(FieldType));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <CoderMode mode>
|
||||||
|
CoderResult CodeFieldType(Coder<mode>& coder, const FieldType* item) {
|
||||||
|
STATIC_ASSERT_ENCODING_OR_SIZING;
|
||||||
|
return coder.writeBytes((const void*)item, sizeof(FieldType));
|
||||||
|
}
|
||||||
|
|
||||||
|
CoderResult CodeRefType(Coder<MODE_DECODE>& coder, RefType* item) {
|
||||||
|
return coder.readBytes((void*)item, sizeof(RefType));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <CoderMode mode>
|
||||||
|
CoderResult CodeRefType(Coder<mode>& coder, const RefType* item) {
|
||||||
|
STATIC_ASSERT_ENCODING_OR_SIZING;
|
||||||
|
return coder.writeBytes((const void*)item, sizeof(RefType));
|
||||||
|
}
|
||||||
|
|
||||||
|
// WasmValue.h
|
||||||
|
|
||||||
|
template <CoderMode mode>
|
||||||
|
CoderResult CodeLitVal(Coder<mode>& coder, CoderArg<mode, LitVal> item) {
|
||||||
|
MOZ_TRY(CodeValType(coder, &item->type_));
|
||||||
|
MOZ_TRY(CodePod(coder, &item->cell_));
|
||||||
|
return Ok();
|
||||||
|
}
|
||||||
|
|
||||||
// WasmInitExpr.h
|
// WasmInitExpr.h
|
||||||
|
|
||||||
template <CoderMode mode>
|
template <CoderMode mode>
|
||||||
CoderResult CodeInitExpr(Coder<mode>& coder, CoderArg<mode, InitExpr> item) {
|
CoderResult CodeInitExpr(Coder<mode>& coder, CoderArg<mode, InitExpr> item) {
|
||||||
WASM_VERIFY_SERIALIZATION_FOR_SIZE(wasm::InitExpr, 80);
|
WASM_VERIFY_SERIALIZATION_FOR_SIZE(wasm::InitExpr, 80);
|
||||||
MOZ_TRY(CodePod(coder, &item->kind_));
|
MOZ_TRY(CodePod(coder, &item->kind_));
|
||||||
MOZ_TRY(CodePod(coder, &item->type_));
|
MOZ_TRY(CodeValType(coder, &item->type_));
|
||||||
switch (item->kind_) {
|
switch (item->kind_) {
|
||||||
case InitExprKind::Literal:
|
case InitExprKind::Literal:
|
||||||
MOZ_TRY(CodePod(coder, &item->literal_));
|
MOZ_TRY(CodeLitVal(coder, &item->literal_));
|
||||||
break;
|
break;
|
||||||
case InitExprKind::Variable:
|
case InitExprKind::Variable:
|
||||||
MOZ_TRY(CodePodVector(coder, &item->bytecode_));
|
MOZ_TRY(CodePodVector(coder, &item->bytecode_));
|
||||||
|
@ -437,21 +477,40 @@ CoderResult CodeInitExpr(Coder<mode>& coder, CoderArg<mode, InitExpr> item) {
|
||||||
template <CoderMode mode>
|
template <CoderMode mode>
|
||||||
CoderResult CodeFuncType(Coder<mode>& coder, CoderArg<mode, FuncType> item) {
|
CoderResult CodeFuncType(Coder<mode>& coder, CoderArg<mode, FuncType> item) {
|
||||||
WASM_VERIFY_SERIALIZATION_FOR_SIZE(wasm::FuncType, 208);
|
WASM_VERIFY_SERIALIZATION_FOR_SIZE(wasm::FuncType, 208);
|
||||||
MOZ_TRY(CodePodVector(coder, &item->results_));
|
MOZ_TRY((CodeVector<mode, ValType, &CodeValType<mode>>(coder, &item->args_)));
|
||||||
MOZ_TRY(CodePodVector(coder, &item->args_));
|
MOZ_TRY(
|
||||||
|
(CodeVector<mode, ValType, &CodeValType<mode>>(coder, &item->results_)));
|
||||||
MOZ_TRY(CodePod(coder, &item->immediateTypeId_));
|
MOZ_TRY(CodePod(coder, &item->immediateTypeId_));
|
||||||
return Ok();
|
return Ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <CoderMode mode>
|
||||||
|
CoderResult CodeStructField(Coder<mode>& coder,
|
||||||
|
CoderArg<mode, StructField> item) {
|
||||||
|
MOZ_TRY(CodeFieldType(coder, &item->type));
|
||||||
|
MOZ_TRY(CodePod(coder, &item->offset));
|
||||||
|
MOZ_TRY(CodePod(coder, &item->isMutable));
|
||||||
|
return Ok();
|
||||||
|
}
|
||||||
|
|
||||||
template <CoderMode mode>
|
template <CoderMode mode>
|
||||||
CoderResult CodeStructType(Coder<mode>& coder,
|
CoderResult CodeStructType(Coder<mode>& coder,
|
||||||
CoderArg<mode, StructType> item) {
|
CoderArg<mode, StructType> item) {
|
||||||
WASM_VERIFY_SERIALIZATION_FOR_SIZE(wasm::StructType, 48);
|
WASM_VERIFY_SERIALIZATION_FOR_SIZE(wasm::StructType, 48);
|
||||||
MOZ_TRY(CodePodVector(coder, &item->fields_));
|
MOZ_TRY((CodeVector<mode, StructField, &CodeStructField<mode>>(
|
||||||
|
coder, &item->fields_)));
|
||||||
MOZ_TRY(CodePod(coder, &item->size_));
|
MOZ_TRY(CodePod(coder, &item->size_));
|
||||||
return Ok();
|
return Ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <CoderMode mode>
|
||||||
|
CoderResult CodeArrayType(Coder<mode>& coder, CoderArg<mode, ArrayType> item) {
|
||||||
|
WASM_VERIFY_SERIALIZATION_FOR_SIZE(wasm::ArrayType, 48);
|
||||||
|
MOZ_TRY(CodeFieldType(coder, &item->elementType_));
|
||||||
|
MOZ_TRY(CodePod(coder, &item->isMutable_));
|
||||||
|
return Ok();
|
||||||
|
}
|
||||||
|
|
||||||
template <CoderMode mode>
|
template <CoderMode mode>
|
||||||
CoderResult CodeTypeDef(Coder<mode>& coder, CoderArg<mode, TypeDef> item) {
|
CoderResult CodeTypeDef(Coder<mode>& coder, CoderArg<mode, TypeDef> item) {
|
||||||
WASM_VERIFY_SERIALIZATION_FOR_SIZE(wasm::TypeDef, 216);
|
WASM_VERIFY_SERIALIZATION_FOR_SIZE(wasm::TypeDef, 216);
|
||||||
|
@ -477,7 +536,10 @@ CoderResult CodeTypeDef(Coder<mode>& coder, CoderArg<mode, TypeDef> item) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TypeDefKind::Array: {
|
case TypeDefKind::Array: {
|
||||||
MOZ_TRY(CodePod(coder, &item->arrayType_));
|
if constexpr (mode == MODE_DECODE) {
|
||||||
|
new (&item->arrayType_) ArrayType();
|
||||||
|
}
|
||||||
|
MOZ_TRY(CodeArrayType(coder, &item->arrayType_));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TypeDefKind::None: {
|
case TypeDefKind::None: {
|
||||||
|
@ -525,7 +587,8 @@ CoderResult CodeGlobalDesc(Coder<mode>& coder,
|
||||||
template <CoderMode mode>
|
template <CoderMode mode>
|
||||||
CoderResult CodeTagType(Coder<mode>& coder, CoderArg<mode, TagType> item) {
|
CoderResult CodeTagType(Coder<mode>& coder, CoderArg<mode, TagType> item) {
|
||||||
WASM_VERIFY_SERIALIZATION_FOR_SIZE(wasm::TagType, 168);
|
WASM_VERIFY_SERIALIZATION_FOR_SIZE(wasm::TagType, 168);
|
||||||
MOZ_TRY(CodePodVector(coder, &item->argTypes_));
|
MOZ_TRY(
|
||||||
|
(CodeVector<mode, ValType, &CodeValType<mode>>(coder, &item->argTypes_)));
|
||||||
MOZ_TRY(CodePodVector(coder, &item->argOffsets_));
|
MOZ_TRY(CodePodVector(coder, &item->argOffsets_));
|
||||||
MOZ_TRY(CodePod(coder, &item->size_));
|
MOZ_TRY(CodePod(coder, &item->size_));
|
||||||
return Ok();
|
return Ok();
|
||||||
|
@ -548,7 +611,7 @@ CoderResult CodeElemSegment(Coder<mode>& coder,
|
||||||
WASM_VERIFY_SERIALIZATION_FOR_SIZE(wasm::ElemSegment, 184);
|
WASM_VERIFY_SERIALIZATION_FOR_SIZE(wasm::ElemSegment, 184);
|
||||||
MOZ_TRY(CodePod(coder, &item->kind));
|
MOZ_TRY(CodePod(coder, &item->kind));
|
||||||
MOZ_TRY(CodePod(coder, &item->tableIndex));
|
MOZ_TRY(CodePod(coder, &item->tableIndex));
|
||||||
MOZ_TRY(CodePod(coder, &item->elemType));
|
MOZ_TRY(CodeRefType(coder, &item->elemType));
|
||||||
MOZ_TRY((CodeMaybe<mode, InitExpr, &CodeInitExpr<mode>>(
|
MOZ_TRY((CodeMaybe<mode, InitExpr, &CodeInitExpr<mode>>(
|
||||||
coder, &item->offsetIfActive)));
|
coder, &item->offsetIfActive)));
|
||||||
MOZ_TRY(CodePodVector(coder, &item->elemFuncIndices));
|
MOZ_TRY(CodePodVector(coder, &item->elemFuncIndices));
|
||||||
|
@ -575,6 +638,18 @@ CoderResult CodeCustomSection(Coder<mode>& coder,
|
||||||
return Ok();
|
return Ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <CoderMode mode>
|
||||||
|
CoderResult CodeTableDesc(Coder<mode>& coder, CoderArg<mode, TableDesc> item) {
|
||||||
|
WASM_VERIFY_SERIALIZATION_FOR_SIZE(wasm::TableDesc, 48);
|
||||||
|
MOZ_TRY(CodeRefType(coder, &item->elemType));
|
||||||
|
MOZ_TRY(CodePod(coder, &item->isImportedOrExported));
|
||||||
|
MOZ_TRY(CodePod(coder, &item->isAsmJS));
|
||||||
|
MOZ_TRY(CodePod(coder, &item->globalDataOffset));
|
||||||
|
MOZ_TRY(CodePod(coder, &item->initialLength));
|
||||||
|
MOZ_TRY(CodePod(coder, &item->maximumLength));
|
||||||
|
return Ok();
|
||||||
|
}
|
||||||
|
|
||||||
// WasmCodegenTypes.h
|
// WasmCodegenTypes.h
|
||||||
|
|
||||||
template <CoderMode mode>
|
template <CoderMode mode>
|
||||||
|
@ -805,7 +880,8 @@ CoderResult CodeMetadata(Coder<mode>& coder,
|
||||||
MOZ_TRY((CodePod(coder, &item->typeIdsOffsetStart)));
|
MOZ_TRY((CodePod(coder, &item->typeIdsOffsetStart)));
|
||||||
MOZ_TRY((CodeVector<mode, GlobalDesc, &CodeGlobalDesc<mode>>(
|
MOZ_TRY((CodeVector<mode, GlobalDesc, &CodeGlobalDesc<mode>>(
|
||||||
coder, &item->globals)));
|
coder, &item->globals)));
|
||||||
MOZ_TRY(CodePodVector(coder, &item->tables));
|
MOZ_TRY((
|
||||||
|
CodeVector<mode, TableDesc, &CodeTableDesc<mode>>(coder, &item->tables)));
|
||||||
MOZ_TRY((CodeVector<mode, TagDesc, &CodeTagDesc<mode>>(coder, &item->tags)));
|
MOZ_TRY((CodeVector<mode, TagDesc, &CodeTagDesc<mode>>(coder, &item->tags)));
|
||||||
MOZ_TRY(CodePod(coder, &item->moduleName));
|
MOZ_TRY(CodePod(coder, &item->moduleName));
|
||||||
MOZ_TRY(CodePodVector(coder, &item->funcNames));
|
MOZ_TRY(CodePodVector(coder, &item->funcNames));
|
||||||
|
|
|
@ -217,12 +217,8 @@ struct StructField {
|
||||||
FieldType type;
|
FieldType type;
|
||||||
uint32_t offset;
|
uint32_t offset;
|
||||||
bool isMutable;
|
bool isMutable;
|
||||||
|
|
||||||
WASM_CHECK_CACHEABLE_POD(type, offset, isMutable);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
WASM_DECLARE_CACHEABLE_POD(StructField);
|
|
||||||
|
|
||||||
using StructFieldVector = Vector<StructField, 0, SystemAllocPolicy>;
|
using StructFieldVector = Vector<StructField, 0, SystemAllocPolicy>;
|
||||||
|
|
||||||
class StructType {
|
class StructType {
|
||||||
|
@ -300,9 +296,8 @@ class ArrayType {
|
||||||
FieldType elementType_; // field type
|
FieldType elementType_; // field type
|
||||||
bool isMutable_; // mutability
|
bool isMutable_; // mutability
|
||||||
|
|
||||||
WASM_CHECK_CACHEABLE_POD(elementType_, isMutable_);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
ArrayType() : isMutable_(false) {}
|
||||||
ArrayType(FieldType elementType, bool isMutable)
|
ArrayType(FieldType elementType, bool isMutable)
|
||||||
: elementType_(elementType), isMutable_(isMutable) {}
|
: elementType_(elementType), isMutable_(isMutable) {}
|
||||||
|
|
||||||
|
|
|
@ -57,8 +57,6 @@ union PackedTypeCode {
|
||||||
PackedRepr pointerTag_ : PointerTagBits;
|
PackedRepr pointerTag_ : PointerTagBits;
|
||||||
};
|
};
|
||||||
|
|
||||||
WASM_CHECK_CACHEABLE_POD(bits_);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static constexpr uint32_t NoTypeCode = (1 << TypeCodeBits) - 1;
|
static constexpr uint32_t NoTypeCode = (1 << TypeCodeBits) - 1;
|
||||||
static constexpr uint32_t NoTypeIndex = (1 << TypeIndexBits) - 1;
|
static constexpr uint32_t NoTypeIndex = (1 << TypeIndexBits) - 1;
|
||||||
|
@ -162,11 +160,7 @@ union PackedTypeCode {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
WASM_DECLARE_CACHEABLE_POD(PackedTypeCode);
|
|
||||||
|
|
||||||
static_assert(sizeof(PackedTypeCode) == sizeof(uint32_t), "packed");
|
static_assert(sizeof(PackedTypeCode) == sizeof(uint32_t), "packed");
|
||||||
static_assert(std::is_pod_v<PackedTypeCode>,
|
|
||||||
"must be POD to be simply serialized/deserialized");
|
|
||||||
|
|
||||||
// An enum that describes the representation classes for tables; The table
|
// An enum that describes the representation classes for tables; The table
|
||||||
// element type is mapped into this by Table::repr().
|
// element type is mapped into this by Table::repr().
|
||||||
|
@ -188,8 +182,6 @@ class RefType {
|
||||||
private:
|
private:
|
||||||
PackedTypeCode ptc_;
|
PackedTypeCode ptc_;
|
||||||
|
|
||||||
WASM_CHECK_CACHEABLE_POD(ptc_);
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
bool isValid() const {
|
bool isValid() const {
|
||||||
switch (ptc_.typeCode()) {
|
switch (ptc_.typeCode()) {
|
||||||
|
@ -265,8 +257,6 @@ class RefType {
|
||||||
bool operator!=(const RefType& that) const { return ptc_ != that.ptc_; }
|
bool operator!=(const RefType& that) const { return ptc_ != that.ptc_; }
|
||||||
};
|
};
|
||||||
|
|
||||||
WASM_DECLARE_CACHEABLE_POD(RefType);
|
|
||||||
|
|
||||||
class FieldTypeTraits {
|
class FieldTypeTraits {
|
||||||
public:
|
public:
|
||||||
enum Kind {
|
enum Kind {
|
||||||
|
@ -415,8 +405,6 @@ class PackedType : public T {
|
||||||
protected:
|
protected:
|
||||||
PackedTypeCode tc_;
|
PackedTypeCode tc_;
|
||||||
|
|
||||||
WASM_CHECK_CACHEABLE_POD(tc_);
|
|
||||||
|
|
||||||
explicit PackedType(TypeCode c) : tc_(PackedTypeCode::pack(c)) {
|
explicit PackedType(TypeCode c) : tc_(PackedTypeCode::pack(c)) {
|
||||||
MOZ_ASSERT(c != AbstractReferenceTypeIndexCode);
|
MOZ_ASSERT(c != AbstractReferenceTypeIndexCode);
|
||||||
MOZ_ASSERT(isValid());
|
MOZ_ASSERT(isValid());
|
||||||
|
@ -692,9 +680,6 @@ class PackedType : public T {
|
||||||
using ValType = PackedType<ValTypeTraits>;
|
using ValType = PackedType<ValTypeTraits>;
|
||||||
using FieldType = PackedType<FieldTypeTraits>;
|
using FieldType = PackedType<FieldTypeTraits>;
|
||||||
|
|
||||||
WASM_DECLARE_CACHEABLE_POD(ValType);
|
|
||||||
WASM_DECLARE_CACHEABLE_POD(FieldType);
|
|
||||||
|
|
||||||
// The dominant use of this data type is for locals and args, and profiling
|
// The dominant use of this data type is for locals and args, and profiling
|
||||||
// with ZenGarden and Tanks suggests an initial size of 16 minimises heap
|
// with ZenGarden and Tanks suggests an initial size of 16 minimises heap
|
||||||
// allocation, both in terms of blocks and bytes.
|
// allocation, both in terms of blocks and bytes.
|
||||||
|
|
|
@ -276,21 +276,18 @@ class LitVal {
|
||||||
|
|
||||||
Cell() : v128_() {}
|
Cell() : v128_() {}
|
||||||
~Cell() = default;
|
~Cell() = default;
|
||||||
|
|
||||||
|
WASM_CHECK_CACHEABLE_POD(i32_, i64_, f32_, f64_, v128_);
|
||||||
|
WASM_ALLOW_NON_CACHEABLE_POD_FIELD(
|
||||||
|
ref_,
|
||||||
|
"The pointer value in ref_ is guaranteed to always be null in a "
|
||||||
|
"LitVal.");
|
||||||
};
|
};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ValType type_;
|
ValType type_;
|
||||||
Cell cell_;
|
Cell cell_;
|
||||||
|
|
||||||
// We check the fields of cell_ here instead of in the union to avoid a
|
|
||||||
// template issue. In addition, Cell is only cacheable POD when used in
|
|
||||||
// LitVal and not Val, so checking here makes sense.
|
|
||||||
WASM_CHECK_CACHEABLE_POD(type_, cell_.i32_, cell_.i64_, cell_.f32_,
|
|
||||||
cell_.f64_, cell_.v128_);
|
|
||||||
WASM_ALLOW_NON_CACHEABLE_POD_FIELD(
|
|
||||||
cell_.ref_,
|
|
||||||
"The pointer value in ref_ is guaranteed to always be null in a LitVal.");
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
LitVal() : type_(ValType()), cell_{} {}
|
LitVal() : type_(ValType()), cell_{} {}
|
||||||
|
|
||||||
|
@ -369,9 +366,11 @@ class LitVal {
|
||||||
MOZ_ASSERT(type_ == ValType::V128);
|
MOZ_ASSERT(type_ == ValType::V128);
|
||||||
return cell_.v128_;
|
return cell_.v128_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WASM_DECLARE_FRIEND_SERIALIZE(LitVal);
|
||||||
};
|
};
|
||||||
|
|
||||||
WASM_DECLARE_CACHEABLE_POD(LitVal);
|
WASM_DECLARE_CACHEABLE_POD(LitVal::Cell);
|
||||||
|
|
||||||
// A Val is a LitVal that can contain (non-null) pointers to GC things. All Vals
|
// A Val is a LitVal that can contain (non-null) pointers to GC things. All Vals
|
||||||
// must be used with the rooting APIs as they may contain JS objects.
|
// must be used with the rooting APIs as they may contain JS objects.
|
||||||
|
|
Загрузка…
Ссылка в новой задаче