/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- * vim: set ts=8 sts=2 et sw=2 tw=80:
*/ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
bool TestInternalWeakMaps() { for (auto keyMarkColor : AllCellColors) { for (auto delegateMarkColor : AllCellColors) { if (keyMarkColor == CellColor::White &&
delegateMarkColor == CellColor::White) { continue;
}
// The map is black. The delegate marks its key via wrapper preservation. // The key maps its delegate and the value. Thus, all three end up the // maximum of the key and delegate colors.
CellColor expected = std::max(keyMarkColor, delegateMarkColor);
CHECK(TestInternalWeakMap(keyMarkColor, delegateMarkColor, expected));
// Test marking a JS WeakMap object. // // This marks the map and one of the key or delegate. The key/delegate and the // value can end up different colors depending on the color of the map.
// If both map and key are marked the same color, test both possible // orderings. unsigned markOrderings = weakMapMarkColor == keyOrDelegateMarkColor ? 2 : 1;
bool TestJSWeakMapWithGrayUnmarking(MarkKeyOrDelegate markKey,
CellColor weakMapMarkColor,
CellColor keyOrDelegateMarkColor,
CellColor expectedValueColor) { // This is like the previous test, but things are marked black by gray // unmarking during incremental GC.
// If both map and key are marked the same color, test both possible // orderings. unsigned markOrderings = weakMapMarkColor == keyOrDelegateMarkColor ? 2 : 1;
// Start an incremental GC and run until gray roots have been pushed onto // the mark stack.
JS::PrepareForFullGC(cx);
JS::SliceBudget budget(JS::TimeBudget(1000000));
JS::StartIncrementalGC(cx, JS::GCOptions::Normal, JS::GCReason::DEBUG_GC,
budget);
MOZ_ASSERT(cx->runtime()->gc.state() == gc::State::Sweep);
MOZ_ASSERT(cx->zone()->gcState() == Zone::MarkBlackAndGray);
// Unmark gray things as specified. if (markOrder != 0) {
MaybeExposeObject(weakMap, weakMapMarkColor);
MaybeExposeObject(keyOrDelegate, keyOrDelegateMarkColor);
} else {
MaybeExposeObject(keyOrDelegate, keyOrDelegateMarkColor);
MaybeExposeObject(weakMap, weakMapMarkColor);
}
// If both key and delegate are marked the same color, test both possible // orderings. unsigned markOrderings = keyMarkColor == delegateMarkColor ? 2 : 1;
// If both key and delegate are marked the same color, test both possible // orderings. unsigned markOrderings = keyMarkColor == delegateMarkColor ? 2 : 1;
// Start an incremental GC and run until gray roots have been pushed onto // the mark stack.
JS::PrepareForFullGC(cx);
JS::SliceBudget budget(JS::TimeBudget(1000000));
JS::StartIncrementalGC(cx, JS::GCOptions::Normal, JS::GCReason::DEBUG_GC,
budget);
MOZ_ASSERT(cx->runtime()->gc.state() == gc::State::Sweep);
MOZ_ASSERT(cx->zone()->gcState() == Zone::MarkBlackAndGray);
// Unmark gray things as specified. if (markOrder != 0) {
MaybeExposeObject(key, keyMarkColor);
MaybeExposeObject(delegate, delegateMarkColor);
} else {
MaybeExposeObject(key, keyMarkColor);
MaybeExposeObject(delegate, delegateMarkColor);
}
// Test behaviour of gray CCWs marked black by a barrier during incremental // GC.
// Initial state: source and target are gray.
blackRoot = nullptr;
grayRoots.grayRoot1 = wrapper;
grayRoots.grayRoot2 = nullptr;
JS_GC(cx);
CHECK(IsMarkedGray(wrapper));
CHECK(IsMarkedGray(target));
// Incremental zone GC started: the source is now unmarked.
JS::PrepareZoneForGC(cx, wrapper->zone());
budget = JS::SliceBudget(JS::WorkBudget(1));
rt->gc.startDebugGC(JS::GCOptions::Normal, budget); while (rt->gc.state() == gc::State::Prepare) {
rt->gc.debugGCSlice(budget);
}
CHECK(JS::IsIncrementalGCInProgress(cx));
CHECK(wrapper->zone()->isGCMarkingBlackOnly());
CHECK(!target->zone()->wasGCStarted());
CHECK(!IsMarkedBlack(wrapper));
CHECK(!IsMarkedGray(wrapper));
CHECK(IsMarkedGray(target));
// Betweeen GC slices: source marked black by barrier, target is // still gray. Target will be marked gray // eventually. ObjectIsMarkedGray() is conservative and reports // that target is not marked gray; AssertObjectIsNotGray() will // assert.
grayRoots.grayRoot1.get();
CHECK(IsMarkedBlack(wrapper));
CHECK(IsMarkedGray(target));
CHECK(!JS::ObjectIsMarkedGray(target));
// Final state: source and target are black.
JS::FinishIncrementalGC(cx, JS::GCReason::API);
CHECK(IsMarkedBlack(wrapper));
CHECK(IsMarkedBlack(target));
booloperator()(JSObject* obj) { if (!CheckCellColor(obj, color)) { returnfalse;
}
NativeObject& nobj = obj->as<NativeObject>(); if (!CheckCellColor(nobj.shape(), color)) { returnfalse;
}
NativeShape* shape = nobj.shape(); if (!CheckCellColor(shape, color)) { returnfalse;
}
// Shapes and symbols are never marked gray.
ShapePropertyIter<NoGC> iter(shape);
jsid id = iter->key(); if (id.isGCThing() &&
!CheckCellColor(id.toGCCellPtr().asCell(), MarkColor::Black)) { returnfalse;
}
JSObject* AllocObjectChain(size_t length) { // Allocate a chain of linked JSObjects.
// Use a unique property name so the shape is not shared with any other // objects.
RootedString nextPropName(cx, JS_NewStringCopyZ(cx, "unique14142135"));
RootedId nextId(cx); if (!JS_StringToId(cx, nextPropName, &nextId)) { return nullptr;
}
RootedObject head(cx); for (size_t i = 0; i < length; i++) {
RootedValue next(cx, ObjectOrNullValue(head));
head = AllocPlainObject(); if (!head) { return nullptr;
} if (!JS_DefinePropertyById(cx, head, nextId, next, 0)) { return nullptr;
}
}
return head;
}
template <typename F> bool IterateObjectChain(JSObject* chain, F f) {
RootedObject obj(cx, chain); while (obj) { if (!f(obj)) { returnfalse;
}
// Access the 'next' property via the object's slots to avoid triggering // gray marking assertions when calling JS_GetPropertyById.
NativeObject& nobj = obj->as<NativeObject>();
MOZ_ASSERT(nobj.slotSpan() == 1);
obj = nobj.getSlot(0).toObjectOrNull();
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.