author | Jon Coppeard <jcoppeard@mozilla.com> |
Wed, 06 Sep 2017 09:07:09 +0100 | |
changeset 379295 | eb00a7039454986b07be0caab31063e7876dea57 |
parent 379294 | f80146e7ec85b8fd309b7b42f51032304136d835 |
child 379296 | 8d1a2ad4d81160488a7ec54cb0ed3abfa369ba77 |
push id | 32453 |
push user | archaeopteryx@coole-files.de |
push date | Thu, 07 Sep 2017 10:39:44 +0000 |
treeherder | mozilla-central@37b95547f0d2 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | sfink |
bugs | 1396931 |
milestone | 57.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/js/src/gc/Marking.cpp +++ b/js/src/gc/Marking.cpp @@ -2970,22 +2970,18 @@ js::TenuringTracer::moveObjectToTenured( // Move the slots and elements, if we need to. if (src->isNative()) { NativeObject* ndst = &dst->as<NativeObject>(); NativeObject* nsrc = &src->as<NativeObject>(); tenuredSize += moveSlotsToTenured(ndst, nsrc, dstKind); tenuredSize += moveElementsToTenured(ndst, nsrc, dstKind); - // The shape's list head may point into the old object. This can only - // happen for dictionaries, which are native objects. - if (&nsrc->shape_ == ndst->shape_->listp) { - MOZ_ASSERT(nsrc->shape_->inDictionary()); - ndst->shape_->listp = &ndst->shape_; - } + // There is a pointer into a dictionary mode object from the head of its + // 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);
--- a/js/src/gc/Nursery.cpp +++ b/js/src/gc/Nursery.cpp @@ -1074,11 +1074,13 @@ js::Nursery::queueDictionaryModeObjectTo } void js::Nursery::sweepDictionaryModeObjects() { for (auto obj : dictionaryModeObjects_) { if (!IsForwarded(obj)) obj->sweepDictionaryListPointer(); + else + Forwarded(obj)->updateDictionaryListPointerAfterMinorGC(obj); } dictionaryModeObjects_.clear(); }
--- a/js/src/jsobjinlines.h +++ b/js/src/jsobjinlines.h @@ -138,16 +138,27 @@ js::NativeObject::sweepDictionaryListPoi // For dictionary objects (which must be native), it's possible that // unreachable shapes may be marked whose listp points into this object. In // case this happens, null out the shape's pointer so that a moving GC will // not try to access the dead object. if (shape_->listp == &shape_) shape_->listp = nullptr; } +MOZ_ALWAYS_INLINE void +js::NativeObject::updateDictionaryListPointerAfterMinorGC(NativeObject* old) +{ + MOZ_ASSERT(this == Forwarded(old)); + + // Dictionary objects can be allocated in the nursery and when they are + // tenured the shape's pointer into the object needs to be updated. + if (shape_->listp == &old->shape_) + shape_->listp = &shape_; +} + /* static */ inline bool JSObject::setSingleton(JSContext* cx, js::HandleObject obj) { MOZ_ASSERT(!IsInsideNursery(obj)); js::ObjectGroup* group = js::ObjectGroup::lazySingletonGroup(cx, obj->getClass(), obj->taggedProto()); if (!group)
--- a/js/src/vm/NativeObject.h +++ b/js/src/vm/NativeObject.h @@ -1339,16 +1339,17 @@ class NativeObject : public ShapedObject } static inline NativeObject* copy(JSContext* cx, gc::AllocKind kind, gc::InitialHeap heap, HandleNativeObject templateObject); void updateShapeAfterMovingGC(); void sweepDictionaryListPointer(); + void updateDictionaryListPointerAfterMinorGC(NativeObject* old); /* JIT Accessors */ static size_t offsetOfElements() { return offsetof(NativeObject, elements_); } static size_t offsetOfFixedElements() { return sizeof(NativeObject) + sizeof(ObjectElements); } static size_t getFixedSlotOffset(size_t slot) {