Bug 1124563 - Fixup base shape table after moving GC r=terrence

This commit is contained in:
Jon Coppeard 2015-01-29 09:58:06 +00:00
parent 3b846be591
commit dab1fbf356
6 changed files with 57 additions and 10 deletions

View File

@ -0,0 +1,4 @@
try {
gc(0, 'shrinking')({x: 0})
} catch (e) {}
eval("({x: 0, x: 0})[{x: 0}]")

View File

@ -60,6 +60,12 @@ static const js::Class NurseryClass = {
BEGIN_TEST(testGCNurseryFinalizer)
{
#ifdef JS_GC_ZEAL
// Running extra GCs during this test will make us get incorrect
// finalization counts.
AutoLeaveZeal nozeal(cx);
#endif /* JS_GC_ZEAL */
JS::RootedObject obj(cx);
obj = JS_NewObject(cx, Jsvalify(&TenuredClass), JS::NullPtr(), JS::NullPtr());

View File

@ -655,6 +655,7 @@ void JSCompartment::fixupAfterMovingGC()
fixupNewTypeObjectTable(newTypeObjects);
fixupNewTypeObjectTable(lazyTypeObjects);
fixupInitialShapeTable();
fixupBaseShapeTable();
}
void

View File

@ -402,6 +402,7 @@ struct JSCompartment
void fixupNewTypeObjectTable(js::types::NewTypeObjectTable &table);
void fixupAfterMovingGC();
void fixupGlobal();
void fixupBaseShapeTable();
bool hasObjectMetadataCallback() const { return objectMetadataCallback; }
void setObjectMetadataCallback(js::ObjectMetadataCallback callback);

View File

@ -1361,19 +1361,53 @@ BaseShape::assertConsistency()
#endif
}
bool
BaseShape::fixupBaseShapeTableEntry()
{
bool updated = false;
if (parent && IsForwarded(parent.get())) {
parent = Forwarded(parent.get());
updated = true;
}
if (metadata && IsForwarded(metadata.get())) {
metadata = Forwarded(metadata.get());
updated = true;
}
return updated;
}
void
JSCompartment::fixupBaseShapeTable()
{
if (!baseShapes.initialized())
return;
for (BaseShapeSet::Enum e(baseShapes); !e.empty(); e.popFront()) {
UnownedBaseShape *base = e.front().unbarrieredGet();
if (base->fixupBaseShapeTableEntry()) {
StackBaseShape sbase(base);
ReadBarriered<UnownedBaseShape *> b(base);
e.rekeyFront(&sbase, b);
}
}
}
void
JSCompartment::sweepBaseShapeTable()
{
if (baseShapes.initialized()) {
for (BaseShapeSet::Enum e(baseShapes); !e.empty(); e.popFront()) {
UnownedBaseShape *base = e.front().unbarrieredGet();
if (IsBaseShapeAboutToBeFinalizedFromAnyThread(&base)) {
e.removeFront();
} else if (base != e.front().unbarrieredGet()) {
StackBaseShape sbase(base);
ReadBarriered<UnownedBaseShape *> b(base);
e.rekeyFront(&sbase, b);
}
if (!baseShapes.initialized())
return;
for (BaseShapeSet::Enum e(baseShapes); !e.empty(); e.popFront()) {
UnownedBaseShape *base = e.front().unbarrieredGet();
MOZ_ASSERT_IF(base->getObjectParent(), !IsForwarded(base->getObjectParent()));
MOZ_ASSERT_IF(base->getObjectMetadata(), !IsForwarded(base->getObjectMetadata()));
if (IsBaseShapeAboutToBeFinalizedFromAnyThread(&base)) {
e.removeFront();
} else if (base != e.front().unbarrieredGet()) {
StackBaseShape sbase(base);
ReadBarriered<UnownedBaseShape *> b(base);
e.rekeyFront(&sbase, b);
}
}
}

View File

@ -533,6 +533,7 @@ class BaseShape : public gc::TenuredCell
}
void fixupAfterMovingGC();
bool fixupBaseShapeTableEntry();
private:
static void staticAsserts() {