mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 629817 - Add an AutoShapeVector to root shape vectors on the stack (r=luke)
This commit is contained in:
parent
b84e4431ab
commit
667b23ee82
@ -1867,7 +1867,7 @@ js::array_sort(JSContext *cx, uintN argc, Value *vp)
|
||||
* the root set covered by tvr.count.
|
||||
*/
|
||||
Value *mergesort_tmp = vec + newlen;
|
||||
MakeValueRangeGCSafe(mergesort_tmp, newlen);
|
||||
MakeRangeGCSafe(mergesort_tmp, newlen);
|
||||
tvr.changeLength(newlen * 2);
|
||||
|
||||
/* Here len == 2 * (newlen + undefs + number_of_holes). */
|
||||
@ -1932,7 +1932,7 @@ js::array_sort(JSContext *cx, uintN argc, Value *vp)
|
||||
return false;
|
||||
}
|
||||
mergesort_tmp = vec + 2 * newlen;
|
||||
MakeValueRangeGCSafe(mergesort_tmp, 2 * newlen);
|
||||
MakeRangeGCSafe(mergesort_tmp, 2 * newlen);
|
||||
tvr.changeArray(vec, newlen * 4);
|
||||
elemsize = 2 * sizeof(Value);
|
||||
}
|
||||
|
115
js/src/jscntxt.h
115
js/src/jscntxt.h
@ -2241,7 +2241,8 @@ class AutoGCRooter {
|
||||
DESCRIPTOR = -13, /* js::AutoPropertyDescriptorRooter */
|
||||
STRING = -14, /* js::AutoStringRooter */
|
||||
IDVECTOR = -15, /* js::AutoIdVector */
|
||||
BINDINGS = -16 /* js::Bindings */
|
||||
BINDINGS = -16, /* js::Bindings */
|
||||
SHAPEVECTOR = -17 /* js::AutoShapeVector */
|
||||
};
|
||||
|
||||
private:
|
||||
@ -3227,28 +3228,28 @@ ContextAllocPolicy::reportAllocOverflow() const
|
||||
js_ReportAllocationOverflow(cx);
|
||||
}
|
||||
|
||||
class AutoValueVector : private AutoGCRooter
|
||||
template<class T>
|
||||
class AutoVectorRooter : protected AutoGCRooter
|
||||
{
|
||||
public:
|
||||
explicit AutoValueVector(JSContext *cx
|
||||
JS_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: AutoGCRooter(cx, VALVECTOR), vector(cx)
|
||||
explicit AutoVectorRooter(JSContext *cx, ptrdiff_t tag
|
||||
JS_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: AutoGCRooter(cx, tag), vector(cx)
|
||||
{
|
||||
JS_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
}
|
||||
|
||||
size_t length() const { return vector.length(); }
|
||||
|
||||
bool append(const Value &v) { return vector.append(v); }
|
||||
bool append(const T &v) { return vector.append(v); }
|
||||
|
||||
void popBack() { vector.popBack(); }
|
||||
|
||||
bool growBy(size_t inc) {
|
||||
/* N.B. Value's default ctor leaves the Value undefined */
|
||||
size_t oldLength = vector.length();
|
||||
if (!vector.growByUninitialized(inc))
|
||||
return false;
|
||||
MakeValueRangeGCSafe(vector.begin() + oldLength, vector.end());
|
||||
MakeRangeGCSafe(vector.begin() + oldLength, vector.end());
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -3258,10 +3259,9 @@ class AutoValueVector : private AutoGCRooter
|
||||
vector.shrinkBy(oldLength - newLength);
|
||||
return true;
|
||||
}
|
||||
/* N.B. Value's default ctor leaves the Value undefined */
|
||||
if (!vector.growByUninitialized(newLength - oldLength))
|
||||
return false;
|
||||
MakeValueRangeGCSafe(vector.begin() + oldLength, vector.end());
|
||||
MakeRangeGCSafe(vector.begin() + oldLength, vector.end());
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -3269,14 +3269,33 @@ class AutoValueVector : private AutoGCRooter
|
||||
return vector.reserve(newLength);
|
||||
}
|
||||
|
||||
Value &operator[](size_t i) { return vector[i]; }
|
||||
const Value &operator[](size_t i) const { return vector[i]; }
|
||||
T &operator[](size_t i) { return vector[i]; }
|
||||
const T &operator[](size_t i) const { return vector[i]; }
|
||||
|
||||
const Value *begin() const { return vector.begin(); }
|
||||
Value *begin() { return vector.begin(); }
|
||||
const T *begin() const { return vector.begin(); }
|
||||
T *begin() { return vector.begin(); }
|
||||
|
||||
const Value *end() const { return vector.end(); }
|
||||
Value *end() { return vector.end(); }
|
||||
const T *end() const { return vector.end(); }
|
||||
T *end() { return vector.end(); }
|
||||
|
||||
const T &back() const { return vector.back(); }
|
||||
|
||||
friend void AutoGCRooter::trace(JSTracer *trc);
|
||||
|
||||
private:
|
||||
Vector<T, 8> vector;
|
||||
JS_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
};
|
||||
|
||||
class AutoValueVector : public AutoVectorRooter<Value>
|
||||
{
|
||||
public:
|
||||
explicit AutoValueVector(JSContext *cx
|
||||
JS_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: AutoVectorRooter<Value>(cx, VALVECTOR)
|
||||
{
|
||||
JS_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
}
|
||||
|
||||
const jsval *jsval_begin() const { return Jsvalify(begin()); }
|
||||
jsval *jsval_begin() { return Jsvalify(begin()); }
|
||||
@ -3284,72 +3303,32 @@ class AutoValueVector : private AutoGCRooter
|
||||
const jsval *jsval_end() const { return Jsvalify(end()); }
|
||||
jsval *jsval_end() { return Jsvalify(end()); }
|
||||
|
||||
const Value &back() const { return vector.back(); }
|
||||
|
||||
friend void AutoGCRooter::trace(JSTracer *trc);
|
||||
|
||||
private:
|
||||
Vector<Value, 8> vector;
|
||||
JS_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
};
|
||||
|
||||
class AutoIdVector : private AutoGCRooter
|
||||
class AutoIdVector : public AutoVectorRooter<jsid>
|
||||
{
|
||||
public:
|
||||
explicit AutoIdVector(JSContext *cx
|
||||
JS_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: AutoGCRooter(cx, IDVECTOR), vector(cx)
|
||||
: AutoVectorRooter<jsid>(cx, IDVECTOR)
|
||||
{
|
||||
JS_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
}
|
||||
|
||||
size_t length() const { return vector.length(); }
|
||||
JS_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
};
|
||||
|
||||
bool append(jsid id) { return vector.append(id); }
|
||||
|
||||
void popBack() { vector.popBack(); }
|
||||
|
||||
bool growBy(size_t inc) {
|
||||
/* N.B. jsid's default ctor leaves the jsid undefined */
|
||||
size_t oldLength = vector.length();
|
||||
if (!vector.growByUninitialized(inc))
|
||||
return false;
|
||||
MakeIdRangeGCSafe(vector.begin() + oldLength, vector.end());
|
||||
return true;
|
||||
class AutoShapeVector : public AutoVectorRooter<const Shape *>
|
||||
{
|
||||
public:
|
||||
explicit AutoShapeVector(JSContext *cx
|
||||
JS_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: AutoVectorRooter<const Shape *>(cx, SHAPEVECTOR)
|
||||
{
|
||||
JS_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
}
|
||||
|
||||
bool resize(size_t newLength) {
|
||||
size_t oldLength = vector.length();
|
||||
if (newLength <= oldLength) {
|
||||
vector.shrinkBy(oldLength - newLength);
|
||||
return true;
|
||||
}
|
||||
/* N.B. jsid's default ctor leaves the jsid undefined */
|
||||
if (!vector.growByUninitialized(newLength - oldLength))
|
||||
return false;
|
||||
MakeIdRangeGCSafe(vector.begin() + oldLength, vector.end());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool reserve(size_t newLength) {
|
||||
return vector.reserve(newLength);
|
||||
}
|
||||
|
||||
jsid &operator[](size_t i) { return vector[i]; }
|
||||
const jsid &operator[](size_t i) const { return vector[i]; }
|
||||
|
||||
const jsid *begin() const { return vector.begin(); }
|
||||
jsid *begin() { return vector.begin(); }
|
||||
|
||||
const jsid *end() const { return vector.end(); }
|
||||
jsid *end() { return vector.end(); }
|
||||
|
||||
const jsid &back() const { return vector.back(); }
|
||||
|
||||
friend void AutoGCRooter::trace(JSTracer *trc);
|
||||
|
||||
private:
|
||||
Vector<jsid, 8> vector;
|
||||
JS_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
};
|
||||
|
||||
|
@ -248,7 +248,7 @@ StackSpace::pushInvokeArgs(JSContext *cx, uintN argc, InvokeArgsGuard *ag)
|
||||
|
||||
Value *vp = start;
|
||||
Value *vpend = vp + nvals;
|
||||
/* Don't need to MakeValueRangeGCSafe: the VM stack is conservatively marked. */
|
||||
/* Don't need to MakeRangeGCSafe: the VM stack is conservatively marked. */
|
||||
|
||||
/* Use invokeArgEnd to root [vp, vpend) until the frame is pushed. */
|
||||
ag->prevInvokeArgEnd = invokeArgEnd;
|
||||
|
@ -1601,6 +1601,12 @@ AutoGCRooter::trace(JSTracer *trc)
|
||||
return;
|
||||
}
|
||||
|
||||
case SHAPEVECTOR: {
|
||||
Vector<const Shape *, 8> &vector = static_cast<js::AutoShapeVector *>(this)->vector;
|
||||
MarkShapeRange(trc, vector.length(), vector.begin(), "js::AutoShapeVector.vector");
|
||||
return;
|
||||
}
|
||||
|
||||
case BINDINGS: {
|
||||
static_cast<js::AutoBindingsRooter *>(this)->bindings.trace(trc);
|
||||
return;
|
||||
|
@ -623,6 +623,21 @@ MarkValueRange(JSTracer *trc, size_t len, Value *vec, const char *name)
|
||||
MarkValueRange(trc, vec, vec + len, name);
|
||||
}
|
||||
|
||||
static inline void
|
||||
MarkShapeRange(JSTracer *trc, const Shape **beg, const Shape **end, const char *name)
|
||||
{
|
||||
for (const Shape **sp = beg; sp < end; ++sp) {
|
||||
JS_SET_TRACING_INDEX(trc, name, sp - beg);
|
||||
(*sp)->trace(trc);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
MarkShapeRange(JSTracer *trc, size_t len, const Shape **vec, const char *name)
|
||||
{
|
||||
MarkShapeRange(trc, vec, vec + len, name);
|
||||
}
|
||||
|
||||
/* N.B. Assumes JS_SET_TRACING_NAME/INDEX has already been called. */
|
||||
static inline void
|
||||
MarkGCThing(JSTracer *trc, void *thing, uint32 kind)
|
||||
|
@ -3426,7 +3426,7 @@ JSObject::copyPropertiesFrom(JSContext *cx, JSObject *obj)
|
||||
if (!isNative())
|
||||
return true;
|
||||
|
||||
Vector<const Shape *> shapes(cx);
|
||||
AutoShapeVector shapes(cx);
|
||||
for (Shape::Range r(obj->lastProperty()); !r.empty(); r.popFront()) {
|
||||
if (!shapes.append(&r.front()))
|
||||
return false;
|
||||
@ -3725,8 +3725,8 @@ js_XDRBlockObject(JSXDRState *xdr, JSObject **objp)
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
Vector<const Shape *, 8> shapes(cx);
|
||||
shapes.growByUninitialized(count);
|
||||
AutoShapeVector shapes(cx);
|
||||
shapes.growBy(count);
|
||||
|
||||
for (Shape::Range r(obj->lastProperty()); !r.empty(); r.popFront()) {
|
||||
shape = &r.front();
|
||||
|
@ -1145,28 +1145,40 @@ ValueArgToConstRef(const Value &v)
|
||||
/******************************************************************************/
|
||||
|
||||
static JS_ALWAYS_INLINE void
|
||||
MakeValueRangeGCSafe(Value *vec, size_t len)
|
||||
MakeRangeGCSafe(Value *vec, size_t len)
|
||||
{
|
||||
PodZero(vec, len);
|
||||
}
|
||||
|
||||
static JS_ALWAYS_INLINE void
|
||||
MakeValueRangeGCSafe(Value *beg, Value *end)
|
||||
MakeRangeGCSafe(Value *beg, Value *end)
|
||||
{
|
||||
PodZero(beg, end - beg);
|
||||
}
|
||||
|
||||
static JS_ALWAYS_INLINE void
|
||||
MakeIdRangeGCSafe(jsid *beg, jsid *end)
|
||||
MakeRangeGCSafe(jsid *beg, jsid *end)
|
||||
{
|
||||
for (jsid *id = beg; id != end; ++id)
|
||||
*id = INT_TO_JSID(0);
|
||||
}
|
||||
|
||||
static JS_ALWAYS_INLINE void
|
||||
MakeIdRangeGCSafe(jsid *vec, size_t len)
|
||||
MakeRangeGCSafe(jsid *vec, size_t len)
|
||||
{
|
||||
MakeIdRangeGCSafe(vec, vec + len);
|
||||
MakeRangeGCSafe(vec, vec + len);
|
||||
}
|
||||
|
||||
static JS_ALWAYS_INLINE void
|
||||
MakeRangeGCSafe(const Shape **beg, const Shape **end)
|
||||
{
|
||||
PodZero(beg, end - beg);
|
||||
}
|
||||
|
||||
static JS_ALWAYS_INLINE void
|
||||
MakeRangeGCSafe(const Shape **vec, size_t len)
|
||||
{
|
||||
PodZero(vec, len);
|
||||
}
|
||||
|
||||
static JS_ALWAYS_INLINE void
|
||||
|
Loading…
Reference in New Issue
Block a user