mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-17 23:35:34 +00:00
Bug 1396613 - Replace special cases with use of objectMoved hook when tenuring r=sfink
This commit is contained in:
parent
1077972535
commit
2a663c4c5a
@ -2126,9 +2126,12 @@ InlineTypedObject::obj_trace(JSTracer* trc, JSObject* object)
|
||||
typedObj.typeDescr().traceInstances(trc, typedObj.inlineTypedMem(), 1);
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
InlineTypedObject::objectMovedDuringMinorGC(JSTracer* trc, JSObject* dst, JSObject* src)
|
||||
/* static */ size_t
|
||||
InlineTypedObject::obj_moved(JSObject* dst, JSObject* src)
|
||||
{
|
||||
if (!IsInsideNursery(src))
|
||||
return 0;
|
||||
|
||||
// Inline typed object element arrays can be preserved on the stack by Ion
|
||||
// and need forwarding pointers created during a minor GC. We can't do this
|
||||
// in the trace hook because we don't have any stale data to determine
|
||||
@ -2140,9 +2143,12 @@ InlineTypedObject::objectMovedDuringMinorGC(JSTracer* trc, JSObject* dst, JSObje
|
||||
// but they will not set any direct forwarding pointers.
|
||||
uint8_t* oldData = reinterpret_cast<uint8_t*>(src) + offsetOfDataStart();
|
||||
uint8_t* newData = dst->as<InlineTypedObject>().inlineTypedMem();
|
||||
dst->zone()->group()->nursery().maybeSetForwardingPointer(trc, oldData, newData,
|
||||
descr.size() >= sizeof(uintptr_t));
|
||||
auto& nursery = dst->zone()->group()->nursery();
|
||||
bool direct = descr.size() >= sizeof(uintptr_t);
|
||||
nursery.setForwardingPointerWhileTenuring(oldData, newData, direct);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ArrayBufferObject*
|
||||
@ -2219,7 +2225,7 @@ const ObjectOps TypedObject::objectOps_ = {
|
||||
nullptr, /* thisValue */
|
||||
};
|
||||
|
||||
#define DEFINE_TYPEDOBJ_CLASS(Name, Trace, flag) \
|
||||
#define DEFINE_TYPEDOBJ_CLASS(Name, Trace, Moved, flag) \
|
||||
static const ClassOps Name##ClassOps = { \
|
||||
nullptr, /* addProperty */ \
|
||||
nullptr, /* delProperty */ \
|
||||
@ -2233,20 +2239,34 @@ const ObjectOps TypedObject::objectOps_ = {
|
||||
nullptr, /* construct */ \
|
||||
Trace, \
|
||||
}; \
|
||||
static const ClassExtension Name##ClassExt = { \
|
||||
nullptr, /* weakmapKeyDelegateOp */ \
|
||||
Moved /* objectMovedOp */ \
|
||||
}; \
|
||||
const Class Name::class_ = { \
|
||||
# Name, \
|
||||
Class::NON_NATIVE | flag, \
|
||||
&Name##ClassOps, \
|
||||
JS_NULL_CLASS_SPEC, \
|
||||
JS_NULL_CLASS_EXT, \
|
||||
&Name##ClassExt, \
|
||||
&TypedObject::objectOps_ \
|
||||
}
|
||||
|
||||
DEFINE_TYPEDOBJ_CLASS(OutlineTransparentTypedObject, OutlineTypedObject::obj_trace, 0);
|
||||
DEFINE_TYPEDOBJ_CLASS(OutlineOpaqueTypedObject, OutlineTypedObject::obj_trace, 0);
|
||||
DEFINE_TYPEDOBJ_CLASS(InlineTransparentTypedObject, InlineTypedObject::obj_trace,
|
||||
DEFINE_TYPEDOBJ_CLASS(OutlineTransparentTypedObject,
|
||||
OutlineTypedObject::obj_trace,
|
||||
nullptr,
|
||||
0);
|
||||
DEFINE_TYPEDOBJ_CLASS(OutlineOpaqueTypedObject,
|
||||
OutlineTypedObject::obj_trace,
|
||||
nullptr,
|
||||
0);
|
||||
DEFINE_TYPEDOBJ_CLASS(InlineTransparentTypedObject,
|
||||
InlineTypedObject::obj_trace,
|
||||
InlineTypedObject::obj_moved,
|
||||
JSCLASS_DELAY_METADATA_BUILDER);
|
||||
DEFINE_TYPEDOBJ_CLASS(InlineOpaqueTypedObject, InlineTypedObject::obj_trace,
|
||||
DEFINE_TYPEDOBJ_CLASS(InlineOpaqueTypedObject,
|
||||
InlineTypedObject::obj_trace,
|
||||
InlineTypedObject::obj_moved,
|
||||
JSCLASS_DELAY_METADATA_BUILDER);
|
||||
|
||||
static int32_t
|
||||
|
@ -723,7 +723,7 @@ class InlineTypedObject : public TypedObject
|
||||
}
|
||||
|
||||
static void obj_trace(JSTracer* trace, JSObject* object);
|
||||
static void objectMovedDuringMinorGC(JSTracer* trc, JSObject* dst, JSObject* src);
|
||||
static size_t obj_moved(JSObject* dst, JSObject* src);
|
||||
|
||||
static size_t offsetOfDataStart() {
|
||||
return offsetof(InlineTypedObject, data_);
|
||||
|
@ -2976,15 +2976,10 @@ js::TenuringTracer::moveObjectToTenured(JSObject* dst, JSObject* src, AllocKind
|
||||
// shape list. This is updated in Nursery::sweepDictionaryModeObjects().
|
||||
}
|
||||
|
||||
if (src->is<InlineTypedObject>()) {
|
||||
InlineTypedObject::objectMovedDuringMinorGC(this, dst, src);
|
||||
} else if (src->is<TypedArrayObject>()) {
|
||||
tenuredSize += TypedArrayObject::objectMovedDuringMinorGC(this, dst, src, dstKind);
|
||||
} else if (src->is<UnboxedArrayObject>()) {
|
||||
tenuredSize += UnboxedArrayObject::objectMovedDuringMinorGC(this, dst, src, dstKind);
|
||||
} else if (src->is<ArgumentsObject>()) {
|
||||
tenuredSize += ArgumentsObject::objectMovedDuringMinorGC(this, dst, src);
|
||||
} else if (src->is<ProxyObject>()) {
|
||||
if (src->is<ProxyObject>()) {
|
||||
// TODO: Push this logic into proxy_ObjectMoved and make all proxies use
|
||||
// this.
|
||||
|
||||
// Objects in the nursery are never swapped so the proxy must have an
|
||||
// inline ProxyValueArray.
|
||||
MOZ_ASSERT(src->as<ProxyObject>().usingInlineValueArray());
|
||||
|
@ -217,7 +217,12 @@ class Nursery
|
||||
void forwardBufferPointer(HeapSlot** pSlotsElems);
|
||||
|
||||
void maybeSetForwardingPointer(JSTracer* trc, void* oldData, void* newData, bool direct) {
|
||||
if (trc->isTenuringTracer() && isInside(oldData))
|
||||
if (trc->isTenuringTracer())
|
||||
setForwardingPointerWhileTenuring(oldData, newData, direct);
|
||||
}
|
||||
|
||||
void setForwardingPointerWhileTenuring(void* oldData, void* newData, bool direct) {
|
||||
if (isInside(oldData))
|
||||
setForwardingPointer(oldData, newData, direct);
|
||||
}
|
||||
|
||||
|
@ -855,12 +855,15 @@ ArgumentsObject::trace(JSTracer* trc, JSObject* obj)
|
||||
}
|
||||
|
||||
/* static */ size_t
|
||||
ArgumentsObject::objectMovedDuringMinorGC(JSTracer* trc, JSObject* dst, JSObject* src)
|
||||
ArgumentsObject::objectMoved(JSObject* dst, JSObject* src)
|
||||
{
|
||||
ArgumentsObject* ndst = &dst->as<ArgumentsObject>();
|
||||
ArgumentsObject* nsrc = &src->as<ArgumentsObject>();
|
||||
const ArgumentsObject* nsrc = &src->as<ArgumentsObject>();
|
||||
MOZ_ASSERT(ndst->data() == nsrc->data());
|
||||
|
||||
if (!IsInsideNursery(src))
|
||||
return 0;
|
||||
|
||||
Nursery& nursery = dst->zone()->group()->nursery();
|
||||
|
||||
size_t nbytesTotal = 0;
|
||||
@ -917,6 +920,11 @@ const ClassOps MappedArgumentsObject::classOps_ = {
|
||||
ArgumentsObject::trace
|
||||
};
|
||||
|
||||
const js::ClassExtension MappedArgumentsObject::classExt_ = {
|
||||
nullptr, /* weakmapKeyDelegateOp */
|
||||
ArgumentsObject::objectMoved /* objectMovedOp */
|
||||
};
|
||||
|
||||
const ObjectOps MappedArgumentsObject::objectOps_ = {
|
||||
nullptr, /* lookupProperty */
|
||||
MappedArgumentsObject::obj_defineProperty
|
||||
@ -931,7 +939,7 @@ const Class MappedArgumentsObject::class_ = {
|
||||
JSCLASS_BACKGROUND_FINALIZE,
|
||||
&MappedArgumentsObject::classOps_,
|
||||
nullptr,
|
||||
nullptr,
|
||||
&MappedArgumentsObject::classExt_,
|
||||
&MappedArgumentsObject::objectOps_
|
||||
};
|
||||
|
||||
@ -953,6 +961,11 @@ const ClassOps UnmappedArgumentsObject::classOps_ = {
|
||||
ArgumentsObject::trace
|
||||
};
|
||||
|
||||
const js::ClassExtension UnmappedArgumentsObject::classExt_ = {
|
||||
nullptr, /* weakmapKeyDelegateOp */
|
||||
ArgumentsObject::objectMoved /* objectMovedOp */
|
||||
};
|
||||
|
||||
const Class UnmappedArgumentsObject::class_ = {
|
||||
"Arguments",
|
||||
JSCLASS_DELAY_METADATA_BUILDER |
|
||||
@ -960,5 +973,7 @@ const Class UnmappedArgumentsObject::class_ = {
|
||||
JSCLASS_HAS_CACHED_PROTO(JSProto_Object) |
|
||||
JSCLASS_SKIP_NURSERY_FINALIZE |
|
||||
JSCLASS_BACKGROUND_FINALIZE,
|
||||
&UnmappedArgumentsObject::classOps_
|
||||
&UnmappedArgumentsObject::classOps_,
|
||||
nullptr,
|
||||
&UnmappedArgumentsObject::classExt_
|
||||
};
|
||||
|
@ -361,7 +361,7 @@ class ArgumentsObject : public NativeObject
|
||||
|
||||
static void finalize(FreeOp* fop, JSObject* obj);
|
||||
static void trace(JSTracer* trc, JSObject* obj);
|
||||
static size_t objectMovedDuringMinorGC(JSTracer* trc, JSObject* dst, JSObject* src);
|
||||
static size_t objectMoved(JSObject* dst, JSObject* src);
|
||||
|
||||
/* For jit use: */
|
||||
static size_t getDataSlotOffset() {
|
||||
@ -399,6 +399,7 @@ class ArgumentsObject : public NativeObject
|
||||
class MappedArgumentsObject : public ArgumentsObject
|
||||
{
|
||||
static const ClassOps classOps_;
|
||||
static const ClassExtension classExt_;
|
||||
static const ObjectOps objectOps_;
|
||||
|
||||
public:
|
||||
@ -428,6 +429,7 @@ class MappedArgumentsObject : public ArgumentsObject
|
||||
class UnmappedArgumentsObject : public ArgumentsObject
|
||||
{
|
||||
static const ClassOps classOps_;
|
||||
static const ClassExtension classExt_;
|
||||
|
||||
public:
|
||||
static const Class class_;
|
||||
|
@ -184,25 +184,7 @@ TypedArrayObject::finalize(FreeOp* fop, JSObject* obj)
|
||||
TypedArrayObject::objectMoved(JSObject* obj, JSObject* old)
|
||||
{
|
||||
TypedArrayObject* newObj = &obj->as<TypedArrayObject>();
|
||||
const TypedArrayObject* oldObj = &old->as<TypedArrayObject>();
|
||||
|
||||
// Typed arrays with a buffer object do not need an update.
|
||||
if (oldObj->hasBuffer())
|
||||
return 0;
|
||||
|
||||
// Update the data slot pointer if it points to the old JSObject.
|
||||
if (oldObj->hasInlineElements())
|
||||
newObj->setInlineElements();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* static */ size_t
|
||||
TypedArrayObject::objectMovedDuringMinorGC(JSTracer* trc, JSObject* obj, const JSObject* old,
|
||||
gc::AllocKind newAllocKind)
|
||||
{
|
||||
TypedArrayObject* newObj = &obj->as<TypedArrayObject>();
|
||||
const TypedArrayObject* oldObj = &old->as<TypedArrayObject>();
|
||||
TypedArrayObject* oldObj = &old->as<TypedArrayObject>();
|
||||
MOZ_ASSERT(newObj->elementsRaw() == oldObj->elementsRaw());
|
||||
MOZ_ASSERT(obj->isTenured());
|
||||
|
||||
@ -210,6 +192,14 @@ TypedArrayObject::objectMovedDuringMinorGC(JSTracer* trc, JSObject* obj, const J
|
||||
if (oldObj->hasBuffer())
|
||||
return 0;
|
||||
|
||||
if (!IsInsideNursery(old)) {
|
||||
// Update the data slot pointer if it points to the old JSObject.
|
||||
if (oldObj->hasInlineElements())
|
||||
newObj->setInlineElements();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Nursery& nursery = obj->zone()->group()->nursery();
|
||||
void* buf = oldObj->elements();
|
||||
|
||||
@ -236,6 +226,7 @@ JS_FOR_EACH_TYPED_ARRAY(OBJECT_MOVED_TYPED_ARRAY)
|
||||
size_t headerSize = dataOffset() + sizeof(HeapSlot);
|
||||
|
||||
// See AllocKindForLazyBuffer.
|
||||
AllocKind newAllocKind = obj->asTenured().getAllocKind();
|
||||
MOZ_ASSERT_IF(nbytes == 0, headerSize + sizeof(uint8_t) <= GetGCKindBytes(newAllocKind));
|
||||
|
||||
if (headerSize + nbytes <= GetGCKindBytes(newAllocKind)) {
|
||||
@ -262,8 +253,8 @@ JS_FOR_EACH_TYPED_ARRAY(OBJECT_MOVED_TYPED_ARRAY)
|
||||
|
||||
// Set a forwarding pointer for the element buffers in case they were
|
||||
// preserved on the stack by Ion.
|
||||
nursery.maybeSetForwardingPointer(trc, oldObj->elements(), newObj->elements(),
|
||||
/* direct = */nbytes >= sizeof(uintptr_t));
|
||||
nursery.setForwardingPointerWhileTenuring(oldObj->elements(), newObj->elements(),
|
||||
/* direct = */nbytes >= sizeof(uintptr_t));
|
||||
|
||||
return newObj->hasInlineElements() ? 0 : nbytes;
|
||||
}
|
||||
|
@ -274,8 +274,6 @@ class TypedArrayObject : public NativeObject
|
||||
static void trace(JSTracer* trc, JSObject* obj);
|
||||
static void finalize(FreeOp* fop, JSObject* obj);
|
||||
static size_t objectMoved(JSObject* obj, JSObject* old);
|
||||
static size_t objectMovedDuringMinorGC(JSTracer* trc, JSObject* obj, const JSObject* old,
|
||||
gc::AllocKind allocKind);
|
||||
|
||||
/* Initialization bits */
|
||||
|
||||
|
@ -1203,19 +1203,6 @@ UnboxedArrayObject::trace(JSTracer* trc, JSObject* obj)
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ size_t
|
||||
UnboxedArrayObject::objectMoved(JSObject* obj, JSObject* old)
|
||||
{
|
||||
UnboxedArrayObject& dst = obj->as<UnboxedArrayObject>();
|
||||
const UnboxedArrayObject& src = old->as<UnboxedArrayObject>();
|
||||
|
||||
// Fix up possible inline data pointer.
|
||||
if (src.hasInlineElements())
|
||||
dst.setInlineElements();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
UnboxedArrayObject::finalize(FreeOp* fop, JSObject* obj)
|
||||
{
|
||||
@ -1225,15 +1212,21 @@ UnboxedArrayObject::finalize(FreeOp* fop, JSObject* obj)
|
||||
}
|
||||
|
||||
/* static */ size_t
|
||||
UnboxedArrayObject::objectMovedDuringMinorGC(JSTracer* trc, JSObject* dst, JSObject* src,
|
||||
gc::AllocKind allocKind)
|
||||
UnboxedArrayObject::objectMoved(JSObject* dst, JSObject* src)
|
||||
{
|
||||
UnboxedArrayObject* ndst = &dst->as<UnboxedArrayObject>();
|
||||
UnboxedArrayObject* nsrc = &src->as<UnboxedArrayObject>();
|
||||
MOZ_ASSERT(ndst->elements() == nsrc->elements());
|
||||
|
||||
Nursery& nursery = dst->zone()->group()->nursery();
|
||||
if (!IsInsideNursery(src)) {
|
||||
// Fix up possible inline data pointer.
|
||||
if (nsrc->hasInlineElements())
|
||||
ndst->setInlineElements();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Nursery& nursery = dst->zone()->group()->nursery();
|
||||
if (!nursery.isInside(nsrc->elements())) {
|
||||
nursery.removeMallocedBuffer(nsrc->elements());
|
||||
return 0;
|
||||
@ -1243,7 +1236,8 @@ UnboxedArrayObject::objectMovedDuringMinorGC(JSTracer* trc, JSObject* dst, JSObj
|
||||
// possible, the nursery will have picked an allocation size that is large
|
||||
// enough.
|
||||
size_t nbytes = nsrc->capacity() * nsrc->elementSize();
|
||||
if (offsetOfInlineElements() + nbytes <= GetGCKindBytes(allocKind)) {
|
||||
gc::AllocKind allocKind = dst->asTenured().getAllocKind();
|
||||
if (offsetOfInlineElements() + nbytes <= gc::GetGCKindBytes(allocKind)) {
|
||||
ndst->setInlineElements();
|
||||
} else {
|
||||
MOZ_ASSERT(allocKind == gc::AllocKind::OBJECT0);
|
||||
@ -1260,7 +1254,7 @@ UnboxedArrayObject::objectMovedDuringMinorGC(JSTracer* trc, JSObject* dst, JSObj
|
||||
// Set a forwarding pointer for the element buffers in case they were
|
||||
// preserved on the stack by Ion.
|
||||
bool direct = nsrc->capacity() * nsrc->elementSize() >= sizeof(uintptr_t);
|
||||
nursery.maybeSetForwardingPointer(trc, nsrc->elements(), ndst->elements(), direct);
|
||||
nursery.setForwardingPointerWhileTenuring(nsrc->elements(), ndst->elements(), direct);
|
||||
|
||||
return ndst->hasInlineElements() ? 0 : nbytes;
|
||||
}
|
||||
|
@ -446,9 +446,6 @@ class UnboxedArrayObject : public UnboxedObject
|
||||
static size_t objectMoved(JSObject* obj, JSObject* old);
|
||||
static void finalize(FreeOp* fop, JSObject* obj);
|
||||
|
||||
static size_t objectMovedDuringMinorGC(JSTracer* trc, JSObject* dst, JSObject* src,
|
||||
gc::AllocKind allocKind);
|
||||
|
||||
uint8_t* elements() {
|
||||
return elements_;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user