Bug 1635185 - Part 2: Use the stored capacity for NativeObject::numDynamicSlots() r=jandem

This renames methods that calculate the required slot count to calculateDynamicSlots().

Differential Revision: https://phabricator.services.mozilla.com/D87597
This commit is contained in:
Jon Coppeard 2020-08-27 15:24:00 +00:00
Родитель 2e30498ca3
Коммит d73df31279
9 изменённых файлов: 40 добавлений и 30 удалений

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

@ -4688,8 +4688,8 @@ AttachDecision SetPropIRGenerator::tryAttachAddSlotStub(
trackAttached("AddSlot");
} else {
size_t offset = holder->dynamicSlotIndex(propShape->slot()) * sizeof(Value);
uint32_t numOldSlots = NativeObject::dynamicSlotsCount(oldShape);
uint32_t numNewSlots = NativeObject::dynamicSlotsCount(propShape);
uint32_t numOldSlots = NativeObject::calculateDynamicSlots(oldShape);
uint32_t numNewSlots = holder->numDynamicSlots();
if (numOldSlots == numNewSlots) {
writer.addAndStoreDynamicSlot(objId, offset, rhsValId, changeGroup,
newGroup, propShape);

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

@ -76,10 +76,7 @@ inline bool NativeTemplateObject::hasDynamicSlots() const {
}
inline uint32_t NativeTemplateObject::numDynamicSlots() const {
// We can't call numDynamicSlots because that uses shape->base->clasp and
// shape->base can change when we create a ShapeTable.
return NativeObject::dynamicSlotsCount(numFixedSlots(), slotSpan(),
obj_->getClass());
return asNative().numDynamicSlots();
}
inline uint32_t NativeTemplateObject::numUsedFixedSlots() const {

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

@ -50,7 +50,7 @@ inline void ArrayObject::setLength(JSContext* cx, uint32_t length) {
// which allow named properties to be stored in the fixed slots.
MOZ_ASSERT(shape->numFixedSlots() == 0);
size_t nDynamicSlots = dynamicSlotsCount(0, shape->slotSpan(), clasp);
size_t nDynamicSlots = calculateDynamicSlots(0, shape->slotSpan(), clasp);
JSObject* obj = js::AllocateObject(cx, kind, nDynamicSlots, heap, clasp);
if (!obj) {
return nullptr;

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

@ -98,8 +98,8 @@ inline JSFunction* CloneFunctionObjectIfNotSingleton(
MOZ_ASSERT(clasp->isJSFunction());
static constexpr size_t NumDynamicSlots = 0;
MOZ_ASSERT(dynamicSlotsCount(shape->numFixedSlots(), shape->slotSpan(),
clasp) == NumDynamicSlots);
MOZ_ASSERT(calculateDynamicSlots(shape->numFixedSlots(), shape->slotSpan(),
clasp) == NumDynamicSlots);
JSObject* obj = js::AllocateObject(cx, kind, NumDynamicSlots, heap, clasp);
if (!obj) {

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

@ -39,10 +39,16 @@ static inline gc::AllocKind NewObjectGCKind(const JSClass* clasp) {
} // namespace js
MOZ_ALWAYS_INLINE uint32_t js::NativeObject::numDynamicSlots() const {
return dynamicSlotsCount(numFixedSlots(), slotSpan(), getClass());
uint32_t slots = hasDynamicSlots() ? getSlotsHeader()->capacity() : 0;
MOZ_ASSERT(slots == calculateDynamicSlots());
return slots;
}
/* static */ MOZ_ALWAYS_INLINE uint32_t js::NativeObject::dynamicSlotsCount(
MOZ_ALWAYS_INLINE uint32_t js::NativeObject::calculateDynamicSlots() const {
return calculateDynamicSlots(numFixedSlots(), slotSpan(), getClass());
}
/* static */ MOZ_ALWAYS_INLINE uint32_t js::NativeObject::calculateDynamicSlots(
uint32_t nfixed, uint32_t span, const JSClass* clasp) {
if (span <= nfixed) {
return 0;
@ -66,9 +72,9 @@ MOZ_ALWAYS_INLINE uint32_t js::NativeObject::numDynamicSlots() const {
}
/* static */ MOZ_ALWAYS_INLINE uint32_t
js::NativeObject::dynamicSlotsCount(Shape* shape) {
return dynamicSlotsCount(shape->numFixedSlots(), shape->slotSpan(),
shape->getObjectClass());
js::NativeObject::calculateDynamicSlots(Shape* shape) {
return calculateDynamicSlots(shape->numFixedSlots(), shape->slotSpan(),
shape->getObjectClass());
}
inline void JSObject::finalize(JSFreeOp* fop) {

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

@ -1498,7 +1498,7 @@ bool NativeObject::fillInAfterSwap(JSContext* cx, HandleNativeObject obj,
}
if (size_t ndynamic =
dynamicSlotsCount(nfixed, values.length(), obj->getClass())) {
calculateDynamicSlots(nfixed, values.length(), obj->getClass())) {
HeapSlot* allocation =
cx->pod_malloc<HeapSlot>(ObjectSlots::allocCount(ndynamic));
if (!allocation) {

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

@ -510,7 +510,7 @@ inline bool NativeObject::isInWholeCellBuffer() const {
MOZ_ASSERT(!clasp->isJSFunction(), "should use JSFunction::create");
size_t nDynamicSlots =
dynamicSlotsCount(shape->numFixedSlots(), shape->slotSpan(), clasp);
calculateDynamicSlots(shape->numFixedSlots(), shape->slotSpan(), clasp);
JSObject* obj = js::AllocateObject(cx, kind, nDynamicSlots, heap, clasp);
if (!obj) {
@ -550,8 +550,8 @@ MOZ_ALWAYS_INLINE bool NativeObject::updateSlotsForSpan(JSContext* cx,
size_t newSpan) {
MOZ_ASSERT(oldSpan != newSpan);
size_t oldCount = dynamicSlotsCount(numFixedSlots(), oldSpan, getClass());
size_t newCount = dynamicSlotsCount(numFixedSlots(), newSpan, getClass());
size_t oldCount = numDynamicSlots();
size_t newCount = calculateDynamicSlots(numFixedSlots(), newSpan, getClass());
if (oldSpan < newSpan) {
if (oldCount < newCount && !growSlots(cx, oldCount, newCount)) {

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

@ -345,8 +345,11 @@ void NativeObject::setLastPropertyShrinkFixedSlots(Shape* shape) {
MOZ_ASSERT(newFixed < oldFixed);
MOZ_ASSERT(shape->slotSpan() <= oldFixed);
MOZ_ASSERT(shape->slotSpan() <= newFixed);
MOZ_ASSERT(dynamicSlotsCount(oldFixed, shape->slotSpan(), getClass()) == 0);
MOZ_ASSERT(dynamicSlotsCount(newFixed, shape->slotSpan(), getClass()) == 0);
MOZ_ASSERT(numDynamicSlots() == 0);
MOZ_ASSERT(calculateDynamicSlots(oldFixed, shape->slotSpan(), getClass()) ==
0);
MOZ_ASSERT(calculateDynamicSlots(newFixed, shape->slotSpan(), getClass()) ==
0);
setShape(shape);
}
@ -504,8 +507,12 @@ void NativeObject::shrinkSlots(JSContext* cx, uint32_t oldCapacity,
cx, this, reinterpret_cast<HeapSlot*>(oldHeaderSlots), oldAllocated,
newAllocated);
if (!allocation) {
// It's possible for realloc to fail when shrinking an allocation. In this
// case we continue using the original allocation but still update the
// capacity to the new requested capacity, which is smaller than the actual
// capacity.
cx->recoverFromOutOfMemory();
return; // Leave slots at its old size.
allocation = reinterpret_cast<HeapSlot*>(getSlotsHeader());
}
RemoveCellMemory(this, ObjectSlots::allocSize(oldCapacity),

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

@ -896,7 +896,9 @@ class NativeObject : public JSObject {
bool hasDynamicSlots() const { return !!slots_; }
/* Compute dynamicSlotsCount() for this object. */
/* Compute the number of dynamic slots required for this object. */
MOZ_ALWAYS_INLINE uint32_t calculateDynamicSlots() const;
MOZ_ALWAYS_INLINE uint32_t numDynamicSlots() const;
bool empty() const { return lastProperty()->isEmptyShape(); }
@ -1195,15 +1197,13 @@ class NativeObject : public JSObject {
}
/*
* Get the number of dynamic slots to allocate to cover the properties in
* an object with the given number of fixed slots and slot span. The slot
* capacity is not stored explicitly, and the allocated size of the slot
* array is kept in sync with this count.
* Calculate the number of dynamic slots to allocate to cover the properties
* in an object with the given number of fixed slots and slot span.
*/
static MOZ_ALWAYS_INLINE uint32_t dynamicSlotsCount(uint32_t nfixed,
uint32_t span,
const JSClass* clasp);
static MOZ_ALWAYS_INLINE uint32_t dynamicSlotsCount(Shape* shape);
static MOZ_ALWAYS_INLINE uint32_t calculateDynamicSlots(uint32_t nfixed,
uint32_t span,
const JSClass* clasp);
static MOZ_ALWAYS_INLINE uint32_t calculateDynamicSlots(Shape* shape);
ObjectSlots* getSlotsHeader() const { return ObjectSlots::fromSlots(slots_); }