Bug 1660177 - Replace SpliceableJSONWriter::Splice(const char*) with better calls where possible - r=canaltinova

In most calls to `SpliceableJSONWriter::Splice(const char*)`:
- The data comes from a `ChunkedJSONWriteFunc` and is copied to a new buffer, which is then copied again through `Write()`. Instead we can copy the data directly from the `ChunkedJSONWriteFunc`; and this is a nice complement to `TakeAndSplice()` below.
- Or the length is already known, so we can pass it to a new `Splice(const char*, size_t)`, which forwards it to `Write(const char*, size_t)`, saving one `strlen` call.

Differential Revision: https://phabricator.services.mozilla.com/D87703
This commit is contained in:
Gerald Squelart 2020-08-26 08:03:20 +00:00
parent af0143531b
commit 1628f9ba8d
6 changed files with 25 additions and 11 deletions

View File

@ -205,9 +205,8 @@ UniqueJSONStrings::UniqueJSONStrings(const UniqueJSONStrings& aOther) {
mStringHashToIndexMap.putNewInfallible(iter.get().key(),
iter.get().value());
}
UniquePtr<char[]> stringTableJSON =
aOther.mStringTableWriter.ChunkedWriteFunc().CopyData();
mStringTableWriter.Splice(stringTableJSON.get());
mStringTableWriter.CopyAndSplice(
aOther.mStringTableWriter.ChunkedWriteFunc());
}
}

View File

@ -2927,7 +2927,7 @@ static void locked_profiler_save_profile_to_file(PSLockRef aLock,
Vector<std::string> exitProfiles = ActivePS::MoveExitProfiles(aLock);
for (auto& exitProfile : exitProfiles) {
if (!exitProfile.empty()) {
w.Splice(exitProfile.c_str());
w.Splice(exitProfile.c_str(), exitProfile.length());
}
}
w.EndArray();

View File

@ -186,12 +186,26 @@ class SpliceableJSONWriter : public JSONWriter {
mNeedComma[mDepth] = true;
}
void Splice(const char* aStr, size_t aLen) {
Separator();
WriteFunc()->Write(aStr, aLen);
mNeedComma[mDepth] = true;
}
// Splice the given JSON directly in, without quoting.
void SplicedJSONProperty(const char* aMaybePropertyName,
const char* aJsonValue) {
Scalar(aMaybePropertyName, aJsonValue);
}
void CopyAndSplice(const ChunkedJSONWriteFunc& aFunc) {
Separator();
for (size_t i = 0; i < aFunc.mChunkList.length(); i++) {
WriteFunc()->Write(aFunc.mChunkList[i].get(), aFunc.mChunkLengths[i]);
}
mNeedComma[mDepth] = true;
}
// 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.

View File

@ -217,9 +217,8 @@ UniqueJSONStrings::UniqueJSONStrings(const UniqueJSONStrings& aOther) {
mStringHashToIndexMap.putNewInfallible(iter.get().key(),
iter.get().value());
}
UniquePtr<char[]> stringTableJSON =
aOther.mStringTableWriter.ChunkedWriteFunc().CopyData();
mStringTableWriter.Splice(stringTableJSON.get());
mStringTableWriter.CopyAndSplice(
aOther.mStringTableWriter.ChunkedWriteFunc());
}
}
@ -357,7 +356,8 @@ UniqueStacks::LookupFramesForJITAddressFromBufferPos(void* aJITAddress,
auto frameJSON =
jitFrameInfoRange.mJITFrameToFrameJSONMap.lookup(jitFrameKey);
MOZ_RELEASE_ASSERT(frameJSON, "Should have cached JSON for this frame");
mFrameTableWriter.Splice(frameJSON->value().get());
mFrameTableWriter.Splice(frameJSON->value().get(),
frameJSON->value().Length());
MOZ_RELEASE_ASSERT(mFrameToIndexMap.add(entry, frameKey, index));
}
MOZ_RELEASE_ASSERT(frameKeys.append(std::move(frameKey)));

View File

@ -4418,7 +4418,7 @@ static void locked_profiler_save_profile_to_file(
Vector<nsCString> exitProfiles = ActivePS::MoveExitProfiles(aLock);
for (auto& exitProfile : exitProfiles) {
if (!exitProfile.IsEmpty()) {
w.Splice(exitProfile.get());
w.Splice(exitProfile.get(), exitProfile.Length());
}
}
w.EndArray();

View File

@ -807,7 +807,8 @@ void nsProfiler::GatheredOOPProfile(const nsACString& aProfile) {
"Should always have a writer if mGathering is true");
if (!aProfile.IsEmpty()) {
mWriter->Splice(PromiseFlatCString(aProfile).get());
// TODO: Remove PromiseFlatCString, see bug 1657033.
mWriter->Splice(PromiseFlatCString(aProfile).get(), aProfile.Length());
}
mPendingProfiles--;
@ -890,7 +891,7 @@ RefPtr<nsProfiler::GatheringPromise> nsProfiler::StartGathering(
Vector<nsCString> exitProfiles = profiler_move_exit_profiles();
for (auto& exitProfile : exitProfiles) {
if (!exitProfile.IsEmpty()) {
mWriter->Splice(exitProfile.get());
mWriter->Splice(exitProfile.get(), exitProfile.Length());
}
}