Bug 1253461 - Fix race condition in Shape::fixupDictionaryShapeAfterMovingGC r=terrence

This commit is contained in:
Jon Coppeard 2016-03-08 17:14:34 +00:00
Родитель 1902f1c620
Коммит 461e16de02
1 изменённых файлов: 22 добавлений и 14 удалений

Просмотреть файл

@ -226,32 +226,40 @@ Shape::fixupDictionaryShapeAfterMovingGC()
if (!listp)
return;
// Get a fake cell pointer to use for the calls below. This might not point
// to the beginning of a cell, but will point into the right arena and will
// have the right alignment.
Cell* cell = reinterpret_cast<Cell*>(uintptr_t(listp) & ~CellMask);
// It's possible that this shape is unreachable and that listp points to the
// location of a dead object in the nursery, in which case we should never
// touch it again.
if (IsInsideNursery(cell)) {
if (IsInsideNursery(reinterpret_cast<Cell*>(listp))) {
listp = nullptr;
return;
}
// The listp field either points to the parent field of the next shape in
// the list if there is one. Otherwise if this shape is the last in the
// list then it points to the shape_ field of the object the list is for.
// We can tell which it is because the base shape is owned if this is the
// last property and not otherwise.
bool listpPointsIntoShape = !base()->isOwned();
#ifdef DEBUG
// Check that we got this right by interrogating the arena.
// We use a fake cell pointer for this: it might not point to the beginning
// of a cell, but will point into the right arena and will have the right
// alignment.
Cell* cell = reinterpret_cast<Cell*>(uintptr_t(listp) & ~CellMask);
AllocKind kind = TenuredCell::fromPointer(cell)->getAllocKind();
MOZ_ASSERT(kind == AllocKind::SHAPE ||
kind == AllocKind::ACCESSOR_SHAPE ||
IsObjectAllocKind(kind));
if (kind == AllocKind::SHAPE || kind == AllocKind::ACCESSOR_SHAPE) {
MOZ_ASSERT_IF(listpPointsIntoShape,
kind == AllocKind::SHAPE || kind == AllocKind::ACCESSOR_SHAPE);
MOZ_ASSERT_IF(!listpPointsIntoShape, IsObjectAllocKind(kind));
#endif
if (listpPointsIntoShape) {
// listp points to the parent field of the next shape.
Shape* next = reinterpret_cast<Shape*>(uintptr_t(listp) -
offsetof(Shape, parent));
Shape* next = reinterpret_cast<Shape*>(uintptr_t(listp) - offsetof(Shape, parent));
listp = &gc::MaybeForwarded(next)->parent;
} else {
// listp points to the shape_ field of an object.
JSObject* last = reinterpret_cast<JSObject*>(uintptr_t(listp) -
JSObject::offsetOfShape());
JSObject* last = reinterpret_cast<JSObject*>(uintptr_t(listp) - JSObject::offsetOfShape());
listp = &gc::MaybeForwarded(last)->as<NativeObject>().shape_;
}
}