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:
Nicholas Nethercote 2013-10-31 22:33:29 -07:00
Родитель 4eb837e562
Коммит 3d05765fa7
1 изменённых файлов: 68 добавлений и 103 удалений

Просмотреть файл

@ -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;