From 985f53dfd3d500dca7bb4fdb03e25cd611ead091 Mon Sep 17 00:00:00 2001 From: "brendan%mozilla.org" Date: Tue, 5 Dec 2006 00:52:05 +0000 Subject: [PATCH] Add JS_DHASH_{,DEFAULT_}CAPACITY macros for realloc-free init (356116, r/sr=mrbkap+shaver/dbaron). git-svn-id: svn://10.0.0.236/trunk@216470 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/js/src/jsdhash.c | 4 ++-- mozilla/js/src/jsdhash.h | 24 ++++++++++++++++++++++++ mozilla/js/src/jsgc.c | 6 +++--- mozilla/js/src/jsparse.c | 5 +++-- mozilla/js/src/jsscript.c | 3 ++- mozilla/js/src/jsxdrapi.c | 7 ++++--- mozilla/xpcom/glue/pldhash.c | 4 ++-- mozilla/xpcom/glue/pldhash.h | 24 ++++++++++++++++++++++++ 8 files changed, 64 insertions(+), 13 deletions(-) diff --git a/mozilla/js/src/jsdhash.c b/mozilla/js/src/jsdhash.c index 295883b2fdf..38853e30bc3 100644 --- a/mozilla/js/src/jsdhash.c +++ b/mozilla/js/src/jsdhash.c @@ -240,8 +240,8 @@ JS_DHashTableInit(JSDHashTable *table, const JSDHashTableOps *ops, void *data, if (capacity >= JS_DHASH_SIZE_LIMIT) return JS_FALSE; table->hashShift = JS_DHASH_BITS - log2; - table->maxAlphaFrac = 0xC0; /* .75 */ - table->minAlphaFrac = 0x40; /* .25 */ + table->maxAlphaFrac = (uint8)(0x100 * JS_DHASH_DEFAULT_MAX_ALPHA); + table->minAlphaFrac = (uint8)(0x100 * JS_DHASH_DEFAULT_MIN_ALPHA); table->entrySize = entrySize; table->entryCount = table->removedCount = 0; table->generation = 0; diff --git a/mozilla/js/src/jsdhash.h b/mozilla/js/src/jsdhash.h index 76867e52a61..61056cb5e44 100644 --- a/mozilla/js/src/jsdhash.h +++ b/mozilla/js/src/jsdhash.h @@ -455,6 +455,30 @@ JS_DHashTableSetAlphaBounds(JSDHashTable *table, ((float)((table)->entrySize / sizeof(void *) - 1) \ / ((table)->entrySize / sizeof(void *) + (k))) +/* + * Default max/min alpha, and macros to compute the value for the |capacity| + * parameter to JS_NewDHashTable and JS_DHashTableInit, given default or any + * max alpha, such that adding entryCount entries right after initializing the + * table will not require a reallocation (so JS_DHASH_ADD can't fail for those + * JS_DHashTableOperate calls). + * + * NB: JS_DHASH_CAP is a helper macro meant for use only in JS_DHASH_CAPACITY. + * Don't use it directly! + */ +#define JS_DHASH_DEFAULT_MAX_ALPHA 0.75 +#define JS_DHASH_DEFAULT_MIN_ALPHA 0.25 + +#define JS_DHASH_CAP(entryCount, maxAlpha) \ + ((uint32)((double)(entryCount) / (maxAlpha))) + +#define JS_DHASH_CAPACITY(entryCount, maxAlpha) \ + (JS_DHASH_CAP(entryCount, maxAlpha) + \ + (((JS_DHASH_CAP(entryCount, maxAlpha) * (uint8)(0x100 * (maxAlpha))) \ + >> 8) < (entryCount))) + +#define JS_DHASH_DEFAULT_CAPACITY(entryCount) \ + JS_DHASH_CAPACITY(entryCount, JS_DHASH_DEFAULT_MAX_ALPHA) + /* * Finalize table's data, free its entry storage using table->ops->freeTable, * and leave its members unchanged from their last live values (which leaves diff --git a/mozilla/js/src/jsgc.c b/mozilla/js/src/jsgc.c index e6f67a38cd2..c1790f300af 100644 --- a/mozilla/js/src/jsgc.c +++ b/mozilla/js/src/jsgc.c @@ -784,8 +784,8 @@ js_AddRootRT(JSRuntime *rt, void *rp, const char *name) } while (rt->gcLevel > 0); } #endif - rhe = (JSGCRootHashEntry *) JS_DHashTableOperate(&rt->gcRootsHash, rp, - JS_DHASH_ADD); + rhe = (JSGCRootHashEntry *) + JS_DHashTableOperate(&rt->gcRootsHash, rp, JS_DHASH_ADD); if (rhe) { rhe->root = rp; rhe->name = name; @@ -1667,7 +1667,7 @@ js_LockGCThingRT(JSRuntime *rt, void *thing) } lhe = (JSGCLockHashEntry *) - JS_DHashTableOperate(rt->gcLocksHash, thing, JS_DHASH_ADD); + JS_DHashTableOperate(rt->gcLocksHash, thing, JS_DHASH_ADD); if (!lhe) { ok = JS_FALSE; goto done; diff --git a/mozilla/js/src/jsparse.c b/mozilla/js/src/jsparse.c index 5e1169fb1ec..747b1fdefe3 100644 --- a/mozilla/js/src/jsparse.c +++ b/mozilla/js/src/jsparse.c @@ -2068,8 +2068,9 @@ FindPropertyValue(JSParseNode *pn, JSParseNode *pnid, FindPropValData *data) data->numvars >= BIG_DESTRUCTURING && pn->pn_count >= BIG_OBJECT_INIT && JS_DHashTableInit(&data->table, &FindPropValOps, pn, - sizeof(FindPropValEntry), pn->pn_count)) { - + sizeof(FindPropValEntry), + JS_DHASH_DEFAULT_CAPACITY(pn->pn_count))) + { for (pn = pn->pn_head; pn; pn = pn->pn_next) { ASSERT_VALID_PROPERTY_KEY(pn->pn_left); entry = (FindPropValEntry *) diff --git a/mozilla/js/src/jsscript.c b/mozilla/js/src/jsscript.c index d53c247021d..efbbaef1bff 100644 --- a/mozilla/js/src/jsscript.c +++ b/mozilla/js/src/jsscript.c @@ -1474,7 +1474,8 @@ js_GetSrcNoteCached(JSContext *cx, JSScript *script, jsbytecode *pc) ++nsrcnotes; } if (!JS_DHashTableInit(&JS_GSN_CACHE(cx).table, JS_DHashGetStubOps(), - NULL, sizeof(GSNCacheEntry), nsrcnotes)) { + NULL, sizeof(GSNCacheEntry), + JS_DHASH_DEFAULT_CAPACITY(nsrcnotes))) { JS_GSN_CACHE(cx).table.ops = NULL; } else { pc = script->code; diff --git a/mozilla/js/src/jsxdrapi.c b/mozilla/js/src/jsxdrapi.c index 2855c608e92..463a759acf7 100644 --- a/mozilla/js/src/jsxdrapi.c +++ b/mozilla/js/src/jsxdrapi.c @@ -790,9 +790,10 @@ JS_XDRFindClassIdByName(JSXDRState *xdr, const char *name) /* Bootstrap reghash from registry on first overpopulated Find. */ if (!xdr->reghash) { - xdr->reghash = JS_NewDHashTable(JS_DHashGetStubOps(), NULL, - sizeof(JSRegHashEntry), - numclasses); + xdr->reghash = + JS_NewDHashTable(JS_DHashGetStubOps(), NULL, + sizeof(JSRegHashEntry), + JS_DHASH_DEFAULT_CAPACITY(numclasses)); if (xdr->reghash) { for (i = 0; i < numclasses; i++) { JSClass *clasp = xdr->registry[i]; diff --git a/mozilla/xpcom/glue/pldhash.c b/mozilla/xpcom/glue/pldhash.c index 503dfb1aa82..8de47a50b69 100644 --- a/mozilla/xpcom/glue/pldhash.c +++ b/mozilla/xpcom/glue/pldhash.c @@ -241,8 +241,8 @@ PL_DHashTableInit(PLDHashTable *table, const PLDHashTableOps *ops, void *data, if (capacity >= PL_DHASH_SIZE_LIMIT) return PR_FALSE; table->hashShift = PL_DHASH_BITS - log2; - table->maxAlphaFrac = 0xC0; /* .75 */ - table->minAlphaFrac = 0x40; /* .25 */ + table->maxAlphaFrac = (uint8)(0x100 * PL_DHASH_DEFAULT_MAX_ALPHA); + table->minAlphaFrac = (uint8)(0x100 * PL_DHASH_DEFAULT_MIN_ALPHA); table->entrySize = entrySize; table->entryCount = table->removedCount = 0; table->generation = 0; diff --git a/mozilla/xpcom/glue/pldhash.h b/mozilla/xpcom/glue/pldhash.h index 028ee77b034..135ff657013 100644 --- a/mozilla/xpcom/glue/pldhash.h +++ b/mozilla/xpcom/glue/pldhash.h @@ -456,6 +456,30 @@ PL_DHashTableSetAlphaBounds(PLDHashTable *table, ((float)((table)->entrySize / sizeof(void *) - 1) \ / ((table)->entrySize / sizeof(void *) + (k))) +/* + * Default max/min alpha, and macros to compute the value for the |capacity| + * parameter to PL_NewDHashTable and PL_DHashTableInit, given default or any + * max alpha, such that adding entryCount entries right after initializing the + * table will not require a reallocation (so PL_DHASH_ADD can't fail for those + * PL_DHashTableOperate calls). + * + * NB: PL_DHASH_CAP is a helper macro meant for use only in PL_DHASH_CAPACITY. + * Don't use it directly! + */ +#define PL_DHASH_DEFAULT_MAX_ALPHA 0.75 +#define PL_DHASH_DEFAULT_MIN_ALPHA 0.25 + +#define PL_DHASH_CAP(entryCount, maxAlpha) \ + ((PRUint32)((double)(entryCount) / (maxAlpha))) + +#define PL_DHASH_CAPACITY(entryCount, maxAlpha) \ + (PL_DHASH_CAP(entryCount, maxAlpha) + \ + (((PL_DHASH_CAP(entryCount, maxAlpha) * (uint8)(0x100 * (maxAlpha))) \ + >> 8) < (entryCount))) + +#define PL_DHASH_DEFAULT_CAPACITY(entryCount) \ + PL_DHASH_CAPACITY(entryCount, PL_DHASH_DEFAULT_MAX_ALPHA) + /* * Finalize table's data, free its entry storage using table->ops->freeTable, * and leave its members unchanged from their last live values (which leaves