gecko-dev/xpcom/components/nsCategoryManager.h
Kris Maglione 7aa3564a28 Bug 1477579: Part 3 - Avoid duplicating static strings in category manager entries. r=froydnj
Much like the component manager, many of the strings that we use for category
manager entries are statically allocated. There's no need to duplicate these
strings.

This patch changes the category manager APIs to take nsACStrings rather than
raw pointers, and to pass literal nsCStrings when we know we have a literal
string to begin with. When adding the category entry, it then skips making
copies of any strings with the LITERAL flag.

MozReview-Commit-ID: EJEcYSdNMWs
***
amend-catman

--HG--
extra : source : aa9a8f18e98f930a3d8359565eef02f3f6efc5f9
extra : absorb_source : 81a22ab26ee8017ac43321ff2c987d8096182d37
2018-07-23 17:41:06 -07:00

158 lines
4.3 KiB
C++

/* -*- 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/. */
#ifndef NSCATEGORYMANAGER_H
#define NSCATEGORYMANAGER_H
#include "prio.h"
#include "nsClassHashtable.h"
#include "nsICategoryManager.h"
#include "nsIMemoryReporter.h"
#include "mozilla/ArenaAllocator.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/Mutex.h"
#include "mozilla/Attributes.h"
class nsIMemoryReporter;
typedef mozilla::ArenaAllocator<1024*8, 8> CategoryAllocator;
/* 16d222a6-1dd2-11b2-b693-f38b02c021b2 */
#define NS_CATEGORYMANAGER_CID \
{ 0x16d222a6, 0x1dd2, 0x11b2, \
{0xb6, 0x93, 0xf3, 0x8b, 0x02, 0xc0, 0x21, 0xb2} }
/**
* a "leaf-node", managed by the nsCategoryNode hashtable.
*
* we need to keep a "persistent value" (which will be written to the registry)
* and a non-persistent value (for the current runtime): these are usually
* the same, except when aPersist==false. The strings are permanently arena-
* allocated, and will never go away.
*/
class CategoryLeaf : public nsDepCharHashKey
{
public:
explicit CategoryLeaf(const char* aKey) : nsDepCharHashKey(aKey), value(nullptr) {}
const char* value;
};
/**
* CategoryNode keeps a hashtable of its entries.
* the CategoryNode itself is permanently allocated in
* the arena.
*/
class CategoryNode
{
public:
nsresult GetLeaf(const nsACString& aEntryName,
nsACString& aResult);
nsresult AddLeaf(const nsACString& aEntryName,
const nsACString& aValue,
bool aReplace,
nsACString& aResult,
CategoryAllocator* aArena);
void DeleteLeaf(const nsACString& aEntryName);
void Clear()
{
mozilla::MutexAutoLock lock(mLock);
mTable.Clear();
}
uint32_t Count()
{
mozilla::MutexAutoLock lock(mLock);
uint32_t tCount = mTable.Count();
return tCount;
}
nsresult Enumerate(nsISimpleEnumerator** aResult);
// CategoryNode is arena-allocated, with the strings
static CategoryNode* Create(CategoryAllocator* aArena);
~CategoryNode();
void operator delete(void*) {}
size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf);
private:
CategoryNode() : mLock("CategoryLeaf") {}
void* operator new(size_t aSize, CategoryAllocator* aArena);
nsTHashtable<CategoryLeaf> mTable;
mozilla::Mutex mLock;
};
/**
* The main implementation of nsICategoryManager.
*
* This implementation is thread-safe.
*/
class nsCategoryManager final
: public nsICategoryManager
, public nsIMemoryReporter
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSICATEGORYMANAGER
NS_DECL_NSIMEMORYREPORTER
/**
* Suppress or unsuppress notifications of category changes to the
* observer service. This is to be used by nsComponentManagerImpl
* on startup while reading the stored category list.
*/
nsresult SuppressNotifications(bool aSuppress);
void AddCategoryEntry(const nsACString& aCategory,
const nsACString& aKey,
const nsACString& aValue,
bool aReplace,
nsACString& aOldValue);
void AddCategoryEntry(const nsACString& aCategory,
const nsACString& aKey,
const nsACString& aValue,
bool aReplace = true)
{
nsCString oldValue;
return AddCategoryEntry(aCategory, aKey, aValue, aReplace, oldValue);
}
static nsresult Create(nsISupports* aOuter, REFNSIID aIID, void** aResult);
void InitMemoryReporter();
static nsCategoryManager* GetSingleton();
static void Destroy();
private:
static nsCategoryManager* gCategoryManager;
nsCategoryManager();
~nsCategoryManager();
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf);
CategoryNode* get_category(const nsACString& aName);
void NotifyObservers(const char* aTopic,
const nsACString& aCategoryName, // must be a static string
const nsACString& aEntryName);
CategoryAllocator mArena;
nsClassHashtable<nsDepCharHashKey, CategoryNode> mTable;
mozilla::Mutex mLock;
bool mSuppressNotifications;
};
#endif