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
Родитель af0143531b
Коммит 1628f9ba8d
6 изменённых файлов: 25 добавлений и 11 удалений

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

@ -186,12 +186,26 @@ class SpliceableJSONWriter : public JSONWriter {
mNeedComma[mDepth] = true; 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. // Splice the given JSON directly in, without quoting.
void SplicedJSONProperty(const char* aMaybePropertyName, void SplicedJSONProperty(const char* aMaybePropertyName,
const char* aJsonValue) { const char* aJsonValue) {
Scalar(aMaybePropertyName, 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 // Takes the chunks from aFunc and write them. If move is not possible
// (e.g., using OStreamJSONWriteFunc), aFunc's chunks are copied and its // (e.g., using OStreamJSONWriteFunc), aFunc's chunks are copied and its
// storage cleared. // storage cleared.

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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