mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 720753 - hoist EvalCache from JSCompartment into JSRuntime (r=igor)
This commit is contained in:
parent
e511623bf4
commit
2b2f0ea130
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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() {
|
||||
|
Loading…
Reference in New Issue
Block a user