diff options
Diffstat (limited to 'memory/replace/dmd/DMD.h')
-rw-r--r-- | memory/replace/dmd/DMD.h | 310 |
1 files changed, 0 insertions, 310 deletions
diff --git a/memory/replace/dmd/DMD.h b/memory/replace/dmd/DMD.h deleted file mode 100644 index ca3ccab16..000000000 --- a/memory/replace/dmd/DMD.h +++ /dev/null @@ -1,310 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=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/. */ - -#ifndef DMD_h___ -#define DMD_h___ - -#include <string.h> -#include <stdarg.h> - -#include "mozilla/DebugOnly.h" -#include "mozilla/Move.h" -#include "mozilla/Types.h" -#include "mozilla/UniquePtr.h" - -#include "replace_malloc_bridge.h" - -namespace mozilla { - -class JSONWriteFunc; - -namespace dmd { - -struct Sizes -{ - size_t mStackTracesUsed; - size_t mStackTracesUnused; - size_t mStackTraceTable; - size_t mLiveBlockTable; - size_t mDeadBlockTable; - - Sizes() { Clear(); } - void Clear() { memset(this, 0, sizeof(Sizes)); } -}; - -// See further below for a description of each method. The DMDFuncs class -// should contain a virtual method for each of them (except IsRunning, -// which can be inferred from the DMDFuncs singleton existing). -struct DMDFuncs -{ - virtual void Report(const void*); - - virtual void ReportOnAlloc(const void*); - - virtual void ClearReports(); - - virtual void Analyze(UniquePtr<JSONWriteFunc>); - - virtual void SizeOf(Sizes*); - - virtual void StatusMsg(const char*, va_list); - - virtual void ResetEverything(const char*); - -#ifndef REPLACE_MALLOC_IMPL - // We deliberately don't use ReplaceMalloc::GetDMDFuncs here, because if we - // did, the following would happen. - // - The code footprint of each call to Get() larger as GetDMDFuncs ends - // up inlined. - // - When no replace-malloc library is loaded, the number of instructions - // executed is equivalent, but don't necessarily fit in the same cache - // line. - // - When a non-DMD replace-malloc library is loaded, the overhead is - // higher because there is first a check for the replace malloc bridge - // and then for the DMDFuncs singleton. - // Initializing the DMDFuncs singleton on the first access makes the - // overhead even worse. Either Get() is inlined and massive, or it isn't - // and a simple value check becomes a function call. - static DMDFuncs* Get() { return sSingleton.Get(); } - -private: - // Wrapper class keeping a pointer to the DMD functions. It is statically - // initialized because it needs to be set early enough. - // Debug builds also check that it's never accessed before the static - // initialization actually occured, which could be the case if some other - // static initializer ended up calling into DMD. - class Singleton - { - public: - Singleton() - : mValue(ReplaceMalloc::GetDMDFuncs()) -#ifdef DEBUG - , mInitialized(true) -#endif - {} - - DMDFuncs* Get() - { - MOZ_ASSERT(mInitialized); - return mValue; - } - - private: - DMDFuncs* mValue; -#ifdef DEBUG - bool mInitialized; -#endif - }; - - // This singleton pointer must be defined on the program side. In Gecko, - // this is done in xpcom/base/nsMemoryInfoDumper.cpp. - static /* DMDFuncs:: */Singleton sSingleton; -#endif -}; - -#ifndef REPLACE_MALLOC_IMPL -// Mark a heap block as reported by a memory reporter. -inline void -Report(const void* aPtr) -{ - DMDFuncs* funcs = DMDFuncs::Get(); - if (funcs) { - funcs->Report(aPtr); - } -} - -// Mark a heap block as reported immediately on allocation. -inline void -ReportOnAlloc(const void* aPtr) -{ - DMDFuncs* funcs = DMDFuncs::Get(); - if (funcs) { - funcs->ReportOnAlloc(aPtr); - } -} - -// Clears existing reportedness data from any prior runs of the memory -// reporters. The following sequence should be used. -// - ClearReports() -// - run the memory reporters -// - Analyze() -// This sequence avoids spurious twice-reported warnings. -inline void -ClearReports() -{ - DMDFuncs* funcs = DMDFuncs::Get(); - if (funcs) { - funcs->ClearReports(); - } -} - -// Determines which heap blocks have been reported, and dumps JSON output -// (via |aWriter|) describing the heap. -// -// The following sample output contains comments that explain the format and -// design choices. The output files can be quite large, so a number of -// decisions were made to minimize size, such as using short property names and -// omitting properties whenever possible. -// -// { -// // The version number of the format, which will be incremented each time -// // backwards-incompatible changes are made. A mandatory integer. -// // -// // Version history: -// // - 1: Bug 1044709 -// // - 2: Bug 1094552 -// // - 3: Bug 1100851 -// // - 4: Bug 1121830 -// // - 5: Bug 1253512 -// "version": 5, -// -// // Information about how DMD was invoked. A mandatory object. -// "invocation": { -// // The contents of the $DMD environment variable. A string, or |null| if -// // $DMD is undefined. -// "dmdEnvVar": "--mode=dark-matter", -// -// // The profiling mode. A mandatory string taking one of the following -// // values: "live", "dark-matter", "cumulative", "scan". -// "mode": "dark-matter", -// }, -// -// // Details of all analyzed heap blocks. A mandatory array. -// "blockList": [ -// // An example of a heap block. -// { -// // Requested size, in bytes. This is a mandatory integer. -// "req": 3584, -// -// // Requested slop size, in bytes. This is mandatory if it is non-zero, -// // but omitted otherwise. -// "slop": 512, -// -// // The stack trace at which the block was allocated. An optional -// // string that indexes into the "traceTable" object. If omitted, no -// // allocation stack trace was recorded for the block. -// "alloc": "A", -// -// // One or more stack traces at which this heap block was reported by a -// // memory reporter. An optional array that will only be present in -// // "dark-matter" mode. The elements are strings that index into -// // the "traceTable" object. -// "reps": ["B"] -// -// // The number of heap blocks with exactly the above properties. This -// // is mandatory if it is greater than one, but omitted otherwise. -// // (Blocks with identical properties don't have to be aggregated via -// // this property, but it can greatly reduce output file size.) -// "num": 5, -// -// // The address of the block. This is mandatory in "scan" mode, but -// // omitted otherwise. -// "addr": "4e4e4e4e", -// -// // The contents of the block, read one word at a time. This is -// // mandatory in "scan" mode for blocks at least one word long, but -// // omitted otherwise. -// "contents": ["0", "6", "7f7f7f7f", "0"] -// } -// ], -// -// // The stack traces referenced by elements of the "blockList" array. This -// // could be an array, but making it an object makes it easier to see -// // which stacks correspond to which references in the "blockList" array. -// "traceTable": { -// // Each property corresponds to a stack trace mentioned in the "blocks" -// // object. Each element is an index into the "frameTable" object. -// "A": ["D", "E"], -// "B": ["F", "G"] -// }, -// -// // The stack frames referenced by the "traceTable" object. The -// // descriptions can be quite long, so they are stored separately from the -// // "traceTable" object so that each one only has to be written once. -// // This could also be an array, but again, making it an object makes it -// // easier to see which frames correspond to which references in the -// // "traceTable" object. -// "frameTable": { -// // Each property key is a frame key mentioned in the "traceTable" object. -// // Each property value is a string containing a frame description. Each -// // frame description must be in a format recognized by the stack-fixing -// // scripts (e.g. fix_linux_stack.py), which require a frame number at -// // the start. Because each stack frame description in this table can -// // be shared between multiple stack traces, we use a dummy value of -// // #00. The proper frame number can be reconstructed later by scripts -// // that output stack traces in a conventional non-shared format. -// "D": "#00: foo (Foo.cpp:123)", -// "E": "#00: bar (Bar.cpp:234)", -// "F": "#00: baz (Baz.cpp:345)", -// "G": "#00: quux (Quux.cpp:456)" -// } -// } -// -// Implementation note: normally, this function wouldn't be templated, but in -// that case, the function is compiled, which makes the destructor for the -// UniquePtr fire up, and that needs JSONWriteFunc to be fully defined. That, -// in turn, requires to include JSONWriter.h, which includes -// double-conversion.h, which ends up breaking various things built with -// -Werror for various reasons. -// -template <typename JSONWriteFunc> -inline void -Analyze(UniquePtr<JSONWriteFunc> aWriteFunc) -{ - DMDFuncs* funcs = DMDFuncs::Get(); - if (funcs) { - funcs->Analyze(Move(aWriteFunc)); - } -} - -// Gets the size of various data structures. Used to implement a memory -// reporter for DMD. -inline void -SizeOf(Sizes* aSizes) -{ - DMDFuncs* funcs = DMDFuncs::Get(); - if (funcs) { - funcs->SizeOf(aSizes); - } -} - -// Prints a status message prefixed with "DMD[<pid>]". Use sparingly. -inline void -StatusMsg(const char* aFmt, ...) -{ - DMDFuncs* funcs = DMDFuncs::Get(); - if (funcs) { - va_list ap; - va_start(ap, aFmt); - funcs->StatusMsg(aFmt, ap); - va_end(ap); - } -} - -// Indicates whether or not DMD is running. -inline bool -IsRunning() -{ - return !!DMDFuncs::Get(); -} - -// Resets all DMD options and then sets new ones according to those specified -// in |aOptions|. Also clears all recorded data about allocations. Only used -// for testing purposes. -inline void -ResetEverything(const char* aOptions) -{ - DMDFuncs* funcs = DMDFuncs::Get(); - if (funcs) { - funcs->ResetEverything(aOptions); - } -} -#endif - -} // namespace dmd -} // namespace mozilla - -#endif /* DMD_h___ */ |