Bug 1991899 - Use RecordedEventArray for variable-sized recording data. r=aosmond a=RyanVM

Differential Revision: https://phabricator.services.mozilla.com/D267087
This commit is contained in:
Lee Salzman
2025-10-02 14:01:56 +00:00
committed by rvandermeulen@mozilla.com
parent dcb678f865
commit 9121587c58
2 changed files with 160 additions and 93 deletions

View File

@@ -518,6 +518,85 @@ class RecordedStrokeOptionsMixin {
UniquePtr<Float[]> mDashPatternStorage;
};
template <typename T>
class RecordedEventArray {
public:
T* data() { return mData.get(); }
const T* data() const { return mData.get(); }
size_t size() const { return mSize; }
bool empty() const { return !mSize; }
void Assign(const T* aData, size_t aSize) {
mSize = aSize;
mData = MakeUnique<T[]>(aSize);
PodCopy(mData.get(), aData, aSize);
}
bool TryAlloc(size_t aSize) {
if (mSize > 0) {
MOZ_ASSERT_UNREACHABLE();
return false;
}
mData = MakeUniqueFallible<T[]>(aSize);
if (!mData) {
return false;
}
mSize = aSize;
return true;
}
template <typename S>
void Write(S& aStream) const {
if (mSize) {
aStream.write(reinterpret_cast<const char*>(mData.get()),
sizeof(T) * mSize);
}
}
template <typename S>
bool Read(S& aStream, size_t aSize) {
if (!aStream.good() || !TryAlloc(aSize)) {
return false;
}
aStream.read(reinterpret_cast<char*>(mData.get()), sizeof(T) * mSize);
if (!aStream.good()) {
Clear();
return false;
}
return true;
}
void Clear() {
mSize = 0;
mData.reset();
}
protected:
size_t mSize = 0;
UniquePtr<T[]> mData;
};
class RecordedEventCString : public RecordedEventArray<char> {
public:
explicit RecordedEventCString(const char* aStr = nullptr) {
if (aStr) {
if (size_t len = strlen(aStr)) {
Assign(aStr, len + 1);
}
}
}
template <typename S>
bool Read(S& aStream, size_t aSize) {
if (!RecordedEventArray<char>::Read(aStream, aSize) ||
(size() > 0 && !memchr(data(), '\0', size()))) {
Clear();
return false;
}
return true;
}
};
template <class Derived>
class RecordedEventDerived : public RecordedEvent {
using RecordedEvent::RecordedEvent;

View File

@@ -1520,7 +1520,7 @@ class RecordedFontDescriptor
bool mHasDesc;
FontType mType;
std::vector<uint8_t> mData;
RecordedEventArray<uint8_t> mData;
uint32_t mIndex;
ReferencePtr mRefPtr;
@@ -1563,7 +1563,7 @@ class RecordedUnscaledFontCreation
ReferencePtr mRefPtr;
uint64_t mFontDataKey;
uint32_t mIndex;
std::vector<uint8_t> mInstanceData;
RecordedEventArray<uint8_t> mInstanceData;
template <class S>
MOZ_IMPLICIT RecordedUnscaledFontCreation(S& aStream);
@@ -1630,8 +1630,8 @@ class RecordedScaledFontCreation
ReferencePtr mRefPtr;
ReferencePtr mUnscaledFont;
Float mGlyphSize;
std::vector<uint8_t> mInstanceData;
std::vector<FontVariation> mVariations;
RecordedEventArray<uint8_t> mInstanceData;
RecordedEventArray<FontVariation> mVariations;
template <class S>
MOZ_IMPLICIT RecordedScaledFontCreation(S& aStream);
@@ -1719,8 +1719,7 @@ class RecordedFilterNodeSetAttribute
mNode(aNode),
mIndex(aIndex),
mArgType(aArgType) {
mPayload.resize(sizeof(T));
memcpy(&mPayload.front(), &aArgument, sizeof(T));
mPayload.Assign(reinterpret_cast<const uint8_t*>(&aArgument), sizeof(T));
}
RecordedFilterNodeSetAttribute(FilterNode* aNode, uint32_t aIndex,
@@ -1729,8 +1728,8 @@ class RecordedFilterNodeSetAttribute
mNode(aNode),
mIndex(aIndex),
mArgType(ARGTYPE_FLOAT_ARRAY) {
mPayload.resize(sizeof(Float) * aSize);
memcpy(&mPayload.front(), aFloat, sizeof(Float) * aSize);
mPayload.Assign(reinterpret_cast<const uint8_t*>(aFloat),
sizeof(Float) * aSize);
}
bool PlayEvent(Translator* aTranslator) const override;
@@ -1747,7 +1746,7 @@ class RecordedFilterNodeSetAttribute
uint32_t mIndex;
ArgType mArgType;
std::vector<uint8_t> mPayload;
RecordedEventArray<uint8_t> mPayload;
template <class S>
MOZ_IMPLICIT RecordedFilterNodeSetAttribute(S& aStream);
@@ -1809,8 +1808,8 @@ class RecordedLink : public RecordedEventDerived<RecordedLink> {
private:
friend class RecordedEvent;
std::string mLocalDest;
std::string mURI;
RecordedEventCString mLocalDest;
RecordedEventCString mURI;
Rect mRect;
template <class S>
@@ -1834,7 +1833,7 @@ class RecordedDestination : public RecordedEventDerived<RecordedDestination> {
private:
friend class RecordedEvent;
std::string mDestination;
RecordedEventCString mDestination;
Point mPoint;
template <class S>
@@ -4104,10 +4103,8 @@ void RecordedFontDescriptor::Record(S& aStream) const {
WriteElement(aStream, mType);
WriteElement(aStream, mRefPtr);
WriteElement(aStream, mIndex);
WriteElement(aStream, (size_t)mData.size());
if (mData.size()) {
aStream.write((char*)mData.data(), mData.size());
}
WriteElement(aStream, mData.size());
mData.Write(aStream);
}
inline void RecordedFontDescriptor::OutputSimpleEventInfo(
@@ -4118,7 +4115,7 @@ inline void RecordedFontDescriptor::OutputSimpleEventInfo(
inline void RecordedFontDescriptor::SetFontDescriptor(const uint8_t* aData,
uint32_t aSize,
uint32_t aIndex) {
mData.assign(aData, aData + aSize);
mData.Assign(aData, aSize);
mIndex = aIndex;
}
@@ -4129,14 +4126,14 @@ RecordedFontDescriptor::RecordedFontDescriptor(S& aStream)
ReadElement(aStream, mRefPtr);
ReadElement(aStream, mIndex);
size_t size;
size_t size = 0;
ReadElement(aStream, size);
if (!aStream.good()) {
return;
}
if (size) {
mData.resize(size);
aStream.read((char*)mData.data(), size);
if (size && !mData.Read(aStream, size)) {
aStream.SetIsBad();
return;
}
}
@@ -4162,10 +4159,8 @@ void RecordedUnscaledFontCreation::Record(S& aStream) const {
WriteElement(aStream, mRefPtr);
WriteElement(aStream, mFontDataKey);
WriteElement(aStream, mIndex);
WriteElement(aStream, (size_t)mInstanceData.size());
if (mInstanceData.size()) {
aStream.write((char*)mInstanceData.data(), mInstanceData.size());
}
WriteElement(aStream, mInstanceData.size());
mInstanceData.Write(aStream);
}
inline void RecordedUnscaledFontCreation::OutputSimpleEventInfo(
@@ -4176,7 +4171,7 @@ inline void RecordedUnscaledFontCreation::OutputSimpleEventInfo(
inline void RecordedUnscaledFontCreation::SetFontInstanceData(
const uint8_t* aData, uint32_t aSize) {
if (aSize) {
mInstanceData.assign(aData, aData + aSize);
mInstanceData.Assign(aData, aSize);
}
}
@@ -4187,14 +4182,14 @@ RecordedUnscaledFontCreation::RecordedUnscaledFontCreation(S& aStream)
ReadElement(aStream, mFontDataKey);
ReadElement(aStream, mIndex);
size_t size;
size_t size = 0;
ReadElement(aStream, size);
if (!aStream.good()) {
return;
}
if (size) {
mInstanceData.resize(size);
aStream.read((char*)mInstanceData.data(), size);
if (size && !mInstanceData.Read(aStream, size)) {
aStream.SetIsBad();
return;
}
}
@@ -4243,15 +4238,10 @@ void RecordedScaledFontCreation::Record(S& aStream) const {
WriteElement(aStream, mRefPtr);
WriteElement(aStream, mUnscaledFont);
WriteElement(aStream, mGlyphSize);
WriteElement(aStream, (size_t)mInstanceData.size());
if (mInstanceData.size()) {
aStream.write((char*)mInstanceData.data(), mInstanceData.size());
}
WriteElement(aStream, (size_t)mVariations.size());
if (mVariations.size()) {
aStream.write((char*)mVariations.data(),
sizeof(FontVariation) * mVariations.size());
}
WriteElement(aStream, mInstanceData.size());
mInstanceData.Write(aStream);
WriteElement(aStream, mVariations.size());
mVariations.Write(aStream);
}
inline void RecordedScaledFontCreation::OutputSimpleEventInfo(
@@ -4263,10 +4253,10 @@ inline void RecordedScaledFontCreation::SetFontInstanceData(
const uint8_t* aData, uint32_t aSize, const FontVariation* aVariations,
uint32_t aNumVariations) {
if (aSize) {
mInstanceData.assign(aData, aData + aSize);
mInstanceData.Assign(aData, aSize);
}
if (aNumVariations) {
mVariations.assign(aVariations, aVariations + aNumVariations);
mVariations.Assign(aVariations, aNumVariations);
}
}
@@ -4277,25 +4267,24 @@ RecordedScaledFontCreation::RecordedScaledFontCreation(S& aStream)
ReadElement(aStream, mUnscaledFont);
ReadElement(aStream, mGlyphSize);
size_t size;
size_t size = 0;
ReadElement(aStream, size);
if (!aStream.good()) {
return;
}
if (size) {
mInstanceData.resize(size);
aStream.read((char*)mInstanceData.data(), size);
if (size && !mInstanceData.Read(aStream, size)) {
aStream.SetIsBad();
return;
}
size_t numVariations;
size_t numVariations = 0;
ReadElement(aStream, numVariations);
if (!aStream.good()) {
return;
}
if (numVariations) {
mVariations.resize(numVariations);
aStream.read((char*)mVariations.data(),
sizeof(FontVariation) * numVariations);
if (numVariations && !mVariations.Read(aStream, numVariations)) {
aStream.SetIsBad();
return;
}
}
@@ -4373,9 +4362,12 @@ inline bool RecordedFilterNodeSetAttribute::PlayEvent(
return false;
}
#define REPLAY_SET_ATTRIBUTE(type, argtype) \
case ARGTYPE_##argtype: \
ReplaySetAttribute(node, mIndex, *(type*)&mPayload.front()); \
#define REPLAY_SET_ATTRIBUTE(type, argtype) \
case ARGTYPE_##argtype: \
if (mPayload.size() < sizeof(type)) { \
return false; \
} \
ReplaySetAttribute(node, mIndex, *(type*)mPayload.data()); \
break
switch (mArgType) {
@@ -4394,7 +4386,7 @@ inline bool RecordedFilterNodeSetAttribute::PlayEvent(
REPLAY_SET_ATTRIBUTE(DeviceColor, COLOR);
case ARGTYPE_FLOAT_ARRAY:
node->SetAttribute(mIndex,
reinterpret_cast<const Float*>(&mPayload.front()),
reinterpret_cast<const Float*>(mPayload.data()),
mPayload.size() / sizeof(Float));
break;
}
@@ -4407,8 +4399,8 @@ void RecordedFilterNodeSetAttribute::Record(S& aStream) const {
WriteElement(aStream, mNode);
WriteElement(aStream, mIndex);
WriteElement(aStream, mArgType);
WriteElement(aStream, uint64_t(mPayload.size()));
aStream.write((const char*)&mPayload.front(), mPayload.size());
WriteElement(aStream, mPayload.size());
mPayload.Write(aStream);
}
template <class S>
@@ -4418,14 +4410,16 @@ RecordedFilterNodeSetAttribute::RecordedFilterNodeSetAttribute(S& aStream)
ReadElement(aStream, mIndex);
ReadElementConstrained(aStream, mArgType, ArgType::ARGTYPE_UINT32,
ArgType::ARGTYPE_FLOAT_ARRAY);
uint64_t size;
size_t size = 0;
ReadElement(aStream, size);
if (!aStream.good()) {
return;
}
mPayload.resize(size_t(size));
aStream.read((char*)&mPayload.front(), size);
if (size && !mPayload.Read(aStream, size)) {
aStream.SetIsBad();
return;
}
}
inline void RecordedFilterNodeSetAttribute::OutputSimpleEventInfo(
@@ -4484,48 +4478,44 @@ inline bool RecordedLink::PlayEvent(Translator* aTranslator) const {
if (!dt) {
return false;
}
dt->Link(mLocalDest.c_str(), mURI.c_str(), mRect);
dt->Link(mLocalDest.data(), mURI.data(), mRect);
return true;
}
template <class S>
void RecordedLink::Record(S& aStream) const {
WriteElement(aStream, mRect);
uint32_t len = mLocalDest.length();
WriteElement(aStream, len);
if (len) {
aStream.write(mLocalDest.data(), len);
}
len = mURI.length();
WriteElement(aStream, len);
if (len) {
aStream.write(mURI.data(), len);
}
WriteElement(aStream, mLocalDest.size());
mLocalDest.Write(aStream);
WriteElement(aStream, mURI.size());
mURI.Write(aStream);
}
template <class S>
RecordedLink::RecordedLink(S& aStream) : RecordedEventDerived(LINK) {
ReadElement(aStream, mRect);
uint32_t len;
ReadElement(aStream, len);
mLocalDest.resize(size_t(len));
if (len && aStream.good()) {
aStream.read(&mLocalDest.front(), len);
size_t localDestLen = 0;
ReadElement(aStream, localDestLen);
if (!aStream.good() ||
(localDestLen && !mLocalDest.Read(aStream, localDestLen))) {
aStream.SetIsBad();
return;
}
ReadElement(aStream, len);
mURI.resize(size_t(len));
if (len && aStream.good()) {
aStream.read(&mURI.front(), len);
size_t uriLen = 0;
ReadElement(aStream, uriLen);
if (!aStream.good() || (uriLen && !mURI.Read(aStream, uriLen))) {
aStream.SetIsBad();
return;
}
}
inline void RecordedLink::OutputSimpleEventInfo(
std::stringstream& aStringStream) const {
if (mLocalDest.empty()) {
aStringStream << "Link [" << mURI << " @ " << mRect << "]";
aStringStream << "Link [" << mURI.data() << " @ " << mRect << "]";
} else {
aStringStream << "Link [" << mLocalDest << " / " << mURI << " @ " << mRect
<< "]";
aStringStream << "Link [" << mLocalDest.data() << " / " << mURI.data()
<< " @ " << mRect << "]";
}
}
@@ -4534,35 +4524,33 @@ inline bool RecordedDestination::PlayEvent(Translator* aTranslator) const {
if (!dt) {
return false;
}
dt->Destination(mDestination.c_str(), mPoint);
dt->Destination(mDestination.data(), mPoint);
return true;
}
template <class S>
void RecordedDestination::Record(S& aStream) const {
WriteElement(aStream, mPoint);
uint32_t len = mDestination.length();
WriteElement(aStream, len);
if (len) {
aStream.write(mDestination.data(), len);
}
WriteElement(aStream, mDestination.size());
mDestination.Write(aStream);
}
template <class S>
RecordedDestination::RecordedDestination(S& aStream)
: RecordedEventDerived(DESTINATION) {
ReadElement(aStream, mPoint);
uint32_t len;
size_t len = 0;
ReadElement(aStream, len);
mDestination.resize(size_t(len));
if (len && aStream.good()) {
aStream.read(&mDestination.front(), len);
if (!aStream.good() || (len && !mDestination.Read(aStream, len))) {
aStream.SetIsBad();
return;
}
}
inline void RecordedDestination::OutputSimpleEventInfo(
std::stringstream& aStringStream) const {
aStringStream << "Destination [" << mDestination << " @ " << mPoint << "]";
aStringStream << "Destination [" << mDestination.data() << " @ " << mPoint
<< "]";
}
#define FOR_EACH_EVENT(f) \