From bc470f1b6ba3bd147bc3b884c6824378c2f97c70 Mon Sep 17 00:00:00 2001 From: "brendan%mozilla.org" Date: Mon, 29 Oct 2001 19:30:03 +0000 Subject: [PATCH] Consolidate property cache flush under JS_ClearScope (107265, r=shaver, sr=jband). git-svn-id: svn://10.0.0.236/trunk@106560 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/js/src/jscntxt.h | 5 ++++- mozilla/js/src/jsinterp.c | 23 +++++++++++++++++++++++ mozilla/js/src/jsinterp.h | 3 +++ mozilla/js/src/jsscope.c | 20 +++++++++++++++++--- 4 files changed, 47 insertions(+), 4 deletions(-) diff --git a/mozilla/js/src/jscntxt.h b/mozilla/js/src/jscntxt.h index 768d5dec999..92bb4ef340b 100644 --- a/mozilla/js/src/jscntxt.h +++ b/mozilla/js/src/jscntxt.h @@ -334,7 +334,10 @@ struct JSContext { JSPackedBool rval2set; #endif - /* Exception state (NB: throwing packs with rval2set, above). */ + /* True if clearing a scope -- used to coalesce property cache flushes. */ + JSPackedBool clearingScope; + + /* Exception state (NB: throwing packs with clearingScope, above). */ JSPackedBool throwing; /* is there a pending exception? */ jsval exception; /* most-recently-thrown exceptin */ diff --git a/mozilla/js/src/jsinterp.c b/mozilla/js/src/jsinterp.c index 3ae2520b77c..b483aad7e9e 100644 --- a/mozilla/js/src/jsinterp.c +++ b/mozilla/js/src/jsinterp.c @@ -102,6 +102,29 @@ js_FlushPropertyCache(JSContext *cx) cache->flushes++; } +void +js_FlushPropertyCacheByObject(JSContext *cx, JSObject *obj) +{ + JSPropertyCache *cache; + JSPropertyCacheEntry *end, *pce, entry; + JSObject *pce_obj; + + cache = &cx->runtime->propertyCache; + if (cache->empty) + return; + + end = &cache->table[PROPERTY_CACHE_SIZE]; + for (pce = &cache->table[0]; pce < end; pce++) { + PCE_LOAD(cache, pce, entry); + pce_obj = PCE_OBJECT(entry); + if (pce_obj == obj) { + PCE_OBJECT(entry) = NULL; + PCE_PROPERTY(entry) = NULL; + PCE_STORE(cache, pce, entry); + } + } +} + void js_FlushPropertyCacheByProp(JSContext *cx, JSProperty *prop) { diff --git a/mozilla/js/src/jsinterp.h b/mozilla/js/src/jsinterp.h index 991790c63d6..3cc3c2a4b4d 100644 --- a/mozilla/js/src/jsinterp.h +++ b/mozilla/js/src/jsinterp.h @@ -202,6 +202,9 @@ typedef struct JSPropertyCache { extern void js_FlushPropertyCache(JSContext *cx); +extern void +js_FlushPropertyCacheByObject(JSContext *cx, JSObject *obj); + extern void js_FlushPropertyCacheByProp(JSContext *cx, JSProperty *prop); diff --git a/mozilla/js/src/jsscope.c b/mozilla/js/src/jsscope.c index 0f5f6d7fa29..127333bae9b 100644 --- a/mozilla/js/src/jsscope.c +++ b/mozilla/js/src/jsscope.c @@ -229,6 +229,11 @@ js_hash_scope_clear(JSContext *cx, JSScope *scope) JSScopePrivate *priv; JS_ASSERT(JS_IS_SCOPE_LOCKED(scope)); + JS_ASSERT(!cx->clearingScope); + if (!cx->runtime->gcRunning && scope->object) { + cx->clearingScope = JS_TRUE; + js_FlushPropertyCacheByObject(cx, scope->object); + } priv = (JSScopePrivate *) table->allocPriv; priv->context = cx; JS_HashTableEnumerateEntries(table, js_hash_scope_slot_invalidator, NULL); @@ -236,6 +241,7 @@ js_hash_scope_clear(JSContext *cx, JSScope *scope) JS_free(cx, priv); scope->ops = &js_list_scope_ops; scope->data = NULL; + cx->clearingScope = JS_FALSE; } JSScopeOps js_hash_scope_ops = { @@ -358,6 +364,11 @@ js_list_scope_clear(JSContext *cx, JSScope *scope) JSScopeProperty *sprop; JS_ASSERT(JS_IS_SCOPE_LOCKED(scope)); + JS_ASSERT(!cx->clearingScope); + if (!cx->runtime->gcRunning && scope->object) { + cx->clearingScope = JS_TRUE; + js_FlushPropertyCacheByObject(cx, scope->object); + } while ((sym = (JSSymbol *) scope->data) != NULL) { scope->data = sym->entry.next; priv.context = cx; @@ -367,6 +378,7 @@ js_list_scope_clear(JSContext *cx, JSScope *scope) sprop->slot = SPROP_INVALID_SLOT; js_free_symbol(&priv, &sym->entry, HT_FREE_ENTRY); } + cx->clearingScope = JS_FALSE; } JSScopeOps JS_FRIEND_DATA(js_list_scope_ops) = { @@ -559,10 +571,12 @@ js_DestroyScopeProperty(JSContext *cx, JSScope *scope, JSScopeProperty *sprop) } /* - * Purge any cached weak links to prop (unless we're running the gc, which - * flushed the whole cache), then free prop. + * Purge any cached weak links to prop (unless cx is clearing a scope, + * which must be this scope because js_*scope_clear does not nest; and + * unless we're running the gc, which already flushed the whole cache), + * then free prop. */ - if (!cx->runtime->gcRunning) + if (!cx->clearingScope && !cx->runtime->gcRunning) js_FlushPropertyCacheByProp(cx, (JSProperty *)sprop); JS_free(cx, sprop); }