зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1438732 - Use nsClassHashtable for prefs hashtable. r=njn
--HG-- extra : rebase_source : a17b9490b6d52d2ed4e510f27a2410f56724f861
This commit is contained in:
Родитель
1b9bcc15aa
Коммит
cbfd16320a
|
@ -326,9 +326,8 @@ static ArenaAllocator<8192, 1> gPrefNameArena;
|
|||
class Pref
|
||||
{
|
||||
public:
|
||||
explicit Pref(const char* aName)
|
||||
: mName(ArenaStrdup(aName, gPrefNameArena))
|
||||
, mType(static_cast<uint32_t>(PrefType::None))
|
||||
explicit Pref()
|
||||
: mType(static_cast<uint32_t>(PrefType::None))
|
||||
, mIsSticky(false)
|
||||
, mIsLocked(false)
|
||||
, mHasDefaultValue(false)
|
||||
|
@ -341,15 +340,10 @@ public:
|
|||
|
||||
~Pref()
|
||||
{
|
||||
// There's no need to free mName because it's allocated in memory owned by
|
||||
// gPrefNameArena.
|
||||
|
||||
mDefaultValue.Clear(Type());
|
||||
mUserValue.Clear(Type());
|
||||
}
|
||||
|
||||
const char* Name() { return mName; }
|
||||
|
||||
// Types.
|
||||
|
||||
PrefType Type() const { return static_cast<PrefType>(mType); }
|
||||
|
@ -401,15 +395,6 @@ public:
|
|||
|
||||
// Other operations.
|
||||
|
||||
bool MatchEntry(const char* aPrefName)
|
||||
{
|
||||
if (!mName || !aPrefName) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return strcmp(mName, aPrefName) == 0;
|
||||
}
|
||||
|
||||
nsresult GetBoolValue(PrefValueKind aKind, bool* aResult)
|
||||
{
|
||||
if (!IsTypeBool()) {
|
||||
|
@ -469,11 +454,16 @@ public:
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
void ToDomPref(dom::Pref* aDomPref)
|
||||
// Fills out a dom pref with the values from this pref.
|
||||
// @param aDomPref The pref to update.
|
||||
// @param aName Optional. Override the dom pref's name with aName.
|
||||
void ToDomPref(dom::Pref* aDomPref, const char* aName = nullptr)
|
||||
{
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
|
||||
aDomPref->name() = mName;
|
||||
if (aName) {
|
||||
aDomPref->name() = aName;
|
||||
}
|
||||
|
||||
aDomPref->isLocked() = mIsLocked;
|
||||
|
||||
|
@ -502,7 +492,6 @@ public:
|
|||
void FromDomPref(const dom::Pref& aDomPref, bool* aValueChanged)
|
||||
{
|
||||
MOZ_ASSERT(!XRE_IsParentProcess());
|
||||
MOZ_ASSERT(strcmp(mName, aDomPref.name().get()) == 0);
|
||||
|
||||
mIsLocked = aDomPref.isLocked();
|
||||
|
||||
|
@ -688,7 +677,6 @@ public:
|
|||
|
||||
void AddSizeOfIncludingThis(MallocSizeOf aMallocSizeOf, PrefsSizes& aSizes)
|
||||
{
|
||||
// Note: mName is allocated in gPrefNameArena, measured elsewhere.
|
||||
aSizes.mPrefValues += aMallocSizeOf(this);
|
||||
if (IsTypeString()) {
|
||||
if (mHasDefaultValue) {
|
||||
|
@ -701,8 +689,6 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
const char* mName; // allocated in gPrefNameArena
|
||||
|
||||
uint32_t mType : 2;
|
||||
uint32_t mIsSticky : 1;
|
||||
uint32_t mIsLocked : 1;
|
||||
|
@ -714,36 +700,6 @@ private:
|
|||
PrefValue mUserValue;
|
||||
};
|
||||
|
||||
class PrefEntry : public PLDHashEntryHdr
|
||||
{
|
||||
public:
|
||||
Pref* mPref; // Note: this is never null in a live entry.
|
||||
|
||||
static bool MatchEntry(const PLDHashEntryHdr* aEntry, const void* aKey)
|
||||
{
|
||||
auto entry = static_cast<const PrefEntry*>(aEntry);
|
||||
auto prefName = static_cast<const char*>(aKey);
|
||||
|
||||
return entry->mPref->MatchEntry(prefName);
|
||||
}
|
||||
|
||||
static void InitEntry(PLDHashEntryHdr* aEntry, const void* aKey)
|
||||
{
|
||||
auto entry = static_cast<PrefEntry*>(aEntry);
|
||||
auto prefName = static_cast<const char*>(aKey);
|
||||
|
||||
entry->mPref = new Pref(prefName);
|
||||
}
|
||||
|
||||
static void ClearEntry(PLDHashTable* aTable, PLDHashEntryHdr* aEntry)
|
||||
{
|
||||
auto entry = static_cast<PrefEntry*>(aEntry);
|
||||
|
||||
delete entry->mPref;
|
||||
entry->mPref = nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
struct CallbackNode
|
||||
{
|
||||
CallbackNode(const char* aDomain,
|
||||
|
@ -769,7 +725,21 @@ struct CallbackNode
|
|||
CallbackNode* mNext;
|
||||
};
|
||||
|
||||
static PLDHashTable* gHashTable;
|
||||
// Hash key that allocates its string from the `gPrefNameArena`. The base class
|
||||
// `nsDepCharHashKey` does not own the string data and no copies are made.
|
||||
class StringArenaHashKey : public nsDepCharHashKey
|
||||
{
|
||||
public:
|
||||
explicit StringArenaHashKey(const char* aKey)
|
||||
: nsDepCharHashKey(ArenaStrdup(aKey, gPrefNameArena))
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
// Hashtable used to map names to pref objects. StringArenaHashKey is used to
|
||||
// allocate the strings out of an arena.
|
||||
using PrefsTable = nsClassHashtable<StringArenaHashKey, Pref>;
|
||||
static PrefsTable* gHashTable;
|
||||
|
||||
// The callback list contains all the priority callbacks followed by the
|
||||
// non-priority callbacks. gLastPriorityNode records where the first part ends.
|
||||
|
@ -782,14 +752,6 @@ static bool gIsAnyPrefLocked = false;
|
|||
static bool gCallbacksInProgress = false;
|
||||
static bool gShouldCleanupDeadNodes = false;
|
||||
|
||||
static PLDHashTableOps pref_HashTableOps = {
|
||||
PLDHashTable::HashStringKey,
|
||||
PrefEntry::MatchEntry,
|
||||
PLDHashTable::MoveEntryStub,
|
||||
PrefEntry::ClearEntry,
|
||||
PrefEntry::InitEntry,
|
||||
};
|
||||
|
||||
static Pref*
|
||||
pref_HashTableLookup(const char* aPrefName);
|
||||
|
||||
|
@ -803,10 +765,10 @@ pref_savePrefs()
|
|||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
PrefSaveData savedPrefs(gHashTable->EntryCount());
|
||||
PrefSaveData savedPrefs(gHashTable->Count());
|
||||
|
||||
for (auto iter = gHashTable->Iter(); !iter.Done(); iter.Next()) {
|
||||
Pref* pref = static_cast<PrefEntry*>(iter.Get())->mPref;
|
||||
Pref* pref = iter.Data();
|
||||
|
||||
nsAutoCString prefValueStr;
|
||||
if (!pref->UserValueToStringForSaving(prefValueStr)) {
|
||||
|
@ -814,7 +776,7 @@ pref_savePrefs()
|
|||
}
|
||||
|
||||
nsAutoCString prefNameStr;
|
||||
StrEscape(pref->Name(), prefNameStr);
|
||||
StrEscape(iter.Key(), prefNameStr);
|
||||
|
||||
nsPrintfCString str(
|
||||
"user_pref(%s, %s);", prefNameStr.get(), prefValueStr.get());
|
||||
|
@ -865,7 +827,7 @@ IsEarlyPref(const char* aPrefName)
|
|||
|
||||
#endif // DEBUG
|
||||
|
||||
static PrefEntry*
|
||||
static PrefsTable::LookupResult
|
||||
pref_HashTableLookupInner(const char* aPrefName)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread() || mozilla::ServoStyleSet::IsInServoTraversal());
|
||||
|
@ -888,14 +850,14 @@ pref_HashTableLookupInner(const char* aPrefName)
|
|||
}
|
||||
#endif
|
||||
|
||||
return static_cast<PrefEntry*>(gHashTable->Search(aPrefName));
|
||||
return gHashTable->Lookup(aPrefName);
|
||||
}
|
||||
|
||||
static Pref*
|
||||
pref_HashTableLookup(const char* aPrefName)
|
||||
{
|
||||
PrefEntry* entry = pref_HashTableLookupInner(aPrefName);
|
||||
return entry ? entry->mPref : nullptr;
|
||||
PrefsTable::LookupResult entry = pref_HashTableLookupInner(aPrefName);
|
||||
return entry ? static_cast<Pref*>(entry.Data()) : nullptr;
|
||||
}
|
||||
|
||||
static nsresult
|
||||
|
@ -912,12 +874,7 @@ pref_SetPref(const char* aPrefName,
|
|||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
auto entry = static_cast<PrefEntry*>(gHashTable->Add(aPrefName, fallible));
|
||||
if (!entry) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
Pref* pref = entry->mPref;
|
||||
Pref* pref = gHashTable->LookupOrAdd(aPrefName);
|
||||
if (pref->IsTypeNone()) {
|
||||
// New entry. Set the type.
|
||||
pref->SetType(aType);
|
||||
|
@ -2030,13 +1987,11 @@ nsPrefBranch::DeleteBranch(const char* aStartingAt)
|
|||
Substring(branchName, 0, branchName.Length() - 1);
|
||||
|
||||
for (auto iter = gHashTable->Iter(); !iter.Done(); iter.Next()) {
|
||||
Pref* pref = static_cast<PrefEntry*>(iter.Get())->mPref;
|
||||
|
||||
// The first disjunct matches branches: e.g. a branch name "foo.bar."
|
||||
// matches a name "foo.bar.baz" (but it won't match "foo.barrel.baz").
|
||||
// The second disjunct matches leaf nodes: e.g. a branch name "foo.bar."
|
||||
// matches a name "foo.bar" (by ignoring the trailing '.').
|
||||
nsDependentCString name(pref->Name());
|
||||
nsDependentCString name(iter.Key());
|
||||
if (StringBeginsWith(name, branchName) || name.Equals(branchNameNoDot)) {
|
||||
iter.Remove();
|
||||
}
|
||||
|
@ -2071,9 +2026,8 @@ nsPrefBranch::GetChildList(const char* aStartingAt,
|
|||
const PrefName& parent = GetPrefName(aStartingAt);
|
||||
size_t parentLen = parent.Length();
|
||||
for (auto iter = gHashTable->Iter(); !iter.Done(); iter.Next()) {
|
||||
Pref* pref = static_cast<PrefEntry*>(iter.Get())->mPref;
|
||||
if (strncmp(pref->Name(), parent.get(), parentLen) == 0) {
|
||||
prefArray.AppendElement(pref->Name());
|
||||
if (strncmp(iter.Key(), parent.get(), parentLen) == 0) {
|
||||
prefArray.AppendElement(iter.Key());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2685,7 +2639,7 @@ PreferenceServiceReporter::CollectReports(
|
|||
if (gHashTable) {
|
||||
sizes.mHashTable += gHashTable->ShallowSizeOfIncludingThis(mallocSizeOf);
|
||||
for (auto iter = gHashTable->Iter(); !iter.Done(); iter.Next()) {
|
||||
Pref* pref = static_cast<PrefEntry*>(iter.Get())->mPref;
|
||||
Pref* pref = iter.Data();
|
||||
pref->AddSizeOfIncludingThis(mallocSizeOf, sizes);
|
||||
}
|
||||
}
|
||||
|
@ -2878,8 +2832,7 @@ Preferences::GetInstanceForService()
|
|||
sPreferences = new Preferences();
|
||||
|
||||
MOZ_ASSERT(!gHashTable);
|
||||
gHashTable = new PLDHashTable(
|
||||
&pref_HashTableOps, sizeof(PrefEntry), PREF_HASHTABLE_INITIAL_LENGTH);
|
||||
gHashTable = new PrefsTable(PREF_HASHTABLE_INITIAL_LENGTH);
|
||||
|
||||
gTelemetryLoadData =
|
||||
new nsDataHashtable<nsCStringHashKey, TelemetryLoadData>();
|
||||
|
@ -3134,7 +3087,7 @@ Preferences::ResetPrefs()
|
|||
{
|
||||
ENSURE_PARENT_PROCESS("Preferences::ResetPrefs", "all prefs");
|
||||
|
||||
gHashTable->ClearAndPrepareForLength(PREF_HASHTABLE_INITIAL_LENGTH);
|
||||
gHashTable->Clear();
|
||||
gPrefNameArena.Clear();
|
||||
|
||||
return InitInitialObjects().isOk() ? NS_OK : NS_ERROR_FAILURE;
|
||||
|
@ -3149,10 +3102,10 @@ Preferences::ResetUserPrefs()
|
|||
|
||||
Vector<const char*> prefNames;
|
||||
for (auto iter = gHashTable->Iter(); !iter.Done(); iter.Next()) {
|
||||
Pref* pref = static_cast<PrefEntry*>(iter.Get())->mPref;
|
||||
Pref* pref = iter.Data();
|
||||
|
||||
if (pref->HasUserValue()) {
|
||||
if (!prefNames.append(pref->Name())) {
|
||||
if (!prefNames.append(iter.Key())) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
|
@ -3226,12 +3179,7 @@ Preferences::SetPreference(const dom::Pref& aDomPref)
|
|||
|
||||
const char* prefName = aDomPref.name().get();
|
||||
|
||||
auto entry = static_cast<PrefEntry*>(gHashTable->Add(prefName, fallible));
|
||||
if (!entry) {
|
||||
return;
|
||||
}
|
||||
|
||||
Pref* pref = entry->mPref;
|
||||
Pref* pref = gHashTable->LookupOrAdd(prefName);
|
||||
|
||||
bool valueChanged = false;
|
||||
pref->FromDomPref(aDomPref, &valueChanged);
|
||||
|
@ -3247,7 +3195,7 @@ Preferences::SetPreference(const dom::Pref& aDomPref)
|
|||
// needlessly, but that's ok because this case is rare.
|
||||
//
|
||||
if (!pref->HasDefaultValue() && !pref->HasUserValue()) {
|
||||
gHashTable->RemoveEntry(entry);
|
||||
gHashTable->Remove(prefName);
|
||||
}
|
||||
|
||||
// Note: we don't have to worry about HandleDirty() because we are setting
|
||||
|
@ -3275,9 +3223,9 @@ Preferences::GetPreferences(InfallibleTArray<dom::Pref>* aDomPrefs)
|
|||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
aDomPrefs->SetCapacity(gHashTable->EntryCount());
|
||||
aDomPrefs->SetCapacity(gHashTable->Count());
|
||||
for (auto iter = gHashTable->Iter(); !iter.Done(); iter.Next()) {
|
||||
Pref* pref = static_cast<PrefEntry*>(iter.Get())->mPref;
|
||||
Pref* pref = iter.Data();
|
||||
|
||||
if (!pref->MustSendToContentProcesses()) {
|
||||
// The pref value hasn't changed since it was initialized at startup.
|
||||
|
@ -3288,7 +3236,7 @@ Preferences::GetPreferences(InfallibleTArray<dom::Pref>* aDomPrefs)
|
|||
|
||||
if (pref->HasAdvisablySizedValues()) {
|
||||
dom::Pref* setting = aDomPrefs->AppendElement();
|
||||
pref->ToDomPref(setting);
|
||||
pref->ToDomPref(setting, iter.Key());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4184,13 +4132,13 @@ Preferences::ClearUserInAnyProcess(const char* aPrefName)
|
|||
{
|
||||
NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
PrefEntry* entry = pref_HashTableLookupInner(aPrefName);
|
||||
PrefsTable::LookupResult entry = pref_HashTableLookupInner(aPrefName);
|
||||
Pref* pref;
|
||||
if (entry && (pref = entry->mPref) && pref->HasUserValue()) {
|
||||
if (entry && (pref = entry.Data()) && pref->HasUserValue()) {
|
||||
pref->ClearUserValue();
|
||||
|
||||
if (!pref->HasDefaultValue()) {
|
||||
gHashTable->RemoveEntry(entry);
|
||||
entry.Remove();
|
||||
}
|
||||
|
||||
NotifyCallbacks(aPrefName);
|
||||
|
|
Загрузка…
Ссылка в новой задаче