зеркало из https://github.com/mozilla/gecko-dev.git
Bug 660734, part 2 - Add back a ContextAllocPolicy that calls cx->malloc_ and use it in StringBuffer so that the new string's bytes are counted by the GC (r=igor)
--HG-- extra : rebase_source : a9e677e80574352125c93a7a3d775ef20303c551
This commit is contained in:
Родитель
d120c17229
Коммит
be687431b6
|
@ -0,0 +1,13 @@
|
||||||
|
// first build a big honkin' string
|
||||||
|
str = "a";
|
||||||
|
for (var i = 0; i < 20; ++i)
|
||||||
|
str = str + str;
|
||||||
|
str.indexOf('a');
|
||||||
|
|
||||||
|
// copying this sucker should gc
|
||||||
|
makeFinalizeObserver();
|
||||||
|
assertEq(finalizeCount(), 0);
|
||||||
|
// if the assert fails, add more iterations
|
||||||
|
for (var i = 0; i < 50; ++i)
|
||||||
|
str.replace(/(a)/, '$1');
|
||||||
|
assertEq(finalizeCount(), 1);
|
|
@ -1440,28 +1440,6 @@ struct JSContext
|
||||||
|
|
||||||
namespace js {
|
namespace js {
|
||||||
|
|
||||||
/*
|
|
||||||
* Allocation policy that uses JSRuntime::malloc_ and friends, so that
|
|
||||||
* memory pressure is properly accounted for. This is suitable for
|
|
||||||
* long-lived objects owned by the JSRuntime.
|
|
||||||
*
|
|
||||||
* Since it doesn't hold a JSContext (those may not live long enough), it
|
|
||||||
* can't report out-of-memory conditions itself; the caller must check for
|
|
||||||
* OOM and take the appropriate action.
|
|
||||||
*/
|
|
||||||
class RuntimeAllocPolicy
|
|
||||||
{
|
|
||||||
JSRuntime *const runtime;
|
|
||||||
|
|
||||||
public:
|
|
||||||
RuntimeAllocPolicy(JSRuntime *rt) : runtime(rt) {}
|
|
||||||
RuntimeAllocPolicy(JSContext *cx) : runtime(cx->runtime) {}
|
|
||||||
void *malloc_(size_t bytes) { return runtime->malloc_(bytes); }
|
|
||||||
void *realloc_(void *p, size_t bytes) { return runtime->realloc_(p, bytes); }
|
|
||||||
void free_(void *p) { runtime->free_(p); }
|
|
||||||
void reportAllocOverflow() const {}
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef JS_THREADSAFE
|
#ifdef JS_THREADSAFE
|
||||||
# define JS_THREAD_ID(cx) ((cx)->thread() ? (cx)->thread()->id : 0)
|
# define JS_THREAD_ID(cx) ((cx)->thread() ? (cx)->thread()->id : 0)
|
||||||
#endif
|
#endif
|
||||||
|
@ -2630,6 +2608,46 @@ class AutoShapeVector : public AutoVectorRooter<const Shape *>
|
||||||
JSIdArray *
|
JSIdArray *
|
||||||
NewIdArray(JSContext *cx, jsint length);
|
NewIdArray(JSContext *cx, jsint length);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Allocation policy that uses JSRuntime::malloc_ and friends, so that
|
||||||
|
* memory pressure is properly accounted for. This is suitable for
|
||||||
|
* long-lived objects owned by the JSRuntime.
|
||||||
|
*
|
||||||
|
* Since it doesn't hold a JSContext (those may not live long enough), it
|
||||||
|
* can't report out-of-memory conditions itself; the caller must check for
|
||||||
|
* OOM and take the appropriate action.
|
||||||
|
*
|
||||||
|
* FIXME bug 647103 - replace these *AllocPolicy names.
|
||||||
|
*/
|
||||||
|
class RuntimeAllocPolicy
|
||||||
|
{
|
||||||
|
JSRuntime *const runtime;
|
||||||
|
|
||||||
|
public:
|
||||||
|
RuntimeAllocPolicy(JSRuntime *rt) : runtime(rt) {}
|
||||||
|
RuntimeAllocPolicy(JSContext *cx) : runtime(cx->runtime) {}
|
||||||
|
void *malloc_(size_t bytes) { return runtime->malloc_(bytes); }
|
||||||
|
void *realloc_(void *p, size_t bytes) { return runtime->realloc_(p, bytes); }
|
||||||
|
void free_(void *p) { runtime->free_(p); }
|
||||||
|
void reportAllocOverflow() const {}
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FIXME bug 647103 - replace these *AllocPolicy names.
|
||||||
|
*/
|
||||||
|
class ContextAllocPolicy
|
||||||
|
{
|
||||||
|
JSContext *const cx;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ContextAllocPolicy(JSContext *cx) : cx(cx) {}
|
||||||
|
JSContext *context() const { return cx; }
|
||||||
|
void *malloc_(size_t bytes) { return cx->malloc_(bytes); }
|
||||||
|
void *realloc_(void *p, size_t oldBytes, size_t bytes) { return cx->realloc_(p, oldBytes, bytes); }
|
||||||
|
void free_(void *p) { cx->free_(p); }
|
||||||
|
void reportAllocOverflow() const { js_ReportAllocationOverflow(cx); }
|
||||||
|
};
|
||||||
|
|
||||||
} /* namespace js */
|
} /* namespace js */
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
|
|
|
@ -79,7 +79,9 @@ CheckStringLength(JSContext *cx, size_t length)
|
||||||
*/
|
*/
|
||||||
class StringBuffer
|
class StringBuffer
|
||||||
{
|
{
|
||||||
typedef Vector<jschar, 32> CharBuffer;
|
/* cb's buffer is taken by the new string so use ContextAllocPolicy. */
|
||||||
|
typedef Vector<jschar, 32, ContextAllocPolicy> CharBuffer;
|
||||||
|
|
||||||
CharBuffer cb;
|
CharBuffer cb;
|
||||||
|
|
||||||
static inline bool checkLength(JSContext *cx, size_t length);
|
static inline bool checkLength(JSContext *cx, size_t length);
|
||||||
|
|
|
@ -158,7 +158,7 @@ struct VectorImpl<T, N, AP, true>
|
||||||
static inline bool growTo(Vector<T,N,AP> &v, size_t newcap) {
|
static inline bool growTo(Vector<T,N,AP> &v, size_t newcap) {
|
||||||
JS_ASSERT(!v.usingInlineStorage());
|
JS_ASSERT(!v.usingInlineStorage());
|
||||||
size_t bytes = sizeof(T) * newcap;
|
size_t bytes = sizeof(T) * newcap;
|
||||||
size_t oldBytes = sizeof(T) * v.mLength;
|
size_t oldBytes = sizeof(T) * v.mCapacity;
|
||||||
T *newbuf = reinterpret_cast<T *>(v.realloc_(v.mBegin, oldBytes, bytes));
|
T *newbuf = reinterpret_cast<T *>(v.realloc_(v.mBegin, oldBytes, bytes));
|
||||||
if (!newbuf)
|
if (!newbuf)
|
||||||
return false;
|
return false;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче