Backed out changeset ebc075fd132d (bug 1885246) for causing bc failures in /EnumSerializer.h CLOSED TREE

This commit is contained in:
Cristian Tuns 2024-03-23 02:08:24 -04:00
parent 4567c07891
commit ddbddee3ca
18 changed files with 117 additions and 149 deletions

View File

@ -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>

View File

@ -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]>.");
template <class T>
struct Padding {
T ignored;
std::array<T, N> ignored = {};
PaddingField() {}
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);
// -
@ -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); }

View File

@ -244,45 +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;
}
};
// -
#define USE_IS_ENUM_CASE(T) \
template <> \
struct ParamTraits<T> : public ParamTraits_IsEnumCase<T> {};
USE_IS_ENUM_CASE(mozilla::webgl::OptionalRenderableFormatBits)
#undef USE_IS_ENUM_CASE
// -
// ParamTraits_TiedFields
@ -311,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 <>
@ -652,6 +609,35 @@ struct ParamTraits<mozilla::avec3<U>> final {
}
};
// -
template <class TT>
struct ParamTraits_IsEnumCase {
using T = TT;
static void Write(IPC::MessageWriter* const writer, const T& in) {
MOZ_RELEASE_ASSERT(IsEnumCase(in));
WriteParam(writer, mozilla::UnderlyingValue(in));
}
static bool Read(IPC::MessageReader* const reader, T* const out) {
std::underlying_type_t<T> rawVal;
if (!ReadParam(reader, &rawVal)) return false;
*out = static_cast<T>(rawVal);
return IsEnumCase(*out);
}
};
// -
#define USE_IS_ENUM_CASE(T) \
template <> \
struct ParamTraits<T> : public ParamTraits_IsEnumCase<T> {};
USE_IS_ENUM_CASE(mozilla::webgl::OptionalRenderableFormatBits)
#undef USE_IS_ENUM_CASE
} // namespace IPC
#endif

View File

@ -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

View File

@ -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>

View File

@ -1,17 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_ContentParent_NotifyUpdatedDictionaries_h
#define mozilla_dom_ContentParent_NotifyUpdatedDictionaries_h
// Avoid including ContentParent.h because it ends up including WebGLTypes.h,
// where we have our mozilla::malloc(ForbidNarrowing<size_t>) overrides, which
// cause issues with the way hunspell overrides malloc for itself.
namespace mozilla::dom {
void ContentParent_NotifyUpdatedDictionaries();
} // namespace mozilla::dom
#endif // mozilla_dom_ContentParent_NotifyUpdatedDictionaries_h

View File

@ -52,7 +52,6 @@ EXPORTS.mozilla.dom += [
"CoalescedWheelData.h",
"ContentChild.h",
"ContentParent.h",
"ContentParent_NotifyUpdatedDictionaries.h",
"ContentProcess.h",
"ContentProcessManager.h",
"CSPMessageUtils.h",

View File

@ -109,16 +109,12 @@ struct FlacCodecSpecificData {
RefPtr<MediaByteBuffer> mStreamInfoBinaryBlob{new MediaByteBuffer};
};
struct Mp3CodecSpecificData final {
struct Mp3CodecSpecificData {
bool operator==(const Mp3CodecSpecificData& rhs) const {
return mEncoderDelayFrames == rhs.mEncoderDelayFrames &&
mEncoderPaddingFrames == rhs.mEncoderPaddingFrames;
}
auto MutTiedFields() {
return std::tie(mEncoderDelayFrames, mEncoderPaddingFrames);
}
// The number of frames that should be skipped from the beginning of the
// decoded stream.
// See https://bugzilla.mozilla.org/show_bug.cgi?id=1566389 for more info.

View File

@ -15,7 +15,6 @@
#include "ipc/EnumSerializer.h"
#include "mozilla/EnumSet.h"
#include "mozilla/GfxMessageUtils.h"
#include "mozilla/dom/WebGLIpdl.h"
#include "mozilla/gfx/Rect.h"
#include "mozilla/dom/MFCDMSerializers.h"
@ -140,7 +139,7 @@ struct ParamTraits<mozilla::FlacCodecSpecificData> {
template <>
struct ParamTraits<mozilla::Mp3CodecSpecificData>
: public ParamTraits_TiedFields<mozilla::Mp3CodecSpecificData> {};
: public PlainOldDataSerializer<mozilla::Mp3CodecSpecificData> {};
template <>
struct ParamTraits<mozilla::OpusCodecSpecificData> {

View File

@ -49,6 +49,9 @@
#include "secerr.h"
#include "sslerr.h"
#define BUFFER_SIZE 65536
#define NETWORK_STATS_THRESHOLD 65536
using namespace mozilla::dom;
NS_IMPL_CYCLE_COLLECTION(LegacyMozTCPSocket, mGlobal)

View File

@ -69,14 +69,14 @@
#include "nsIPrefBranch.h"
#include "nsIPrefService.h"
#include "nsNetUtil.h"
#include "prenv.h"
#include "mozilla/dom/ContentParent.h"
#include "mozilla/Components.h"
#include "mozilla/Services.h"
#include "mozilla/dom/ContentParent_NotifyUpdatedDictionaries.h"
#include <stdlib.h>
#include <tuple>
using mozilla::dom::ContentParent;
using namespace mozilla;
NS_IMPL_CYCLE_COLLECTING_ADDREF(mozHunspell)
@ -294,7 +294,7 @@ void mozHunspell::DictionariesChanged(bool aNotifyChildProcesses) {
mozInlineSpellChecker::UpdateCanEnableInlineSpellChecking();
if (aNotifyChildProcesses) {
mozilla::dom::ContentParent_NotifyUpdatedDictionaries();
ContentParent::NotifyUpdatedDictionaries();
}
// Check if the current dictionaries are still available.

View File

@ -700,7 +700,7 @@ MOZ_DEFINE_ENUM_CLASS_WITH_BASE(
std::ostream& operator<<(std::ostream& aStream,
const OverscrollBehavior& aBehavior);
struct OverscrollBehaviorInfo final {
struct OverscrollBehaviorInfo {
OverscrollBehaviorInfo();
// Construct from StyleOverscrollBehavior values.
@ -711,8 +711,6 @@ struct OverscrollBehaviorInfo final {
friend std::ostream& operator<<(std::ostream& aStream,
const OverscrollBehaviorInfo& aInfo);
auto MutTiedFields() { return std::tie(mBehaviorX, mBehaviorY); }
OverscrollBehavior mBehaviorX;
OverscrollBehavior mBehaviorY;
};

View File

@ -46,11 +46,9 @@ class TextureHost;
#undef NONE
#undef OPAQUE
struct LayersId final {
struct LayersId {
uint64_t mId = 0;
auto MutTiedFields() { return std::tie(mId); }
bool IsValid() const { return mId != 0; }
// Allow explicit cast to a uint64_t for now
@ -77,11 +75,9 @@ struct LayersId final {
};
template <typename T>
struct BaseTransactionId final {
struct BaseTransactionId {
uint64_t mId = 0;
auto MutTiedFields() { return std::tie(mId); }
bool IsValid() const { return mId != 0; }
[[nodiscard]] BaseTransactionId<T> Next() const {

View File

@ -18,7 +18,6 @@
#include "ipc/IPCMessageUtils.h"
#include "mozilla/ScrollSnapInfo.h"
#include "mozilla/ServoBindings.h"
#include "mozilla/dom/WebGLIpdl.h"
#include "mozilla/ipc/ByteBuf.h"
#include "mozilla/ipc/ProtocolMessageUtils.h"
#include "mozilla/layers/APZInputBridge.h"
@ -49,11 +48,15 @@ namespace IPC {
template <>
struct ParamTraits<mozilla::layers::LayersId>
: public ParamTraits_TiedFields<mozilla::layers::LayersId> {};
: public PlainOldDataSerializer<mozilla::layers::LayersId> {};
template <typename T>
struct ParamTraits<mozilla::layers::BaseTransactionId<T>>
: public ParamTraits_TiedFields<mozilla::layers::BaseTransactionId<T>> {};
: public PlainOldDataSerializer<mozilla::layers::BaseTransactionId<T>> {};
template <>
struct ParamTraits<mozilla::VsyncId>
: public PlainOldDataSerializer<mozilla::VsyncId> {};
template <>
struct ParamTraits<mozilla::VsyncEvent> {
@ -416,7 +419,7 @@ struct ParamTraits<mozilla::StyleScrollSnapStop>
template <>
struct ParamTraits<mozilla::ScrollSnapTargetId>
: public ParamTraits_IsEnumCase<mozilla::ScrollSnapTargetId> {};
: public PlainOldDataSerializer<mozilla::ScrollSnapTargetId> {};
template <>
struct ParamTraits<mozilla::SnapPoint> {
@ -492,12 +495,26 @@ struct ParamTraits<mozilla::ScrollSnapInfo> {
};
template <>
struct ParamTraits<mozilla::layers::OverscrollBehaviorInfo>
: public ParamTraits_TiedFields<mozilla::layers::OverscrollBehaviorInfo> {};
struct ParamTraits<mozilla::layers::OverscrollBehaviorInfo> {
// Not using PlainOldDataSerializer so we get enum validation
// for the members.
typedef mozilla::layers::OverscrollBehaviorInfo paramType;
static void Write(MessageWriter* aWriter, const paramType& aParam) {
WriteParam(aWriter, aParam.mBehaviorX);
WriteParam(aWriter, aParam.mBehaviorY);
}
static bool Read(MessageReader* aReader, paramType* aResult) {
return (ReadParam(aReader, &aResult->mBehaviorX) &&
ReadParam(aReader, &aResult->mBehaviorY));
}
};
template <typename T>
struct ParamTraits<mozilla::ScrollGeneration<T>>
: public ParamTraits_TiedFields<mozilla::ScrollGeneration<T>> {};
: PlainOldDataSerializer<mozilla::ScrollGeneration<T>> {};
template <>
struct ParamTraits<mozilla::ScrollUpdateType>

View File

@ -12,7 +12,6 @@
#include "base/process.h"
#include "ipc/IPCMessageUtils.h"
#include "ipc/IPCMessageUtilsSpecializations.h"
#include "mozilla/dom/WebGLIpdl.h"
#include "mozilla/gfx/Point.h" // for IntSize
namespace mozilla {
@ -27,16 +26,8 @@ class SharedSurfacesMemoryReport final {
int32_t mStride;
uint32_t mConsumers;
bool mCreatorRef;
PaddingField<bool, 3> _padding;
auto MutTiedFields() {
return std::tie(mCreatorPid, mSize, mStride, mConsumers, mCreatorRef,
_padding);
}
};
auto MutTiedFields() { return std::tie(mSurfaces); }
std::unordered_map<uint64_t, SurfaceEntry> mSurfaces;
};
@ -46,13 +37,21 @@ class SharedSurfacesMemoryReport final {
namespace IPC {
template <>
struct ParamTraits<mozilla::layers::SharedSurfacesMemoryReport>
: public ParamTraits_TiedFields<
mozilla::layers::SharedSurfacesMemoryReport> {};
struct ParamTraits<mozilla::layers::SharedSurfacesMemoryReport> {
typedef mozilla::layers::SharedSurfacesMemoryReport paramType;
static void Write(MessageWriter* aWriter, const paramType& aParam) {
WriteParam(aWriter, aParam.mSurfaces);
}
static bool Read(MessageReader* aReader, paramType* aResult) {
return ReadParam(aReader, &aResult->mSurfaces);
}
};
template <>
struct ParamTraits<mozilla::layers::SharedSurfacesMemoryReport::SurfaceEntry>
: public ParamTraits_TiedFields<
: public PlainOldDataSerializer<
mozilla::layers::SharedSurfacesMemoryReport::SurfaceEntry> {};
} // namespace IPC

View File

@ -7,7 +7,6 @@
#include <cstdint>
#include <iosfwd>
#include <tuple>
namespace mozilla {
@ -24,7 +23,7 @@ std::ostream& operator<<(std::ostream& aStream,
const ScrollGeneration<Tag>& aGen);
template <typename Tag>
struct ScrollGeneration final {
struct ScrollGeneration {
friend struct ScrollGenerationCounter;
private:
@ -44,8 +43,6 @@ struct ScrollGeneration final {
friend std::ostream& operator<< <>(std::ostream& aStream,
const ScrollGeneration<Tag>& aGen);
auto MutTiedFields() { return std::tie(mValue); }
private:
uint64_t mValue;
};

View File

@ -17,7 +17,6 @@ namespace mozilla {
enum class ScrollSnapTargetId : uintptr_t {
None = 0,
};
inline constexpr bool IsEnumCase(ScrollSnapTargetId) { return true; }
struct ScrollSnapTargetIds {
CopyableTArray<ScrollSnapTargetId> mIdsOnX;

View File

@ -12,7 +12,6 @@
#include "mozilla/TelemetryProcessEnums.h"
#include "mozilla/TimeStamp.h"
#include "mozilla/Variant.h"
#include "mozilla/dom/WebGLIpdl.h"
#include "nsITelemetry.h"
namespace mozilla {
@ -97,13 +96,6 @@ struct DiscardedData {
uint32_t mDiscardedScalarActions;
uint32_t mDiscardedKeyedScalarActions;
uint32_t mDiscardedChildEvents;
auto MutTiedFields() {
return std::tie(mDiscardedHistogramAccumulations,
mDiscardedKeyedHistogramAccumulations,
mDiscardedScalarActions, mDiscardedKeyedScalarActions,
mDiscardedChildEvents);
}
};
} // namespace Telemetry
@ -401,7 +393,7 @@ struct ParamTraits<mozilla::Telemetry::EventExtraEntry> {
template <>
struct ParamTraits<mozilla::Telemetry::DiscardedData>
: public ParamTraits_TiedFields<mozilla::Telemetry::DiscardedData> {};
: public PlainOldDataSerializer<mozilla::Telemetry::DiscardedData> {};
} // namespace IPC