Loading dom/canvas/QueueParamTraits.h +9 −0 Original line number Diff line number Diff line Loading @@ -261,6 +261,15 @@ struct QueueParamTraits<bool> { // --------------------------------------------------------------- template <class T> Maybe<T> AsValidEnum(const std::underlying_type_t<T> raw_val) { const auto raw_enum = T{raw_val}; // This is the risk we prevent! if (!IsEnumCase(raw_enum)) return {}; return Some(raw_enum); } // - template <class T> struct QueueParamTraits_IsEnumCase { template <typename ProducerView> Loading dom/canvas/TiedFields.h +30 −22 Original line number Diff line number Diff line Loading @@ -131,34 +131,42 @@ constexpr bool AssertTiedFieldsAreExhaustive() { // - /** * PaddingField<T,N=1> can be used to pad out a struct so that it's not * implicitly padded by struct rules, but also can't be accidentally initialized * via Aggregate Initialization. (TiedFields serialization checks rely on object * fields leaving no implicit padding bytes, but explicit padding fields are * fine) While you can use e.g. `uint8_t _padding[3];`, consider instead * `PaddingField<uint8_t,3> _padding;` for clarity and to move the `3` nearer * to the `uint8_t`. * Padding<T> can be used to pad out a struct so that it's not implicitly * padded by struct rules. * You can also just add your padding to TiedFields, but by explicitly typing * padding like this, serialization can make a choice whether to copy Padding, * or instead to omit the copy. * * Omitting the copy isn't always faster. * struct Entry { * uint16_t key; * Padding<uint16_t> padding; * uint32_t val; * auto MutTiedFields() { return std::tie(key, padding, val); } * }; * If you serialize Padding, the serialized size is 8, and the compiler will * optimize serialization to a single 8-byte memcpy. * If your serialization omits Padding, the serialized size of Entry shrinks * by 25%. If you have a big list of Entrys, maybe this is a big savings! * However, by optimizing for size here you sacrifice speed, because this splits * the single memcpy into two: a 2-byte memcpy and a 4-byte memcpy. * * Explicitly marking padding gives callers the option of choosing. */ template <class T, size_t N = 1> struct PaddingField { static_assert(!std::is_array_v<T>, "Use PaddingField<T,N> not <T[N]>."); std::array<T, N> ignored = {}; PaddingField() {} template <class T> struct Padding { T ignored; friend constexpr bool operator==(const PaddingField&, const PaddingField&) { friend constexpr bool operator==(const Padding&, const Padding&) { return true; } friend constexpr bool operator<(const PaddingField&, const PaddingField&) { friend constexpr bool operator<(const Padding&, const Padding&) { return false; } auto MutTiedFields() { return std::tie(ignored); } }; static_assert(sizeof(PaddingField<bool>) == 1); static_assert(sizeof(PaddingField<bool, 2>) == 2); static_assert(sizeof(PaddingField<int>) == 4); static_assert(sizeof(Padding<bool>) == 1); static_assert(sizeof(Padding<bool[2]>) == 2); static_assert(sizeof(Padding<int>) == 4); // - Loading Loading @@ -194,7 +202,7 @@ static_assert(AreAllBytesTiedFields<Fish>()); struct Eel { // Like a Fish, but you can skip serializing the padding. bool b; PaddingField<bool, 3> padding; Padding<bool> padding[3]; int i; constexpr auto MutTiedFields() { return std::tie(i, b, padding); } Loading dom/canvas/WebGLIpdl.h +0 −33 Original line number Diff line number Diff line Loading @@ -244,35 +244,6 @@ struct ParamTraits<mozilla::dom::PredefinedColorSpace> final : public mozilla::dom::WebIDLEnumSerializer< mozilla::dom::PredefinedColorSpace> {}; // - // ParamTraits_IsEnumCase /* `IsEnumCase(T) -> bool` guarantees that we never have false negatives or false positives due to adding or removing enum cases to enums, and forgetting to update their serializations. Also, it allows enums to be non-continguous, unlike ContiguousEnumSerializer. */ template <class T> struct ParamTraits_IsEnumCase { static bool Write(MessageWriter* const writer, const T& in) { MOZ_ASSERT(IsEnumCase(in)); const auto shadow = static_cast<std::underlying_type_t<T>>(in); WriteParam(writer, shadow); return true; } static bool Read(MessageReader* const reader, T* const out) { auto shadow = std::underlying_type_t<T>{}; if (!ReadParam(reader, &shadow)) return false; const auto e = mozilla::AsValidEnum<T>(shadow); if (!e) return false; *out = *e; return true; } }; // - // ParamTraits_TiedFields Loading Loading @@ -301,10 +272,6 @@ struct ParamTraits_TiedFields { } }; template <class U, size_t N> struct ParamTraits<mozilla::PaddingField<U, N>> final : public ParamTraits_TiedFields<mozilla::PaddingField<U, N>> {}; // - template <> Loading dom/canvas/WebGLTypes.h +0 −9 Original line number Diff line number Diff line Loading @@ -1224,15 +1224,6 @@ inline bool StartsWith(const std::string_view str, // - template <class T> Maybe<T> AsValidEnum(const std::underlying_type_t<T> raw_val) { const auto raw_enum = T{raw_val}; // This is the risk we prevent! if (!IsEnumCase(raw_enum)) return {}; return Some(raw_enum); } // - namespace webgl { // In theory, this number can be unbounded based on the driver. However, no Loading dom/ipc/ContentParent.cpp +0 −4 Original line number Diff line number Diff line Loading @@ -644,10 +644,6 @@ static const char* sObserverTopics[] = { DEFAULT_TIMEZONE_CHANGED_OBSERVER_TOPIC, }; void ContentParent_NotifyUpdatedDictionaries() { ContentParent::NotifyUpdatedDictionaries(); } // PreallocateProcess is called by the PreallocatedProcessManager. // ContentParent then takes this process back within GetNewOrUsedBrowserProcess. /*static*/ already_AddRefed<ContentParent> Loading Loading
dom/canvas/QueueParamTraits.h +9 −0 Original line number Diff line number Diff line Loading @@ -261,6 +261,15 @@ struct QueueParamTraits<bool> { // --------------------------------------------------------------- template <class T> Maybe<T> AsValidEnum(const std::underlying_type_t<T> raw_val) { const auto raw_enum = T{raw_val}; // This is the risk we prevent! if (!IsEnumCase(raw_enum)) return {}; return Some(raw_enum); } // - template <class T> struct QueueParamTraits_IsEnumCase { template <typename ProducerView> Loading
dom/canvas/TiedFields.h +30 −22 Original line number Diff line number Diff line Loading @@ -131,34 +131,42 @@ constexpr bool AssertTiedFieldsAreExhaustive() { // - /** * PaddingField<T,N=1> can be used to pad out a struct so that it's not * implicitly padded by struct rules, but also can't be accidentally initialized * via Aggregate Initialization. (TiedFields serialization checks rely on object * fields leaving no implicit padding bytes, but explicit padding fields are * fine) While you can use e.g. `uint8_t _padding[3];`, consider instead * `PaddingField<uint8_t,3> _padding;` for clarity and to move the `3` nearer * to the `uint8_t`. * Padding<T> can be used to pad out a struct so that it's not implicitly * padded by struct rules. * You can also just add your padding to TiedFields, but by explicitly typing * padding like this, serialization can make a choice whether to copy Padding, * or instead to omit the copy. * * Omitting the copy isn't always faster. * struct Entry { * uint16_t key; * Padding<uint16_t> padding; * uint32_t val; * auto MutTiedFields() { return std::tie(key, padding, val); } * }; * If you serialize Padding, the serialized size is 8, and the compiler will * optimize serialization to a single 8-byte memcpy. * If your serialization omits Padding, the serialized size of Entry shrinks * by 25%. If you have a big list of Entrys, maybe this is a big savings! * However, by optimizing for size here you sacrifice speed, because this splits * the single memcpy into two: a 2-byte memcpy and a 4-byte memcpy. * * Explicitly marking padding gives callers the option of choosing. */ template <class T, size_t N = 1> struct PaddingField { static_assert(!std::is_array_v<T>, "Use PaddingField<T,N> not <T[N]>."); std::array<T, N> ignored = {}; PaddingField() {} template <class T> struct Padding { T ignored; friend constexpr bool operator==(const PaddingField&, const PaddingField&) { friend constexpr bool operator==(const Padding&, const Padding&) { return true; } friend constexpr bool operator<(const PaddingField&, const PaddingField&) { friend constexpr bool operator<(const Padding&, const Padding&) { return false; } auto MutTiedFields() { return std::tie(ignored); } }; static_assert(sizeof(PaddingField<bool>) == 1); static_assert(sizeof(PaddingField<bool, 2>) == 2); static_assert(sizeof(PaddingField<int>) == 4); static_assert(sizeof(Padding<bool>) == 1); static_assert(sizeof(Padding<bool[2]>) == 2); static_assert(sizeof(Padding<int>) == 4); // - Loading Loading @@ -194,7 +202,7 @@ static_assert(AreAllBytesTiedFields<Fish>()); struct Eel { // Like a Fish, but you can skip serializing the padding. bool b; PaddingField<bool, 3> padding; Padding<bool> padding[3]; int i; constexpr auto MutTiedFields() { return std::tie(i, b, padding); } Loading
dom/canvas/WebGLIpdl.h +0 −33 Original line number Diff line number Diff line Loading @@ -244,35 +244,6 @@ struct ParamTraits<mozilla::dom::PredefinedColorSpace> final : public mozilla::dom::WebIDLEnumSerializer< mozilla::dom::PredefinedColorSpace> {}; // - // ParamTraits_IsEnumCase /* `IsEnumCase(T) -> bool` guarantees that we never have false negatives or false positives due to adding or removing enum cases to enums, and forgetting to update their serializations. Also, it allows enums to be non-continguous, unlike ContiguousEnumSerializer. */ template <class T> struct ParamTraits_IsEnumCase { static bool Write(MessageWriter* const writer, const T& in) { MOZ_ASSERT(IsEnumCase(in)); const auto shadow = static_cast<std::underlying_type_t<T>>(in); WriteParam(writer, shadow); return true; } static bool Read(MessageReader* const reader, T* const out) { auto shadow = std::underlying_type_t<T>{}; if (!ReadParam(reader, &shadow)) return false; const auto e = mozilla::AsValidEnum<T>(shadow); if (!e) return false; *out = *e; return true; } }; // - // ParamTraits_TiedFields Loading Loading @@ -301,10 +272,6 @@ struct ParamTraits_TiedFields { } }; template <class U, size_t N> struct ParamTraits<mozilla::PaddingField<U, N>> final : public ParamTraits_TiedFields<mozilla::PaddingField<U, N>> {}; // - template <> Loading
dom/canvas/WebGLTypes.h +0 −9 Original line number Diff line number Diff line Loading @@ -1224,15 +1224,6 @@ inline bool StartsWith(const std::string_view str, // - template <class T> Maybe<T> AsValidEnum(const std::underlying_type_t<T> raw_val) { const auto raw_enum = T{raw_val}; // This is the risk we prevent! if (!IsEnumCase(raw_enum)) return {}; return Some(raw_enum); } // - namespace webgl { // In theory, this number can be unbounded based on the driver. However, no Loading
dom/ipc/ContentParent.cpp +0 −4 Original line number Diff line number Diff line Loading @@ -644,10 +644,6 @@ static const char* sObserverTopics[] = { DEFAULT_TIMEZONE_CHANGED_OBSERVER_TOPIC, }; void ContentParent_NotifyUpdatedDictionaries() { ContentParent::NotifyUpdatedDictionaries(); } // PreallocateProcess is called by the PreallocatedProcessManager. // ContentParent then takes this process back within GetNewOrUsedBrowserProcess. /*static*/ already_AddRefed<ContentParent> Loading