Bug 1056899 - Don't free COW element arrays until after sweeping, r=jonco.

This commit is contained in:
Brian Hackett 2014-08-21 17:54:05 -07:00
parent fd5e9d1fcc
commit 5becdf07b4
2 changed files with 28 additions and 1 deletions

View File

@ -637,8 +637,16 @@ JSObject::finish(js::FreeOp *fop)
if (hasDynamicElements()) {
js::ObjectElements *elements = getElementsHeader();
if (!elements->isCopyOnWrite() || elements->ownerObject() == this)
if (elements->isCopyOnWrite()) {
if (elements->ownerObject() == this) {
// Don't free the elements until object finalization finishes,
// so that other objects can access these elements while they
// are themselves finalized.
fop->freeLater(elements);
}
} else {
fop->free_(elements);
}
}
}

View File

@ -381,6 +381,8 @@ struct RegExpTestCache
*/
class FreeOp : public JSFreeOp
{
Vector<void *, 0, SystemAllocPolicy> freeLaterList;
public:
static FreeOp *get(JSFreeOp *fop) {
return static_cast<FreeOp *>(fop);
@ -390,7 +392,13 @@ class FreeOp : public JSFreeOp
: JSFreeOp(rt)
{}
~FreeOp() {
for (size_t i = 0; i < freeLaterList.length(); i++)
free_(freeLaterList[i]);
}
inline void free_(void *p);
inline void freeLater(void *p);
template <class T>
inline void delete_(T *p) {
@ -1473,6 +1481,17 @@ FreeOp::free_(void *p)
js_free(p);
}
inline void
FreeOp::freeLater(void *p)
{
// FreeOps other than the defaultFreeOp() are constructed on the stack,
// and won't hold onto the pointers to free indefinitely.
JS_ASSERT(this != runtime()->defaultFreeOp());
if (!freeLaterList.append(p))
CrashAtUnhandlableOOM("FreeOp::freeLater");
}
class AutoLockGC
{
public: