зеркало из https://github.com/mozilla/gecko-dev.git
Bug 933605 (part 2) - Don't declare all vars at the top of functions in pldhash.cpp. r=jorendorff.
--HG-- extra : rebase_source : 53da17b46bd986ceefbc66f23e43d2f5b7290fad
This commit is contained in:
Родитель
4eb837e562
Коммит
3d05765fa7
|
@ -170,9 +170,7 @@ PLDHashTable *
|
|||
PL_NewDHashTable(const PLDHashTableOps *ops, void *data, uint32_t entrySize,
|
||||
uint32_t capacity)
|
||||
{
|
||||
PLDHashTable *table;
|
||||
|
||||
table = (PLDHashTable *) malloc(sizeof *table);
|
||||
PLDHashTable *table = (PLDHashTable *) malloc(sizeof *table);
|
||||
if (!table)
|
||||
return nullptr;
|
||||
if (!PL_DHashTableInit(table, ops, data, entrySize, capacity)) {
|
||||
|
@ -193,9 +191,6 @@ bool
|
|||
PL_DHashTableInit(PLDHashTable *table, const PLDHashTableOps *ops, void *data,
|
||||
uint32_t entrySize, uint32_t capacity)
|
||||
{
|
||||
int log2;
|
||||
uint32_t nbytes;
|
||||
|
||||
#ifdef DEBUG
|
||||
if (entrySize > 16 * sizeof(void *)) {
|
||||
printf_stderr(
|
||||
|
@ -211,6 +206,7 @@ PL_DHashTableInit(PLDHashTable *table, const PLDHashTableOps *ops, void *data,
|
|||
if (capacity < PL_DHASH_MIN_SIZE)
|
||||
capacity = PL_DHASH_MIN_SIZE;
|
||||
|
||||
int log2;
|
||||
PR_CEILING_LOG2(log2, capacity);
|
||||
|
||||
capacity = 1u << log2;
|
||||
|
@ -220,6 +216,7 @@ PL_DHashTableInit(PLDHashTable *table, const PLDHashTableOps *ops, void *data,
|
|||
table->entrySize = entrySize;
|
||||
table->entryCount = table->removedCount = 0;
|
||||
table->generation = 0;
|
||||
uint32_t nbytes;
|
||||
if (!SizeOfEntryStore(capacity, entrySize, &nbytes))
|
||||
return false; // overflowed
|
||||
|
||||
|
@ -290,21 +287,17 @@ static inline uint32_t MinLoad(uint32_t size) {
|
|||
void
|
||||
PL_DHashTableFinish(PLDHashTable *table)
|
||||
{
|
||||
char *entryAddr, *entryLimit;
|
||||
uint32_t entrySize;
|
||||
PLDHashEntryHdr *entry;
|
||||
|
||||
INCREMENT_RECURSION_LEVEL(table);
|
||||
|
||||
/* Call finalize before clearing entries, so it can enumerate them. */
|
||||
table->ops->finalize(table);
|
||||
|
||||
/* Clear any remaining live entries. */
|
||||
entryAddr = table->entryStore;
|
||||
entrySize = table->entrySize;
|
||||
entryLimit = entryAddr + PL_DHASH_TABLE_SIZE(table) * entrySize;
|
||||
char *entryAddr = table->entryStore;
|
||||
uint32_t entrySize = table->entrySize;
|
||||
char *entryLimit = entryAddr + PL_DHASH_TABLE_SIZE(table) * entrySize;
|
||||
while (entryAddr < entryLimit) {
|
||||
entry = (PLDHashEntryHdr *)entryAddr;
|
||||
PLDHashEntryHdr *entry = (PLDHashEntryHdr *)entryAddr;
|
||||
if (ENTRY_IS_LIVE(entry)) {
|
||||
METER(table->stats.removeEnums++);
|
||||
table->ops->clearEntry(table, entry);
|
||||
|
@ -323,20 +316,14 @@ static PLDHashEntryHdr * PL_DHASH_FASTCALL
|
|||
SearchTable(PLDHashTable *table, const void *key, PLDHashNumber keyHash,
|
||||
PLDHashOperator op)
|
||||
{
|
||||
PLDHashNumber hash1, hash2;
|
||||
int hashShift, sizeLog2;
|
||||
PLDHashEntryHdr *entry, *firstRemoved;
|
||||
PLDHashMatchEntry matchEntry;
|
||||
uint32_t sizeMask;
|
||||
|
||||
METER(table->stats.searches++);
|
||||
NS_ASSERTION(!(keyHash & COLLISION_FLAG),
|
||||
"!(keyHash & COLLISION_FLAG)");
|
||||
|
||||
/* Compute the primary hash address. */
|
||||
hashShift = table->hashShift;
|
||||
hash1 = HASH1(keyHash, hashShift);
|
||||
entry = ADDRESS_ENTRY(table, hash1);
|
||||
int hashShift = table->hashShift;
|
||||
PLDHashNumber hash1 = HASH1(keyHash, hashShift);
|
||||
PLDHashEntryHdr *entry = ADDRESS_ENTRY(table, hash1);
|
||||
|
||||
/* Miss: return space for a new entry. */
|
||||
if (PL_DHASH_ENTRY_IS_FREE(entry)) {
|
||||
|
@ -345,19 +332,19 @@ SearchTable(PLDHashTable *table, const void *key, PLDHashNumber keyHash,
|
|||
}
|
||||
|
||||
/* Hit: return entry. */
|
||||
matchEntry = table->ops->matchEntry;
|
||||
PLDHashMatchEntry matchEntry = table->ops->matchEntry;
|
||||
if (MATCH_ENTRY_KEYHASH(entry, keyHash) && matchEntry(table, entry, key)) {
|
||||
METER(table->stats.hits++);
|
||||
return entry;
|
||||
}
|
||||
|
||||
/* Collision: double hash. */
|
||||
sizeLog2 = PL_DHASH_BITS - table->hashShift;
|
||||
hash2 = HASH2(keyHash, sizeLog2, hashShift);
|
||||
sizeMask = (1u << sizeLog2) - 1;
|
||||
int sizeLog2 = PL_DHASH_BITS - table->hashShift;
|
||||
PLDHashNumber hash2 = HASH2(keyHash, sizeLog2, hashShift);
|
||||
uint32_t sizeMask = (1u << sizeLog2) - 1;
|
||||
|
||||
/* Save the first removed entry pointer so PL_DHASH_ADD can recycle it. */
|
||||
firstRemoved = nullptr;
|
||||
PLDHashEntryHdr *firstRemoved = nullptr;
|
||||
|
||||
for (;;) {
|
||||
if (MOZ_UNLIKELY(ENTRY_IS_REMOVED(entry))) {
|
||||
|
@ -402,19 +389,14 @@ SearchTable(PLDHashTable *table, const void *key, PLDHashNumber keyHash,
|
|||
static PLDHashEntryHdr * PL_DHASH_FASTCALL
|
||||
FindFreeEntry(PLDHashTable *table, PLDHashNumber keyHash)
|
||||
{
|
||||
PLDHashNumber hash1, hash2;
|
||||
int hashShift, sizeLog2;
|
||||
PLDHashEntryHdr *entry;
|
||||
uint32_t sizeMask;
|
||||
|
||||
METER(table->stats.searches++);
|
||||
NS_ASSERTION(!(keyHash & COLLISION_FLAG),
|
||||
"!(keyHash & COLLISION_FLAG)");
|
||||
|
||||
/* Compute the primary hash address. */
|
||||
hashShift = table->hashShift;
|
||||
hash1 = HASH1(keyHash, hashShift);
|
||||
entry = ADDRESS_ENTRY(table, hash1);
|
||||
int hashShift = table->hashShift;
|
||||
PLDHashNumber hash1 = HASH1(keyHash, hashShift);
|
||||
PLDHashEntryHdr *entry = ADDRESS_ENTRY(table, hash1);
|
||||
|
||||
/* Miss: return space for a new entry. */
|
||||
if (PL_DHASH_ENTRY_IS_FREE(entry)) {
|
||||
|
@ -423,9 +405,9 @@ FindFreeEntry(PLDHashTable *table, PLDHashNumber keyHash)
|
|||
}
|
||||
|
||||
/* Collision: double hash. */
|
||||
sizeLog2 = PL_DHASH_BITS - table->hashShift;
|
||||
hash2 = HASH2(keyHash, sizeLog2, hashShift);
|
||||
sizeMask = (1u << sizeLog2) - 1;
|
||||
int sizeLog2 = PL_DHASH_BITS - table->hashShift;
|
||||
PLDHashNumber hash2 = HASH2(keyHash, sizeLog2, hashShift);
|
||||
uint32_t sizeMask = (1u << sizeLog2) - 1;
|
||||
|
||||
for (;;) {
|
||||
NS_ASSERTION(!ENTRY_IS_REMOVED(entry),
|
||||
|
@ -450,34 +432,25 @@ FindFreeEntry(PLDHashTable *table, PLDHashNumber keyHash)
|
|||
static bool
|
||||
ChangeTable(PLDHashTable *table, int deltaLog2)
|
||||
{
|
||||
int oldLog2, newLog2;
|
||||
uint32_t oldCapacity, newCapacity;
|
||||
char *newEntryStore, *oldEntryStore, *oldEntryAddr;
|
||||
uint32_t entrySize, i, nbytes;
|
||||
PLDHashEntryHdr *oldEntry, *newEntry;
|
||||
PLDHashMoveEntry moveEntry;
|
||||
#ifdef DEBUG
|
||||
uint32_t recursionLevel;
|
||||
#endif
|
||||
|
||||
/* Look, but don't touch, until we succeed in getting new entry store. */
|
||||
oldLog2 = PL_DHASH_BITS - table->hashShift;
|
||||
newLog2 = oldLog2 + deltaLog2;
|
||||
oldCapacity = 1u << oldLog2;
|
||||
newCapacity = 1u << newLog2;
|
||||
int oldLog2 = PL_DHASH_BITS - table->hashShift;
|
||||
int newLog2 = oldLog2 + deltaLog2;
|
||||
uint32_t newCapacity = 1u << newLog2;
|
||||
if (newCapacity > PL_DHASH_MAX_SIZE)
|
||||
return false;
|
||||
entrySize = table->entrySize;
|
||||
|
||||
uint32_t entrySize = table->entrySize;
|
||||
uint32_t nbytes;
|
||||
if (!SizeOfEntryStore(newCapacity, entrySize, &nbytes))
|
||||
return false; // overflowed
|
||||
|
||||
newEntryStore = (char *) table->ops->allocTable(table, nbytes);
|
||||
char *newEntryStore = (char *) table->ops->allocTable(table, nbytes);
|
||||
if (!newEntryStore)
|
||||
return false;
|
||||
|
||||
/* We can't fail from here on, so update table parameters. */
|
||||
#ifdef DEBUG
|
||||
recursionLevel = table->recursionLevel;
|
||||
uint32_t recursionLevel = table->recursionLevel;
|
||||
#endif
|
||||
table->hashShift = PL_DHASH_BITS - newLog2;
|
||||
table->removedCount = 0;
|
||||
|
@ -485,19 +458,21 @@ ChangeTable(PLDHashTable *table, int deltaLog2)
|
|||
|
||||
/* Assign the new entry store to table. */
|
||||
memset(newEntryStore, 0, nbytes);
|
||||
char *oldEntryStore, *oldEntryAddr;
|
||||
oldEntryAddr = oldEntryStore = table->entryStore;
|
||||
table->entryStore = newEntryStore;
|
||||
moveEntry = table->ops->moveEntry;
|
||||
PLDHashMoveEntry moveEntry = table->ops->moveEntry;
|
||||
#ifdef DEBUG
|
||||
table->recursionLevel = recursionLevel;
|
||||
#endif
|
||||
|
||||
/* Copy only live entries, leaving removed ones behind. */
|
||||
for (i = 0; i < oldCapacity; i++) {
|
||||
oldEntry = (PLDHashEntryHdr *)oldEntryAddr;
|
||||
uint32_t oldCapacity = 1u << oldLog2;
|
||||
for (uint32_t i = 0; i < oldCapacity; i++) {
|
||||
PLDHashEntryHdr *oldEntry = (PLDHashEntryHdr *)oldEntryAddr;
|
||||
if (ENTRY_IS_LIVE(oldEntry)) {
|
||||
oldEntry->keyHash &= ~COLLISION_FLAG;
|
||||
newEntry = FindFreeEntry(table, oldEntry->keyHash);
|
||||
PLDHashEntryHdr *newEntry = FindFreeEntry(table, oldEntry->keyHash);
|
||||
NS_ASSERTION(PL_DHASH_ENTRY_IS_FREE(newEntry),
|
||||
"PL_DHASH_ENTRY_IS_FREE(newEntry)");
|
||||
moveEntry(table, oldEntry, newEntry);
|
||||
|
@ -513,15 +488,12 @@ ChangeTable(PLDHashTable *table, int deltaLog2)
|
|||
PLDHashEntryHdr * PL_DHASH_FASTCALL
|
||||
PL_DHashTableOperate(PLDHashTable *table, const void *key, PLDHashOperator op)
|
||||
{
|
||||
PLDHashNumber keyHash;
|
||||
PLDHashEntryHdr *entry;
|
||||
uint32_t size;
|
||||
int deltaLog2;
|
||||
|
||||
MOZ_ASSERT(op == PL_DHASH_LOOKUP || table->recursionLevel == 0);
|
||||
INCREMENT_RECURSION_LEVEL(table);
|
||||
|
||||
keyHash = table->ops->hashKey(table, key);
|
||||
PLDHashNumber keyHash = table->ops->hashKey(table, key);
|
||||
keyHash *= PL_DHASH_GOLDEN_RATIO;
|
||||
|
||||
/* Avoid 0 and 1 hash codes, they indicate free and removed entries. */
|
||||
|
@ -534,15 +506,16 @@ PL_DHashTableOperate(PLDHashTable *table, const void *key, PLDHashOperator op)
|
|||
entry = SearchTable(table, key, keyHash, op);
|
||||
break;
|
||||
|
||||
case PL_DHASH_ADD:
|
||||
case PL_DHASH_ADD: {
|
||||
/*
|
||||
* If alpha is >= .75, grow or compress the table. If key is already
|
||||
* in the table, we may grow once more than necessary, but only if we
|
||||
* are on the edge of being overloaded.
|
||||
*/
|
||||
size = PL_DHASH_TABLE_SIZE(table);
|
||||
uint32_t size = PL_DHASH_TABLE_SIZE(table);
|
||||
if (table->entryCount + table->removedCount >= MaxLoad(size)) {
|
||||
/* Compress if a quarter or more of all entries are removed. */
|
||||
int deltaLog2;
|
||||
if (table->removedCount >= size >> 2) {
|
||||
METER(table->stats.compresses++);
|
||||
deltaLog2 = 0;
|
||||
|
@ -591,6 +564,7 @@ PL_DHashTableOperate(PLDHashTable *table, const void *key, PLDHashOperator op)
|
|||
}
|
||||
METER(else table->stats.addHits++);
|
||||
break;
|
||||
}
|
||||
|
||||
case PL_DHASH_REMOVE:
|
||||
entry = SearchTable(table, key, keyHash, op);
|
||||
|
@ -600,7 +574,7 @@ PL_DHashTableOperate(PLDHashTable *table, const void *key, PLDHashOperator op)
|
|||
PL_DHashTableRawRemove(table, entry);
|
||||
|
||||
/* Shrink if alpha is <= .25 and table isn't too small already. */
|
||||
size = PL_DHASH_TABLE_SIZE(table);
|
||||
uint32_t size = PL_DHASH_TABLE_SIZE(table);
|
||||
if (size > PL_DHASH_MIN_SIZE &&
|
||||
table->entryCount <= MinLoad(size)) {
|
||||
METER(table->stats.shrinks++);
|
||||
|
@ -624,13 +598,13 @@ PL_DHashTableOperate(PLDHashTable *table, const void *key, PLDHashOperator op)
|
|||
void
|
||||
PL_DHashTableRawRemove(PLDHashTable *table, PLDHashEntryHdr *entry)
|
||||
{
|
||||
PLDHashNumber keyHash; /* load first in case clearEntry goofs it */
|
||||
|
||||
MOZ_ASSERT(table->recursionLevel != IMMUTABLE_RECURSION_LEVEL);
|
||||
|
||||
NS_ASSERTION(PL_DHASH_ENTRY_IS_LIVE(entry),
|
||||
"PL_DHASH_ENTRY_IS_LIVE(entry)");
|
||||
keyHash = entry->keyHash;
|
||||
|
||||
/* Load keyHash first in case clearEntry() goofs it. */
|
||||
PLDHashNumber keyHash = entry->keyHash;
|
||||
table->ops->clearEntry(table, entry);
|
||||
if (keyHash & COLLISION_FLAG) {
|
||||
MARK_ENTRY_REMOVED(entry);
|
||||
|
@ -645,24 +619,18 @@ PL_DHashTableRawRemove(PLDHashTable *table, PLDHashEntryHdr *entry)
|
|||
uint32_t
|
||||
PL_DHashTableEnumerate(PLDHashTable *table, PLDHashEnumerator etor, void *arg)
|
||||
{
|
||||
char *entryAddr, *entryLimit;
|
||||
uint32_t i, capacity, entrySize, ceiling;
|
||||
bool didRemove;
|
||||
PLDHashEntryHdr *entry;
|
||||
PLDHashOperator op;
|
||||
|
||||
INCREMENT_RECURSION_LEVEL(table);
|
||||
|
||||
entryAddr = table->entryStore;
|
||||
entrySize = table->entrySize;
|
||||
capacity = PL_DHASH_TABLE_SIZE(table);
|
||||
entryLimit = entryAddr + capacity * entrySize;
|
||||
i = 0;
|
||||
didRemove = false;
|
||||
char *entryAddr = table->entryStore;
|
||||
uint32_t entrySize = table->entrySize;
|
||||
uint32_t capacity = PL_DHASH_TABLE_SIZE(table);
|
||||
char *entryLimit = entryAddr + capacity * entrySize;
|
||||
uint32_t i = 0;
|
||||
bool didRemove = false;
|
||||
while (entryAddr < entryLimit) {
|
||||
entry = (PLDHashEntryHdr *)entryAddr;
|
||||
PLDHashEntryHdr *entry = (PLDHashEntryHdr *)entryAddr;
|
||||
if (ENTRY_IS_LIVE(entry)) {
|
||||
op = etor(table, entry, i++, arg);
|
||||
PLDHashOperator op = etor(table, entry, i++, arg);
|
||||
if (op & PL_DHASH_REMOVE) {
|
||||
METER(table->stats.removeEnums++);
|
||||
PL_DHashTableRawRemove(table, entry);
|
||||
|
@ -693,6 +661,7 @@ PL_DHashTableEnumerate(PLDHashTable *table, PLDHashEnumerator etor, void *arg)
|
|||
if (capacity < PL_DHASH_MIN_SIZE)
|
||||
capacity = PL_DHASH_MIN_SIZE;
|
||||
|
||||
uint32_t ceiling;
|
||||
PR_CEILING_LOG2(ceiling, capacity);
|
||||
ceiling -= PL_DHASH_BITS - table->hashShift;
|
||||
|
||||
|
@ -763,33 +732,29 @@ PL_DHashMarkTableImmutable(PLDHashTable *table)
|
|||
void
|
||||
PL_DHashTableDumpMeter(PLDHashTable *table, PLDHashEnumerator dump, FILE *fp)
|
||||
{
|
||||
char *entryAddr;
|
||||
uint32_t entrySize, entryCount;
|
||||
int hashShift, sizeLog2;
|
||||
uint32_t i, tableSize, sizeMask, chainLen, maxChainLen, chainCount;
|
||||
PLDHashNumber hash1, hash2, saveHash1, maxChainHash1, maxChainHash2;
|
||||
PLDHashNumber hash1, hash2, maxChainHash1, maxChainHash2;
|
||||
double sqsum, mean, variance, sigma;
|
||||
PLDHashEntryHdr *entry, *probe;
|
||||
PLDHashEntryHdr *entry;
|
||||
|
||||
entryAddr = table->entryStore;
|
||||
entrySize = table->entrySize;
|
||||
hashShift = table->hashShift;
|
||||
sizeLog2 = PL_DHASH_BITS - hashShift;
|
||||
tableSize = PL_DHASH_TABLE_SIZE(table);
|
||||
sizeMask = (1u << sizeLog2) - 1;
|
||||
chainCount = maxChainLen = 0;
|
||||
char *entryAddr = table->entryStore;
|
||||
uint32_t entrySize = table->entrySize;
|
||||
int hashShift = table->hashShift;
|
||||
int sizeLog2 = PL_DHASH_BITS - hashShift;
|
||||
uint32_t tableSize = PL_DHASH_TABLE_SIZE(table);
|
||||
uint32_t sizeMask = (1u << sizeLog2) - 1;
|
||||
uint32_t chainCount = 0, maxChainLen = 0;
|
||||
hash2 = 0;
|
||||
sqsum = 0;
|
||||
|
||||
for (i = 0; i < tableSize; i++) {
|
||||
for (uint32_t i = 0; i < tableSize; i++) {
|
||||
entry = (PLDHashEntryHdr *)entryAddr;
|
||||
entryAddr += entrySize;
|
||||
if (!ENTRY_IS_LIVE(entry))
|
||||
continue;
|
||||
hash1 = HASH1(entry->keyHash & ~COLLISION_FLAG, hashShift);
|
||||
saveHash1 = hash1;
|
||||
probe = ADDRESS_ENTRY(table, hash1);
|
||||
chainLen = 1;
|
||||
PLDHashNumber saveHash1 = hash1;
|
||||
PLDHashEntryHdr *probe = ADDRESS_ENTRY(table, hash1);
|
||||
uint32_t chainLen = 1;
|
||||
if (probe == entry) {
|
||||
/* Start of a (possibly unit-length) chain. */
|
||||
chainCount++;
|
||||
|
@ -811,7 +776,7 @@ PL_DHashTableDumpMeter(PLDHashTable *table, PLDHashEnumerator dump, FILE *fp)
|
|||
}
|
||||
}
|
||||
|
||||
entryCount = table->entryCount;
|
||||
uint32_t entryCount = table->entryCount;
|
||||
if (entryCount && chainCount) {
|
||||
mean = (double)entryCount / chainCount;
|
||||
variance = chainCount * sqsum - entryCount * entryCount;
|
||||
|
@ -857,7 +822,7 @@ PL_DHashTableDumpMeter(PLDHashTable *table, PLDHashEnumerator dump, FILE *fp)
|
|||
hash1 = maxChainHash1;
|
||||
hash2 = maxChainHash2;
|
||||
entry = ADDRESS_ENTRY(table, hash1);
|
||||
i = 0;
|
||||
uint32_t i = 0;
|
||||
do {
|
||||
if (dump(table, entry, i++, fp) != PL_DHASH_NEXT)
|
||||
break;
|
||||
|
|
Загрузка…
Ссылка в новой задаче