mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-28 15:23:51 +00:00
Bug 1663365
- Move allocation-logging functions and |JS_COUNT_{CTOR,DTOR}| into a separate header. r=jandem
Differential Revision: https://phabricator.services.mozilla.com/D89334
This commit is contained in:
parent
6d5beafab1
commit
5c5e824b56
78
js/public/AllocationLogging.h
Normal file
78
js/public/AllocationLogging.h
Normal file
@ -0,0 +1,78 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: set ts=8 sts=2 et sw=2 tw=80:
|
||||
* 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/. */
|
||||
|
||||
/*
|
||||
* Embedder-supplied tracking of the allocation and deallocation of various
|
||||
* non-garbage-collected objects in SpiderMonkey.
|
||||
*
|
||||
* This functionality is intended to track allocation of non-user-visible
|
||||
* structures, for debugging the C++ of an embedding. It is not intended to
|
||||
* give the end user visibility into allocations in JS. Instead see
|
||||
* AllocationRecording.h for such functionality.
|
||||
*/
|
||||
|
||||
#ifndef js_AllocationLogging_h
|
||||
#define js_AllocationLogging_h
|
||||
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/PodOperations.h"
|
||||
|
||||
#include <stdint.h> // uint32_t
|
||||
|
||||
#include "jstypes.h" // JS_PUBLIC_API
|
||||
|
||||
namespace JS {
|
||||
|
||||
using LogCtorDtor = void (*)(void*, const char*, uint32_t);
|
||||
|
||||
/**
|
||||
* Set global functions used to monitor classes to highlight leaks.
|
||||
*
|
||||
* For each C++ class that uses these mechanisms, the allocation of an instance
|
||||
* will log the constructor call, and its subsequent deallocation will log the
|
||||
* destructor call. If only the former occurs, the instance/allocation is
|
||||
* leaked. With carefully-written logging functions, this can be used to debug
|
||||
* the origin of the leaks.
|
||||
*/
|
||||
extern JS_PUBLIC_API void SetLogCtorDtorFunctions(LogCtorDtor ctor,
|
||||
LogCtorDtor dtor);
|
||||
|
||||
/**
|
||||
* Log the allocation of |self|, having a type uniquely identified by the string
|
||||
* |type|, with allocation size |sz|.
|
||||
*
|
||||
* You generally should use |JS_COUNT_CTOR| and |JS_COUNT_DTOR| instead of
|
||||
* using this function directly.
|
||||
*/
|
||||
extern JS_PUBLIC_API void LogCtor(void* self, const char* type, uint32_t sz);
|
||||
|
||||
/**
|
||||
* Log the deallocation of |self|, having a type uniquely identified by the
|
||||
* string |type|, with allocation size |sz|.
|
||||
*
|
||||
* You generally should use |JS_COUNT_CTOR| and |JS_COUNT_DTOR| instead of
|
||||
* using this function directly.
|
||||
*/
|
||||
extern JS_PUBLIC_API void LogDtor(void* self, const char* type, uint32_t sz);
|
||||
|
||||
/**
|
||||
* Within each non-delegating constructor of a |Class|, use
|
||||
* |JS_COUNT_CTOR(Class);| to log the allocation of |this|. (If you do this in
|
||||
* delegating constructors, you might count a single allocation multiple times.)
|
||||
*/
|
||||
#define JS_COUNT_CTOR(Class) \
|
||||
(::JS::LogCtor(static_cast<void*>(this), #Class, sizeof(Class)))
|
||||
|
||||
/**
|
||||
* Within the destructor of a |Class|, use |JS_COUNT_DTOR(Class);| to log the
|
||||
* deallocation of |this|.
|
||||
*/
|
||||
#define JS_COUNT_DTOR(Class) \
|
||||
(::JS::LogDtor(static_cast<void*>(this), #Class, sizeof(Class)))
|
||||
|
||||
} // namespace JS
|
||||
|
||||
#endif // js_AllocationLogging_h
|
@ -865,29 +865,6 @@ JS_FRIEND_API void js::SetRealmValidAccessPtr(JSContext* cx,
|
||||
|
||||
JS_FRIEND_API bool js::SystemZoneAvailable(JSContext* cx) { return true; }
|
||||
|
||||
static LogCtorDtor sLogCtor = nullptr;
|
||||
static LogCtorDtor sLogDtor = nullptr;
|
||||
|
||||
JS_FRIEND_API void js::SetLogCtorDtorFunctions(LogCtorDtor ctor,
|
||||
LogCtorDtor dtor) {
|
||||
MOZ_ASSERT(!sLogCtor && !sLogDtor);
|
||||
MOZ_ASSERT(ctor && dtor);
|
||||
sLogCtor = ctor;
|
||||
sLogDtor = dtor;
|
||||
}
|
||||
|
||||
JS_FRIEND_API void js::LogCtor(void* self, const char* type, uint32_t sz) {
|
||||
if (LogCtorDtor fun = sLogCtor) {
|
||||
fun(self, type, sz);
|
||||
}
|
||||
}
|
||||
|
||||
JS_FRIEND_API void js::LogDtor(void* self, const char* type, uint32_t sz) {
|
||||
if (LogCtorDtor fun = sLogDtor) {
|
||||
fun(self, type, sz);
|
||||
}
|
||||
}
|
||||
|
||||
JS_FRIEND_API JS::Value js::MaybeGetScriptPrivate(JSObject* object) {
|
||||
if (!object->is<ScriptSourceObject>()) {
|
||||
return UndefinedValue();
|
||||
|
@ -1042,23 +1042,6 @@ extern JS_FRIEND_API void SetRealmValidAccessPtr(JSContext* cx,
|
||||
// contexts are using it now).
|
||||
extern JS_FRIEND_API bool SystemZoneAvailable(JSContext* cx);
|
||||
|
||||
using LogCtorDtor = void (*)(void*, const char*, uint32_t);
|
||||
|
||||
/**
|
||||
* Set global function used to monitor a few internal classes to highlight
|
||||
* leaks, and to hint at the origin of the leaks.
|
||||
*/
|
||||
extern JS_FRIEND_API void SetLogCtorDtorFunctions(LogCtorDtor ctor,
|
||||
LogCtorDtor dtor);
|
||||
|
||||
extern JS_FRIEND_API void LogCtor(void* self, const char* type, uint32_t sz);
|
||||
|
||||
extern JS_FRIEND_API void LogDtor(void* self, const char* type, uint32_t sz);
|
||||
|
||||
#define JS_COUNT_CTOR(Class) LogCtor((void*)this, #Class, sizeof(Class))
|
||||
|
||||
#define JS_COUNT_DTOR(Class) LogDtor((void*)this, #Class, sizeof(Class))
|
||||
|
||||
/**
|
||||
* This function only reports GC heap memory,
|
||||
* and not malloc allocated memory associated with GC things.
|
||||
|
@ -120,6 +120,7 @@ EXPORTS += [
|
||||
]
|
||||
|
||||
EXPORTS.js += [
|
||||
'../public/AllocationLogging.h',
|
||||
'../public/AllocationRecording.h',
|
||||
'../public/AllocPolicy.h',
|
||||
'../public/Array.h',
|
||||
@ -332,6 +333,7 @@ UNIFIED_SOURCES += [
|
||||
'threading/Mutex.cpp',
|
||||
'threading/ProtectedData.cpp',
|
||||
'threading/Thread.cpp',
|
||||
'util/AllocationLogging.cpp',
|
||||
'util/AllocPolicy.cpp',
|
||||
'util/CompleteFile.cpp',
|
||||
'util/DumpFunctions.cpp',
|
||||
|
31
js/src/util/AllocationLogging.cpp
Normal file
31
js/src/util/AllocationLogging.cpp
Normal file
@ -0,0 +1,31 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: set ts=8 sts=2 et sw=2 tw=80:
|
||||
* 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 "js/AllocationLogging.h"
|
||||
|
||||
#include "mozilla/Assertions.h" // MOZ_ASSERT
|
||||
|
||||
static JS::LogCtorDtor sLogCtor = nullptr;
|
||||
static JS::LogCtorDtor sLogDtor = nullptr;
|
||||
|
||||
void JS::SetLogCtorDtorFunctions(LogCtorDtor ctor, LogCtorDtor dtor) {
|
||||
MOZ_ASSERT(!sLogCtor && !sLogDtor);
|
||||
MOZ_ASSERT(ctor && dtor);
|
||||
sLogCtor = ctor;
|
||||
sLogDtor = dtor;
|
||||
}
|
||||
|
||||
void JS::LogCtor(void* self, const char* type, uint32_t sz) {
|
||||
if (LogCtorDtor fun = sLogCtor) {
|
||||
fun(self, type, sz);
|
||||
}
|
||||
}
|
||||
|
||||
void JS::LogDtor(void* self, const char* type, uint32_t sz) {
|
||||
if (LogCtorDtor fun = sLogDtor) {
|
||||
fun(self, type, sz);
|
||||
}
|
||||
}
|
@ -33,6 +33,7 @@
|
||||
#include "jit/JitRealm.h"
|
||||
#include "jit/mips32/Simulator-mips32.h"
|
||||
#include "jit/mips64/Simulator-mips64.h"
|
||||
#include "js/AllocationLogging.h" // JS_COUNT_CTOR, JS_COUNT_DTOR
|
||||
#include "js/Date.h"
|
||||
#include "js/MemoryMetrics.h"
|
||||
#include "js/SliceBudget.h"
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
#include "XPCWrapper.h"
|
||||
#include "jsfriendapi.h"
|
||||
#include "js/AllocationLogging.h" // JS::SetLogCtorDtorFunctions
|
||||
#include "js/Object.h" // JS::GetClass
|
||||
#include "js/ProfilingStack.h"
|
||||
#include "GeckoProfiler.h"
|
||||
@ -136,7 +137,7 @@ void nsXPConnect::InitStatics() {
|
||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
||||
// These functions are used for reporting leaks, so we register them as early
|
||||
// as possible to avoid missing any classes' creations.
|
||||
js::SetLogCtorDtorFunctions(NS_LogCtor, NS_LogDtor);
|
||||
JS::SetLogCtorDtorFunctions(NS_LogCtor, NS_LogDtor);
|
||||
#endif
|
||||
ReadOnlyPage::Init();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user