Bug 720753 - hoist EvalCache from JSCompartment into JSRuntime (r=igor)

This commit is contained in:
Luke Wagner 2012-05-03 09:12:48 +02:00
parent e511623bf4
commit 2b2f0ea130
5 changed files with 39 additions and 41 deletions

View File

@ -204,6 +204,18 @@ class ToSourceCache
void purge();
};
class EvalCache
{
static const unsigned SHIFT = 6;
static const unsigned LENGTH = 1 << SHIFT;
JSScript *table_[LENGTH];
public:
EvalCache() { PodArrayZero(table_); }
JSScript **bucket(JSLinearString *str);
void purge();
};
class NativeIterCache
{
static const size_t SIZE = size_t(1) << 8;
@ -755,6 +767,7 @@ struct JSRuntime : js::RuntimeFriendFields
js::NewObjectCache newObjectCache;
js::NativeIterCache nativeIterCache;
js::ToSourceCache toSourceCache;
js::EvalCache evalCache;
/* State used by jsdtoa.cpp. */
DtoaState *dtoaState;

View File

@ -92,7 +92,6 @@ JSCompartment::JSCompartment(JSRuntime *rt)
sourceMapMap(NULL),
debugScriptMap(NULL)
{
PodArrayZero(evalCache);
setGCMaxMallocBytes(rt->gcMaxMallocBytes * 0.9);
}
@ -102,11 +101,6 @@ JSCompartment::~JSCompartment()
Foreground::delete_(scriptCountsMap);
Foreground::delete_(sourceMapMap);
Foreground::delete_(debugScriptMap);
#ifdef DEBUG
for (size_t i = 0; i < ArrayLength(evalCache); ++i)
JS_ASSERT(!evalCache[i]);
#endif
}
bool
@ -536,21 +530,6 @@ void
JSCompartment::purge()
{
dtoaCache.purge();
/*
* Clear the hash and reset all evalHashLink to null before the GC. This
* way MarkChildren(trc, JSScript *) can assume that JSScript::u.object is
* not null when we have script owned by an object and not from the eval
* cache.
*/
for (size_t i = 0; i < ArrayLength(evalCache); ++i) {
for (JSScript **listHeadp = &evalCache[i]; *listHeadp; ) {
JSScript *script = *listHeadp;
JS_ASSERT(GetGCThingTraceKind(script) == JSTRACE_SCRIPT);
*listHeadp = NULL;
listHeadp = &script->evalHashLink();
}
}
}
void

View File

@ -61,17 +61,6 @@ namespace js {
/* Defined in jsapi.cpp */
extern Class dummy_class;
} /* namespace js */
#ifndef JS_EVAL_CACHE_SHIFT
# define JS_EVAL_CACHE_SHIFT 6
#endif
/* Number of buckets in the hash of eval scripts. */
#define JS_EVAL_CACHE_SIZE JS_BIT(JS_EVAL_CACHE_SHIFT)
namespace js {
/*
* A single-entry cache for some base-10 double-to-string conversions. This
* helps date-format-xparb.js. It also avoids skewing the results for
@ -207,10 +196,6 @@ struct JSCompartment
/* Type information about the scripts and objects in this compartment. */
js::types::TypeCompartment types;
public:
/* Hashed lists of scripts created by eval to garbage-collect. */
JSScript *evalCache[JS_EVAL_CACHE_SIZE];
void *data;
bool active; // GC flag, whether there are active frames
js::WrapperMap crossCompartmentWrappers;

View File

@ -2893,6 +2893,7 @@ PurgeRuntime(JSTracer *trc)
rt->newObjectCache.purge();
rt->nativeIterCache.purge();
rt->toSourceCache.purge();
rt->evalCache.purge();
for (ContextIter acx(rt); !acx.done(); acx.next())
acx->purge();

View File

@ -744,8 +744,27 @@ AssertInnerizedScopeChain(JSContext *cx, JSObject &scopeobj)
# define EVAL_CACHE_CHAIN_LIMIT 4
#endif
static inline JSScript **
EvalCacheHash(JSContext *cx, JSLinearString *str)
void
EvalCache::purge()
{
/*
* Purge all scripts from the eval cache. In addition to removing them from
* table_, null out the evalHashLink field of any script removed. Since
* evalHashLink is in a union with globalObject, this allows the GC to
* indiscriminately use the union as a nullable globalObject pointer.
*/
for (size_t i = 0; i < ArrayLength(table_); ++i) {
for (JSScript **listHeadp = &table_[i]; *listHeadp; ) {
JSScript *script = *listHeadp;
JS_ASSERT(GetGCThingTraceKind(script) == JSTRACE_SCRIPT);
*listHeadp = script->evalHashLink();
script->evalHashLink() = NULL;
}
}
}
inline JSScript **
EvalCache::bucket(JSLinearString *str)
{
const jschar *s = str->chars();
size_t n = str->length();
@ -757,8 +776,9 @@ EvalCacheHash(JSContext *cx, JSLinearString *str)
h = JS_ROTATE_LEFT32(h, 4) ^ *s;
h *= JS_GOLDEN_RATIO;
h >>= 32 - JS_EVAL_CACHE_SHIFT;
return &cx->compartment->evalCache[h];
h >>= 32 - SHIFT;
JS_ASSERT(h < ArrayLength(table_));
return &table_[h];
}
static JS_ALWAYS_INLINE JSScript *
@ -857,7 +877,7 @@ class EvalScriptGuard
: cx_(cx),
str_(str),
script_(cx) {
bucket_ = EvalCacheHash(cx, str);
bucket_ = cx->runtime->evalCache.bucket(str);
}
~EvalScriptGuard() {