Bug 1466783 - Avoid copying while passing the profiler data with IPC r=mstange

MozReview-Commit-ID: HfskcLojToC

--HG--
extra : rebase_source : e88e6770d29bdda3b7b46ea9eb28ecdc36b3f0ee
This commit is contained in:
Nazım Can Altınova 2018-06-15 11:16:41 -07:00
Родитель 9873588035
Коммит 118413a3d9
5 изменённых файлов: 81 добавлений и 36 удалений

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

@ -37,8 +37,8 @@ ChunkedJSONWriteFunc::Write(const char* aStr)
mChunkLengths.back() += len;
}
mozilla::UniquePtr<char[]>
ChunkedJSONWriteFunc::CopyData() const
size_t
ChunkedJSONWriteFunc::GetTotalLength() const
{
MOZ_ASSERT(mChunkLengths.length() == mChunkList.length());
size_t totalLen = 1;
@ -46,14 +46,31 @@ ChunkedJSONWriteFunc::CopyData() const
MOZ_ASSERT(strlen(mChunkList[i].get()) == mChunkLengths[i]);
totalLen += mChunkLengths[i];
}
mozilla::UniquePtr<char[]> c = mozilla::MakeUnique<char[]>(totalLen);
char* ptr = c.get();
return totalLen;
}
void
ChunkedJSONWriteFunc::CopyDataIntoLazilyAllocatedBuffer(
const std::function<char*(size_t)>& aAllocator) const
{
size_t totalLen = GetTotalLength();
char* ptr = aAllocator(totalLen);
for (size_t i = 0; i < mChunkList.length(); i++) {
size_t len = mChunkLengths[i];
memcpy(ptr, mChunkList[i].get(), len);
ptr += len;
}
*ptr = '\0';
}
mozilla::UniquePtr<char[]>
ChunkedJSONWriteFunc::CopyData() const
{
mozilla::UniquePtr<char[]> c;
CopyDataIntoLazilyAllocatedBuffer([&](size_t allocationSize) {
c = mozilla::MakeUnique<char[]>(allocationSize);
return c.get();
});
return c;
}

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

@ -37,8 +37,13 @@ public:
}
void Write(const char* aStr) override;
void CopyDataIntoLazilyAllocatedBuffer(
const std::function<char*(size_t)>& aAllocator) const;
mozilla::UniquePtr<char[]> CopyData() const;
void Take(ChunkedJSONWriteFunc&& aOther);
// Returns the byte length of the complete combined string, including the
// null terminator byte.
size_t GetTotalLength() const;
private:
void AllocChunk(size_t aChunkSize);

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

@ -2657,29 +2657,57 @@ profiler_shutdown()
}
}
static bool
WriteProfileToJSONWriter(SpliceableChunkedJSONWriter& aWriter,
double aSinceTime,
bool aIsShuttingDown)
{
LOG("WriteProfileToJSONWriter");
MOZ_RELEASE_ASSERT(CorePS::Exists());
aWriter.Start();
{
if (!profiler_stream_json_for_this_process(
aWriter, aSinceTime, aIsShuttingDown)) {
return false;
}
// Don't include profiles from other processes because this is a
// synchronous function.
aWriter.StartArrayProperty("processes");
aWriter.EndArray();
}
aWriter.End();
return true;
}
UniquePtr<char[]>
profiler_get_profile(double aSinceTime, bool aIsShuttingDown)
{
LOG("profiler_get_profile");
MOZ_RELEASE_ASSERT(CorePS::Exists());
SpliceableChunkedJSONWriter b;
if (!WriteProfileToJSONWriter(b, aSinceTime, aIsShuttingDown)) {
return nullptr;
}
return b.WriteFunc()->CopyData();
}
void
profiler_get_profile_json_into_lazily_allocated_buffer(
const std::function<char*(size_t)>& aAllocator,
double aSinceTime,
bool aIsShuttingDown)
{
LOG("profiler_get_profile_json_into_lazily_allocated_buffer");
SpliceableChunkedJSONWriter b;
b.Start();
{
if (!profiler_stream_json_for_this_process(b, aSinceTime,
aIsShuttingDown)) {
return nullptr;
}
// Don't include profiles from other processes because this is a
// synchronous function.
b.StartArrayProperty("processes");
b.EndArray();
if (!WriteProfileToJSONWriter(b, aSinceTime, aIsShuttingDown)) {
return;
}
b.End();
return b.WriteFunc()->CopyData();
b.WriteFunc()->CopyDataIntoLazilyAllocatedBuffer(aAllocator);
}
void

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

@ -88,26 +88,22 @@ CollectProfileOrEmptyString(bool aIsShuttingDown)
return profileCString;
}
Shmem
ProfilerChild::ConvertProfileStringToShmem(const nsCString& aProfileCString) {
Shmem shmem;
if (!AllocShmem(aProfileCString.Length(),
SharedMemory::TYPE_BASIC,
&shmem)) {
return shmem;
}
PodCopy(shmem.get<char>(),
aProfileCString.BeginReading(),
aProfileCString.Length());
return shmem;
}
mozilla::ipc::IPCResult
ProfilerChild::RecvGatherProfile(GatherProfileResolver&& aResolve)
{
nsCString profile = CollectProfileOrEmptyString(/* aIsShuttingDown */ false);
aResolve(ConvertProfileStringToShmem(profile));
mozilla::ipc::Shmem shmem;
profiler_get_profile_json_into_lazily_allocated_buffer(
[&](size_t allocationSize) -> char* {
if (AllocShmem(allocationSize,
mozilla::ipc::Shmem::SharedMemory::TYPE_BASIC,
&shmem)) {
return shmem.get<char>();
}
return nullptr;
},
/* aSinceTime */ 0,
/* aIsShuttingDown */ false);
aResolve(std::move(shmem));
return IPC_OK();
}

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

@ -44,7 +44,6 @@ private:
mozilla::ipc::IPCResult RecvGatherProfile(GatherProfileResolver&& aResolve) override;
void ActorDestroy(ActorDestroyReason aActorDestroyReason) override;
Shmem ConvertProfileStringToShmem(const nsCString& profile);
FORWARD_SHMEM_ALLOCATOR_TO(PProfilerChild)