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:
Luke Wagner 2011-06-17 10:14:30 -07:00
Родитель d120c17229
Коммит be687431b6
4 изменённых файлов: 57 добавлений и 24 удалений

Просмотреть файл

@ -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;