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:
Kan-Ru Chen 2015-05-08 11:05:08 +08:00
parent 5d87284234
commit 00a45d37f4
9 changed files with 203 additions and 2 deletions

View File

@ -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

View File

@ -17,6 +17,7 @@
#include <stddef.h>
#include <stdint.h>
#include "jsfriendapi.h"
#include "jspubtd.h"
#include "jstypes.h"
#include "jsutil.h"

View 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;
}

View File

@ -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;

View File

@ -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());

View File

@ -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 */

View File

@ -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),

View File

@ -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',

View File

@ -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"