mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-29 07:42:04 +00:00
Bug 1123237 - Part 2. MemoryProfiler hooks in js engine. r=terrence
Based on patch from Ting-Yuan Huang <laszio.bugzilla@gmail.com>
This commit is contained in:
parent
5d87284234
commit
00a45d37f4
@ -9,6 +9,7 @@
|
||||
|
||||
#include "mozilla/Atomics.h"
|
||||
|
||||
#include "jsfriendapi.h"
|
||||
#include "jsgc.h"
|
||||
|
||||
#include "gc/Heap.h"
|
||||
@ -985,6 +986,8 @@ class GCRuntime
|
||||
GCSchedulingTunables tunables;
|
||||
GCSchedulingState schedulingState;
|
||||
|
||||
MemProfiler mMemProfiler;
|
||||
|
||||
private:
|
||||
// When empty, chunks reside in the emptyChunks pool and are re-used as
|
||||
// needed or eventually expired if not re-used. The emptyChunks pool gets
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "jsfriendapi.h"
|
||||
#include "jspubtd.h"
|
||||
#include "jstypes.h"
|
||||
#include "jsutil.h"
|
||||
|
48
js/src/gc/MemoryProfiler.cpp
Normal file
48
js/src/gc/MemoryProfiler.cpp
Normal file
@ -0,0 +1,48 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=8 sts=4 et sw=4 tw=99:
|
||||
* 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 "jsfriendapi.h"
|
||||
|
||||
#include "vm/Runtime.h"
|
||||
|
||||
using js::gc::Cell;
|
||||
|
||||
mozilla::Atomic<int> MemProfiler::sActiveProfilerCount;
|
||||
NativeProfiler* MemProfiler::sNativeProfiler;
|
||||
|
||||
GCHeapProfiler*
|
||||
MemProfiler::GetGCHeapProfiler(void* addr)
|
||||
{
|
||||
JSRuntime* runtime = reinterpret_cast<Cell*>(addr)->runtimeFromAnyThread();
|
||||
return runtime->gc.mMemProfiler.mGCHeapProfiler;
|
||||
}
|
||||
|
||||
GCHeapProfiler*
|
||||
MemProfiler::GetGCHeapProfiler(JSRuntime* runtime)
|
||||
{
|
||||
return runtime->gc.mMemProfiler.mGCHeapProfiler;
|
||||
}
|
||||
|
||||
MemProfiler*
|
||||
MemProfiler::GetMemProfiler(JSRuntime* runtime)
|
||||
{
|
||||
return &runtime->gc.mMemProfiler;
|
||||
}
|
||||
|
||||
void
|
||||
MemProfiler::start(GCHeapProfiler* aGCHeapProfiler)
|
||||
{
|
||||
ReleaseAllJITCode(mRuntime->defaultFreeOp());
|
||||
mGCHeapProfiler = aGCHeapProfiler;
|
||||
sActiveProfilerCount++;
|
||||
}
|
||||
|
||||
void
|
||||
MemProfiler::stop()
|
||||
{
|
||||
sActiveProfilerCount--;
|
||||
mGCHeapProfiler = nullptr;
|
||||
}
|
@ -7,10 +7,12 @@
|
||||
|
||||
#include "gc/Nursery-inl.h"
|
||||
|
||||
#include "mozilla/DebugOnly.h"
|
||||
#include "mozilla/IntegerPrintfMacros.h"
|
||||
#include "mozilla/Move.h"
|
||||
|
||||
#include "jscompartment.h"
|
||||
#include "jsfriendapi.h"
|
||||
#include "jsgc.h"
|
||||
#include "jsutil.h"
|
||||
|
||||
@ -34,6 +36,7 @@ using namespace js;
|
||||
using namespace gc;
|
||||
|
||||
using mozilla::ArrayLength;
|
||||
using mozilla::DebugOnly;
|
||||
using mozilla::PodCopy;
|
||||
using mozilla::PodZero;
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include "jit/MacroAssembler-inl.h"
|
||||
|
||||
#include "jsfriendapi.h"
|
||||
#include "jsprf.h"
|
||||
|
||||
#include "builtin/TypedObject.h"
|
||||
@ -31,7 +32,7 @@ using JS::GenericNaN;
|
||||
using JS::ToInt32;
|
||||
|
||||
template <typename Source> void
|
||||
MacroAssembler::guardTypeSet(const Source& address, const TypeSet *types, BarrierKind kind,
|
||||
MacroAssembler::guardTypeSet(const Source& address, const TypeSet* types, BarrierKind kind,
|
||||
Register scratch, Label* miss)
|
||||
{
|
||||
MOZ_ASSERT(kind == BarrierKind::TypeTagOnly || kind == BarrierKind::TypeSet);
|
||||
@ -147,7 +148,7 @@ MacroAssembler::guardTypeSetMightBeIncomplete(TypeSet* types, Register obj, Regi
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::guardObjectType(Register obj, const TypeSet *types,
|
||||
MacroAssembler::guardObjectType(Register obj, const TypeSet* types,
|
||||
Register scratch, Label* miss)
|
||||
{
|
||||
MOZ_ASSERT(!types->unknown());
|
||||
|
@ -7,6 +7,7 @@
|
||||
#ifndef jsfriendapi_h
|
||||
#define jsfriendapi_h
|
||||
|
||||
#include "mozilla/Atomics.h"
|
||||
#include "mozilla/Casting.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
@ -2848,4 +2849,144 @@ JS_StoreStringPostBarrierCallback(JSContext* cx,
|
||||
extern JS_FRIEND_API(void)
|
||||
JS_ClearAllPostBarrierCallbacks(JSRuntime *rt);
|
||||
|
||||
class NativeProfiler
|
||||
{
|
||||
public:
|
||||
virtual ~NativeProfiler() {};
|
||||
virtual void sampleNative(void* addr, uint32_t size) = 0;
|
||||
virtual void removeNative(void* addr) = 0;
|
||||
virtual void reset() = 0;
|
||||
};
|
||||
|
||||
class GCHeapProfiler
|
||||
{
|
||||
public:
|
||||
virtual ~GCHeapProfiler() {};
|
||||
virtual void sampleTenured(void* addr, uint32_t size) = 0;
|
||||
virtual void sampleNursery(void* addr, uint32_t size) = 0;
|
||||
virtual void markTenuredStart() = 0;
|
||||
virtual void markTenured(void* addr) = 0;
|
||||
virtual void sweepTenured() = 0;
|
||||
virtual void sweepNursery() = 0;
|
||||
virtual void moveNurseryToTenured(void* addrOld, void* addrNew) = 0;
|
||||
virtual void reset() = 0;
|
||||
};
|
||||
|
||||
class MemProfiler
|
||||
{
|
||||
static mozilla::Atomic<int> sActiveProfilerCount;
|
||||
static NativeProfiler* sNativeProfiler;
|
||||
|
||||
static GCHeapProfiler* GetGCHeapProfiler(void* addr);
|
||||
static GCHeapProfiler* GetGCHeapProfiler(JSRuntime* runtime);
|
||||
|
||||
static NativeProfiler* GetNativeProfiler() {
|
||||
return sNativeProfiler;
|
||||
}
|
||||
|
||||
GCHeapProfiler* mGCHeapProfiler;
|
||||
JSRuntime* mRuntime;
|
||||
|
||||
public:
|
||||
explicit MemProfiler(JSRuntime* aRuntime) : mGCHeapProfiler(nullptr), mRuntime(aRuntime) {}
|
||||
|
||||
void start(GCHeapProfiler* aGCHeapProfiler);
|
||||
void stop();
|
||||
|
||||
GCHeapProfiler* getGCHeapProfiler() const {
|
||||
return mGCHeapProfiler;
|
||||
}
|
||||
|
||||
static bool enabled() {
|
||||
return sActiveProfilerCount > 0;
|
||||
}
|
||||
|
||||
static MemProfiler* GetMemProfiler(JSRuntime* runtime);
|
||||
|
||||
static void SetNativeProfiler(NativeProfiler* aProfiler) {
|
||||
sNativeProfiler = aProfiler;
|
||||
}
|
||||
|
||||
static void SampleNative(void* addr, uint32_t size) {
|
||||
if (MOZ_LIKELY(!enabled()))
|
||||
return;
|
||||
|
||||
NativeProfiler* profiler = GetNativeProfiler();
|
||||
if (profiler)
|
||||
profiler->sampleNative(addr, size);
|
||||
}
|
||||
|
||||
static void SampleTenured(void* addr, uint32_t size) {
|
||||
if (MOZ_LIKELY(!enabled()))
|
||||
return;
|
||||
|
||||
GCHeapProfiler* profiler = GetGCHeapProfiler(addr);
|
||||
if (profiler)
|
||||
profiler->sampleTenured(addr, size);
|
||||
}
|
||||
|
||||
static void SampleNursery(void* addr, uint32_t size) {
|
||||
if (MOZ_LIKELY(!enabled()))
|
||||
return;
|
||||
|
||||
GCHeapProfiler* profiler = GetGCHeapProfiler(addr);
|
||||
if (profiler)
|
||||
profiler->sampleNursery(addr, size);
|
||||
}
|
||||
|
||||
static void RemoveNative(void* addr) {
|
||||
if (MOZ_LIKELY(!enabled()))
|
||||
return;
|
||||
|
||||
NativeProfiler* profiler = GetNativeProfiler();
|
||||
if (profiler)
|
||||
profiler->removeNative(addr);
|
||||
}
|
||||
|
||||
static void MarkTenuredStart(JSRuntime* runtime) {
|
||||
if (MOZ_LIKELY(!enabled()))
|
||||
return;
|
||||
|
||||
GCHeapProfiler* profiler = GetGCHeapProfiler(runtime);
|
||||
if (profiler)
|
||||
profiler->markTenuredStart();
|
||||
}
|
||||
|
||||
static void MarkTenured(void* addr) {
|
||||
if (MOZ_LIKELY(!enabled()))
|
||||
return;
|
||||
|
||||
GCHeapProfiler* profiler = GetGCHeapProfiler(addr);
|
||||
if (profiler)
|
||||
profiler->markTenured(addr);
|
||||
}
|
||||
|
||||
static void SweepTenured(JSRuntime* runtime) {
|
||||
if (MOZ_LIKELY(!enabled()))
|
||||
return;
|
||||
|
||||
GCHeapProfiler* profiler = GetGCHeapProfiler(runtime);
|
||||
if (profiler)
|
||||
profiler->sweepTenured();
|
||||
}
|
||||
|
||||
static void SweepNursery(JSRuntime* runtime) {
|
||||
if (MOZ_LIKELY(!enabled()))
|
||||
return;
|
||||
|
||||
GCHeapProfiler* profiler = GetGCHeapProfiler(runtime);
|
||||
if (profiler)
|
||||
profiler->sweepNursery();
|
||||
}
|
||||
|
||||
static void MoveNurseryToTenured(void* addrOld, void* addrNew) {
|
||||
if (MOZ_LIKELY(!enabled()))
|
||||
return;
|
||||
|
||||
GCHeapProfiler* profiler = GetGCHeapProfiler(addrOld);
|
||||
if (profiler)
|
||||
profiler->moveNurseryToTenured(addrOld, addrNew);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* jsfriendapi_h */
|
||||
|
@ -197,6 +197,7 @@
|
||||
#include "jsatom.h"
|
||||
#include "jscntxt.h"
|
||||
#include "jscompartment.h"
|
||||
#include "jsfriendapi.h"
|
||||
#include "jsobj.h"
|
||||
#include "jsprf.h"
|
||||
#include "jsscript.h"
|
||||
@ -1099,6 +1100,7 @@ GCRuntime::GCRuntime(JSRuntime* rt) :
|
||||
stats(rt),
|
||||
marker(rt),
|
||||
usage(nullptr),
|
||||
mMemProfiler(rt),
|
||||
maxMallocBytes(0),
|
||||
numArenasFreeCommitted(0),
|
||||
verifyPreData(nullptr),
|
||||
|
@ -172,6 +172,7 @@ UNIFIED_SOURCES += [
|
||||
'gc/Iteration.cpp',
|
||||
'gc/Marking.cpp',
|
||||
'gc/Memory.cpp',
|
||||
'gc/MemoryProfiler.cpp',
|
||||
'gc/Nursery.cpp',
|
||||
'gc/RootMarking.cpp',
|
||||
'gc/Statistics.cpp',
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "jsarray.h"
|
||||
#include "jscntxt.h"
|
||||
#include "jscpucfg.h"
|
||||
#include "jsfriendapi.h"
|
||||
#include "jsnum.h"
|
||||
#include "jsobj.h"
|
||||
#include "jstypes.h"
|
||||
|
Loading…
Reference in New Issue
Block a user