Bug 1171240 - Avoid copies when splicing inside ProfileJSONWriter. (r=mstange)

This commit is contained in:
Shu-yu Guo 2015-06-05 18:43:16 -07:00
parent 36047c8f42
commit 559bc8868f
4 changed files with 54 additions and 20 deletions

View File

@ -400,12 +400,6 @@ UniqueStacks::UniqueStacks(JSRuntime* aRuntime)
mStackTableWriter.StartBareList();
}
UniqueStacks::~UniqueStacks()
{
mFrameTableWriter.EndBareList();
mStackTableWriter.EndBareList();
}
uint32_t UniqueStacks::GetOrAddStackIndex(const StackKey& aStack)
{
uint32_t index;
@ -462,14 +456,16 @@ void UniqueStacks::AddJITFrameDepth(void* aAddr, unsigned depth)
mJITFrameDepthMap.Put(aAddr, depth);
}
void UniqueStacks::SpliceFrameTableElements(SpliceableJSONWriter& aWriter) const
void UniqueStacks::SpliceFrameTableElements(SpliceableJSONWriter& aWriter)
{
aWriter.Splice(mFrameTableWriter.WriteFunc());
mFrameTableWriter.EndBareList();
aWriter.TakeAndSplice(mFrameTableWriter.WriteFunc());
}
void UniqueStacks::SpliceStackTableElements(SpliceableJSONWriter& aWriter) const
void UniqueStacks::SpliceStackTableElements(SpliceableJSONWriter& aWriter)
{
aWriter.Splice(mStackTableWriter.WriteFunc());
mStackTableWriter.EndBareList();
aWriter.TakeAndSplice(mStackTableWriter.WriteFunc());
}
void UniqueStacks::StreamStack(const StackKey& aStack)

View File

@ -87,12 +87,8 @@ public:
mStringTableWriter.StartBareList();
}
~UniqueJSONStrings() {
mStringTableWriter.EndBareList();
}
void SpliceStringTableElements(SpliceableJSONWriter& aWriter) const {
aWriter.Splice(mStringTableWriter.WriteFunc());
void SpliceStringTableElements(SpliceableJSONWriter& aWriter) {
aWriter.TakeAndSplice(mStringTableWriter.WriteFunc());
}
void WriteProperty(mozilla::JSONWriter& aWriter, const char* aName, const char* aStr) {
@ -193,13 +189,12 @@ public:
};
explicit UniqueStacks(JSRuntime* aRuntime);
~UniqueStacks();
Stack BeginStack(const OnStackFrameKey& aRoot);
uint32_t LookupJITFrameDepth(void* aAddr);
void AddJITFrameDepth(void* aAddr, unsigned depth);
void SpliceFrameTableElements(SpliceableJSONWriter& aWriter) const;
void SpliceStackTableElements(SpliceableJSONWriter& aWriter) const;
void SpliceFrameTableElements(SpliceableJSONWriter& aWriter);
void SpliceStackTableElements(SpliceableJSONWriter& aWriter);
private:
uint32_t GetOrAddFrameIndex(const OnStackFrameKey& aFrame);

View File

@ -57,6 +57,21 @@ ChunkedJSONWriteFunc::CopyData() const
return c;
}
void
ChunkedJSONWriteFunc::Take(ChunkedJSONWriteFunc&& aOther)
{
for (size_t i = 0; i < aOther.mChunkList.length(); i++) {
MOZ_ALWAYS_TRUE(mChunkLengths.append(aOther.mChunkLengths[i]));
MOZ_ALWAYS_TRUE(mChunkList.append(mozilla::Move(aOther.mChunkList[i])));
}
mChunkPtr = mChunkList.back().get() + mChunkLengths.back();
mChunkEnd = mChunkPtr;
aOther.mChunkPtr = nullptr;
aOther.mChunkEnd = nullptr;
aOther.mChunkList.clear();
aOther.mChunkLengths.clear();
}
void
ChunkedJSONWriteFunc::AllocChunk(size_t aChunkSize)
{
@ -70,12 +85,16 @@ ChunkedJSONWriteFunc::AllocChunk(size_t aChunkSize)
}
void
SpliceableJSONWriter::Splice(const ChunkedJSONWriteFunc* aFunc)
SpliceableJSONWriter::TakeAndSplice(ChunkedJSONWriteFunc* aFunc)
{
Separator();
for (size_t i = 0; i < aFunc->mChunkList.length(); i++) {
WriteFunc()->Write(aFunc->mChunkList[i].get());
}
aFunc->mChunkPtr = nullptr;
aFunc->mChunkEnd = nullptr;
aFunc->mChunkList.clear();
aFunc->mChunkLengths.clear();
mNeedComma[mDepth] = true;
}
@ -86,3 +105,11 @@ SpliceableJSONWriter::Splice(const char* aStr)
WriteFunc()->Write(aStr);
mNeedComma[mDepth] = true;
}
void
SpliceableChunkedJSONWriter::TakeAndSplice(ChunkedJSONWriteFunc* aFunc)
{
Separator();
WriteFunc()->Take(mozilla::Move(*aFunc));
mNeedComma[mDepth] = true;
}

View File

@ -29,8 +29,16 @@ public:
AllocChunk(kChunkSize);
}
bool IsEmpty() const {
MOZ_ASSERT_IF(!mChunkPtr, !mChunkEnd &&
mChunkList.length() == 0 &&
mChunkLengths.length() == 0);
return !mChunkPtr;
}
void Write(const char* aStr) override;
mozilla::UniquePtr<char[]> CopyData() const;
void Take(ChunkedJSONWriteFunc&& aOther);
private:
void AllocChunk(size_t aChunkSize);
@ -93,6 +101,11 @@ public:
void Splice(const ChunkedJSONWriteFunc* aFunc);
void Splice(const char* aStr);
// Takes the chunks from aFunc and write them. If move is not possible
// (e.g., using OStreamJSONWriteFunc), aFunc's chunks are copied and its
// storage cleared.
virtual void TakeAndSplice(ChunkedJSONWriteFunc* aFunc);
};
class SpliceableChunkedJSONWriter : public SpliceableJSONWriter
@ -105,6 +118,9 @@ public:
ChunkedJSONWriteFunc* WriteFunc() const {
return static_cast<ChunkedJSONWriteFunc*>(JSONWriter::WriteFunc());
}
// Adopts the chunks from aFunc without copying.
virtual void TakeAndSplice(ChunkedJSONWriteFunc* aFunc) override;
};
#endif // PROFILEJSONWRITER_H