diff --git a/mozilla/js/src/Makefile.ref b/mozilla/js/src/Makefile.ref index 26b3a856dce..e5b2af0fc8d 100644 --- a/mozilla/js/src/Makefile.ref +++ b/mozilla/js/src/Makefile.ref @@ -148,6 +148,7 @@ JS_HFILES = \ jsparse.h \ jsarena.h \ jsclist.h \ + jsdhash.h \ jsdtoa.h \ jshash.h \ jslong.h \ @@ -196,6 +197,7 @@ JS_CFILES = \ jscntxt.c \ jsdate.c \ jsdbgapi.c \ + jsdhash.c \ jsdtoa.c \ jsemit.c \ jsexn.c \ diff --git a/mozilla/js/src/jsdhash.c b/mozilla/js/src/jsdhash.c index 553fe12498a..bd41948a6c9 100644 --- a/mozilla/js/src/jsdhash.c +++ b/mozilla/js/src/jsdhash.c @@ -80,11 +80,66 @@ JS_DHashStringKey(JSDHashTable *table, const void *key) return h; } +JS_PUBLIC_API(const void *) +JS_DHashGetKeyStub(JSDHashTable *table, JSDHashEntryHdr *entry) +{ + JSDHashEntryStub *stub = (JSDHashEntryStub *)entry; + + return stub->key; +} + +JS_PUBLIC_API(JSDHashNumber) +JS_DHashVoidPtrKeyStub(JSDHashTable *table, const void *key) +{ + return (JSDHashNumber)key >> 2; +} + +JS_PUBLIC_API(JSBool) +JS_DHashMatchEntryStub(JSDHashTable *table, + const JSDHashEntryHdr *entry, + const void *key) +{ + JSDHashEntryStub *stub = (JSDHashEntryStub *)entry; + + return stub->key == key; +} + +JS_PUBLIC_API(void) +JS_DHashMoveEntryStub(JSDHashTable *table, + const JSDHashEntryHdr *from, + JSDHashEntryHdr *to) +{ + memcpy(to, from, table->entrySize); +} + +JS_PUBLIC_API(void) +JS_DHashClearEntryStub(JSDHashTable *table, JSDHashEntryHdr *entry) +{ + memset(entry, 0, table->entrySize); +} + JS_PUBLIC_API(void) JS_DHashFinalizeStub(JSDHashTable *table) { } +static JSDHashTableOps stub_ops = { + JS_DHashAllocTable, + JS_DHashFreeTable, + JS_DHashGetKeyStub, + JS_DHashVoidPtrKeyStub, + JS_DHashMatchEntryStub, + JS_DHashMoveEntryStub, + JS_DHashClearEntryStub, + JS_DHashFinalizeStub +}; + +JS_PUBLIC_API(JSDHashTableOps *) +JS_DHashGetStubOps(void) +{ + return &stub_ops; +} + JS_PUBLIC_API(JSDHashTable *) JS_NewDHashTable(JSDHashTableOps *ops, void *data, uint32 entrySize, uint32 capacity) @@ -250,10 +305,7 @@ JS_DHashTableOperate(JSDHashTable *table, const void *key, JSDHashOperator op) if (JS_DHASH_ENTRY_IS_BUSY(entry)) { /* Clear this entry and mark it as "removed". */ METER(table->stats.removeHits++); - table->ops->clearEntry(table, entry); - MARK_ENTRY_REMOVED(entry); - table->removedCount++; - table->entryCount--; + JS_DHashTableRawRemove(table, entry); /* Shrink if alpha is <= .25 and table isn't too small already. */ size = JS_BIT(table->sizeLog2); @@ -321,6 +373,15 @@ JS_DHashTableOperate(JSDHashTable *table, const void *key, JSDHashOperator op) return entry; } +JS_PUBLIC_API(void) +JS_DHashTableRawRemove(JSDHashTable *table, JSDHashEntryHdr *entry) +{ + table->ops->clearEntry(table, entry); + MARK_ENTRY_REMOVED(entry); + table->removedCount++; + table->entryCount--; +} + JS_PUBLIC_API(uint32) JS_DHashTableEnumerate(JSDHashTable *table, JSDHashEnumerator etor, void *arg) { @@ -338,10 +399,7 @@ JS_DHashTableEnumerate(JSDHashTable *table, JSDHashEnumerator etor, void *arg) op = etor(table, entry, j++, arg); if (op & JS_DHASH_REMOVE) { METER(table->stats.removeEnums++); - table->ops->clearEntry(table, entry); - MARK_ENTRY_REMOVED(entry); - table->removedCount++; - table->entryCount--; + JS_DHashTableRawRemove(table, entry); } if (op & JS_DHASH_STOP) break; diff --git a/mozilla/js/src/jsdhash.h b/mozilla/js/src/jsdhash.h index 393586efae3..510b77eb78a 100644 --- a/mozilla/js/src/jsdhash.h +++ b/mozilla/js/src/jsdhash.h @@ -55,6 +55,7 @@ JS_BEGIN_EXTERN_C /* Primitive and forward-struct typedefs. */ typedef uint32 JSDHashNumber; typedef struct JSDHashEntryHdr JSDHashEntryHdr; +typedef struct JSDHashEntryStub JSDHashEntryStub; typedef struct JSDHashTable JSDHashTable; typedef struct JSDHashTableOps JSDHashTableOps; @@ -200,7 +201,7 @@ struct JSDHashTableOps { }; /* - * Default implementations for some of the above ops. + * Default implementations for the above ops. */ extern JS_PUBLIC_API(void *) JS_DHashAllocTable(JSDHashTable *table, uint32 nbytes); @@ -211,9 +212,42 @@ JS_DHashFreeTable(JSDHashTable *table, void *ptr); extern JS_PUBLIC_API(JSDHashNumber) JS_DHashStringKey(JSDHashTable *table, const void *key); +/* A minimal entry contains a keyHash header and a void key pointer. */ +struct JSDHashEntryStub { + JSDHashEntryHdr hdr; + const void *key; +}; + +extern JS_PUBLIC_API(const void *) +JS_DHashGetKeyStub(JSDHashTable *table, JSDHashEntryHdr *entry); + +extern JS_PUBLIC_API(JSDHashNumber) +JS_DHashVoidPtrKeyStub(JSDHashTable *table, const void *key); + +extern JS_PUBLIC_API(JSBool) +JS_DHashMatchEntryStub(JSDHashTable *table, + const JSDHashEntryHdr *entry, + const void *key); + +extern JS_PUBLIC_API(void) +JS_DHashMoveEntryStub(JSDHashTable *table, + const JSDHashEntryHdr *from, + JSDHashEntryHdr *to); + +extern JS_PUBLIC_API(void) +JS_DHashClearEntryStub(JSDHashTable *table, JSDHashEntryHdr *entry); + extern JS_PUBLIC_API(void) JS_DHashFinalizeStub(JSDHashTable *table); +/* + * If you use JSDHashEntryStub or a subclass of it as your entry struct, and + * if your entries move via memcpy and clear via memset(0), you can use these + * stub operations. + */ +extern JS_PUBLIC_API(JSDHashTableOps *) +JS_DHashGetStubOps(void); + /* * Dynamically allocate a new JSDHashTable using malloc, initialize it using * JS_DHashTableInit, and return its address. Return null on malloc failure. @@ -294,6 +328,18 @@ typedef enum JSDHashOperator { extern JS_PUBLIC_API(JSDHashEntryHdr *) JS_DHashTableOperate(JSDHashTable *table, const void *key, JSDHashOperator op); +/* + * Remove an entry already accessed via LOOKUP or ADD. + * + * NB: this is a "raw" or low-level routine, intended to be used only where + * the inefficiency of a full JS_DHashTableOperate (which rehashes in order + * to find the entry given its key) is not tolerable. This function does not + * shrink the table if it is underloaded. It does not update stats #ifdef + * JS_DHASHMETER, either. + */ +extern JS_PUBLIC_API(void) +JS_DHashTableRawRemove(JSDHashTable *table, JSDHashEntryHdr *entry); + /* * Enumerate entries in table using etor: * @@ -313,8 +359,8 @@ JS_DHashTableOperate(JSDHashTable *table, const void *key, JSDHashOperator op); * that were enumerated so far. Return the total number of live entries when * enumeration completes normally. * - * If etor adds or removes an entry, it must return JS_DHASH_STOP; otherwise, - * undefined behavior results. + * If etor calls JS_DHashTableOperate on table, it must return JS_DHASH_STOP; + * otherwise undefined behavior results. */ typedef JSDHashOperator (* CRT_CALL JSDHashEnumerator)(JSDHashTable *table, JSDHashEntryHdr *hdr,