mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 02:14:43 +00:00
Bug 1658230 - Deduplicate ProfileJSONWriter classes - r=gregtatum
The main change is removing ProfileJSONWriter.cpp, making ProfileJSONWriter.h point at BaseProfileJSONWriter.h, and exposing `mozilla::baseprofiler::` classes in the top namespace as expected by users of ProfileJSONWriter.h (to minimize changes). These two headers are now always present in the "mozilla" include directory, independent of MOZ_GECKO_PROFILER settings. The rest is just needed tweaks to match the above changes. Differential Revision: https://phabricator.services.mozilla.com/D86504
This commit is contained in:
parent
11bd8d8e4a
commit
cc6cde66ad
@ -2781,7 +2781,7 @@ int32_t RecordContentFrameTime(
|
||||
static const DeserializerTag tag = TagForDeserializer(Deserialize);
|
||||
SerializeTagAndCommonProps(tag, aEntryWriter);
|
||||
}
|
||||
void StreamPayload(SpliceableJSONWriter& aWriter,
|
||||
void StreamPayload(mozilla::baseprofiler::SpliceableJSONWriter& aWriter,
|
||||
const TimeStamp& aProcessStartTime,
|
||||
UniqueStacks& aUniqueStacks) const override {
|
||||
StreamCommonProps("CONTENT_FRAME_TIME", aWriter, aProcessStartTime,
|
||||
|
@ -385,7 +385,7 @@ void ContentCompositorBridgeParent::ShadowLayersUpdated(
|
||||
static const DeserializerTag tag = TagForDeserializer(Deserialize);
|
||||
SerializeTagAndCommonProps(tag, aEntryWriter);
|
||||
}
|
||||
void StreamPayload(SpliceableJSONWriter& aWriter,
|
||||
void StreamPayload(mozilla::baseprofiler::SpliceableJSONWriter& aWriter,
|
||||
const TimeStamp& aProcessStartTime,
|
||||
UniqueStacks& aUniqueStacks) const override {
|
||||
StreamCommonProps("CONTENT_FULL_PAINT_TIME", aWriter, aProcessStartTime,
|
||||
|
@ -239,9 +239,10 @@ class SceneBuiltNotification : public wr::NotificationHandler {
|
||||
TagForDeserializer(Deserialize);
|
||||
SerializeTagAndCommonProps(tag, aEntryWriter);
|
||||
}
|
||||
void StreamPayload(SpliceableJSONWriter& aWriter,
|
||||
const TimeStamp& aProcessStartTime,
|
||||
UniqueStacks& aUniqueStacks) const override {
|
||||
void StreamPayload(
|
||||
mozilla::baseprofiler::SpliceableJSONWriter& aWriter,
|
||||
const TimeStamp& aProcessStartTime,
|
||||
UniqueStacks& aUniqueStacks) const override {
|
||||
StreamCommonProps("CONTENT_FULL_PAINT_TIME", aWriter,
|
||||
aProcessStartTime, aUniqueStacks);
|
||||
}
|
||||
|
@ -7,7 +7,8 @@
|
||||
#include "PageInformation.h"
|
||||
|
||||
#include "BaseProfiler.h"
|
||||
#include "BaseProfileJSONWriter.h"
|
||||
|
||||
#include "mozilla/BaseProfileJSONWriter.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace baseprofiler {
|
||||
|
@ -7,10 +7,9 @@
|
||||
#ifndef ProfileBufferEntry_h
|
||||
#define ProfileBufferEntry_h
|
||||
|
||||
#include "BaseProfileJSONWriter.h"
|
||||
|
||||
#include "gtest/MozGtestFriend.h"
|
||||
#include "BaseProfilingCategory.h"
|
||||
#include "gtest/MozGtestFriend.h"
|
||||
#include "mozilla/BaseProfileJSONWriter.h"
|
||||
#include "mozilla/HashFunctions.h"
|
||||
#include "mozilla/HashTable.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
|
@ -8,7 +8,8 @@
|
||||
|
||||
#include "BaseProfiler.h"
|
||||
#include "ProfileBuffer.h"
|
||||
#include "BaseProfileJSONWriter.h"
|
||||
|
||||
#include "mozilla/BaseProfileJSONWriter.h"
|
||||
|
||||
#if defined(GP_OS_darwin)
|
||||
# include <pthread.h>
|
||||
|
@ -7,11 +7,12 @@
|
||||
#include "ProfilerBacktrace.h"
|
||||
|
||||
#include "BaseProfiler.h"
|
||||
#include "BaseProfileJSONWriter.h"
|
||||
#include "ProfileBuffer.h"
|
||||
#include "ProfiledThreadData.h"
|
||||
#include "ThreadInfo.h"
|
||||
|
||||
#include "mozilla/BaseProfileJSONWriter.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace baseprofiler {
|
||||
|
||||
|
@ -5,15 +5,15 @@
|
||||
|
||||
#include "BaseProfilerMarkerPayload.h"
|
||||
|
||||
#include <inttypes.h>
|
||||
#include "BaseProfiler.h"
|
||||
#include "ProfileBufferEntry.h"
|
||||
#include "ProfilerBacktrace.h"
|
||||
|
||||
#include "mozilla/BaseProfileJSONWriter.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/Sprintf.h"
|
||||
|
||||
#include "BaseProfiler.h"
|
||||
#include "BaseProfileJSONWriter.h"
|
||||
#include "ProfileBufferEntry.h"
|
||||
#include "ProfilerBacktrace.h"
|
||||
#include <inttypes.h>
|
||||
|
||||
namespace mozilla {
|
||||
namespace baseprofiler {
|
||||
|
@ -12,7 +12,6 @@
|
||||
if CONFIG['MOZ_GECKO_PROFILER']:
|
||||
DEFINES['IMPL_MFBT'] = True
|
||||
EXPORTS += [
|
||||
'public/BaseProfileJSONWriter.h',
|
||||
'public/BaseProfilerMarkerPayload.h',
|
||||
'public/BaseProfilerSharedLibraries.h',
|
||||
'public/BaseProfilingCategory.h',
|
||||
@ -80,6 +79,7 @@ EXPORTS += [
|
||||
]
|
||||
|
||||
EXPORTS.mozilla += [
|
||||
'public/BaseProfileJSONWriter.h',
|
||||
'public/BaseProfilerCounts.h',
|
||||
'public/BaseProfilerDetail.h',
|
||||
'public/BlocksRingBuffer.h',
|
||||
|
@ -7,9 +7,9 @@
|
||||
#include "BaseProfiler.h"
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/BaseProfileJSONWriter.h"
|
||||
|
||||
#ifdef MOZ_GECKO_PROFILER
|
||||
# include "BaseProfileJSONWriter.h"
|
||||
# include "BaseProfilerMarkerPayload.h"
|
||||
# include "mozilla/BlocksRingBuffer.h"
|
||||
# include "mozilla/leb128iterator.h"
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
#include "PageInformation.h"
|
||||
|
||||
#include "ProfileJSONWriter.h"
|
||||
#include "mozilla/ProfileJSONWriter.h"
|
||||
|
||||
PageInformation::PageInformation(uint64_t aBrowsingContextID,
|
||||
uint64_t aInnerWindowID, const nsCString& aUrl,
|
||||
|
@ -12,7 +12,11 @@
|
||||
#include "nsISupportsImpl.h"
|
||||
#include "nsString.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace baseprofiler {
|
||||
class SpliceableJSONWriter;
|
||||
} // namespace baseprofiler
|
||||
} // namespace mozilla
|
||||
|
||||
// This class contains information that's relevant to a single page only
|
||||
// while the page information is important and registered with the profiler,
|
||||
@ -29,7 +33,7 @@ class PageInformation final {
|
||||
|
||||
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
|
||||
bool Equals(PageInformation* aOtherPageInfo) const;
|
||||
void StreamJSON(SpliceableJSONWriter& aWriter) const;
|
||||
void StreamJSON(mozilla::baseprofiler::SpliceableJSONWriter& aWriter) const;
|
||||
|
||||
uint64_t InnerWindowID() const { return mInnerWindowID; }
|
||||
uint64_t BrowsingContextID() const { return mBrowsingContextID; }
|
||||
|
@ -7,14 +7,13 @@
|
||||
#ifndef ProfileBufferEntry_h
|
||||
#define ProfileBufferEntry_h
|
||||
|
||||
#include "ProfileJSONWriter.h"
|
||||
|
||||
#include "gtest/MozGtestFriend.h"
|
||||
#include "js/ProfilingCategory.h"
|
||||
#include "js/ProfilingFrameIterator.h"
|
||||
#include "mozilla/HashFunctions.h"
|
||||
#include "mozilla/HashTable.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/ProfileJSONWriter.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "mozilla/Variant.h"
|
||||
#include "mozilla/Vector.h"
|
||||
|
@ -1,123 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "ProfileJSONWriter.h"
|
||||
|
||||
#include "mozilla/HashFunctions.h"
|
||||
|
||||
void ChunkedJSONWriteFunc::Write(const char* aStr) {
|
||||
size_t len = strlen(aStr);
|
||||
Write(aStr, len);
|
||||
}
|
||||
|
||||
void ChunkedJSONWriteFunc::Write(const char* aStr, size_t aLen) {
|
||||
MOZ_ASSERT(mChunkPtr >= mChunkList.back().get() && mChunkPtr <= mChunkEnd);
|
||||
MOZ_ASSERT(mChunkEnd >= mChunkList.back().get() + mChunkLengths.back());
|
||||
MOZ_ASSERT(*mChunkPtr == '\0');
|
||||
|
||||
// Most strings to be written are small, but subprocess profiles (e.g.,
|
||||
// from the content process in e10s) may be huge. If the string is larger
|
||||
// than a chunk, allocate its own chunk.
|
||||
char* newPtr;
|
||||
if (aLen >= kChunkSize) {
|
||||
AllocChunk(aLen + 1);
|
||||
newPtr = mChunkPtr + aLen;
|
||||
} else {
|
||||
newPtr = mChunkPtr + aLen;
|
||||
if (newPtr >= mChunkEnd) {
|
||||
AllocChunk(kChunkSize);
|
||||
newPtr = mChunkPtr + aLen;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(mChunkPtr, aStr, aLen);
|
||||
*newPtr = '\0';
|
||||
mChunkPtr = newPtr;
|
||||
mChunkLengths.back() += aLen;
|
||||
}
|
||||
|
||||
size_t ChunkedJSONWriteFunc::GetTotalLength() const {
|
||||
MOZ_ASSERT(mChunkLengths.length() == mChunkList.length());
|
||||
size_t totalLen = 1;
|
||||
for (size_t i = 0; i < mChunkLengths.length(); i++) {
|
||||
MOZ_ASSERT(strlen(mChunkList[i].get()) == mChunkLengths[i]);
|
||||
totalLen += mChunkLengths[i];
|
||||
}
|
||||
return totalLen;
|
||||
}
|
||||
|
||||
void ChunkedJSONWriteFunc::CopyDataIntoLazilyAllocatedBuffer(
|
||||
const std::function<char*(size_t)>& aAllocator) const {
|
||||
size_t totalLen = GetTotalLength();
|
||||
char* ptr = aAllocator(totalLen);
|
||||
|
||||
if (!ptr) {
|
||||
// Failed to allocate memory.
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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(std::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) {
|
||||
MOZ_ASSERT(mChunkLengths.length() == mChunkList.length());
|
||||
mozilla::UniquePtr<char[]> newChunk = mozilla::MakeUnique<char[]>(aChunkSize);
|
||||
mChunkPtr = newChunk.get();
|
||||
mChunkEnd = mChunkPtr + aChunkSize;
|
||||
*mChunkPtr = '\0';
|
||||
MOZ_ALWAYS_TRUE(mChunkLengths.append(0));
|
||||
MOZ_ALWAYS_TRUE(mChunkList.append(std::move(newChunk)));
|
||||
}
|
||||
|
||||
void 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;
|
||||
}
|
||||
|
||||
void SpliceableJSONWriter::Splice(const char* aStr) {
|
||||
Separator();
|
||||
WriteFunc()->Write(aStr);
|
||||
mNeedComma[mDepth] = true;
|
||||
}
|
||||
|
||||
void SpliceableChunkedJSONWriter::TakeAndSplice(ChunkedJSONWriteFunc* aFunc) {
|
||||
Separator();
|
||||
WriteFunc()->Take(std::move(*aFunc));
|
||||
mNeedComma[mDepth] = true;
|
||||
}
|
@ -7,10 +7,10 @@
|
||||
#include "ProfiledThreadData.h"
|
||||
|
||||
#include "ProfileBuffer.h"
|
||||
#include "ProfileJSONWriter.h"
|
||||
|
||||
#include "js/TraceLoggerAPI.h"
|
||||
#include "mozilla/dom/ContentChild.h"
|
||||
#include "mozilla/ProfileJSONWriter.h"
|
||||
|
||||
#if defined(GP_OS_darwin)
|
||||
# include <pthread.h>
|
||||
|
@ -8,9 +8,10 @@
|
||||
|
||||
#include "ProfileBuffer.h"
|
||||
#include "ProfiledThreadData.h"
|
||||
#include "ProfileJSONWriter.h"
|
||||
#include "ThreadInfo.h"
|
||||
|
||||
#include "mozilla/ProfileJSONWriter.h"
|
||||
|
||||
ProfilerBacktrace::ProfilerBacktrace(
|
||||
const char* aName, int aThreadId,
|
||||
mozilla::UniquePtr<mozilla::ProfileChunkedBuffer> aProfileChunkedBuffer,
|
||||
|
@ -14,13 +14,15 @@
|
||||
|
||||
class ProfileBuffer;
|
||||
class ProfilerCodeAddressService;
|
||||
class SpliceableJSONWriter;
|
||||
class ThreadInfo;
|
||||
class UniqueStacks;
|
||||
|
||||
namespace mozilla {
|
||||
class ProfileChunkedBuffer;
|
||||
class TimeStamp;
|
||||
namespace baseprofiler {
|
||||
class SpliceableJSONWriter;
|
||||
} // namespace baseprofiler
|
||||
} // namespace mozilla
|
||||
|
||||
// ProfilerBacktrace encapsulates a synchronous sample.
|
||||
@ -38,7 +40,7 @@ class ProfilerBacktrace {
|
||||
// That is, markers that contain backtraces should not need their own stack,
|
||||
// frame, and string tables. They should instead reuse their parent
|
||||
// profile's tables.
|
||||
void StreamJSON(SpliceableJSONWriter& aWriter,
|
||||
void StreamJSON(mozilla::baseprofiler::SpliceableJSONWriter& aWriter,
|
||||
const mozilla::TimeStamp& aProcessStartTime,
|
||||
UniqueStacks& aUniqueStacks);
|
||||
|
||||
|
@ -7,7 +7,6 @@
|
||||
|
||||
#include "GeckoProfiler.h"
|
||||
#include "ProfileBufferEntry.h"
|
||||
#include "ProfileJSONWriter.h"
|
||||
#include "ProfilerBacktrace.h"
|
||||
|
||||
#include "gfxASurface.h"
|
||||
@ -16,6 +15,7 @@
|
||||
#include "mozilla/net/HttpBaseChannel.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/ProfileBufferEntrySerializationGeckoExtensions.h"
|
||||
#include "mozilla/ProfileJSONWriter.h"
|
||||
#include "mozilla/Sprintf.h"
|
||||
|
||||
#include <inttypes.h>
|
||||
|
@ -10,13 +10,13 @@
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/MozPromise.h"
|
||||
#include "mozilla/ProfileJSONWriter.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "mozilla/Vector.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "nsIProfiler.h"
|
||||
#include "nsITimer.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "ProfileJSONWriter.h"
|
||||
#include "ProfilerCodeAddressService.h"
|
||||
|
||||
class nsProfiler final : public nsIProfiler, public nsIObserver {
|
||||
|
@ -13,7 +13,6 @@ if CONFIG['MOZ_GECKO_PROFILER']:
|
||||
EXPORTS += [
|
||||
'public/ChildProfilerController.h',
|
||||
'public/GeckoProfilerReporter.h',
|
||||
'public/ProfileJSONWriter.h',
|
||||
'public/ProfilerChild.h',
|
||||
'public/ProfilerCodeAddressService.h',
|
||||
'public/ProfilerMarkerPayload.h',
|
||||
@ -26,7 +25,6 @@ if CONFIG['MOZ_GECKO_PROFILER']:
|
||||
'core/ProfileBuffer.cpp',
|
||||
'core/ProfileBufferEntry.cpp',
|
||||
'core/ProfiledThreadData.cpp',
|
||||
'core/ProfileJSONWriter.cpp',
|
||||
'core/ProfilerBacktrace.cpp',
|
||||
'core/ProfilerCodeAddressService.cpp',
|
||||
'core/ProfilerMarkerPayload.cpp',
|
||||
@ -138,6 +136,7 @@ EXPORTS += [
|
||||
|
||||
EXPORTS.mozilla += [
|
||||
'public/ProfileBufferEntrySerializationGeckoExtensions.h',
|
||||
'public/ProfileJSONWriter.h',
|
||||
# vm/GeckoProfiler.h needs to include this and doesn't like #include "ProfilerCounts.h"
|
||||
'public/ProfilerCounts.h',
|
||||
]
|
||||
|
@ -111,9 +111,11 @@ static inline UniqueProfilerBacktrace profiler_get_backtrace() {
|
||||
class ProfilerBacktrace;
|
||||
class ProfilerCodeAddressService;
|
||||
class ProfilerMarkerPayload;
|
||||
class SpliceableJSONWriter;
|
||||
namespace mozilla {
|
||||
class ProfileBufferControlledChunkManager;
|
||||
namespace baseprofiler {
|
||||
class SpliceableJSONWriter;
|
||||
} // namespace baseprofiler
|
||||
namespace net {
|
||||
struct TimingStruct;
|
||||
enum CacheDisposition : uint8_t;
|
||||
@ -1054,7 +1056,7 @@ mozilla::UniquePtr<char[]> profiler_get_profile(double aSinceTime = 0,
|
||||
// Write the profile for this process (excluding subprocesses) into aWriter.
|
||||
// Returns false if the profiler is inactive.
|
||||
bool profiler_stream_json_for_this_process(
|
||||
SpliceableJSONWriter& aWriter, double aSinceTime = 0,
|
||||
mozilla::baseprofiler::SpliceableJSONWriter& aWriter, double aSinceTime = 0,
|
||||
bool aIsShuttingDown = false,
|
||||
ProfilerCodeAddressService* aService = nullptr);
|
||||
|
||||
|
@ -6,138 +6,13 @@
|
||||
#ifndef PROFILEJSONWRITER_H
|
||||
#define PROFILEJSONWRITER_H
|
||||
|
||||
#include "mozilla/JSONWriter.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "mozilla/BaseProfileJSONWriter.h"
|
||||
|
||||
#include <functional>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
|
||||
class SpliceableChunkedJSONWriter;
|
||||
|
||||
// On average, profile JSONs are large enough such that we want to avoid
|
||||
// reallocating its buffer when expanding. Additionally, the contents of the
|
||||
// profile are not accessed until the profile is entirely written. For these
|
||||
// reasons we use a chunked writer that keeps an array of chunks, which is
|
||||
// concatenated together after writing is finished.
|
||||
class ChunkedJSONWriteFunc : public mozilla::JSONWriteFunc {
|
||||
public:
|
||||
friend class SpliceableJSONWriter;
|
||||
|
||||
ChunkedJSONWriteFunc() : mChunkPtr{nullptr}, mChunkEnd{nullptr} {
|
||||
AllocChunk(kChunkSize);
|
||||
}
|
||||
|
||||
bool IsEmpty() const {
|
||||
MOZ_ASSERT_IF(!mChunkPtr, !mChunkEnd && mChunkList.length() == 0 &&
|
||||
mChunkLengths.length() == 0);
|
||||
return !mChunkPtr;
|
||||
}
|
||||
|
||||
void Write(const char* aStr) override;
|
||||
void Write(const char* aStr, size_t aLen) 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);
|
||||
|
||||
static const size_t kChunkSize = 4096 * 512;
|
||||
|
||||
// Pointer for writing inside the current chunk.
|
||||
//
|
||||
// The current chunk is always at the back of mChunkList, i.e.,
|
||||
// mChunkList.back() <= mChunkPtr <= mChunkEnd.
|
||||
char* mChunkPtr;
|
||||
|
||||
// Pointer to the end of the current chunk.
|
||||
//
|
||||
// The current chunk is always at the back of mChunkList, i.e.,
|
||||
// mChunkEnd >= mChunkList.back() + mChunkLengths.back().
|
||||
char* mChunkEnd;
|
||||
|
||||
// List of chunks and their lengths.
|
||||
//
|
||||
// For all i, the length of the string in mChunkList[i] is
|
||||
// mChunkLengths[i].
|
||||
mozilla::Vector<mozilla::UniquePtr<char[]>> mChunkList;
|
||||
mozilla::Vector<size_t> mChunkLengths;
|
||||
};
|
||||
|
||||
struct OStreamJSONWriteFunc : public mozilla::JSONWriteFunc {
|
||||
explicit OStreamJSONWriteFunc(std::ostream& aStream) : mStream(aStream) {}
|
||||
|
||||
void Write(const char* aStr) override { mStream << aStr; }
|
||||
void Write(const char* aStr, size_t aLen) override { mStream << aStr; }
|
||||
|
||||
std::ostream& mStream;
|
||||
};
|
||||
|
||||
class SpliceableJSONWriter : public mozilla::JSONWriter {
|
||||
public:
|
||||
explicit SpliceableJSONWriter(
|
||||
mozilla::UniquePtr<mozilla::JSONWriteFunc> aWriter)
|
||||
: JSONWriter(std::move(aWriter)) {}
|
||||
|
||||
void StartBareList(CollectionStyle aStyle = MultiLineStyle) {
|
||||
StartCollection(nullptr, "", aStyle);
|
||||
}
|
||||
|
||||
void EndBareList() { EndCollection(""); }
|
||||
|
||||
void NullElements(uint32_t aCount) {
|
||||
for (uint32_t i = 0; i < aCount; i++) {
|
||||
NullElement();
|
||||
}
|
||||
}
|
||||
|
||||
void Splice(const ChunkedJSONWriteFunc* aFunc);
|
||||
void Splice(const char* aStr);
|
||||
|
||||
// Splice the given JSON directly in, without quoting.
|
||||
void SplicedJSONProperty(const char* aMaybePropertyName,
|
||||
const char* aJsonValue) {
|
||||
Scalar(aMaybePropertyName, aJsonValue);
|
||||
}
|
||||
|
||||
// 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 {
|
||||
public:
|
||||
explicit SpliceableChunkedJSONWriter()
|
||||
: SpliceableJSONWriter(mozilla::MakeUnique<ChunkedJSONWriteFunc>()) {}
|
||||
|
||||
ChunkedJSONWriteFunc* WriteFunc() const {
|
||||
return static_cast<ChunkedJSONWriteFunc*>(JSONWriter::WriteFunc());
|
||||
}
|
||||
|
||||
// Adopts the chunks from aFunc without copying.
|
||||
virtual void TakeAndSplice(ChunkedJSONWriteFunc* aFunc) override;
|
||||
};
|
||||
|
||||
class JSONSchemaWriter {
|
||||
mozilla::JSONWriter& mWriter;
|
||||
uint32_t mIndex;
|
||||
|
||||
public:
|
||||
explicit JSONSchemaWriter(mozilla::JSONWriter& aWriter)
|
||||
: mWriter(aWriter), mIndex(0) {
|
||||
aWriter.StartObjectProperty("schema",
|
||||
SpliceableJSONWriter::SingleLineStyle);
|
||||
}
|
||||
|
||||
void WriteField(const char* aName) { mWriter.IntProperty(aName, mIndex++); }
|
||||
|
||||
~JSONSchemaWriter() { mWriter.EndObject(); }
|
||||
};
|
||||
using ChunkedJSONWriteFunc = mozilla::baseprofiler::ChunkedJSONWriteFunc;
|
||||
using JSONSchemaWriter = mozilla::baseprofiler::JSONSchemaWriter;
|
||||
using OStreamJSONWriteFunc = mozilla::baseprofiler::OStreamJSONWriteFunc;
|
||||
using SpliceableChunkedJSONWriter =
|
||||
mozilla::baseprofiler::SpliceableChunkedJSONWriter;
|
||||
using SpliceableJSONWriter = mozilla::baseprofiler::SpliceableJSONWriter;
|
||||
|
||||
#endif // PROFILEJSONWRITER_H
|
||||
|
@ -30,12 +30,14 @@
|
||||
#include "mozilla/ServoTraversalStatistics.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace baseprofiler {
|
||||
class SpliceableJSONWriter;
|
||||
} // namespace baseprofiler
|
||||
namespace layers {
|
||||
class Layer;
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
||||
class SpliceableJSONWriter;
|
||||
class UniqueStacks;
|
||||
|
||||
// This is an abstract class that can be implemented to supply data to be
|
||||
@ -90,9 +92,10 @@ class ProfilerMarkerPayload {
|
||||
return deserializer(aER);
|
||||
}
|
||||
|
||||
virtual void StreamPayload(SpliceableJSONWriter& aWriter,
|
||||
const mozilla::TimeStamp& aProcessStartTime,
|
||||
UniqueStacks& aUniqueStacks) const = 0;
|
||||
virtual void StreamPayload(
|
||||
mozilla::baseprofiler::SpliceableJSONWriter& aWriter,
|
||||
const mozilla::TimeStamp& aProcessStartTime,
|
||||
UniqueStacks& aUniqueStacks) const = 0;
|
||||
|
||||
const mozilla::TimeStamp& GetStartTime() const {
|
||||
return mCommonProps.mStartTime;
|
||||
@ -155,12 +158,14 @@ class ProfilerMarkerPayload {
|
||||
static CommonProps DeserializeCommonProps(
|
||||
mozilla::ProfileBufferEntryReader& aEntryReader);
|
||||
|
||||
void StreamType(const char* aMarkerType, SpliceableJSONWriter& aWriter) const;
|
||||
void StreamType(const char* aMarkerType,
|
||||
mozilla::baseprofiler::SpliceableJSONWriter& aWriter) const;
|
||||
|
||||
void StreamCommonProps(const char* aMarkerType, SpliceableJSONWriter& aWriter,
|
||||
void StreamCommonProps(const char* aMarkerType,
|
||||
mozilla::baseprofiler::SpliceableJSONWriter& aWriter,
|
||||
const mozilla::TimeStamp& aProcessStartTime,
|
||||
UniqueStacks& aUniqueStacks) const;
|
||||
void StreamStartEndTime(SpliceableJSONWriter& aWriter,
|
||||
void StreamStartEndTime(mozilla::baseprofiler::SpliceableJSONWriter& aWriter,
|
||||
const mozilla::TimeStamp& aProcessStartTime) const;
|
||||
|
||||
private:
|
||||
@ -178,7 +183,7 @@ class ProfilerMarkerPayload {
|
||||
};
|
||||
|
||||
#define DECL_STREAM_PAYLOAD \
|
||||
void StreamPayload(SpliceableJSONWriter& aWriter, \
|
||||
void StreamPayload(mozilla::baseprofiler::SpliceableJSONWriter& aWriter, \
|
||||
const mozilla::TimeStamp& aProcessStartTime, \
|
||||
UniqueStacks& aUniqueStacks) const override; \
|
||||
static mozilla::UniquePtr<ProfilerMarkerPayload> Deserialize( \
|
||||
|
@ -12,7 +12,6 @@
|
||||
#include "GeckoProfiler.h"
|
||||
#include "platform.h"
|
||||
#include "ProfileBuffer.h"
|
||||
#include "ProfileJSONWriter.h"
|
||||
#include "ProfilerMarkerPayload.h"
|
||||
|
||||
#include "js/Initialization.h"
|
||||
@ -22,6 +21,7 @@
|
||||
#include "mozilla/Atomics.h"
|
||||
#include "mozilla/BlocksRingBuffer.h"
|
||||
#include "mozilla/ProfileBufferEntrySerializationGeckoExtensions.h"
|
||||
#include "mozilla/ProfileJSONWriter.h"
|
||||
#include "mozilla/UniquePtrExtensions.h"
|
||||
#include "mozilla/net/HttpBaseChannel.h"
|
||||
#include "nsIThread.h"
|
||||
@ -829,7 +829,7 @@ TEST(GeckoProfiler, Markers)
|
||||
|
||||
SpliceableChunkedJSONWriter w;
|
||||
w.Start();
|
||||
EXPECT_TRUE(profiler_stream_json_for_this_process(w));
|
||||
EXPECT_TRUE(::profiler_stream_json_for_this_process(w));
|
||||
w.End();
|
||||
|
||||
// The GTestMarkerPayloads should have been deserialized, streamed, and
|
||||
@ -1467,7 +1467,7 @@ TEST(GeckoProfiler, Markers)
|
||||
profiler_start(PROFILER_DEFAULT_ENTRIES, PROFILER_DEFAULT_INTERVAL, features,
|
||||
filters, MOZ_ARRAY_LENGTH(filters), 0);
|
||||
|
||||
EXPECT_TRUE(profiler_stream_json_for_this_process(w));
|
||||
EXPECT_TRUE(::profiler_stream_json_for_this_process(w));
|
||||
|
||||
profiler_stop();
|
||||
|
||||
@ -1541,7 +1541,7 @@ TEST(GeckoProfiler, Counters)
|
||||
|
||||
// Verify we got counters in the output
|
||||
SpliceableChunkedJSONWriter w;
|
||||
ASSERT_TRUE(profiler_stream_json_for_this_process(w));
|
||||
ASSERT_TRUE(::profiler_stream_json_for_this_process(w));
|
||||
|
||||
UniquePtr<char[]> profile = w.WriteFunc()->CopyData();
|
||||
|
||||
@ -1554,7 +1554,7 @@ TEST(GeckoProfiler, Counters)
|
||||
AUTO_PROFILER_COUNT_TOTAL(TestCounter2, 10);
|
||||
PR_Sleep(PR_MillisecondsToInterval(200));
|
||||
|
||||
ASSERT_TRUE(profiler_stream_json_for_this_process(w));
|
||||
ASSERT_TRUE(::profiler_stream_json_for_this_process(w));
|
||||
|
||||
profile = w.WriteFunc()->CopyData();
|
||||
ASSERT_TRUE(strstr(profile.get(), COUNTER_NAME));
|
||||
@ -1634,13 +1634,13 @@ TEST(GeckoProfiler, StreamJSONForThisProcess)
|
||||
const char* filters[] = {"GeckoMain"};
|
||||
|
||||
SpliceableChunkedJSONWriter w;
|
||||
ASSERT_TRUE(!profiler_stream_json_for_this_process(w));
|
||||
ASSERT_TRUE(!::profiler_stream_json_for_this_process(w));
|
||||
|
||||
profiler_start(PROFILER_DEFAULT_ENTRIES, PROFILER_DEFAULT_INTERVAL, features,
|
||||
filters, MOZ_ARRAY_LENGTH(filters), 0);
|
||||
|
||||
w.Start();
|
||||
ASSERT_TRUE(profiler_stream_json_for_this_process(w));
|
||||
ASSERT_TRUE(::profiler_stream_json_for_this_process(w));
|
||||
w.End();
|
||||
|
||||
UniquePtr<char[]> profile = w.WriteFunc()->CopyData();
|
||||
@ -1649,7 +1649,7 @@ TEST(GeckoProfiler, StreamJSONForThisProcess)
|
||||
|
||||
profiler_stop();
|
||||
|
||||
ASSERT_TRUE(!profiler_stream_json_for_this_process(w));
|
||||
ASSERT_TRUE(!::profiler_stream_json_for_this_process(w));
|
||||
}
|
||||
|
||||
TEST(GeckoProfiler, StreamJSONForThisProcessThreaded)
|
||||
@ -1663,7 +1663,7 @@ TEST(GeckoProfiler, StreamJSONForThisProcessThreaded)
|
||||
const char* filters[] = {"GeckoMain"};
|
||||
|
||||
SpliceableChunkedJSONWriter w;
|
||||
ASSERT_TRUE(!profiler_stream_json_for_this_process(w));
|
||||
ASSERT_TRUE(!::profiler_stream_json_for_this_process(w));
|
||||
|
||||
// Start the profiler on the main thread.
|
||||
profiler_start(PROFILER_DEFAULT_ENTRIES, PROFILER_DEFAULT_INTERVAL, features,
|
||||
@ -1675,7 +1675,7 @@ TEST(GeckoProfiler, StreamJSONForThisProcessThreaded)
|
||||
"GeckoProfiler_StreamJSONForThisProcessThreaded_Test::TestBody",
|
||||
[&]() {
|
||||
w.Start();
|
||||
ASSERT_TRUE(profiler_stream_json_for_this_process(w));
|
||||
ASSERT_TRUE(::profiler_stream_json_for_this_process(w));
|
||||
w.End();
|
||||
}),
|
||||
NS_DISPATCH_SYNC);
|
||||
@ -1691,13 +1691,13 @@ TEST(GeckoProfiler, StreamJSONForThisProcessThreaded)
|
||||
"GeckoProfiler_StreamJSONForThisProcessThreaded_Test::TestBody",
|
||||
[&]() {
|
||||
profiler_stop();
|
||||
ASSERT_TRUE(!profiler_stream_json_for_this_process(w));
|
||||
ASSERT_TRUE(!::profiler_stream_json_for_this_process(w));
|
||||
}),
|
||||
NS_DISPATCH_SYNC);
|
||||
thread->Shutdown();
|
||||
|
||||
// Call profiler_stream_json_for_this_process on the main thread.
|
||||
ASSERT_TRUE(!profiler_stream_json_for_this_process(w));
|
||||
ASSERT_TRUE(!::profiler_stream_json_for_this_process(w));
|
||||
}
|
||||
|
||||
TEST(GeckoProfiler, ProfilingStack)
|
||||
|
Loading…
Reference in New Issue
Block a user