зеркало из 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;
|
||||
Maybe<uint32_t> maximumLength;
|
||||
|
||||
WASM_CHECK_CACHEABLE_POD(elemType, isImportedOrExported, isAsmJS,
|
||||
globalDataOffset, initialLength, maximumLength);
|
||||
|
||||
TableDesc() = default;
|
||||
TableDesc(RefType elemType, uint32_t initialLength,
|
||||
Maybe<uint32_t> maximumLength, bool isAsmJS,
|
||||
|
@ -629,8 +626,6 @@ struct TableDesc {
|
|||
maximumLength(maximumLength) {}
|
||||
};
|
||||
|
||||
WASM_DECLARE_CACHEABLE_POD(TableDesc);
|
||||
|
||||
using TableDescVector = Vector<TableDesc, 0, SystemAllocPolicy>;
|
||||
|
||||
} // namespace wasm
|
||||
|
|
|
@ -412,16 +412,56 @@ CoderResult CodeShareableBytes(Coder<mode>& coder,
|
|||
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
|
||||
|
||||
template <CoderMode mode>
|
||||
CoderResult CodeInitExpr(Coder<mode>& coder, CoderArg<mode, InitExpr> item) {
|
||||
WASM_VERIFY_SERIALIZATION_FOR_SIZE(wasm::InitExpr, 80);
|
||||
MOZ_TRY(CodePod(coder, &item->kind_));
|
||||
MOZ_TRY(CodePod(coder, &item->type_));
|
||||
MOZ_TRY(CodeValType(coder, &item->type_));
|
||||
switch (item->kind_) {
|
||||
case InitExprKind::Literal:
|
||||
MOZ_TRY(CodePod(coder, &item->literal_));
|
||||
MOZ_TRY(CodeLitVal(coder, &item->literal_));
|
||||
break;
|
||||
case InitExprKind::Variable:
|
||||
MOZ_TRY(CodePodVector(coder, &item->bytecode_));
|
||||
|
@ -437,21 +477,40 @@ CoderResult CodeInitExpr(Coder<mode>& coder, CoderArg<mode, InitExpr> item) {
|
|||
template <CoderMode mode>
|
||||
CoderResult CodeFuncType(Coder<mode>& coder, CoderArg<mode, FuncType> item) {
|
||||
WASM_VERIFY_SERIALIZATION_FOR_SIZE(wasm::FuncType, 208);
|
||||
MOZ_TRY(CodePodVector(coder, &item->results_));
|
||||
MOZ_TRY(CodePodVector(coder, &item->args_));
|
||||
MOZ_TRY((CodeVector<mode, ValType, &CodeValType<mode>>(coder, &item->args_)));
|
||||
MOZ_TRY(
|
||||
(CodeVector<mode, ValType, &CodeValType<mode>>(coder, &item->results_)));
|
||||
MOZ_TRY(CodePod(coder, &item->immediateTypeId_));
|
||||
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>
|
||||
CoderResult CodeStructType(Coder<mode>& coder,
|
||||
CoderArg<mode, StructType> item) {
|
||||
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_));
|
||||
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>
|
||||
CoderResult CodeTypeDef(Coder<mode>& coder, CoderArg<mode, TypeDef> item) {
|
||||
WASM_VERIFY_SERIALIZATION_FOR_SIZE(wasm::TypeDef, 216);
|
||||
|
@ -477,7 +536,10 @@ CoderResult CodeTypeDef(Coder<mode>& coder, CoderArg<mode, TypeDef> item) {
|
|||
break;
|
||||
}
|
||||
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;
|
||||
}
|
||||
case TypeDefKind::None: {
|
||||
|
@ -525,7 +587,8 @@ CoderResult CodeGlobalDesc(Coder<mode>& coder,
|
|||
template <CoderMode mode>
|
||||
CoderResult CodeTagType(Coder<mode>& coder, CoderArg<mode, TagType> item) {
|
||||
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(CodePod(coder, &item->size_));
|
||||
return Ok();
|
||||
|
@ -548,7 +611,7 @@ CoderResult CodeElemSegment(Coder<mode>& coder,
|
|||
WASM_VERIFY_SERIALIZATION_FOR_SIZE(wasm::ElemSegment, 184);
|
||||
MOZ_TRY(CodePod(coder, &item->kind));
|
||||
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>>(
|
||||
coder, &item->offsetIfActive)));
|
||||
MOZ_TRY(CodePodVector(coder, &item->elemFuncIndices));
|
||||
|
@ -575,6 +638,18 @@ CoderResult CodeCustomSection(Coder<mode>& coder,
|
|||
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
|
||||
|
||||
template <CoderMode mode>
|
||||
|
@ -805,7 +880,8 @@ CoderResult CodeMetadata(Coder<mode>& coder,
|
|||
MOZ_TRY((CodePod(coder, &item->typeIdsOffsetStart)));
|
||||
MOZ_TRY((CodeVector<mode, GlobalDesc, &CodeGlobalDesc<mode>>(
|
||||
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(CodePod(coder, &item->moduleName));
|
||||
MOZ_TRY(CodePodVector(coder, &item->funcNames));
|
||||
|
|
|
@ -217,12 +217,8 @@ struct StructField {
|
|||
FieldType type;
|
||||
uint32_t offset;
|
||||
bool isMutable;
|
||||
|
||||
WASM_CHECK_CACHEABLE_POD(type, offset, isMutable);
|
||||
};
|
||||
|
||||
WASM_DECLARE_CACHEABLE_POD(StructField);
|
||||
|
||||
using StructFieldVector = Vector<StructField, 0, SystemAllocPolicy>;
|
||||
|
||||
class StructType {
|
||||
|
@ -300,9 +296,8 @@ class ArrayType {
|
|||
FieldType elementType_; // field type
|
||||
bool isMutable_; // mutability
|
||||
|
||||
WASM_CHECK_CACHEABLE_POD(elementType_, isMutable_);
|
||||
|
||||
public:
|
||||
ArrayType() : isMutable_(false) {}
|
||||
ArrayType(FieldType elementType, bool isMutable)
|
||||
: elementType_(elementType), isMutable_(isMutable) {}
|
||||
|
||||
|
|
|
@ -57,8 +57,6 @@ union PackedTypeCode {
|
|||
PackedRepr pointerTag_ : PointerTagBits;
|
||||
};
|
||||
|
||||
WASM_CHECK_CACHEABLE_POD(bits_);
|
||||
|
||||
public:
|
||||
static constexpr uint32_t NoTypeCode = (1 << TypeCodeBits) - 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(std::is_pod_v<PackedTypeCode>,
|
||||
"must be POD to be simply serialized/deserialized");
|
||||
|
||||
// An enum that describes the representation classes for tables; The table
|
||||
// element type is mapped into this by Table::repr().
|
||||
|
@ -188,8 +182,6 @@ class RefType {
|
|||
private:
|
||||
PackedTypeCode ptc_;
|
||||
|
||||
WASM_CHECK_CACHEABLE_POD(ptc_);
|
||||
|
||||
#ifdef DEBUG
|
||||
bool isValid() const {
|
||||
switch (ptc_.typeCode()) {
|
||||
|
@ -265,8 +257,6 @@ class RefType {
|
|||
bool operator!=(const RefType& that) const { return ptc_ != that.ptc_; }
|
||||
};
|
||||
|
||||
WASM_DECLARE_CACHEABLE_POD(RefType);
|
||||
|
||||
class FieldTypeTraits {
|
||||
public:
|
||||
enum Kind {
|
||||
|
@ -415,8 +405,6 @@ class PackedType : public T {
|
|||
protected:
|
||||
PackedTypeCode tc_;
|
||||
|
||||
WASM_CHECK_CACHEABLE_POD(tc_);
|
||||
|
||||
explicit PackedType(TypeCode c) : tc_(PackedTypeCode::pack(c)) {
|
||||
MOZ_ASSERT(c != AbstractReferenceTypeIndexCode);
|
||||
MOZ_ASSERT(isValid());
|
||||
|
@ -692,9 +680,6 @@ class PackedType : public T {
|
|||
using ValType = PackedType<ValTypeTraits>;
|
||||
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
|
||||
// with ZenGarden and Tanks suggests an initial size of 16 minimises heap
|
||||
// allocation, both in terms of blocks and bytes.
|
||||
|
|
|
@ -276,21 +276,18 @@ class LitVal {
|
|||
|
||||
Cell() : v128_() {}
|
||||
~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:
|
||||
ValType type_;
|
||||
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:
|
||||
LitVal() : type_(ValType()), cell_{} {}
|
||||
|
||||
|
@ -369,9 +366,11 @@ class LitVal {
|
|||
MOZ_ASSERT(type_ == ValType::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
|
||||
// must be used with the rooting APIs as they may contain JS objects.
|
||||
|
|
Загрузка…
Ссылка в новой задаче