зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1466783 - Avoid copying while passing the profiler data with IPC r=mstange
MozReview-Commit-ID: HfskcLojToC --HG-- extra : rebase_source : 361efe4349cbe97303313d47450e60f35a91d1b0
This commit is contained in:
Родитель
647372a88b
Коммит
d36bbb96e0
|
@ -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)
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче