mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 711626 - More missing barriers around object properties; r=billm
This adds post barriers in several locations where they are needed inside of object manipulation. --HG-- extra : rebase_source : ce956417a74d70551c1f9258ef7587d0563c0157
This commit is contained in:
parent
2e8557928f
commit
44161208ba
@ -104,6 +104,13 @@ HeapValue::init(const Value &v)
|
||||
post();
|
||||
}
|
||||
|
||||
inline void
|
||||
HeapValue::init(JSCompartment *comp, const Value &v)
|
||||
{
|
||||
value = v;
|
||||
post(comp);
|
||||
}
|
||||
|
||||
inline void
|
||||
HeapValue::writeBarrierPre(const Value &value)
|
||||
{
|
||||
|
@ -302,6 +302,7 @@ class HeapValue
|
||||
inline ~HeapValue();
|
||||
|
||||
inline void init(const Value &v);
|
||||
inline void init(JSCompartment *comp, const Value &v);
|
||||
|
||||
inline HeapValue &operator=(const Value &v);
|
||||
inline HeapValue &operator=(const HeapValue &v);
|
||||
|
@ -1735,7 +1735,7 @@ JSFunction::initBoundFunction(JSContext *cx, const Value &thisArg,
|
||||
setSlot(JSSLOT_BOUND_FUNCTION_THIS, thisArg);
|
||||
setSlot(JSSLOT_BOUND_FUNCTION_ARGS_COUNT, PrivateUint32Value(argslen));
|
||||
|
||||
copySlotRange(BOUND_FUNCTION_RESERVED_SLOTS, args, argslen, false);
|
||||
initSlotRange(BOUND_FUNCTION_RESERVED_SLOTS, args, argslen);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -3620,7 +3620,7 @@ js_PutBlockObject(JSContext *cx, JSBool normalUnwind)
|
||||
if (normalUnwind) {
|
||||
uintN slot = JSSLOT_BLOCK_FIRST_FREE_SLOT;
|
||||
depth += fp->numFixed();
|
||||
obj->copySlotRange(slot, fp->slots() + depth, count, true);
|
||||
obj->copySlotRange(slot, fp->slots() + depth, count);
|
||||
}
|
||||
|
||||
/* We must clear the private slot even with errors. */
|
||||
@ -4037,7 +4037,7 @@ JSObject::TradeGuts(JSContext *cx, JSObject *a, JSObject *b, TradeGutsReserved &
|
||||
a->shape_ = reserved.newashape;
|
||||
|
||||
a->slots = reserved.newaslots;
|
||||
a->copySlotRange(0, reserved.bvals.begin(), bcap, false);
|
||||
a->initSlotRange(0, reserved.bvals.begin(), bcap);
|
||||
if (a->hasPrivate())
|
||||
a->setPrivate(bpriv);
|
||||
|
||||
@ -4047,7 +4047,7 @@ JSObject::TradeGuts(JSContext *cx, JSObject *a, JSObject *b, TradeGutsReserved &
|
||||
b->shape_ = reserved.newbshape;
|
||||
|
||||
b->slots = reserved.newbslots;
|
||||
b->copySlotRange(0, reserved.avals.begin(), acap, false);
|
||||
b->initSlotRange(0, reserved.avals.begin(), acap);
|
||||
if (b->hasPrivate())
|
||||
b->setPrivate(apriv);
|
||||
|
||||
@ -4524,27 +4524,57 @@ js_InitClass(JSContext *cx, JSObject *obj, JSObject *protoProto,
|
||||
}
|
||||
|
||||
void
|
||||
JSObject::copySlotRange(size_t start, const Value *vector, size_t length, bool valid)
|
||||
JSObject::getSlotRange(size_t start, size_t length,
|
||||
HeapValue **fixedStart, HeapValue **fixedEnd,
|
||||
HeapValue **slotsStart, HeapValue **slotsEnd)
|
||||
{
|
||||
if (valid)
|
||||
prepareSlotRangeForOverwrite(start, start + length);
|
||||
|
||||
JS_ASSERT(!isDenseArray());
|
||||
JS_ASSERT(slotInRange(start + length, SENTINEL_ALLOWED));
|
||||
|
||||
size_t fixed = numFixedSlots();
|
||||
if (start < fixed) {
|
||||
if (start + length < fixed) {
|
||||
memcpy(fixedSlots() + start, vector, length * sizeof(Value));
|
||||
*fixedStart = &fixedSlots()[start];
|
||||
*fixedEnd = &fixedSlots()[start + length];
|
||||
*slotsStart = *slotsEnd = NULL;
|
||||
} else {
|
||||
size_t localCopy = fixed - start;
|
||||
memcpy(fixedSlots() + start, vector, localCopy * sizeof(Value));
|
||||
memcpy(slots, vector + localCopy, (length - localCopy) * sizeof(Value));
|
||||
*fixedStart = &fixedSlots()[start];
|
||||
*fixedEnd = &fixedSlots()[start + localCopy];
|
||||
*slotsStart = &slots[0];
|
||||
*slotsEnd = &slots[length - localCopy];
|
||||
}
|
||||
} else {
|
||||
memcpy(slots + start - fixed, vector, length * sizeof(Value));
|
||||
*fixedStart = *fixedEnd = NULL;
|
||||
*slotsStart = &slots[start - fixed];
|
||||
*slotsEnd = &slots[start - fixed + length];
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
JSObject::initSlotRange(size_t start, const Value *vector, size_t length)
|
||||
{
|
||||
JSCompartment *comp = compartment();
|
||||
HeapValue *fixedStart, *fixedEnd, *slotsStart, *slotsEnd;
|
||||
getSlotRange(start, length, &fixedStart, &fixedEnd, &slotsStart, &slotsEnd);
|
||||
for (HeapValue *vp = fixedStart; vp != fixedEnd; vp++)
|
||||
vp->init(comp, *vector++);
|
||||
for (HeapValue *vp = slotsStart; vp != slotsEnd; vp++)
|
||||
vp->init(comp, *vector++);
|
||||
}
|
||||
|
||||
void
|
||||
JSObject::copySlotRange(size_t start, const Value *vector, size_t length)
|
||||
{
|
||||
JSCompartment *comp = compartment();
|
||||
HeapValue *fixedStart, *fixedEnd, *slotsStart, *slotsEnd;
|
||||
getSlotRange(start, length, &fixedStart, &fixedEnd, &slotsStart, &slotsEnd);
|
||||
for (HeapValue *vp = fixedStart; vp != fixedEnd; vp++)
|
||||
vp->set(comp, *vector++);
|
||||
for (HeapValue *vp = slotsStart; vp != slotsEnd; vp++)
|
||||
vp->set(comp, *vector++);
|
||||
}
|
||||
|
||||
inline void
|
||||
JSObject::invalidateSlotRange(size_t start, size_t length)
|
||||
{
|
||||
|
@ -639,6 +639,14 @@ struct JSObject : js::gc::Cell
|
||||
|
||||
private:
|
||||
inline js::HeapValue* fixedSlots() const;
|
||||
|
||||
/*
|
||||
* Get internal pointers to the range of values starting at start and
|
||||
* running for length.
|
||||
*/
|
||||
void getSlotRange(size_t start, size_t length,
|
||||
js::HeapValue **fixedStart, js::HeapValue **fixedEnd,
|
||||
js::HeapValue **slotsStart, js::HeapValue **slotsEnd);
|
||||
public:
|
||||
|
||||
/* Accessors for properties. */
|
||||
@ -690,7 +698,6 @@ struct JSObject : js::gc::Cell
|
||||
inline bool updateSlotsForSpan(JSContext *cx, size_t oldSpan, size_t newSpan);
|
||||
|
||||
public:
|
||||
|
||||
/*
|
||||
* Trigger the write barrier on a range of slots that will no longer be
|
||||
* reachable.
|
||||
@ -699,12 +706,16 @@ struct JSObject : js::gc::Cell
|
||||
inline void prepareElementRangeForOverwrite(size_t start, size_t end);
|
||||
|
||||
/*
|
||||
* Copy a flat array of slots to this object at a start slot. Caller must
|
||||
* ensure there are enough slots in this object. If |valid|, then the slots
|
||||
* being overwritten hold valid data and must be invalidated for the write
|
||||
* barrier.
|
||||
* Initialize a flat array of slots to this object at a start slot. The
|
||||
* caller must ensure that are enough slots.
|
||||
*/
|
||||
void copySlotRange(size_t start, const js::Value *vector, size_t length, bool valid);
|
||||
void initSlotRange(size_t start, const js::Value *vector, size_t length);
|
||||
|
||||
/*
|
||||
* Copy a flat array of slots to this object at a start slot. Caller must
|
||||
* ensure there are enough slots in this object.
|
||||
*/
|
||||
void copySlotRange(size_t start, const js::Value *vector, size_t length);
|
||||
|
||||
inline uint32_t slotSpan() const;
|
||||
|
||||
|
@ -634,16 +634,18 @@ inline void
|
||||
JSObject::copyDenseArrayElements(uintN dstStart, const js::Value *src, uintN count)
|
||||
{
|
||||
JS_ASSERT(dstStart + count <= getDenseArrayCapacity());
|
||||
JSCompartment *comp = compartment();
|
||||
for (unsigned i = 0; i < count; ++i)
|
||||
elements[dstStart + i] = src[i];
|
||||
elements[dstStart + i].set(comp, src[i]);
|
||||
}
|
||||
|
||||
inline void
|
||||
JSObject::initDenseArrayElements(uintN dstStart, const js::Value *src, uintN count)
|
||||
{
|
||||
JS_ASSERT(dstStart + count <= getDenseArrayCapacity());
|
||||
JSCompartment *comp = compartment();
|
||||
for (unsigned i = 0; i < count; ++i)
|
||||
elements[dstStart + i].init(src[i]);
|
||||
elements[dstStart + i].init(comp, src[i]);
|
||||
}
|
||||
|
||||
inline void
|
||||
|
@ -165,8 +165,8 @@ inline void
|
||||
CallObject::copyValues(uintN nargs, Value *argv, uintN nvars, Value *slots)
|
||||
{
|
||||
JS_ASSERT(slotInRange(RESERVED_SLOTS + nargs + nvars, SENTINEL_ALLOWED));
|
||||
copySlotRange(RESERVED_SLOTS, argv, nargs, true);
|
||||
copySlotRange(RESERVED_SLOTS + nargs, slots, nvars, true);
|
||||
copySlotRange(RESERVED_SLOTS, argv, nargs);
|
||||
copySlotRange(RESERVED_SLOTS + nargs, slots, nvars);
|
||||
}
|
||||
|
||||
inline js::HeapValueArray
|
||||
|
Loading…
Reference in New Issue
Block a user