Bug 1062473: Make JSObject::allocKindForTenure out of GetObjectAllocKindForCopy. r=terrence

This commit is contained in:
Jim Blandy 2015-04-01 17:57:41 -07:00
parent 17532b1ec3
commit bb74e19f0e
3 changed files with 66 additions and 62 deletions

View File

@ -411,67 +411,6 @@ class MinorCollectionTracer : public JS::CallbackTracer
} /* namespace gc */
} /* namespace js */
static AllocKind
GetObjectAllocKindForCopy(const Nursery& nursery, JSObject* obj)
{
if (obj->is<ArrayObject>()) {
ArrayObject* aobj = &obj->as<ArrayObject>();
MOZ_ASSERT(aobj->numFixedSlots() == 0);
/* Use minimal size object if we are just going to copy the pointer. */
if (!nursery.isInside(aobj->getElementsHeader()))
return AllocKind::OBJECT0_BACKGROUND;
size_t nelements = aobj->getDenseCapacity();
return GetBackgroundAllocKind(GetGCArrayKind(nelements));
}
if (obj->is<JSFunction>())
return obj->as<JSFunction>().getAllocKind();
/*
* Typed arrays in the nursery may have a lazily allocated buffer, make
* sure there is room for the array's fixed data when moving the array.
*/
if (obj->is<TypedArrayObject>() && !obj->as<TypedArrayObject>().buffer()) {
size_t nbytes = obj->as<TypedArrayObject>().byteLength();
return GetBackgroundAllocKind(TypedArrayObject::AllocKindForLazyBuffer(nbytes));
}
// Proxies have finalizers and are not nursery allocated.
MOZ_ASSERT(!IsProxy(obj));
// Unboxed plain objects are sized according to the data they store.
if (obj->is<UnboxedPlainObject>()) {
size_t nbytes = obj->as<UnboxedPlainObject>().layoutDontCheckGeneration().size();
return GetGCObjectKindForBytes(UnboxedPlainObject::offsetOfData() + nbytes);
}
// Inlined typed objects are followed by their data, so make sure we copy
// it all over to the new object.
if (obj->is<InlineTypedObject>()) {
// Figure out the size of this object, from the prototype's TypeDescr.
// The objects we are traversing here are all tenured, so we don't need
// to check forwarding pointers.
TypeDescr* descr = &obj->as<InlineTypedObject>().typeDescr();
MOZ_ASSERT(!IsInsideNursery(descr));
return InlineTypedObject::allocKindForTypeDescriptor(descr);
}
// Outline typed objects use the minimum allocation kind.
if (obj->is<OutlineTypedObject>())
return AllocKind::OBJECT0;
// All nursery allocatable non-native objects are handled above.
MOZ_ASSERT(obj->isNative());
AllocKind kind = GetGCObjectFixedSlotsKind(obj->as<NativeObject>().numFixedSlots());
MOZ_ASSERT(!IsBackgroundFinalized(kind));
if (!CanBeFinalizedInBackground(kind, obj->getClass()))
return kind;
return GetBackgroundAllocKind(kind);
}
MOZ_ALWAYS_INLINE TenuredCell*
js::Nursery::allocateFromTenured(Zone* zone, AllocKind thingKind)
{
@ -656,7 +595,7 @@ void*
js::Nursery::moveToTenured(MinorCollectionTracer* trc, JSObject* src)
{
AllocKind dstKind = GetObjectAllocKindForCopy(*this, src);
AllocKind dstKind = src->allocKindForTenure(*this);
Zone* zone = src->zone();
JSObject* dst = reinterpret_cast<JSObject*>(allocateFromTenured(zone, dstKind));
if (!dst)

View File

@ -3897,6 +3897,68 @@ js::DumpBacktrace(JSContext* cx)
/* * */
js::gc::AllocKind
JSObject::allocKindForTenure(const js::Nursery& nursery) const
{
if (is<ArrayObject>()) {
const ArrayObject& aobj = as<ArrayObject>();
MOZ_ASSERT(aobj.numFixedSlots() == 0);
/* Use minimal size object if we are just going to copy the pointer. */
if (!nursery.isInside(aobj.getElementsHeader()))
return AllocKind::OBJECT0_BACKGROUND;
size_t nelements = aobj.getDenseCapacity();
return GetBackgroundAllocKind(GetGCArrayKind(nelements));
}
if (is<JSFunction>())
return as<JSFunction>().getAllocKind();
/*
* Typed arrays in the nursery may have a lazily allocated buffer, make
* sure there is room for the array's fixed data when moving the array.
*/
if (is<TypedArrayObject>() && !as<TypedArrayObject>().buffer()) {
size_t nbytes = as<TypedArrayObject>().byteLength();
return GetBackgroundAllocKind(TypedArrayObject::AllocKindForLazyBuffer(nbytes));
}
// Proxies have finalizers and are not nursery allocated.
MOZ_ASSERT(!IsProxy(this));
// Unboxed plain objects are sized according to the data they store.
if (is<UnboxedPlainObject>()) {
size_t nbytes = as<UnboxedPlainObject>().layoutDontCheckGeneration().size();
return GetGCObjectKindForBytes(UnboxedPlainObject::offsetOfData() + nbytes);
}
// Inlined typed objects are followed by their data, so make sure we copy
// it all over to the new object.
if (is<InlineTypedObject>()) {
// Figure out the size of this object, from the prototype's TypeDescr.
// The objects we are traversing here are all tenured, so we don't need
// to check forwarding pointers.
TypeDescr& descr = as<InlineTypedObject>().typeDescr();
MOZ_ASSERT(!IsInsideNursery(&descr));
return InlineTypedObject::allocKindForTypeDescriptor(&descr);
}
// Outline typed objects use the minimum allocation kind.
if (is<OutlineTypedObject>())
return AllocKind::OBJECT0;
// All nursery allocatable non-native objects are handled above.
MOZ_ASSERT(isNative());
AllocKind kind = GetGCObjectFixedSlotsKind(as<NativeObject>().numFixedSlots());
MOZ_ASSERT(!IsBackgroundFinalized(kind));
if (!CanBeFinalizedInBackground(kind, getClass()))
return kind;
return GetBackgroundAllocKind(kind);
}
void
JSObject::addSizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf, JS::ClassInfo* info)
{

View File

@ -289,6 +289,9 @@ class JSObject : public js::gc::Cell
static MOZ_ALWAYS_INLINE void writeBarrierPostRelocate(JSObject* obj, void* cellp);
static MOZ_ALWAYS_INLINE void writeBarrierPostRemove(JSObject* obj, void* cellp);
/* Return the allocKind we would use if we were to tenure this object. */
js::gc::AllocKind allocKindForTenure(const js::Nursery &nursery) const;
size_t tenuredSizeOfThis() const {
MOZ_ASSERT(isTenured());
return js::gc::Arena::thingSize(asTenured().getAllocKind());