Bug 1676361 - Clean up profiler includes. r=gerald

Differential Revision: https://phabricator.services.mozilla.com/D96539

Depends on D96538
This commit is contained in:
Simon Giesecke 2020-11-23 16:09:13 +00:00
parent 73d4d57082
commit 2499964dc8
11 changed files with 130 additions and 94 deletions

View File

@ -11,6 +11,7 @@
#include "ProfileBuffer.h"
#include "ProfilerBacktrace.h"
#include "js/ProfilingFrameIterator.h"
#include "jsapi.h"
#include "jsfriendapi.h"
#include "mozilla/Logging.h"

View File

@ -7,9 +7,13 @@
#ifndef ProfileBufferEntry_h
#define ProfileBufferEntry_h
#include <cstdint>
#include <cstdlib>
#include <functional>
#include <utility>
#include "gtest/MozGtestFriend.h"
#include "js/ProfilingCategory.h"
#include "js/ProfilingFrameIterator.h"
#include "mozilla/Attributes.h"
#include "mozilla/HashFunctions.h"
#include "mozilla/HashTable.h"
#include "mozilla/Maybe.h"
@ -21,6 +25,7 @@
#include "nsString.h"
class ProfilerCodeAddressService;
struct JSContext;
class ProfileBufferEntry {
public:

View File

@ -7,16 +7,24 @@
#ifndef ProfiledThreadData_h
#define ProfiledThreadData_h
#include "platform.h"
#include "ProfileBufferEntry.h"
#include "ThreadInfo.h"
#include "js/ProfilingStack.h"
#include "mozilla/Maybe.h"
#include "mozilla/TimeStamp.h"
#include "mozilla/UniquePtr.h"
#include "nsIEventTarget.h"
#include "mozilla/RefPtr.h"
#include "nsStringFwd.h"
class ProfileBuffer;
class ProfilerCodeAddressService;
class UniqueStacks;
class nsIEventTarget;
struct JITFrameInfo;
struct JSContext;
namespace mozilla::baseprofiler {
class SpliceableJSONWriter;
}
// This class contains information about a thread that is only relevant while
// the profiler is running, for any threads (both alive and dead) whose thread
@ -61,14 +69,15 @@ class ProfiledThreadData final {
mozilla::Maybe<uint64_t>& LastSample() { return mLastSample; }
void StreamJSON(const ProfileBuffer& aBuffer, JSContext* aCx,
SpliceableJSONWriter& aWriter, const nsACString& aProcessName,
const nsACString& aETLDplus1,
mozilla::baseprofiler::SpliceableJSONWriter& aWriter,
const nsACString& aProcessName, const nsACString& aETLDplus1,
const mozilla::TimeStamp& aProcessStartTime,
double aSinceTime, bool aJSTracerEnabled,
ProfilerCodeAddressService* aService);
void StreamTraceLoggerJSON(JSContext* aCx, SpliceableJSONWriter& aWriter,
const mozilla::TimeStamp& aProcessStartTime);
void StreamTraceLoggerJSON(
JSContext* aCx, mozilla::baseprofiler::SpliceableJSONWriter& aWriter,
const mozilla::TimeStamp& aProcessStartTime);
const RefPtr<ThreadInfo> Info() const { return mThreadInfo; }
@ -119,14 +128,13 @@ class ProfiledThreadData final {
// Stream all samples and markers from aBuffer with the given aThreadId (or 0
// for everything, which is assumed to be a single backtrace sample.)
// Returns the thread id of the output sample(s), or 0 if none was present.
int StreamSamplesAndMarkers(const char* aName, int aThreadId,
const ProfileBuffer& aBuffer,
SpliceableJSONWriter& aWriter,
const nsACString& aProcessName,
const nsACString& aETLDplus1,
const mozilla::TimeStamp& aProcessStartTime,
const mozilla::TimeStamp& aRegisterTime,
const mozilla::TimeStamp& aUnregisterTime,
double aSinceTime, UniqueStacks& aUniqueStacks);
int StreamSamplesAndMarkers(
const char* aName, int aThreadId, const ProfileBuffer& aBuffer,
mozilla::baseprofiler::SpliceableJSONWriter& aWriter,
const nsACString& aProcessName, const nsACString& aETLDplus1,
const mozilla::TimeStamp& aProcessStartTime,
const mozilla::TimeStamp& aRegisterTime,
const mozilla::TimeStamp& aUnregisterTime, double aSinceTime,
UniqueStacks& aUniqueStacks);
#endif // ProfiledThreadData_h

View File

@ -6,6 +6,19 @@
#include "RegisteredThread.h"
#include "js/AllocationRecording.h"
#include "js/ProfilingStack.h"
#include "js/TraceLoggerAPI.h"
RacyRegisteredThread::RacyRegisteredThread(int aThreadId)
: mProfilingStackOwner(
mozilla::MakeNotNull<RefPtr<mozilla::ProfilingStackOwner>>()),
mThreadId(aThreadId),
mSleep(AWAKE),
mIsBeingProfiled(false) {
MOZ_COUNT_CTOR(RacyRegisteredThread);
}
RegisteredThread::RegisteredThread(ThreadInfo* aInfo, nsIThread* aThread,
void* aStackTop)
: mRacyRegisteredThread(aInfo->ThreadId()),
@ -61,3 +74,56 @@ void RegisteredThread::GetRunningEventDelay(const mozilla::TimeStamp& aNow,
aDelay = mozilla::TimeDuration();
aRunning = mozilla::TimeDuration();
}
void RegisteredThread::SetJSContext(JSContext* aContext) {
// This function runs on-thread.
MOZ_ASSERT(aContext && !mContext);
mContext = aContext;
// We give the JS engine a non-owning reference to the ProfilingStack. It's
// important that the JS engine doesn't touch this once the thread dies.
js::SetContextProfilingStack(aContext,
&RacyRegisteredThread().ProfilingStack());
}
void RegisteredThread::PollJSSampling() {
// This function runs on-thread.
// We can't start/stop profiling until we have the thread's JSContext.
if (mContext) {
// It is possible for mJSSampling to go through the following sequences.
//
// - INACTIVE, ACTIVE_REQUESTED, INACTIVE_REQUESTED, INACTIVE
//
// - ACTIVE, INACTIVE_REQUESTED, ACTIVE_REQUESTED, ACTIVE
//
// Therefore, the if and else branches here aren't always interleaved.
// This is ok because the JS engine can handle that.
//
if (mJSSampling == ACTIVE_REQUESTED) {
mJSSampling = ACTIVE;
js::EnableContextProfilingStack(mContext, true);
if (JSTracerEnabled()) {
JS::StartTraceLogger(mContext);
}
if (JSAllocationsEnabled()) {
// TODO - This probability should not be hardcoded. See Bug 1547284.
JS::EnableRecordingAllocations(mContext,
profiler_add_js_allocation_marker, 0.01);
}
js::RegisterContextProfilingEventMarker(mContext, profiler_add_js_marker);
} else if (mJSSampling == INACTIVE_REQUESTED) {
mJSSampling = INACTIVE;
js::EnableContextProfilingStack(mContext, false);
if (JSTracerEnabled()) {
JS::StopTraceLogger(mContext);
}
if (JSAllocationsEnabled()) {
JS::DisableRecordingAllocations(mContext);
}
}
}
}

View File

@ -7,17 +7,18 @@
#ifndef RegisteredThread_h
#define RegisteredThread_h
#include "GeckoProfiler.h"
#include "platform.h"
#include "ThreadInfo.h"
#include "js/TraceLoggerAPI.h"
#include "jsapi.h"
#include "mozilla/NotNull.h"
#include "mozilla/RefPtr.h"
#include "nsIEventTarget.h"
#include "nsIThread.h"
namespace mozilla {
class ProfilingStackOwner;
}
// This class contains the state for a single thread that is accessible without
// protection from gPSMutex in platform.cpp. Because there is no external
// protection against data races, it must provide internal protection. Hence
@ -25,14 +26,7 @@
//
class RacyRegisteredThread final {
public:
explicit RacyRegisteredThread(int aThreadId)
: mProfilingStackOwner(
mozilla::MakeNotNull<RefPtr<mozilla::ProfilingStackOwner>>()),
mThreadId(aThreadId),
mSleep(AWAKE),
mIsBeingProfiled(false) {
MOZ_COUNT_CTOR(RacyRegisteredThread);
}
explicit RacyRegisteredThread(int aThreadId);
MOZ_COUNTED_DTOR(RacyRegisteredThread)
@ -177,18 +171,7 @@ class RegisteredThread final {
// Set the JSContext of the thread to be sampled. Sampling cannot begin until
// this has been set.
void SetJSContext(JSContext* aContext) {
// This function runs on-thread.
MOZ_ASSERT(aContext && !mContext);
mContext = aContext;
// We give the JS engine a non-owning reference to the ProfilingStack. It's
// important that the JS engine doesn't touch this once the thread dies.
js::SetContextProfilingStack(aContext,
&RacyRegisteredThread().ProfilingStack());
}
void SetJSContext(JSContext* aContext);
void ClearJSContext() {
// This function runs on-thread.
@ -224,46 +207,7 @@ class RegisteredThread final {
}
// Poll to see if JS sampling should be started/stopped.
void PollJSSampling() {
// This function runs on-thread.
// We can't start/stop profiling until we have the thread's JSContext.
if (mContext) {
// It is possible for mJSSampling to go through the following sequences.
//
// - INACTIVE, ACTIVE_REQUESTED, INACTIVE_REQUESTED, INACTIVE
//
// - ACTIVE, INACTIVE_REQUESTED, ACTIVE_REQUESTED, ACTIVE
//
// Therefore, the if and else branches here aren't always interleaved.
// This is ok because the JS engine can handle that.
//
if (mJSSampling == ACTIVE_REQUESTED) {
mJSSampling = ACTIVE;
js::EnableContextProfilingStack(mContext, true);
if (JSTracerEnabled()) {
JS::StartTraceLogger(mContext);
}
if (JSAllocationsEnabled()) {
// TODO - This probability should not be hardcoded. See Bug 1547284.
JS::EnableRecordingAllocations(
mContext, profiler_add_js_allocation_marker, 0.01);
}
js::RegisterContextProfilingEventMarker(mContext,
profiler_add_js_marker);
} else if (mJSSampling == INACTIVE_REQUESTED) {
mJSSampling = INACTIVE;
js::EnableContextProfilingStack(mContext, false);
if (JSTracerEnabled()) {
JS::StopTraceLogger(mContext);
}
if (JSAllocationsEnabled()) {
JS::DisableRecordingAllocations(mContext);
}
}
}
}
void PollJSSampling();
private:
class RacyRegisteredThread mRacyRegisteredThread;

View File

@ -31,15 +31,16 @@
#include "PlatformMacros.h"
#include "GeckoProfiler.h"
#include "mozilla/Logging.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/Vector.h"
#include "nsString.h"
#include <cstddef>
#include <cstdint>
#include <functional>
#include <stdint.h>
class ProfilerCodeAddressService;
namespace mozilla {
struct SymbolTable;

View File

@ -16,6 +16,7 @@
#include <fstream>
#include "platform.h"
#include "shared-libraries.h"
#include "GeckoProfiler.h"
#include "mozilla/Sprintf.h"
#include "mozilla/Unused.h"
#include "nsDebug.h"

View File

@ -87,11 +87,9 @@ profiler_capture_backtrace() {
#else // !MOZ_GECKO_PROFILER
# include "js/AllocationRecording.h"
# include "js/ProfilingFrameIterator.h"
# include "js/ProfilingCategory.h"
# include "js/ProfilingStack.h"
# include "js/RootingAPI.h"
# include "js/TypeDecls.h"
# include "mozilla/Assertions.h"
# include "mozilla/Atomics.h"
# include "mozilla/Attributes.h"
@ -109,6 +107,12 @@ profiler_capture_backtrace() {
class ProfilerBacktrace;
class ProfilerCodeAddressService;
struct JSContext;
namespace JS {
struct RecordAllocationInfo;
}
namespace mozilla {
class ProfileBufferControlledChunkManager;
class ProfileChunkedBuffer;

View File

@ -35,9 +35,6 @@
#include "mozilla/BaseProfilerMarkers.h"
#include "mozilla/ProfilerMarkersDetail.h"
// TODO: Move common stuff to shared header instead.
#include "GeckoProfiler.h"
#ifndef MOZ_GECKO_PROFILER
# define PROFILER_MARKER_UNTYPED(markerName, categoryName, ...)
@ -50,6 +47,14 @@
#else // ndef MOZ_GECKO_PROFILER
namespace mozilla {
class ProfileChunkedBuffer;
}
bool profiler_can_accept_markers();
bool profiler_capture_backtrace_into(
mozilla::ProfileChunkedBuffer& aChunkedBuffer);
// Bring category names from Base Profiler into the geckoprofiler::category
// namespace, for consistency with other Gecko Profiler identifiers.
namespace geckoprofiler::category {

View File

@ -10,10 +10,11 @@
#include "mozilla/BlockingResourceBase.h"
#include "mozilla/PlatformConditionVariable.h"
#include "mozilla/Mutex.h"
#include "mozilla/TimeStamp.h"
#ifdef MOZILLA_INTERNAL_API
#if defined(MOZILLA_INTERNAL_API) && !defined(DEBUG)
# include "GeckoProfiler.h"
#endif // MOZILLA_INTERNAL_API
#endif // defined( MOZILLA_INTERNAL_API) && !defined(DEBUG)
namespace mozilla {

View File

@ -9,9 +9,9 @@
#include "prmon.h"
#ifdef MOZILLA_INTERNAL_API
#if defined(MOZILLA_INTERNAL_API) && !defined(DEBUG)
# include "GeckoProfiler.h"
#endif // MOZILLA_INTERNAL_API
#endif // defined( MOZILLA_INTERNAL_API) && !defined(DEBUG)
#include "mozilla/BlockingResourceBase.h"
#include "nsISupports.h"