From 7a16c0211e63f3919c76d7b8cd7c3997ce05186a Mon Sep 17 00:00:00 2001 From: Ehsan Akhgari Date: Thu, 11 Aug 2011 10:57:08 -0400 Subject: [PATCH] Bug 669116 - Add memory reporter for the spell checker; r=njn,khuey --- configure.in | 10 ++ .../spellcheck/hunspell/src/Makefile.in | 2 + .../hunspell/src/hunspell_alloc_hooks.h | 108 ++++++++++++++++++ .../spellcheck/hunspell/src/mozHunspell.cpp | 28 +++++ .../spellcheck/hunspell/src/mozHunspell.h | 6 +- 5 files changed, 153 insertions(+), 1 deletion(-) create mode 100644 extensions/spellcheck/hunspell/src/hunspell_alloc_hooks.h diff --git a/configure.in b/configure.in index 5b0773167099..0df993fae02e 100644 --- a/configure.in +++ b/configure.in @@ -9366,6 +9366,16 @@ _EGREP_PATTERN="${_EGREP_PATTERN}dummy_never_defined)" * is defined before is included. */ #define __STDC_LIMIT_MACROS +/* Force-include hunspell_alloc_hooks.h for hunspell, so that we don't need to + * modify it directly. + * + * HUNSPELL_STATIC is defined in extensions/spellcheck/hunspell/src/Makefile.in, + * unless --enable-system-hunspell is defined. + */ +#if defined(HUNSPELL_STATIC) +#include "hunspell_alloc_hooks.h" +#endif + #endif /* _MOZILLA_CONFIG_H_ */ EOF diff --git a/extensions/spellcheck/hunspell/src/Makefile.in b/extensions/spellcheck/hunspell/src/Makefile.in index 6db9cc966d41..7ca1316e3085 100644 --- a/extensions/spellcheck/hunspell/src/Makefile.in +++ b/extensions/spellcheck/hunspell/src/Makefile.in @@ -64,6 +64,8 @@ CPPSRCS += affentry.cpp \ suggestmgr.cpp \ $(NULL) +# This variable is referenced in configure.in. Make sure to change that file +# too if you need to change this variable. DEFINES = -DHUNSPELL_STATIC endif diff --git a/extensions/spellcheck/hunspell/src/hunspell_alloc_hooks.h b/extensions/spellcheck/hunspell/src/hunspell_alloc_hooks.h new file mode 100644 index 000000000000..fd24caeb2967 --- /dev/null +++ b/extensions/spellcheck/hunspell/src/hunspell_alloc_hooks.h @@ -0,0 +1,108 @@ +/******* BEGIN LICENSE BLOCK ******* + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Initial Developers of the Original Code is Mozilla Foundation. + * Portions created by the Initial Developers + * are Copyright (C) 2011 the Initial Developers. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + ******* END LICENSE BLOCK *******/ + +#ifndef alloc_hooks_h__ +#define alloc_hooks_h__ + +/** + * This file is force-included in hunspell code. Its purpose is to add memory + * reporting to hunspell without modifying its code, in order to ease future + * upgrades. + * + * This file is force-included through mozilla-config.h which is generated + * during the configure step. + * + * Currently, the memory allocated using operator new/new[] is not being + * tracked, but that's OK, since almost all of the memory used by Hunspell is + * allocated using C memory allocation functions. + */ + +// Prevent the standard macros from being redefined +#define mozilla_mozalloc_macro_wrappers_h + +#include "mozilla/mozalloc.h" + +extern void HunspellReportMemoryAllocation(void*); +extern void HunspellReportMemoryDeallocation(void*); + +inline void* hunspell_malloc(size_t size) +{ + void* result = moz_malloc(size); + HunspellReportMemoryAllocation(result); + return result; +} +#define malloc(size) hunspell_malloc(size) + +inline void* hunspell_calloc(size_t count, size_t size) +{ + void* result = moz_calloc(count, size); + HunspellReportMemoryAllocation(result); + return result; +} +#define calloc(count, size) hunspell_calloc(count, size) + +inline void hunspell_free(void* ptr) +{ + HunspellReportMemoryDeallocation(ptr); + moz_free(ptr); +} +#define free(ptr) hunspell_free(ptr) + +inline void* hunspell_realloc(void* ptr, size_t size) +{ + HunspellReportMemoryDeallocation(ptr); + void* result = moz_realloc(ptr, size); + HunspellReportMemoryAllocation(result); + return result; +} +#define realloc(ptr, size) hunspell_realloc(ptr, size) + +inline char* hunspell_strdup(const char* str) +{ + char* result = moz_strdup(str); + HunspellReportMemoryAllocation(result); + return result; +} +#define strdup(str) hunspell_strdup(str) + +#if defined(HAVE_STRNDUP) +inline char* hunspell_strndup(const char* str, size_t size) +{ + char* result = moz_strndup(str, size); + HunspellReportMemoryAllocation(result); + return result; +} +#define strndup(str, size) hunspell_strndup(str, size) +#endif + +#endif diff --git a/extensions/spellcheck/hunspell/src/mozHunspell.cpp b/extensions/spellcheck/hunspell/src/mozHunspell.cpp index 674f2e526c95..7c67933f3a63 100644 --- a/extensions/spellcheck/hunspell/src/mozHunspell.cpp +++ b/extensions/spellcheck/hunspell/src/mozHunspell.cpp @@ -71,6 +71,7 @@ #include "nsUnicharUtils.h" #include "nsCRT.h" #include +#include "nsIMemoryReporter.h" static NS_DEFINE_CID(kCharsetConverterManagerCID, NS_ICHARSETCONVERTERMANAGER_CID); static NS_DEFINE_CID(kUnicharUtilCID, NS_UNICHARUTIL_CID); @@ -91,6 +92,28 @@ NS_IMPL_CYCLE_COLLECTION_3(mozHunspell, mEncoder, mDecoder) +// Memory reporting stuff +static PRInt64 gHunspellAllocatedSize = 0; + +void HunspellReportMemoryAllocation(void* ptr) { + gHunspellAllocatedSize += moz_malloc_usable_size(ptr); +} +void HunspellReportMemoryDeallocation(void* ptr) { + gHunspellAllocatedSize -= moz_malloc_usable_size(ptr); +} +static PRInt64 HunspellGetCurrentAllocatedSize() { + return gHunspellAllocatedSize; +} + +NS_MEMORY_REPORTER_IMPLEMENT(Hunspell, + "explicit/spell-check", + KIND_HEAP, + UNITS_BYTES, + HunspellGetCurrentAllocatedSize, + "Memory used by the Hunspell spell checking engine. This number accounts " + "for the memory in use by Hunspell's internal data structures." +); + nsresult mozHunspell::Init() { @@ -105,6 +128,9 @@ mozHunspell::Init() obs->AddObserver(this, "profile-do-change", PR_TRUE); } + mHunspellReporter = new NS_MEMORY_REPORTER_NAME(Hunspell); + NS_RegisterMemoryReporter(mHunspellReporter); + return NS_OK; } @@ -112,6 +138,8 @@ mozHunspell::~mozHunspell() { mPersonalDictionary = nsnull; delete mHunspell; + + NS_UnregisterMemoryReporter(mHunspellReporter); } /* attribute wstring dictionary; */ diff --git a/extensions/spellcheck/hunspell/src/mozHunspell.h b/extensions/spellcheck/hunspell/src/mozHunspell.h index fd8cdcfca752..5b76d0c36013 100644 --- a/extensions/spellcheck/hunspell/src/mozHunspell.h +++ b/extensions/spellcheck/hunspell/src/mozHunspell.h @@ -77,6 +77,8 @@ { 0x56c778e4, 0x1bee, 0x45f3, \ { 0xa6, 0x89, 0x88, 0x66, 0x92, 0xa9, 0x7f, 0xe7 } } +class nsIMemoryReporter; + class mozHunspell : public mozISpellCheckingEngine, public nsIObserver, public nsSupportsWeakReference @@ -87,7 +89,7 @@ class mozHunspell : public mozISpellCheckingEngine, NS_DECL_NSIOBSERVER NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(mozHunspell, mozISpellCheckingEngine) - mozHunspell() : mHunspell(nsnull) { } + mozHunspell() : mHunspell(nsnull), mHunspellReporter(nsnull) { } virtual ~mozHunspell(); nsresult Init(); @@ -109,6 +111,8 @@ class mozHunspell : public mozISpellCheckingEngine, nsString mLanguage; Hunspell *mHunspell; + + nsIMemoryReporter* mHunspellReporter; }; #endif