From bb74e19f0eb7ce1657da1d3ea0b75895fb7d67dd Mon Sep 17 00:00:00 2001 From: Jim Blandy Date: Wed, 1 Apr 2015 17:57:41 -0700 Subject: [PATCH] Bug 1062473: Make JSObject::allocKindForTenure out of GetObjectAllocKindForCopy. r=terrence --- js/src/gc/Nursery.cpp | 63 +------------------------------------------ js/src/jsobj.cpp | 62 ++++++++++++++++++++++++++++++++++++++++++ js/src/jsobj.h | 3 +++ 3 files changed, 66 insertions(+), 62 deletions(-) diff --git a/js/src/gc/Nursery.cpp b/js/src/gc/Nursery.cpp index 1c2b6f9228f..8209b54cf20 100644 --- a/js/src/gc/Nursery.cpp +++ b/js/src/gc/Nursery.cpp @@ -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* aobj = &obj->as(); - 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()) - return obj->as().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() && !obj->as().buffer()) { - size_t nbytes = obj->as().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()) { - size_t nbytes = obj->as().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()) { - // 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().typeDescr(); - MOZ_ASSERT(!IsInsideNursery(descr)); - return InlineTypedObject::allocKindForTypeDescriptor(descr); - } - - // Outline typed objects use the minimum allocation kind. - if (obj->is()) - return AllocKind::OBJECT0; - - // All nursery allocatable non-native objects are handled above. - MOZ_ASSERT(obj->isNative()); - - AllocKind kind = GetGCObjectFixedSlotsKind(obj->as().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(allocateFromTenured(zone, dstKind)); if (!dst) diff --git a/js/src/jsobj.cpp b/js/src/jsobj.cpp index 29cfba90fd4..e20f67c81d2 100644 --- a/js/src/jsobj.cpp +++ b/js/src/jsobj.cpp @@ -3897,6 +3897,68 @@ js::DumpBacktrace(JSContext* cx) /* * */ +js::gc::AllocKind +JSObject::allocKindForTenure(const js::Nursery& nursery) const +{ + if (is()) { + const ArrayObject& aobj = as(); + 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()) + return as().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() && !as().buffer()) { + size_t nbytes = as().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()) { + size_t nbytes = as().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()) { + // 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().typeDescr(); + MOZ_ASSERT(!IsInsideNursery(&descr)); + return InlineTypedObject::allocKindForTypeDescriptor(&descr); + } + + // Outline typed objects use the minimum allocation kind. + if (is()) + return AllocKind::OBJECT0; + + // All nursery allocatable non-native objects are handled above. + MOZ_ASSERT(isNative()); + + AllocKind kind = GetGCObjectFixedSlotsKind(as().numFixedSlots()); + MOZ_ASSERT(!IsBackgroundFinalized(kind)); + if (!CanBeFinalizedInBackground(kind, getClass())) + return kind; + return GetBackgroundAllocKind(kind); +} + + void JSObject::addSizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf, JS::ClassInfo* info) { diff --git a/js/src/jsobj.h b/js/src/jsobj.h index 7a075c6f392..a4162e4b303 100644 --- a/js/src/jsobj.h +++ b/js/src/jsobj.h @@ -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());