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; 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> template <class Derived>
class RecordedEventDerived : public RecordedEvent { class RecordedEventDerived : public RecordedEvent {
using RecordedEvent::RecordedEvent; using RecordedEvent::RecordedEvent;

View File

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