зеркало из https://github.com/mozilla/gecko-dev.git
Backout 86b5cb334b73 and db7cbf61b001 (bug 810718, parts 1 and 2) for multiple perf regressions.
--HG-- extra : rebase_source : c20c81d0cf47b607815c0592d748d4f0a430d430
This commit is contained in:
Родитель
cf2e68463e
Коммит
50e3df7443
|
@ -127,8 +127,10 @@ nsHTMLEntities::AddRefTable(void)
|
||||||
if (!entry->node)
|
if (!entry->node)
|
||||||
entry->node = node;
|
entry->node = node;
|
||||||
}
|
}
|
||||||
|
#ifdef DEBUG
|
||||||
PL_DHashMarkTableImmutable(&gUnicodeToEntity);
|
PL_DHashMarkTableImmutable(&gUnicodeToEntity);
|
||||||
PL_DHashMarkTableImmutable(&gEntityToUnicode);
|
PL_DHashMarkTableImmutable(&gEntityToUnicode);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
++gTableRefCnt;
|
++gTableRefCnt;
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
|
@ -956,8 +956,10 @@ mFailedLockCount(0)
|
||||||
for (size_t i = 0; i < ArrayLength(trackedDBs); i++)
|
for (size_t i = 0; i < ArrayLength(trackedDBs); i++)
|
||||||
mTrackedDBs.PutEntry(nsDependentCString(trackedDBs[i]));
|
mTrackedDBs.PutEntry(nsDependentCString(trackedDBs[i]));
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
// Mark immutable to prevent asserts on simultaneous access from multiple threads
|
// Mark immutable to prevent asserts on simultaneous access from multiple threads
|
||||||
mTrackedDBs.MarkImmutable();
|
mTrackedDBs.MarkImmutable();
|
||||||
|
#endif
|
||||||
mReporter = new TelemetryReporter();
|
mReporter = new TelemetryReporter();
|
||||||
NS_RegisterMemoryReporter(mReporter);
|
NS_RegisterMemoryReporter(mReporter);
|
||||||
}
|
}
|
||||||
|
|
|
@ -177,7 +177,9 @@ nsStaticCaseInsensitiveNameTable::Init(const char* const aNames[], int32_t Count
|
||||||
entry->mString = strPtr; // not owned!
|
entry->mString = strPtr; // not owned!
|
||||||
entry->mIndex = index;
|
entry->mIndex = index;
|
||||||
}
|
}
|
||||||
|
#ifdef DEBUG
|
||||||
PL_DHashMarkTableImmutable(&mNameTable);
|
PL_DHashMarkTableImmutable(&mNameTable);
|
||||||
|
#endif
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -275,6 +275,7 @@ public:
|
||||||
return PL_DHashTableSizeOfExcludingThis(&mTable, nullptr, mallocSizeOf);
|
return PL_DHashTableSizeOfExcludingThis(&mTable, nullptr, mallocSizeOf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
/**
|
/**
|
||||||
* Mark the table as constant after initialization.
|
* Mark the table as constant after initialization.
|
||||||
*
|
*
|
||||||
|
@ -287,6 +288,7 @@ public:
|
||||||
|
|
||||||
PL_DHashMarkTableImmutable(&mTable);
|
PL_DHashMarkTableImmutable(&mTable);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
PLDHashTable mTable;
|
PLDHashTable mTable;
|
||||||
|
|
|
@ -24,28 +24,21 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The following code is used to ensure that calls to one of table->ops or to
|
* The following DEBUG-only code is used to assert that calls to one of
|
||||||
* an enumerator do not cause re-entry into a call that can mutate the table.
|
* table->ops or to an enumerator do not cause re-entry into a call that
|
||||||
* Any check that fails will cause an immediate abort, even in non-debug
|
* can mutate the table.
|
||||||
* builds.
|
|
||||||
*/
|
*/
|
||||||
|
#ifdef DEBUG
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Most callers that check the recursion level don't care about this magical
|
* Most callers that assert about the recursion level don't care about
|
||||||
* value because they are checking that mutation is allowed (and therefore the
|
* this magical value because they are asserting that mutation is
|
||||||
* level is 0 or 1, depending on whether they incremented it).
|
* allowed (and therefore the level is 0 or 1, depending on whether they
|
||||||
|
* incremented it).
|
||||||
*
|
*
|
||||||
* Only PL_DHashTableFinish needs to allow this special value.
|
* Only PL_DHashTableFinish needs to allow this special value.
|
||||||
*/
|
*/
|
||||||
#define IMMUTABLE_RECURSION_LEVEL ((uint32_t)-1)
|
#define IMMUTABLE_RECURSION_LEVEL ((uint16_t)-1)
|
||||||
|
|
||||||
/* This aborts in all builds. */
|
|
||||||
#define ABORT_UNLESS(condition) \
|
|
||||||
do { \
|
|
||||||
if (!(condition)) { \
|
|
||||||
NS_RUNTIMEABORT("fatal error in pldhash"); \
|
|
||||||
} \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define RECURSION_LEVEL_SAFE_TO_FINISH(table_) \
|
#define RECURSION_LEVEL_SAFE_TO_FINISH(table_) \
|
||||||
(table_->recursionLevel == 0 || \
|
(table_->recursionLevel == 0 || \
|
||||||
|
@ -55,14 +48,21 @@
|
||||||
do { \
|
do { \
|
||||||
if (table_->recursionLevel != IMMUTABLE_RECURSION_LEVEL) \
|
if (table_->recursionLevel != IMMUTABLE_RECURSION_LEVEL) \
|
||||||
++table_->recursionLevel; \
|
++table_->recursionLevel; \
|
||||||
} while (0)
|
} while(0)
|
||||||
#define DECREMENT_RECURSION_LEVEL(table_) \
|
#define DECREMENT_RECURSION_LEVEL(table_) \
|
||||||
do { \
|
do { \
|
||||||
if (table->recursionLevel != IMMUTABLE_RECURSION_LEVEL) { \
|
if (table->recursionLevel != IMMUTABLE_RECURSION_LEVEL) { \
|
||||||
ABORT_UNLESS(table->recursionLevel > 0); \
|
MOZ_ASSERT(table->recursionLevel > 0); \
|
||||||
--table->recursionLevel; \
|
--table->recursionLevel; \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while(0)
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define INCREMENT_RECURSION_LEVEL(table_) do { } while(0)
|
||||||
|
#define DECREMENT_RECURSION_LEVEL(table_) do { } while(0)
|
||||||
|
|
||||||
|
#endif /* defined(DEBUG) */
|
||||||
|
|
||||||
using namespace mozilla;
|
using namespace mozilla;
|
||||||
|
|
||||||
|
@ -213,7 +213,6 @@ PL_DHashTableInit(PLDHashTable *table, const PLDHashTableOps *ops, void *data,
|
||||||
return false;
|
return false;
|
||||||
table->hashShift = PL_DHASH_BITS - log2;
|
table->hashShift = PL_DHASH_BITS - log2;
|
||||||
table->entrySize = entrySize;
|
table->entrySize = entrySize;
|
||||||
ABORT_UNLESS(uint32_t(table->entrySize) == entrySize);
|
|
||||||
table->entryCount = table->removedCount = 0;
|
table->entryCount = table->removedCount = 0;
|
||||||
table->generation = 0;
|
table->generation = 0;
|
||||||
uint32_t nbytes;
|
uint32_t nbytes;
|
||||||
|
@ -226,7 +225,9 @@ PL_DHashTableInit(PLDHashTable *table, const PLDHashTableOps *ops, void *data,
|
||||||
memset(table->entryStore, 0, nbytes);
|
memset(table->entryStore, 0, nbytes);
|
||||||
METER(memset(&table->stats, 0, sizeof table->stats));
|
METER(memset(&table->stats, 0, sizeof table->stats));
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
table->recursionLevel = 0;
|
table->recursionLevel = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -304,7 +305,7 @@ PL_DHashTableFinish(PLDHashTable *table)
|
||||||
}
|
}
|
||||||
|
|
||||||
DECREMENT_RECURSION_LEVEL(table);
|
DECREMENT_RECURSION_LEVEL(table);
|
||||||
ABORT_UNLESS(RECURSION_LEVEL_SAFE_TO_FINISH(table));
|
MOZ_ASSERT(RECURSION_LEVEL_SAFE_TO_FINISH(table));
|
||||||
|
|
||||||
/* Free entry storage last. */
|
/* Free entry storage last. */
|
||||||
table->ops->freeTable(table, table->entryStore);
|
table->ops->freeTable(table, table->entryStore);
|
||||||
|
@ -447,7 +448,9 @@ ChangeTable(PLDHashTable *table, int deltaLog2)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* We can't fail from here on, so update table parameters. */
|
/* We can't fail from here on, so update table parameters. */
|
||||||
|
#ifdef DEBUG
|
||||||
uint32_t recursionLevel = table->recursionLevel;
|
uint32_t recursionLevel = table->recursionLevel;
|
||||||
|
#endif
|
||||||
table->hashShift = PL_DHASH_BITS - newLog2;
|
table->hashShift = PL_DHASH_BITS - newLog2;
|
||||||
table->removedCount = 0;
|
table->removedCount = 0;
|
||||||
table->generation++;
|
table->generation++;
|
||||||
|
@ -458,7 +461,9 @@ ChangeTable(PLDHashTable *table, int deltaLog2)
|
||||||
oldEntryAddr = oldEntryStore = table->entryStore;
|
oldEntryAddr = oldEntryStore = table->entryStore;
|
||||||
table->entryStore = newEntryStore;
|
table->entryStore = newEntryStore;
|
||||||
PLDHashMoveEntry moveEntry = table->ops->moveEntry;
|
PLDHashMoveEntry moveEntry = table->ops->moveEntry;
|
||||||
|
#ifdef DEBUG
|
||||||
table->recursionLevel = recursionLevel;
|
table->recursionLevel = recursionLevel;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Copy only live entries, leaving removed ones behind. */
|
/* Copy only live entries, leaving removed ones behind. */
|
||||||
uint32_t oldCapacity = 1u << oldLog2;
|
uint32_t oldCapacity = 1u << oldLog2;
|
||||||
|
@ -484,7 +489,7 @@ PL_DHashTableOperate(PLDHashTable *table, const void *key, PLDHashOperator op)
|
||||||
{
|
{
|
||||||
PLDHashEntryHdr *entry;
|
PLDHashEntryHdr *entry;
|
||||||
|
|
||||||
ABORT_UNLESS(op == PL_DHASH_LOOKUP || table->recursionLevel == 0);
|
MOZ_ASSERT(op == PL_DHASH_LOOKUP || table->recursionLevel == 0);
|
||||||
INCREMENT_RECURSION_LEVEL(table);
|
INCREMENT_RECURSION_LEVEL(table);
|
||||||
|
|
||||||
PLDHashNumber keyHash = table->ops->hashKey(table, key);
|
PLDHashNumber keyHash = table->ops->hashKey(table, key);
|
||||||
|
@ -592,7 +597,7 @@ PL_DHashTableOperate(PLDHashTable *table, const void *key, PLDHashOperator op)
|
||||||
void
|
void
|
||||||
PL_DHashTableRawRemove(PLDHashTable *table, PLDHashEntryHdr *entry)
|
PL_DHashTableRawRemove(PLDHashTable *table, PLDHashEntryHdr *entry)
|
||||||
{
|
{
|
||||||
ABORT_UNLESS(table->recursionLevel != IMMUTABLE_RECURSION_LEVEL);
|
MOZ_ASSERT(table->recursionLevel != IMMUTABLE_RECURSION_LEVEL);
|
||||||
|
|
||||||
NS_ASSERTION(PL_DHASH_ENTRY_IS_LIVE(entry),
|
NS_ASSERTION(PL_DHASH_ENTRY_IS_LIVE(entry),
|
||||||
"PL_DHASH_ENTRY_IS_LIVE(entry)");
|
"PL_DHASH_ENTRY_IS_LIVE(entry)");
|
||||||
|
@ -636,7 +641,7 @@ PL_DHashTableEnumerate(PLDHashTable *table, PLDHashEnumerator etor, void *arg)
|
||||||
entryAddr += entrySize;
|
entryAddr += entrySize;
|
||||||
}
|
}
|
||||||
|
|
||||||
ABORT_UNLESS(!didRemove || table->recursionLevel == 1);
|
MOZ_ASSERT(!didRemove || table->recursionLevel == 1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Shrink or compress if a quarter or more of all entries are removed, or
|
* Shrink or compress if a quarter or more of all entries are removed, or
|
||||||
|
@ -711,11 +716,13 @@ PL_DHashTableSizeOfIncludingThis(const PLDHashTable *table,
|
||||||
mallocSizeOf, arg);
|
mallocSizeOf, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
void
|
void
|
||||||
PL_DHashMarkTableImmutable(PLDHashTable *table)
|
PL_DHashMarkTableImmutable(PLDHashTable *table)
|
||||||
{
|
{
|
||||||
table->recursionLevel = IMMUTABLE_RECURSION_LEVEL;
|
table->recursionLevel = IMMUTABLE_RECURSION_LEVEL;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef PL_DHASHMETER
|
#ifdef PL_DHASHMETER
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
/*
|
/*
|
||||||
* Double hashing, a la Knuth 6.
|
* Double hashing, a la Knuth 6.
|
||||||
*/
|
*/
|
||||||
#include "mozilla/Atomics.h"
|
|
||||||
#include "mozilla/MemoryReporting.h"
|
#include "mozilla/MemoryReporting.h"
|
||||||
#include "mozilla/Types.h"
|
#include "mozilla/Types.h"
|
||||||
#include "nscore.h"
|
#include "nscore.h"
|
||||||
|
@ -183,8 +182,14 @@ struct PLDHashTable {
|
||||||
const PLDHashTableOps *ops; /* virtual operations, see below */
|
const PLDHashTableOps *ops; /* virtual operations, see below */
|
||||||
void *data; /* ops- and instance-specific data */
|
void *data; /* ops- and instance-specific data */
|
||||||
int16_t hashShift; /* multiplicative hash shift */
|
int16_t hashShift; /* multiplicative hash shift */
|
||||||
uint16_t entrySize; /* number of bytes in an entry */
|
/*
|
||||||
mozilla::Atomic<uint32_t> recursionLevel; /* detects unsafe re-entry */
|
* |recursionLevel| is only used in debug builds, but is present in opt
|
||||||
|
* builds to avoid binary compatibility problems when mixing DEBUG and
|
||||||
|
* non-DEBUG components. (Actually, even if it were removed,
|
||||||
|
* sizeof(PLDHashTable) wouldn't change, due to struct padding.)
|
||||||
|
*/
|
||||||
|
uint16_t recursionLevel; /* used to detect unsafe re-entry */
|
||||||
|
uint32_t entrySize; /* number of bytes in an entry */
|
||||||
uint32_t entryCount; /* number of entries in table */
|
uint32_t entryCount; /* number of entries in table */
|
||||||
uint32_t removedCount; /* removed entry sentinels in table */
|
uint32_t removedCount; /* removed entry sentinels in table */
|
||||||
uint32_t generation; /* entry storage generation number */
|
uint32_t generation; /* entry storage generation number */
|
||||||
|
@ -544,22 +549,24 @@ PL_DHashTableSizeOfIncludingThis(const PLDHashTable *table,
|
||||||
mozilla::MallocSizeOf mallocSizeOf,
|
mozilla::MallocSizeOf mallocSizeOf,
|
||||||
void *arg = nullptr);
|
void *arg = nullptr);
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
/**
|
/**
|
||||||
* Mark a table as immutable for the remainder of its lifetime. This
|
* Mark a table as immutable for the remainder of its lifetime. This
|
||||||
* changes the implementation from checking one set of invariants to
|
* changes the implementation from ASSERTing one set of invariants to
|
||||||
* checking a different set.
|
* ASSERTing a different set.
|
||||||
*
|
*
|
||||||
* When a table is NOT marked as immutable, the table implementation
|
* When a table is NOT marked as immutable, the table implementation
|
||||||
* checks that the table is not mutated from its own callbacks. It
|
* asserts that the table is not mutated from its own callbacks. It
|
||||||
* assumes the caller protects the table from being accessed on multiple
|
* assumes the caller protects the table from being accessed on multiple
|
||||||
* threads simultaneously.
|
* threads simultaneously.
|
||||||
*
|
*
|
||||||
* When the table is marked as immutable, the re-entry checks will
|
* When the table is marked as immutable, the re-entry assertions will
|
||||||
* no longer trigger erroneously due to multi-threaded access. Instead,
|
* no longer trigger erroneously due to multi-threaded access. Instead,
|
||||||
* mutations will cause checks to fail.
|
* mutations will cause assertions.
|
||||||
*/
|
*/
|
||||||
NS_COM_GLUE void
|
NS_COM_GLUE void
|
||||||
PL_DHashMarkTableImmutable(PLDHashTable *table);
|
PL_DHashMarkTableImmutable(PLDHashTable *table);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef PL_DHASHMETER
|
#ifdef PL_DHASHMETER
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
Загрузка…
Ссылка в новой задаче