#ifndef gc_ObjectKind_inl_h
#define gc_ObjectKind_inl_h
#include "vm/NativeObject.h"
namespace js {
namespace gc {
static inline bool CanBeFinalizedInBackground(AllocKind kind,
const Class* clasp) {
MOZ_ASSERT(IsObjectAllocKind(kind));
return (
!IsBackgroundFinalized(kind) &&
(!clasp->hasFinalize() || (clasp->flags & JSCLASS_BACKGROUND_FINALIZE)));
}
static inline AllocKind GetBackgroundAllocKind(AllocKind kind) {
MOZ_ASSERT(!IsBackgroundFinalized(kind));
MOZ_ASSERT(IsObjectAllocKind(kind));
return AllocKind(size_t(kind) + 1);
}
const size_t SLOTS_TO_THING_KIND_LIMIT = 17;
extern const AllocKind slotsToThingKind[];
static inline AllocKind GetGCObjectKind(size_t numSlots) {
if (numSlots >= SLOTS_TO_THING_KIND_LIMIT) {
return AllocKind::OBJECT16;
}
return slotsToThingKind[numSlots];
}
static inline AllocKind GetGCObjectKind(const Class* clasp) {
if (clasp == FunctionClassPtr) {
return AllocKind::FUNCTION;
}
MOZ_ASSERT(!clasp->isProxy(), "Proxies should use GetProxyGCObjectKind");
uint32_t nslots = JSCLASS_RESERVED_SLOTS(clasp);
if (clasp->flags & JSCLASS_HAS_PRIVATE) {
nslots++;
}
return GetGCObjectKind(nslots);
}
static inline AllocKind GetGCArrayKind(size_t numElements) {
JS_STATIC_ASSERT(ObjectElements::VALUES_PER_HEADER == 2);
if (numElements > NativeObject::MAX_DENSE_ELEMENTS_COUNT ||
numElements + ObjectElements::VALUES_PER_HEADER >=
SLOTS_TO_THING_KIND_LIMIT) {
return AllocKind::OBJECT2;
}
return slotsToThingKind[numElements + ObjectElements::VALUES_PER_HEADER];
}
static inline AllocKind GetGCObjectFixedSlotsKind(size_t numFixedSlots) {
MOZ_ASSERT(numFixedSlots < SLOTS_TO_THING_KIND_LIMIT);
return slotsToThingKind[numFixedSlots];
}
static inline AllocKind GetGCObjectKindForBytes(size_t nbytes) {
MOZ_ASSERT(nbytes <= JSObject::MAX_BYTE_SIZE);
if (nbytes <= sizeof(NativeObject)) {
return AllocKind::OBJECT0;
}
nbytes -= sizeof(NativeObject);
size_t dataSlots = AlignBytes(nbytes, sizeof(Value)) / sizeof(Value);
MOZ_ASSERT(nbytes <= dataSlots * sizeof(Value));
return GetGCObjectKind(dataSlots);
}
static inline size_t GetGCKindSlots(AllocKind thingKind) {
switch (thingKind) {
case AllocKind::FUNCTION:
case AllocKind::OBJECT0:
case AllocKind::OBJECT0_BACKGROUND:
return 0;
case AllocKind::FUNCTION_EXTENDED:
case AllocKind::OBJECT2:
case AllocKind::OBJECT2_BACKGROUND:
return 2;
case AllocKind::OBJECT4:
case AllocKind::OBJECT4_BACKGROUND:
return 4;
case AllocKind::OBJECT8:
case AllocKind::OBJECT8_BACKGROUND:
return 8;
case AllocKind::OBJECT12:
case AllocKind::OBJECT12_BACKGROUND:
return 12;
case AllocKind::OBJECT16:
case AllocKind::OBJECT16_BACKGROUND:
return 16;
default:
MOZ_CRASH("Bad object alloc kind");
}
}
static inline size_t GetGCKindSlots(AllocKind thingKind, const Class* clasp) {
size_t nslots = GetGCKindSlots(thingKind);
if (clasp->flags & JSCLASS_HAS_PRIVATE) {
MOZ_ASSERT(nslots > 0);
nslots--;
}
if (clasp == FunctionClassPtr) {
nslots = 0;
}
return nslots;
}
static inline size_t GetGCKindBytes(AllocKind thingKind) {
return sizeof(JSObject_Slots0) + GetGCKindSlots(thingKind) * sizeof(Value);
}
} }
#endif