Bug 1675409 - Migrated NativeAllocationMarkerPayload to Markers 2.0 API - r=gregtatum

Because it's easy to send markers to the main thread, we don't need to store the main thread id in memory_hooks functions and objects.

Differential Revision: https://phabricator.services.mozilla.com/D96049
This commit is contained in:
Gerald Squelart 2020-11-17 11:36:04 +00:00
Родитель b96f5eccc0
Коммит 3b2fc2777a
6 изменённых файлов: 34 добавлений и 66 удалений

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

@ -265,10 +265,6 @@ class ThreadIntercept {
// or disabled.
static mozilla::Atomic<bool, mozilla::Relaxed> sAllocationsFeatureEnabled;
// The markers will be stored on the main thread. Retain the id to the main
// thread of this process here.
static mozilla::Atomic<int, mozilla::Relaxed> sMainThreadId;
ThreadIntercept() = default;
// Only allow consumers to access this information if they run
@ -315,14 +311,9 @@ class ThreadIntercept {
bool IsBlocked() const { return ThreadIntercept::IsBlocked_(); }
static void EnableAllocationFeature(int aMainThreadId) {
sAllocationsFeatureEnabled = true;
sMainThreadId = aMainThreadId;
}
static void EnableAllocationFeature() { sAllocationsFeatureEnabled = true; }
static void DisableAllocationFeature() { sAllocationsFeatureEnabled = false; }
static int MainThreadId() { return sMainThreadId; }
};
PROFILER_THREAD_LOCAL(bool) ThreadIntercept::tlsIsBlocked;
@ -330,8 +321,6 @@ PROFILER_THREAD_LOCAL(bool) ThreadIntercept::tlsIsBlocked;
mozilla::Atomic<bool, mozilla::Relaxed>
ThreadIntercept::sAllocationsFeatureEnabled(false);
mozilla::Atomic<int, mozilla::Relaxed> ThreadIntercept::sMainThreadId(0);
// An object of this class must be created (on the stack) before running any
// code that might allocate.
class AutoBlockIntercepts {
@ -389,7 +378,7 @@ static void AllocCallback(void* aPtr, size_t aReqSize) {
gBernoulli->trial(actualSize) &&
// Second, attempt to add a marker if the Bernoulli trial passed.
profiler_add_native_allocation_marker(
ThreadIntercept::MainThreadId(), static_cast<int64_t>(actualSize),
static_cast<int64_t>(actualSize),
reinterpret_cast<uintptr_t>(aPtr))) {
MOZ_ASSERT(gAllocationTracker,
"gAllocationTracker must be properly installed for the memory "
@ -432,8 +421,7 @@ static void FreeCallback(void* aPtr) {
"gAllocationTracker must be properly installed for the memory hooks.");
if (gAllocationTracker->RemoveMemoryAddressIfFound(aPtr)) {
// This size here is negative, indicating a deallocation.
profiler_add_native_allocation_marker(ThreadIntercept::MainThreadId(),
signedSize,
profiler_add_native_allocation_marker(signedSize,
reinterpret_cast<uintptr_t>(aPtr));
}
}
@ -567,7 +555,7 @@ void install_memory_hooks() {
// leak these values.
void remove_memory_hooks() { jemalloc_replace_dynamic(nullptr); }
void enable_native_allocations(int aMainThreadId) {
void enable_native_allocations() {
// The bloat log tracks allocations and deallocations. This can conflict
// with the memory hook machinery, as the bloat log creates its own
// allocations. This means we can re-enter inside the bloat log machinery. At
@ -596,7 +584,7 @@ void enable_native_allocations(int aMainThreadId) {
EnsureBernoulliIsInstalled();
EnsureAllocationTrackerIsInstalled();
ThreadIntercept::EnableAllocationFeature(aMainThreadId);
ThreadIntercept::EnableAllocationFeature();
}
// This is safe to call even if native allocations hasn't been enabled.

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

@ -13,7 +13,7 @@ namespace profiler {
void install_memory_hooks();
void remove_memory_hooks();
void enable_native_allocations(int aMainThreadId);
void enable_native_allocations();
void disable_native_allocations();
} // namespace profiler

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

@ -4595,7 +4595,7 @@ static void locked_profiler_start(PSLockRef aLock, PowerOfTwo32 aCapacity,
}
// Set up profiling for each registered thread, if appropriate.
Maybe<int> mainThreadId;
bool isMainThreadBeingProfiled = false;
int tid = profiler_current_thread_id();
const Vector<UniquePtr<RegisteredThread>>& registeredThreads =
CorePS::RegisteredThreads(aLock);
@ -4622,7 +4622,7 @@ static void locked_profiler_start(PSLockRef aLock, PowerOfTwo32 aCapacity,
}
}
if (info->IsMainThread()) {
mainThreadId = Some(info->ThreadId());
isMainThreadBeingProfiled = true;
}
registeredThread->RacyRegisteredThread().ReinitializeOnResume();
if (registeredThread->GetJSContext()) {
@ -4658,8 +4658,8 @@ static void locked_profiler_start(PSLockRef aLock, PowerOfTwo32 aCapacity,
#if defined(MOZ_REPLACE_MALLOC) && defined(MOZ_PROFILER_MEMORY)
if (ActivePS::FeatureNativeAllocations(aLock)) {
if (mainThreadId.isSome()) {
mozilla::profiler::enable_native_allocations(mainThreadId.value());
if (isMainThreadBeingProfiled) {
mozilla::profiler::enable_native_allocations();
} else {
NS_WARNING(
"The nativeallocations feature is turned on, but the main thread is "
@ -5722,7 +5722,7 @@ void profiler_add_marker_for_mainthread(JS::ProfilingCategoryPair aCategoryPair,
aMarkerName, aPayload);
}
bool profiler_add_native_allocation_marker(int aMainThreadId, int64_t aSize,
bool profiler_add_native_allocation_marker(int64_t aSize,
uintptr_t aMemoryAddress) {
if (!profiler_can_accept_markers()) {
return false;
@ -5739,13 +5739,27 @@ bool profiler_add_native_allocation_marker(int aMainThreadId, int64_t aSize,
return false;
}
AUTO_PROFILER_STATS(add_marker_with_NativeAllocationMarkerPayload);
maybelocked_profiler_add_marker_for_thread(
aMainThreadId, JS::ProfilingCategoryPair::OTHER, "Native allocation",
NativeAllocationMarkerPayload(TimeStamp::Now(), aSize, aMemoryAddress,
profiler_current_thread_id(),
profiler_get_backtrace()),
nullptr);
struct NativeAllocationMarker {
static constexpr mozilla::Span<const char> MarkerTypeName() {
return mozilla::MakeStringSpan("Native allocation");
}
static void StreamJSONMarkerData(
mozilla::baseprofiler::SpliceableJSONWriter& aWriter, int64_t aSize,
uintptr_t aMemoryAddress, int aThreadId) {
aWriter.IntProperty("size", aSize);
aWriter.IntProperty("memoryAddress",
static_cast<int64_t>(aMemoryAddress));
aWriter.IntProperty("threadId", aThreadId);
}
static mozilla::MarkerSchema MarkerTypeDisplay() {
return mozilla::MarkerSchema::SpecialFrontendLocation{};
}
};
profiler_add_marker("Native allocation", geckoprofiler::category::OTHER,
{MarkerThreadId::MainThread(), MarkerStack::Capture()},
NativeAllocationMarker{}, aSize, aMemoryAddress,
profiler_current_thread_id());
return true;
}

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

@ -912,8 +912,8 @@ void profiler_add_js_allocation_marker(JS::RecordAllocationInfo&& info);
// Returns true or or false depending on whether the marker was actually added
// or not.
bool profiler_add_native_allocation_marker(int aMainThreadId, int64_t aSize,
uintptr_t aMemorySize);
bool profiler_add_native_allocation_marker(int64_t aSize,
uintptr_t aMemoryAddress);
// Returns true if the profiler lock is currently held *on the current thread*.
// This may be used by re-entrant code that may call profiler functions while

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

@ -38,25 +38,6 @@ using UserTimingMeasure = mozilla::baseprofiler::markers::UserTimingMeasure;
using MediaSampleMarker = mozilla::baseprofiler::markers::MediaSampleMarker;
using ContentBuildMarker = mozilla::baseprofiler::markers::ContentBuildMarker;
// This payload is for collecting information about native allocations. There is
// a memory hook into malloc and other memory functions that can sample a subset
// of the allocations. This information is then stored in this payload.
struct NativeAllocationMarkerPayload {
static constexpr mozilla::Span<const char> MarkerTypeName() {
return mozilla::MakeStringSpan("Native allocation");
}
static void StreamJSONMarkerData(
mozilla::baseprofiler::SpliceableJSONWriter& aWriter, int64_t aSize,
uintptr_t aMemoryAddress, int aThreadId) {
aWriter.IntProperty("size", aSize);
aWriter.IntProperty("memoryAddress", static_cast<int64_t>(aMemoryAddress));
aWriter.IntProperty("threadId", aThreadId);
}
static mozilla::MarkerSchema MarkerTypeDisplay() {
return mozilla::MarkerSchema::SpecialFrontendLocation{};
}
};
struct IPCMarkerPayload {
static constexpr mozilla::Span<const char> MarkerTypeName() {
return mozilla::MakeStringSpan("IPC");

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

@ -763,10 +763,6 @@ TEST(GeckoProfiler, Markers)
// Other markers in alphabetical order of payload class names.
PROFILER_ADD_MARKER_WITH_PAYLOAD("NativeAllocationMarkerPayload marker",
OTHER, NativeAllocationMarkerPayload,
(ts1, 9876543210, 1234, 5678, nullptr));
nsCOMPtr<nsIURI> uri;
ASSERT_TRUE(
NS_SUCCEEDED(NS_NewURI(getter_AddRefs(uri), "http://mozilla.org/"_ns)));
@ -958,7 +954,6 @@ TEST(GeckoProfiler, Markers)
S_Markers2ExplicitDefaultEmptyOptions,
S_Markers2ExplicitDefaultWithOptions,
S_FirstMarker,
S_NativeAllocationMarkerPayload,
S_NetworkMarkerPayload_start,
S_NetworkMarkerPayload_stop,
S_NetworkMarkerPayload_redirect,
@ -1306,16 +1301,6 @@ TEST(GeckoProfiler, Markers)
ts2Double = marker[END_TIME].asDouble();
state = State(S_FirstMarker + 1);
} else if (nameString == "NativeAllocationMarkerPayload marker") {
EXPECT_EQ(state, S_NativeAllocationMarkerPayload);
state = State(S_NativeAllocationMarkerPayload + 1);
EXPECT_EQ(typeString, "Native allocation");
EXPECT_TIMING_INSTANT_AT(ts1Double);
EXPECT_TRUE(payload["stack"].isNull());
EXPECT_EQ_JSON(payload["size"], Int64, 9876543210);
EXPECT_EQ_JSON(payload["memoryAddress"], Int64, 1234);
EXPECT_EQ_JSON(payload["threadId"], Int64, 5678);
} else if (nameString == "Load 1: http://mozilla.org/") {
EXPECT_EQ(state, S_NetworkMarkerPayload_start);
state = State(S_NetworkMarkerPayload_start + 1);