Bug 614155: free memory for source cache on GC. (r=lw)

This commit is contained in:
Chris Leary 2011-02-16 10:17:49 -08:00
parent 281e6dc4a4
commit 4d67bb4c5f
4 changed files with 24 additions and 9 deletions

View File

@ -146,9 +146,6 @@ JSCompartment::init()
return false;
#endif
if (!toSourceCache.init())
return false;
#if ENABLE_YARR_JIT
regExpAllocator = JSC::ExecutableAllocator::create();
if (!regExpAllocator)
@ -550,7 +547,7 @@ JSCompartment::purge(JSContext *cx)
js_DestroyScriptsToGC(cx, this);
nativeIterCache.purge();
toSourceCache.clear();
toSourceCache.destroyIfConstructed();
#ifdef JS_TRACER
/*

View File

@ -442,7 +442,8 @@ struct JS_FRIEND_API(JSCompartment) {
js::NativeIterCache nativeIterCache;
js::ToSourceCache toSourceCache;
typedef js::LazilyConstructed<js::ToSourceCache> LazyToSourceCache;
LazyToSourceCache toSourceCache;
JSCompartment(JSRuntime *rt);
~JSCompartment();

View File

@ -2044,8 +2044,8 @@ fun_toStringHelper(JSContext *cx, JSObject *obj, uintN indent)
if (!fun)
return NULL;
if (!indent) {
ToSourceCache::Ptr p = cx->compartment->toSourceCache.lookup(fun);
if (!indent && !cx->compartment->toSourceCache.empty()) {
ToSourceCache::Ptr p = cx->compartment->toSourceCache.ref().lookup(fun);
if (p)
return p->value;
}
@ -2054,8 +2054,17 @@ fun_toStringHelper(JSContext *cx, JSObject *obj, uintN indent)
if (!str)
return false;
if (!indent)
cx->compartment->toSourceCache.put(fun, str);
if (!indent) {
LazilyConstructed<ToSourceCache> &lazy = cx->compartment->toSourceCache;
if (lazy.empty()) {
lazy.construct();
if (!lazy.ref().init())
return false;
}
lazy.ref().put(fun, str);
}
return str;
}

View File

@ -311,6 +311,9 @@ class LazilyConstructed
T &asT() { return *storage.addr(); }
LazilyConstructed operator=(const LazilyConstructed &other);
explicit LazilyConstructed(const LazilyConstructed &other);
public:
LazilyConstructed() { constructed = false; }
~LazilyConstructed() { if (constructed) asT().~T(); }
@ -365,6 +368,11 @@ class LazilyConstructed
ref().~T();
constructed = false;
}
void destroyIfConstructed() {
if (!empty())
destroy();
}
};