--- a/modules/libpref/Preferences.cpp
+++ b/modules/libpref/Preferences.cpp
@@ -155,120 +155,81 @@ PrefTypeToString(PrefType aType)
case PrefType::Bool:
return "bool";
default:
MOZ_CRASH("Unhandled enum value");
}
}
#endif
-// Keep the type of the preference, as well as the flags guiding its behaviour.
-class PrefTypeFlags
+class PrefHashEntry : public PLDHashEntryHdr
{
public:
- PrefTypeFlags()
- : mValue(AsInt(PrefType::Invalid))
- {
- }
-
- explicit PrefTypeFlags(PrefType aType)
- : mValue(AsInt(aType))
- {
- }
-
- bool IsTypeValid() const { return !IsPrefType(PrefType::Invalid); }
- bool IsTypeString() const { return IsPrefType(PrefType::String); }
- bool IsTypeInt() const { return IsPrefType(PrefType::Int); }
- bool IsTypeBool() const { return IsPrefType(PrefType::Bool); }
- bool IsPrefType(PrefType type) const { return GetPrefType() == type; }
-
- void SetPrefType(PrefType aType)
- {
- mValue = mValue - AsInt(GetPrefType()) + AsInt(aType);
- }
-
- PrefType GetPrefType() const
- {
- return (PrefType)(mValue & (AsInt(PrefType::String) | AsInt(PrefType::Int) |
- AsInt(PrefType::Bool)));
- }
-
- bool HasDefaultValue() const { return mValue & PREF_FLAG_HAS_DEFAULT_VALUE; }
-
- void SetHasDefaultValue(bool aSetOrUnset)
- {
- SetFlag(PREF_FLAG_HAS_DEFAULT_VALUE, aSetOrUnset);
- }
-
- bool IsSticky() const { return mValue & PREF_FLAG_STICKY; }
-
- void SetIsSticky(bool aSetOrUnset)
- {
- SetFlag(PREF_FLAG_STICKY, aSetOrUnset);
- }
-
- bool IsLocked() const { return mValue & PREF_FLAG_LOCKED; }
-
- void SetLocked(bool aSetOrUnset) { SetFlag(PREF_FLAG_LOCKED, aSetOrUnset); }
-
- bool HasUserValue() const { return mValue & PREF_FLAG_HAS_USER_VALUE; }
-
- void SetHasUserValue(bool aSetOrUnset)
- {
- SetFlag(PREF_FLAG_HAS_USER_VALUE, aSetOrUnset);
- }
-
-private:
- static uint16_t AsInt(PrefType aType) { return (uint16_t)aType; }
-
- void SetFlag(uint16_t aFlag, bool aSetOrUnset)
- {
- mValue = aSetOrUnset ? mValue | aFlag : mValue & ~aFlag;
- }
-
- // We pack both the value of type (PrefType) and flags into the same int. The
- // flag enum starts at 4 so that the PrefType can occupy the bottom two bits.
- enum
- {
- PREF_FLAG_LOCKED = 4,
- PREF_FLAG_HAS_USER_VALUE = 8,
- PREF_FLAG_HAS_DEFAULT_VALUE = 16,
- PREF_FLAG_STICKY = 32,
- };
- uint16_t mValue;
-};
-
-struct PrefHashEntry : PLDHashEntryHdr
-{
- PrefTypeFlags mPrefFlags; // this field first to minimize 64-bit struct size
- const char* mKey;
- PrefValue mDefaultValue;
- PrefValue mUserValue;
+ // Types.
+
+ PrefType Type() const { return static_cast<PrefType>(mType); }
+ void SetType(PrefType aType) { mType = static_cast<uint32_t>(aType); }
+
+ bool IsType(PrefType aType) const { return Type() == aType; }
+ bool IsTypeString() const { return IsType(PrefType::String); }
+ bool IsTypeInt() const { return IsType(PrefType::Int); }
+ bool IsTypeBool() const { return IsType(PrefType::Bool); }
+
+ // Other properties.
+
+ bool IsSticky() const { return mIsSticky; }
+ void SetIsSticky(bool aValue) { mIsSticky = aValue; }
+
+ bool IsLocked() const { return mIsLocked; }
+ void SetLocked(bool aValue) { mIsLocked = aValue; }
+
+ bool HasDefaultValue() const { return mHasDefaultValue; }
+ void SetHasDefaultValue(bool aValue) { mHasDefaultValue = aValue; }
+
+ bool HasUserValue() const { return mHasUserValue; }
+ void SetHasUserValue(bool aValue) { mHasUserValue = aValue; }
+
+ // Other operations.
size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf)
{
// Note: mKey is allocated in gPrefNameArena, measured elsewhere.
size_t n = 0;
- if (mPrefFlags.IsTypeString()) {
- if (mPrefFlags.HasDefaultValue()) {
+ if (IsTypeString()) {
+ if (HasDefaultValue()) {
n += aMallocSizeOf(mDefaultValue.mStringVal);
}
- if (mPrefFlags.HasUserValue()) {
+ if (HasUserValue()) {
n += aMallocSizeOf(mUserValue.mStringVal);
}
}
return n;
}
+
+private:
+ // These fields go first to minimize this struct's size on 64-bit. (Because
+ // this a subclass of PLDHashEntryHdr, there's a preceding 32-bit mKeyHash
+ // field.)
+ uint32_t mType : 2;
+ uint32_t mIsSticky : 1;
+ uint32_t mIsLocked : 1;
+ uint32_t mHasUserValue : 1;
+ uint32_t mHasDefaultValue : 1;
+
+public:
+ const char* mKey;
+ PrefValue mDefaultValue;
+ PrefValue mUserValue;
};
static void
ClearPrefEntry(PLDHashTable* aTable, PLDHashEntryHdr* aEntry)
{
auto pref = static_cast<PrefHashEntry*>(aEntry);
- if (pref->mPrefFlags.IsTypeString()) {
+ if (pref->IsTypeString()) {
free(const_cast<char*>(pref->mDefaultValue.mStringVal));
free(const_cast<char*>(pref->mUserValue.mStringVal));
}
// Don't need to free this because it's allocated in memory owned by
// gPrefNameArena.
pref->mKey = nullptr;
memset(aEntry, 0, aTable->EntrySize());
@@ -410,65 +371,63 @@ pref_savePrefs()
PrefSaveData savedPrefs(gHashTable->EntryCount());
for (auto iter = gHashTable->Iter(); !iter.Done(); iter.Next()) {
auto pref = static_cast<PrefHashEntry*>(iter.Get());
// where we're getting our pref from
PrefValue* sourceValue;
- if (pref->mPrefFlags.HasUserValue() &&
- (pref_ValueChanged(pref->mDefaultValue,
- pref->mUserValue,
- pref->mPrefFlags.GetPrefType()) ||
- !pref->mPrefFlags.HasDefaultValue() ||
- pref->mPrefFlags.IsSticky())) {
+ if (pref->HasUserValue() &&
+ (pref_ValueChanged(
+ pref->mDefaultValue, pref->mUserValue, pref->Type()) ||
+ !pref->HasDefaultValue() || pref->IsSticky())) {
sourceValue = &pref->mUserValue;
} else {
// do not save default prefs that haven't changed
continue;
}
nsAutoCString prefName;
StrEscape(pref->mKey, prefName);
nsAutoCString prefValue;
- if (pref->mPrefFlags.IsTypeString()) {
+ if (pref->IsTypeString()) {
StrEscape(sourceValue->mStringVal, prefValue);
- } else if (pref->mPrefFlags.IsTypeInt()) {
+ } else if (pref->IsTypeInt()) {
prefValue.AppendInt(sourceValue->mIntVal);
- } else if (pref->mPrefFlags.IsTypeBool()) {
+ } else if (pref->IsTypeBool()) {
prefValue = sourceValue->mBoolVal ? "true" : "false";
}
nsPrintfCString str("user_pref(%s, %s);", prefName.get(), prefValue.get());
savedPrefs.AppendElement(str);
}
return savedPrefs;
}
static bool
pref_EntryHasAdvisablySizedValues(PrefHashEntry* aPref)
{
- if (aPref->mPrefFlags.GetPrefType() != PrefType::String) {
+ if (!aPref->IsTypeString()) {
return true;
}
const char* stringVal;
- if (aPref->mPrefFlags.HasDefaultValue()) {
+ if (aPref->HasDefaultValue()) {
stringVal = aPref->mDefaultValue.mStringVal;
if (strlen(stringVal) > MAX_ADVISABLE_PREF_LENGTH) {
return false;
}
}
- if (aPref->mPrefFlags.HasUserValue()) {
+ if (aPref->HasUserValue()) {
stringVal = aPref->mUserValue.mStringVal;
if (strlen(stringVal) > MAX_ADVISABLE_PREF_LENGTH) {
return false;
}
}
return true;
}
@@ -485,17 +444,17 @@ GetPrefValueFromEntry(PrefHashEntry* aPr
aSetting->userValue() = dom::PrefValue();
settingValue = &aSetting->userValue().get_PrefValue();
} else {
value = &aPref->mDefaultValue;
aSetting->defaultValue() = dom::PrefValue();
settingValue = &aSetting->defaultValue().get_PrefValue();
}
- switch (aPref->mPrefFlags.GetPrefType()) {
+ switch (aPref->Type()) {
case PrefType::String:
*settingValue = nsDependentCString(value->mStringVal);
return;
case PrefType::Int:
*settingValue = value->mIntVal;
return;
case PrefType::Bool:
*settingValue = !!value->mBoolVal;
@@ -505,23 +464,23 @@ GetPrefValueFromEntry(PrefHashEntry* aPr
}
}
static void
pref_GetPrefFromEntry(PrefHashEntry* aPref, dom::PrefSetting* aSetting)
{
aSetting->name() = aPref->mKey;
- if (aPref->mPrefFlags.HasDefaultValue()) {
+ if (aPref->HasDefaultValue()) {
GetPrefValueFromEntry(aPref, aSetting, PrefValueKind::Default);
} else {
aSetting->defaultValue() = null_t();
}
- if (aPref->mPrefFlags.HasUserValue()) {
+ if (aPref->HasUserValue()) {
GetPrefValueFromEntry(aPref, aSetting, PrefValueKind::User);
} else {
aSetting->userValue() = null_t();
}
MOZ_ASSERT(aSetting->defaultValue().type() == dom::MaybePrefValue::Tnull_t ||
aSetting->userValue().type() == dom::MaybePrefValue::Tnull_t ||
(aSetting->defaultValue().get_PrefValue().type() ==
@@ -531,32 +490,32 @@ pref_GetPrefFromEntry(PrefHashEntry* aPr
static bool
PREF_HasUserPref(const char* aPrefName)
{
if (!gHashTable) {
return false;
}
PrefHashEntry* pref = pref_HashTableLookup(aPrefName);
- return pref && pref->mPrefFlags.HasUserValue();
+ return pref && pref->HasUserValue();
}
// Clears the given pref (reverts it to its default value).
static nsresult
PREF_ClearUserPref(const char* aPrefName)
{
if (!gHashTable) {
return NS_ERROR_NOT_INITIALIZED;
}
PrefHashEntry* pref = pref_HashTableLookup(aPrefName);
- if (pref && pref->mPrefFlags.HasUserValue()) {
- pref->mPrefFlags.SetHasUserValue(false);
-
- if (!pref->mPrefFlags.HasDefaultValue()) {
+ if (pref && pref->HasUserValue()) {
+ pref->SetHasUserValue(false);
+
+ if (!pref->HasDefaultValue()) {
gHashTable->RemoveEntry(pref);
}
pref_DoCallback(aPrefName);
Preferences::HandleDirty();
}
return NS_OK;
}
@@ -570,23 +529,23 @@ PREF_ClearAllUserPrefs()
if (!gHashTable) {
return NS_ERROR_NOT_INITIALIZED;
}
Vector<const char*> prefNames;
for (auto iter = gHashTable->Iter(); !iter.Done(); iter.Next()) {
auto pref = static_cast<PrefHashEntry*>(iter.Get());
- if (pref->mPrefFlags.HasUserValue()) {
+ if (pref->HasUserValue()) {
if (!prefNames.append(pref->mKey)) {
return NS_ERROR_OUT_OF_MEMORY;
}
- pref->mPrefFlags.SetHasUserValue(false);
- if (!pref->mPrefFlags.HasDefaultValue()) {
+ pref->SetHasUserValue(false);
+ if (!pref->HasDefaultValue()) {
iter.Remove();
}
}
}
for (const char* prefName : prefNames) {
pref_DoCallback(prefName);
}
@@ -605,23 +564,23 @@ PREF_LockPref(const char* aKey, bool aLo
}
PrefHashEntry* pref = pref_HashTableLookup(aKey);
if (!pref) {
return NS_ERROR_UNEXPECTED;
}
if (aLockIt) {
- if (!pref->mPrefFlags.IsLocked()) {
- pref->mPrefFlags.SetLocked(true);
+ if (!pref->IsLocked()) {
+ pref->SetLocked(true);
gIsAnyPrefLocked = true;
pref_DoCallback(aKey);
}
- } else if (pref->mPrefFlags.IsLocked()) {
- pref->mPrefFlags.SetLocked(false);
+ } else if (pref->IsLocked()) {
+ pref->SetLocked(false);
pref_DoCallback(aKey);
}
return NS_OK;
}
//
// Hash table functions
@@ -757,77 +716,72 @@ pref_SetPref(const char* aKey,
auto pref = static_cast<PrefHashEntry*>(gHashTable->Add(aKey, fallible));
if (!pref) {
return NS_ERROR_OUT_OF_MEMORY;
}
if (!pref->mKey) {
// New (zeroed) entry. Initialize it.
- pref->mPrefFlags.SetPrefType(aType);
+ pref->SetType(aType);
pref->mKey = ArenaStrdup(aKey, gPrefNameArena);
- } else if (pref->mPrefFlags.HasDefaultValue() &&
- !pref->mPrefFlags.IsPrefType(aType)) {
+ } else if (pref->HasDefaultValue() && !pref->IsType(aType)) {
NS_WARNING(
nsPrintfCString(
"Ignoring attempt to overwrite value of default pref %s (type %s) with "
"the wrong type (%s)!",
aKey,
- PrefTypeToString(pref->mPrefFlags.GetPrefType()),
+ PrefTypeToString(pref->Type()),
PrefTypeToString(aType))
.get());
return NS_ERROR_UNEXPECTED;
}
bool valueChanged = false;
if (aFlags & kPrefSetDefault) {
- if (!pref->mPrefFlags.IsLocked()) {
+ if (!pref->IsLocked()) {
// ?? change of semantics?
if (pref_ValueChanged(pref->mDefaultValue, aValue, aType) ||
- !pref->mPrefFlags.HasDefaultValue()) {
- pref_SetValue(
- &pref->mDefaultValue, pref->mPrefFlags.GetPrefType(), aValue, aType);
- pref->mPrefFlags.SetPrefType(aType);
- pref->mPrefFlags.SetHasDefaultValue(true);
+ !pref->HasDefaultValue()) {
+ pref_SetValue(&pref->mDefaultValue, pref->Type(), aValue, aType);
+ pref->SetType(aType);
+ pref->SetHasDefaultValue(true);
if (aFlags & kPrefSticky) {
- pref->mPrefFlags.SetIsSticky(true);
+ pref->SetIsSticky(true);
}
- if (!pref->mPrefFlags.HasUserValue()) {
+ if (!pref->HasUserValue()) {
valueChanged = true;
}
}
// What if we change the default to be the same as the user value?
// Should we clear the user value?
}
} else {
// If new value is same as the default value and it's not a "sticky" pref,
// then un-set the user value. Otherwise, set the user value only if it has
// changed.
- if ((pref->mPrefFlags.HasDefaultValue()) &&
- !(pref->mPrefFlags.IsSticky()) &&
+ if (pref->HasDefaultValue() && !pref->IsSticky() &&
!pref_ValueChanged(pref->mDefaultValue, aValue, aType) &&
!(aFlags & kPrefForceSet)) {
- if (pref->mPrefFlags.HasUserValue()) {
+ if (pref->HasUserValue()) {
// XXX should we free a user-set string value if there is one?
- pref->mPrefFlags.SetHasUserValue(false);
- if (!pref->mPrefFlags.IsLocked()) {
+ pref->SetHasUserValue(false);
+ if (!pref->IsLocked()) {
Preferences::HandleDirty();
valueChanged = true;
}
}
- } else if (!pref->mPrefFlags.HasUserValue() ||
- !pref->mPrefFlags.IsPrefType(aType) ||
+ } else if (!pref->HasUserValue() || !pref->IsType(aType) ||
pref_ValueChanged(pref->mUserValue, aValue, aType)) {
- pref_SetValue(
- &pref->mUserValue, pref->mPrefFlags.GetPrefType(), aValue, aType);
- pref->mPrefFlags.SetPrefType(aType);
- pref->mPrefFlags.SetHasUserValue(true);
- if (!pref->mPrefFlags.IsLocked()) {
+ pref_SetValue(&pref->mUserValue, pref->Type(), aValue, aType);
+ pref->SetType(aType);
+ pref->SetHasUserValue(true);
+ if (!pref->IsLocked()) {
Preferences::HandleDirty();
valueChanged = true;
}
}
}
if (valueChanged) {
return pref_DoCallback(aKey);
@@ -839,17 +793,17 @@ pref_SetPref(const char* aKey,
// Bool function that returns whether or not the preference is locked and
// therefore cannot be changed.
static bool
PREF_PrefIsLocked(const char* aPrefName)
{
bool result = false;
if (gIsAnyPrefLocked && gHashTable) {
PrefHashEntry* pref = pref_HashTableLookup(aPrefName);
- if (pref && pref->mPrefFlags.IsLocked()) {
+ if (pref && pref->IsLocked()) {
result = true;
}
}
return result;
}
// Adds a node to the callback list; the position depends on aIsPriority. The
@@ -1996,17 +1950,17 @@ nsPrefBranch::GetPrefType(const char* aP
{
NS_ENSURE_ARG(aPrefName);
const PrefName& prefName = GetPrefName(aPrefName);
PrefType type = PrefType::Invalid;
if (gHashTable) {
PrefHashEntry* pref = pref_HashTableLookup(prefName.get());
if (pref) {
- type = pref->mPrefFlags.GetPrefType();
+ type = pref->Type();
}
}
switch (type) {
case PrefType::String:
*aRetVal = PREF_STRING;
break;
@@ -4488,25 +4442,25 @@ Preferences::InitInitialObjects()
/* static */ nsresult
Preferences::GetBool(const char* aPrefName, bool* aResult, PrefValueKind aKind)
{
NS_PRECONDITION(aResult, "aResult must not be NULL");
NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
PrefHashEntry* pref = pref_HashTableLookup(aPrefName);
- if (!pref || !pref->mPrefFlags.IsTypeBool()) {
+ if (!pref || !pref->IsTypeBool()) {
return NS_ERROR_UNEXPECTED;
}
- if (aKind == PrefValueKind::Default || pref->mPrefFlags.IsLocked() ||
- !pref->mPrefFlags.HasUserValue()) {
+ if (aKind == PrefValueKind::Default || pref->IsLocked() ||
+ !pref->HasUserValue()) {
// Do we have a default?
- if (!pref->mPrefFlags.HasDefaultValue()) {
+ if (!pref->HasDefaultValue()) {
return NS_ERROR_UNEXPECTED;
}
*aResult = pref->mDefaultValue.mBoolVal;
} else {
*aResult = pref->mUserValue.mBoolVal;
}
return NS_OK;
@@ -4516,25 +4470,25 @@ Preferences::GetBool(const char* aPrefNa
Preferences::GetInt(const char* aPrefName,
int32_t* aResult,
PrefValueKind aKind)
{
NS_PRECONDITION(aResult, "aResult must not be NULL");
NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
PrefHashEntry* pref = pref_HashTableLookup(aPrefName);
- if (!pref || !pref->mPrefFlags.IsTypeInt()) {
+ if (!pref || !pref->IsTypeInt()) {
return NS_ERROR_UNEXPECTED;
}
- if (aKind == PrefValueKind::Default || pref->mPrefFlags.IsLocked() ||
- !pref->mPrefFlags.HasUserValue()) {
+ if (aKind == PrefValueKind::Default || pref->IsLocked() ||
+ !pref->HasUserValue()) {
// Do we have a default?
- if (!pref->mPrefFlags.HasDefaultValue()) {
+ if (!pref->HasDefaultValue()) {
return NS_ERROR_UNEXPECTED;
}
*aResult = pref->mDefaultValue.mIntVal;
} else {
*aResult = pref->mUserValue.mIntVal;
}
return NS_OK;
@@ -4560,26 +4514,26 @@ Preferences::GetCString(const char* aPre
nsACString& aResult,
PrefValueKind aKind)
{
NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
aResult.SetIsVoid(true);
PrefHashEntry* pref = pref_HashTableLookup(aPrefName);
- if (!pref || !pref->mPrefFlags.IsTypeString()) {
+ if (!pref || !pref->IsTypeString()) {
return NS_ERROR_UNEXPECTED;
}
const char* stringVal = nullptr;
- if (aKind == PrefValueKind::Default || pref->mPrefFlags.IsLocked() ||
- !pref->mPrefFlags.HasUserValue()) {
+ if (aKind == PrefValueKind::Default || pref->IsLocked() ||
+ !pref->HasUserValue()) {
// Do we have a default?
- if (!pref->mPrefFlags.HasDefaultValue()) {
+ if (!pref->HasDefaultValue()) {
return NS_ERROR_UNEXPECTED;
}
stringVal = pref->mDefaultValue.mStringVal;
} else {
stringVal = pref->mUserValue.mStringVal;
}
if (!stringVal) {