mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 21:31:04 +00:00
Backed out 5 changesets (bug 1212624) for breaking stuff.
Backed out changeset cf5ffa45a4a2 Backed out changeset 0d7a968d2d64 (bug 1212624) Backed out changeset 379edefa8e47 (bug 1212624) Backed out changeset f73fca35daad (bug 1212624) Backed out changeset 4f499d30a0e0 (bug 1212624)
This commit is contained in:
parent
2d1131de73
commit
833a3ce77b
@ -1775,7 +1775,7 @@ GCMarker::enterWeakMarkingMode()
|
||||
tag_ = TracerKindTag::WeakMarking;
|
||||
|
||||
for (GCZoneGroupIter zone(runtime()); !zone.done(); zone.next()) {
|
||||
for (WeakMapBase* m : zone->gcWeakMapList) {
|
||||
for (WeakMapBase* m = zone->gcWeakMapList; m; m = m->next) {
|
||||
if (m->marked)
|
||||
m->markEphemeronEntries(this);
|
||||
}
|
||||
|
@ -220,7 +220,7 @@ struct PersistentRootedMarker
|
||||
static void
|
||||
markChain(JSTracer* trc, List& list, const char* name)
|
||||
{
|
||||
for (Element* r : list)
|
||||
for (Element* r = list.getFirst(); r; r = r->getNext())
|
||||
TraceFn(trc, r->address(), name);
|
||||
}
|
||||
};
|
||||
|
@ -27,6 +27,7 @@ JS::Zone::Zone(JSRuntime* rt)
|
||||
debuggers(nullptr),
|
||||
arenas(rt),
|
||||
types(this),
|
||||
gcWeakMapList(nullptr),
|
||||
compartments(),
|
||||
gcGrayRoots(),
|
||||
gcMallocBytes(0),
|
||||
|
@ -283,8 +283,8 @@ struct Zone : public JS::shadow::Zone,
|
||||
|
||||
js::TypeZone types;
|
||||
|
||||
/* Live weakmaps in this zone. */
|
||||
mozilla::LinkedList<js::WeakMapBase> gcWeakMapList;
|
||||
/* Linked list of live weakmaps in this zone. */
|
||||
js::WeakMapBase* gcWeakMapList;
|
||||
|
||||
// The set of compartments in this zone.
|
||||
typedef js::Vector<JSCompartment*, 1, js::SystemAllocPolicy> CompartmentVector;
|
||||
|
@ -25,6 +25,7 @@ using namespace js::gc;
|
||||
WeakMapBase::WeakMapBase(JSObject* memOf, Zone* zone)
|
||||
: memberOf(memOf),
|
||||
zone(zone),
|
||||
next(WeakMapNotInList),
|
||||
marked(false)
|
||||
{
|
||||
MOZ_ASSERT_IF(memberOf, memberOf->compartment()->zone() == zone);
|
||||
@ -33,6 +34,9 @@ WeakMapBase::WeakMapBase(JSObject* memOf, Zone* zone)
|
||||
WeakMapBase::~WeakMapBase()
|
||||
{
|
||||
MOZ_ASSERT(CurrentThreadIsGCSweeping() || CurrentThreadIsHandlingInitFailure());
|
||||
MOZ_ASSERT_IF(CurrentThreadIsGCSweeping(), !isInList());
|
||||
if (isInList())
|
||||
removeWeakMapFromList(this);
|
||||
}
|
||||
|
||||
void
|
||||
@ -67,7 +71,7 @@ WeakMapBase::trace(JSTracer* tracer)
|
||||
void
|
||||
WeakMapBase::unmarkZone(JS::Zone* zone)
|
||||
{
|
||||
for (WeakMapBase* m : zone->gcWeakMapList)
|
||||
for (WeakMapBase* m = zone->gcWeakMapList; m; m = m->next)
|
||||
m->marked = false;
|
||||
}
|
||||
|
||||
@ -75,7 +79,7 @@ void
|
||||
WeakMapBase::markAll(JS::Zone* zone, JSTracer* tracer)
|
||||
{
|
||||
MOZ_ASSERT(tracer->weakMapAction() != DoNotTraceWeakMaps);
|
||||
for (WeakMapBase* m : zone->gcWeakMapList) {
|
||||
for (WeakMapBase* m = zone->gcWeakMapList; m; m = m->next) {
|
||||
m->trace(tracer);
|
||||
if (m->memberOf)
|
||||
TraceEdge(tracer, &m->memberOf, "memberOf");
|
||||
@ -86,7 +90,7 @@ bool
|
||||
WeakMapBase::markZoneIteratively(JS::Zone* zone, JSTracer* tracer)
|
||||
{
|
||||
bool markedAny = false;
|
||||
for (WeakMapBase* m : zone->gcWeakMapList) {
|
||||
for (WeakMapBase* m = zone->gcWeakMapList; m; m = m->next) {
|
||||
if (m->marked && m->markIteratively(tracer))
|
||||
markedAny = true;
|
||||
}
|
||||
@ -96,7 +100,7 @@ WeakMapBase::markZoneIteratively(JS::Zone* zone, JSTracer* tracer)
|
||||
bool
|
||||
WeakMapBase::findInterZoneEdges(JS::Zone* zone)
|
||||
{
|
||||
for (WeakMapBase* m : zone->gcWeakMapList) {
|
||||
for (WeakMapBase* m = zone->gcWeakMapList; m; m = m->next) {
|
||||
if (!m->findZoneEdges())
|
||||
return false;
|
||||
}
|
||||
@ -106,20 +110,24 @@ WeakMapBase::findInterZoneEdges(JS::Zone* zone)
|
||||
void
|
||||
WeakMapBase::sweepZone(JS::Zone* zone)
|
||||
{
|
||||
for (WeakMapBase* m = zone->gcWeakMapList.getFirst(); m; ) {
|
||||
WeakMapBase* next = m->getNext();
|
||||
WeakMapBase** tailPtr = &zone->gcWeakMapList;
|
||||
for (WeakMapBase* m = zone->gcWeakMapList; m; ) {
|
||||
WeakMapBase* next = m->next;
|
||||
if (m->marked) {
|
||||
m->sweep();
|
||||
*tailPtr = m;
|
||||
tailPtr = &m->next;
|
||||
} else {
|
||||
/* Destroy the hash map now to catch any use after this point. */
|
||||
m->finish();
|
||||
m->removeFrom(zone->gcWeakMapList);
|
||||
m->next = WeakMapNotInList;
|
||||
}
|
||||
m = next;
|
||||
}
|
||||
*tailPtr = nullptr;
|
||||
|
||||
#ifdef DEBUG
|
||||
for (WeakMapBase* m : zone->gcWeakMapList)
|
||||
for (WeakMapBase* m = zone->gcWeakMapList; m; m = m->next)
|
||||
MOZ_ASSERT(m->isInList() && m->marked);
|
||||
#endif
|
||||
}
|
||||
@ -129,7 +137,7 @@ WeakMapBase::traceAllMappings(WeakMapTracer* tracer)
|
||||
{
|
||||
JSRuntime* rt = tracer->runtime;
|
||||
for (ZonesIter zone(rt, SkipAtoms); !zone.done(); zone.next()) {
|
||||
for (WeakMapBase* m : zone->gcWeakMapList) {
|
||||
for (WeakMapBase* m = zone->gcWeakMapList; m; m = m->next) {
|
||||
// The WeakMapTracer callback is not allowed to GC.
|
||||
JS::AutoSuppressGCAnalysis nogc;
|
||||
m->traceMappings(tracer);
|
||||
@ -140,7 +148,7 @@ WeakMapBase::traceAllMappings(WeakMapTracer* tracer)
|
||||
bool
|
||||
WeakMapBase::saveZoneMarkedWeakMaps(JS::Zone* zone, WeakMapSet& markedWeakMaps)
|
||||
{
|
||||
for (WeakMapBase* m : zone->gcWeakMapList) {
|
||||
for (WeakMapBase* m = zone->gcWeakMapList; m; m = m->next) {
|
||||
if (m->marked && !markedWeakMaps.put(m))
|
||||
return false;
|
||||
}
|
||||
@ -158,6 +166,19 @@ WeakMapBase::restoreMarkedWeakMaps(WeakMapSet& markedWeakMaps)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WeakMapBase::removeWeakMapFromList(WeakMapBase* weakmap)
|
||||
{
|
||||
JS::Zone* zone = weakmap->zone;
|
||||
for (WeakMapBase** p = &zone->gcWeakMapList; *p; p = &(*p)->next) {
|
||||
if (*p == weakmap) {
|
||||
*p = (*p)->next;
|
||||
weakmap->next = WeakMapNotInList;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
ObjectValueMap::findZoneEdges()
|
||||
{
|
||||
@ -196,6 +217,11 @@ ObjectWeakMap::init()
|
||||
return map.init();
|
||||
}
|
||||
|
||||
ObjectWeakMap::~ObjectWeakMap()
|
||||
{
|
||||
WeakMapBase::removeWeakMapFromList(&map);
|
||||
}
|
||||
|
||||
JSObject*
|
||||
ObjectWeakMap::lookup(const JSObject* obj)
|
||||
{
|
||||
|
@ -7,7 +7,6 @@
|
||||
#ifndef jsweakmap_h
|
||||
#define jsweakmap_h
|
||||
|
||||
#include "mozilla/LinkedList.h"
|
||||
#include "mozilla/Move.h"
|
||||
|
||||
#include "jscompartment.h"
|
||||
@ -36,12 +35,14 @@ class WeakMapBase;
|
||||
// implementation takes care of the iterative marking needed for weak tables and removing
|
||||
// table entries when collection is complete.
|
||||
|
||||
// The value for the next pointer for maps not in the map list.
|
||||
static WeakMapBase * const WeakMapNotInList = reinterpret_cast<WeakMapBase*>(1);
|
||||
|
||||
typedef HashSet<WeakMapBase*, DefaultHasher<WeakMapBase*>, SystemAllocPolicy> WeakMapSet;
|
||||
|
||||
// Common base class for all WeakMap specializations. The collector uses this to call
|
||||
// their markIteratively and sweep methods.
|
||||
class WeakMapBase : public mozilla::LinkedListElement<WeakMapBase>
|
||||
{
|
||||
class WeakMapBase {
|
||||
friend void js::GCMarker::enterWeakMarkingMode();
|
||||
|
||||
public:
|
||||
@ -74,12 +75,17 @@ class WeakMapBase : public mozilla::LinkedListElement<WeakMapBase>
|
||||
// Trace all delayed weak map bindings. Used by the cycle collector.
|
||||
static void traceAllMappings(WeakMapTracer* tracer);
|
||||
|
||||
bool isInList() { return next != WeakMapNotInList; }
|
||||
|
||||
// Save information about which weak maps are marked for a zone.
|
||||
static bool saveZoneMarkedWeakMaps(JS::Zone* zone, WeakMapSet& markedWeakMaps);
|
||||
|
||||
// Restore information about which weak maps are marked for many zones.
|
||||
static void restoreMarkedWeakMaps(WeakMapSet& markedWeakMaps);
|
||||
|
||||
// Remove a weakmap from its zone's weakmaps list.
|
||||
static void removeWeakMapFromList(WeakMapBase* weakmap);
|
||||
|
||||
// Any weakmap key types that want to participate in the non-iterative
|
||||
// ephemeron marking must override this method.
|
||||
virtual void maybeMarkEntry(JSTracer* trc, gc::Cell* markedCell, JS::GCCellPtr l) = 0;
|
||||
@ -103,6 +109,11 @@ class WeakMapBase : public mozilla::LinkedListElement<WeakMapBase>
|
||||
// Zone containing this weak map.
|
||||
JS::Zone* zone;
|
||||
|
||||
// Link in a list of all WeakMaps in a Zone, headed by
|
||||
// JS::Zone::gcWeakMapList. The last element of the list has nullptr as its
|
||||
// next. Maps not in the list have WeakMapNotInList as their next.
|
||||
WeakMapBase* next;
|
||||
|
||||
// Whether this object has been traced during garbage collection.
|
||||
bool marked;
|
||||
};
|
||||
@ -136,7 +147,8 @@ class WeakMap : public HashMap<Key, Value, HashPolicy, RuntimeAllocPolicy>, publ
|
||||
bool init(uint32_t len = 16) {
|
||||
if (!Base::init(len))
|
||||
return false;
|
||||
zone->gcWeakMapList.insertFront(this);
|
||||
next = zone->gcWeakMapList;
|
||||
zone->gcWeakMapList = this;
|
||||
marked = JS::IsIncrementalGCInProgress(zone->runtimeFromMainThread());
|
||||
return true;
|
||||
}
|
||||
@ -165,9 +177,6 @@ class WeakMap : public HashMap<Key, Value, HashPolicy, RuntimeAllocPolicy>, publ
|
||||
return p;
|
||||
}
|
||||
|
||||
// Resolve ambiguity with LinkedListElement<>::remove.
|
||||
using Base::remove;
|
||||
|
||||
// The WeakMap and some part of the key are marked. If the entry is marked
|
||||
// according to the exact semantics of this WeakMap, then mark the value.
|
||||
// (For a standard WeakMap, the entry is marked if either the key its
|
||||
@ -409,6 +418,7 @@ class ObjectWeakMap
|
||||
public:
|
||||
explicit ObjectWeakMap(JSContext* cx);
|
||||
bool init();
|
||||
~ObjectWeakMap();
|
||||
|
||||
JSObject* lookup(const JSObject* obj);
|
||||
bool add(JSContext* cx, JSObject* obj, JSObject* target);
|
||||
|
@ -2439,7 +2439,7 @@ Debugger::markIncomingCrossCompartmentEdges(JSTracer* trc)
|
||||
gc::State state = rt->gc.state();
|
||||
MOZ_ASSERT(state == gc::MARK_ROOTS || state == gc::COMPACT);
|
||||
|
||||
for (Debugger* dbg : rt->debuggerList) {
|
||||
for (Debugger* dbg = rt->debuggerList.getFirst(); dbg; dbg = dbg->getNext()) {
|
||||
Zone* zone = dbg->object->zone();
|
||||
if ((state == gc::MARK_ROOTS && !zone->isCollecting()) ||
|
||||
(state == gc::COMPACT && !zone->isGCCompacting()))
|
||||
@ -2535,7 +2535,7 @@ Debugger::markAllIteratively(GCMarker* trc)
|
||||
Debugger::markAll(JSTracer* trc)
|
||||
{
|
||||
JSRuntime* rt = trc->runtime();
|
||||
for (Debugger* dbg : rt->debuggerList) {
|
||||
for (Debugger* dbg = rt->debuggerList.getFirst(); dbg; dbg = dbg->getNext()) {
|
||||
WeakGlobalObjectSet& debuggees = dbg->debuggees;
|
||||
for (WeakGlobalObjectSet::Enum e(debuggees); !e.empty(); e.popFront()) {
|
||||
GlobalObject* global = e.front();
|
||||
@ -2607,7 +2607,7 @@ Debugger::sweepAll(FreeOp* fop)
|
||||
{
|
||||
JSRuntime* rt = fop->runtime();
|
||||
|
||||
for (Debugger* dbg : rt->debuggerList) {
|
||||
for (Debugger* dbg = rt->debuggerList.getFirst(); dbg; dbg = dbg->getNext()) {
|
||||
if (IsAboutToBeFinalized(&dbg->object)) {
|
||||
/*
|
||||
* dbg is being GC'd. Detach it from its debuggees. The debuggee
|
||||
@ -2638,7 +2638,10 @@ Debugger::findZoneEdges(Zone* zone, js::gc::ComponentFinder<Zone>& finder)
|
||||
* This ensure that debuggers and their debuggees are finalized in the same
|
||||
* group.
|
||||
*/
|
||||
for (Debugger* dbg : zone->runtimeFromMainThread()->debuggerList) {
|
||||
for (Debugger* dbg = zone->runtimeFromMainThread()->debuggerList.getFirst();
|
||||
dbg;
|
||||
dbg = dbg->getNext())
|
||||
{
|
||||
Zone* w = dbg->object->zone();
|
||||
if (w == zone || !w->isGCMarking())
|
||||
continue;
|
||||
@ -8476,7 +8479,7 @@ FireOnGarbageCollectionHook(JSContext* cx, JS::dbg::GarbageCollectionEvent::Ptr&
|
||||
// participated in this GC.
|
||||
AutoCheckCannotGC noGC;
|
||||
|
||||
for (Debugger* dbg : cx->runtime()->debuggerList) {
|
||||
for (Debugger* dbg = cx->runtime()->debuggerList.getFirst(); dbg; dbg = dbg->getNext()) {
|
||||
if (dbg->enabled &&
|
||||
dbg->observedGC(data->majorGCNumber()) &&
|
||||
dbg->getHook(Debugger::OnGarbageCollection))
|
||||
|
@ -93,6 +93,16 @@ class DebuggerWeakMap : private WeakMap<PreBarriered<UnbarrieredKey>, Relocatabl
|
||||
compartment(cx->compartment())
|
||||
{ }
|
||||
|
||||
~DebuggerWeakMap() {
|
||||
// If our owning Debugger fails construction after already initializing
|
||||
// this DebuggerWeakMap, we need to make sure that we aren't in the
|
||||
// compartment's weak map list anymore. Normally, when we are destroyed
|
||||
// because the GC finds us unreachable, the GC takes care of removing us
|
||||
// from this list.
|
||||
if (WeakMapBase::isInList())
|
||||
WeakMapBase::removeWeakMapFromList(this);
|
||||
}
|
||||
|
||||
public:
|
||||
/* Expose those parts of HashMap public interface that are used by Debugger methods. */
|
||||
|
||||
@ -200,7 +210,6 @@ class Debugger : private mozilla::LinkedListElement<Debugger>
|
||||
friend class DebuggerMemory;
|
||||
friend class SavedStacks;
|
||||
friend class mozilla::LinkedListElement<Debugger>;
|
||||
friend class mozilla::LinkedList<Debugger>;
|
||||
friend bool (::JS_DefineDebuggerObject)(JSContext* cx, JS::HandleObject obj);
|
||||
friend bool (::JS::dbg::IsDebugger)(JSObject&);
|
||||
friend bool (::JS::dbg::GetDebuggeeGlobals)(JSContext*, JSObject&, AutoObjectVector&);
|
||||
|
@ -1780,7 +1780,10 @@ ComputePlainObjectLayout(ExclusiveContext* cx, Shape* templateShape,
|
||||
// properties, which will allow us to generate better code if the objects
|
||||
// have a subtype/supertype relation and are accessed at common sites.
|
||||
UnboxedLayout* bestExisting = nullptr;
|
||||
for (UnboxedLayout* existing : cx->compartment()->unboxedLayouts) {
|
||||
for (UnboxedLayout* existing = cx->compartment()->unboxedLayouts.getFirst();
|
||||
existing;
|
||||
existing = existing->getNext())
|
||||
{
|
||||
if (PropertiesAreSuperset(properties, existing)) {
|
||||
if (!bestExisting ||
|
||||
existing->properties().length() > bestExisting->properties().length())
|
||||
|
@ -53,7 +53,12 @@ void
|
||||
JS::WeakMapPtr<K, V>::destroy()
|
||||
{
|
||||
MOZ_ASSERT(initialized());
|
||||
js_delete(Utils<K, V>::cast(ptr));
|
||||
auto map = Utils<K, V>::cast(ptr);
|
||||
// If this destruction happens mid-GC, we might be in the compartment's list
|
||||
// of known live weakmaps. If we are, remove ourselves before deleting.
|
||||
if (map->isInList())
|
||||
WeakMapBase::removeWeakMapFromList(map);
|
||||
js_delete(map);
|
||||
ptr = nullptr;
|
||||
}
|
||||
|
||||
|
@ -299,26 +299,6 @@ private:
|
||||
LinkedListElement<T> sentinel;
|
||||
|
||||
public:
|
||||
class Iterator {
|
||||
T* mCurrent;
|
||||
|
||||
public:
|
||||
explicit Iterator(T* aCurrent) : mCurrent(aCurrent) {}
|
||||
|
||||
T* operator *() const {
|
||||
return mCurrent;
|
||||
}
|
||||
|
||||
const Iterator& operator++() {
|
||||
mCurrent = mCurrent->getNext();
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator!=(Iterator& aOther) const {
|
||||
return mCurrent != aOther.mCurrent;
|
||||
}
|
||||
};
|
||||
|
||||
LinkedList() : sentinel(LinkedListElement<T>::NODE_KIND_SENTINEL) { }
|
||||
|
||||
LinkedList(LinkedList<T>&& aOther)
|
||||
@ -403,18 +383,6 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Allow range-based iteration:
|
||||
*
|
||||
* for (MyElementType* elt : myList) { ... }
|
||||
*/
|
||||
Iterator begin() {
|
||||
return Iterator(getFirst());
|
||||
}
|
||||
Iterator end() {
|
||||
return Iterator(nullptr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Measures the memory consumption of the list excluding |this|. Note that
|
||||
* it only measures the list elements themselves. If the list elements
|
||||
|
@ -1,147 +0,0 @@
|
||||
/* -*- 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/. */
|
||||
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/LinkedList.h"
|
||||
|
||||
using mozilla::LinkedList;
|
||||
using mozilla::LinkedListElement;
|
||||
|
||||
struct SomeClass : public LinkedListElement<SomeClass> {
|
||||
unsigned int mValue;
|
||||
explicit SomeClass(int aValue) : mValue(aValue) {}
|
||||
void incr() { ++mValue; }
|
||||
};
|
||||
|
||||
struct PrivateClass : private LinkedListElement<PrivateClass> {
|
||||
friend class LinkedList<PrivateClass>;
|
||||
friend class LinkedListElement<PrivateClass>;
|
||||
};
|
||||
|
||||
template <size_t N>
|
||||
static void
|
||||
CheckListValues(LinkedList<SomeClass>& list, unsigned int (&values)[N])
|
||||
{
|
||||
size_t count = 0;
|
||||
for (SomeClass* x : list) {
|
||||
MOZ_RELEASE_ASSERT(x->mValue == values[count]);
|
||||
++count;
|
||||
}
|
||||
MOZ_RELEASE_ASSERT(count == N);
|
||||
}
|
||||
|
||||
static void
|
||||
TestList()
|
||||
{
|
||||
LinkedList<SomeClass> list;
|
||||
|
||||
SomeClass one(1), two(2), three(3);
|
||||
|
||||
MOZ_RELEASE_ASSERT(list.isEmpty());
|
||||
MOZ_RELEASE_ASSERT(!list.getFirst());
|
||||
MOZ_RELEASE_ASSERT(!list.getLast());
|
||||
MOZ_RELEASE_ASSERT(!list.popFirst());
|
||||
MOZ_RELEASE_ASSERT(!list.popLast());
|
||||
|
||||
for (SomeClass* x : list) {
|
||||
MOZ_RELEASE_ASSERT(x);
|
||||
MOZ_RELEASE_ASSERT(false);
|
||||
}
|
||||
|
||||
list.insertFront(&one);
|
||||
{ unsigned int check[] { 1 }; CheckListValues(list, check); }
|
||||
|
||||
MOZ_RELEASE_ASSERT(one.isInList());
|
||||
MOZ_RELEASE_ASSERT(!two.isInList());
|
||||
MOZ_RELEASE_ASSERT(!three.isInList());
|
||||
|
||||
MOZ_RELEASE_ASSERT(!list.isEmpty());
|
||||
MOZ_RELEASE_ASSERT(list.getFirst()->mValue == 1);
|
||||
MOZ_RELEASE_ASSERT(list.getLast()->mValue == 1);
|
||||
|
||||
list.insertFront(&two);
|
||||
{ unsigned int check[] { 2, 1 }; CheckListValues(list, check); }
|
||||
|
||||
MOZ_RELEASE_ASSERT(list.getFirst()->mValue == 2);
|
||||
MOZ_RELEASE_ASSERT(list.getLast()->mValue == 1);
|
||||
|
||||
list.insertBack(&three);
|
||||
{ unsigned int check[] { 2, 1, 3 }; CheckListValues(list, check); }
|
||||
|
||||
MOZ_RELEASE_ASSERT(list.getFirst()->mValue == 2);
|
||||
MOZ_RELEASE_ASSERT(list.getLast()->mValue == 3);
|
||||
|
||||
one.removeFrom(list);
|
||||
{ unsigned int check[] { 2, 3 }; CheckListValues(list, check); }
|
||||
|
||||
three.setPrevious(&one);
|
||||
{ unsigned int check[] { 2, 1, 3 }; CheckListValues(list, check); }
|
||||
|
||||
three.removeFrom(list);
|
||||
{ unsigned int check[] { 2, 1 }; CheckListValues(list, check); }
|
||||
|
||||
two.setPrevious(&three);
|
||||
{ unsigned int check[] { 3, 2, 1 }; CheckListValues(list, check); }
|
||||
|
||||
three.removeFrom(list);
|
||||
{ unsigned int check[] { 2, 1 }; CheckListValues(list, check); }
|
||||
|
||||
two.setNext(&three);
|
||||
{ unsigned int check[] { 2, 3, 1 }; CheckListValues(list, check); }
|
||||
|
||||
one.remove();
|
||||
{ unsigned int check[] { 2, 3 }; CheckListValues(list, check); }
|
||||
|
||||
two.remove();
|
||||
{ unsigned int check[] { 3 }; CheckListValues(list, check); }
|
||||
|
||||
three.setPrevious(&two);
|
||||
{ unsigned int check[] { 2, 3 }; CheckListValues(list, check); }
|
||||
|
||||
three.remove();
|
||||
{ unsigned int check[] { 2 }; CheckListValues(list, check); }
|
||||
|
||||
two.remove();
|
||||
|
||||
list.insertBack(&three);
|
||||
{ unsigned int check[] { 3 }; CheckListValues(list, check); }
|
||||
|
||||
list.insertFront(&two);
|
||||
{ unsigned int check[] { 2, 3 }; CheckListValues(list, check); }
|
||||
|
||||
for (SomeClass* x : list) {
|
||||
x->incr();
|
||||
}
|
||||
|
||||
MOZ_RELEASE_ASSERT(list.getFirst() == &two);
|
||||
MOZ_RELEASE_ASSERT(list.getLast() == &three);
|
||||
MOZ_RELEASE_ASSERT(list.getFirst()->mValue == 3);
|
||||
MOZ_RELEASE_ASSERT(list.getLast()->mValue == 4);
|
||||
}
|
||||
|
||||
static void
|
||||
TestPrivate()
|
||||
{
|
||||
LinkedList<PrivateClass> list;
|
||||
PrivateClass one, two;
|
||||
list.insertBack(&one);
|
||||
list.insertBack(&two);
|
||||
|
||||
size_t count = 0;
|
||||
for (PrivateClass* p : list) {
|
||||
MOZ_RELEASE_ASSERT(p, "cannot have null elements in list");
|
||||
count++;
|
||||
}
|
||||
MOZ_RELEASE_ASSERT(count == 2);
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
TestList();
|
||||
TestPrivate();
|
||||
return 0;
|
||||
}
|
@ -22,7 +22,6 @@ CppUnitTests([
|
||||
'TestIntegerPrintfMacros',
|
||||
'TestIntegerRange',
|
||||
'TestJSONWriter',
|
||||
'TestLinkedList',
|
||||
'TestMacroArgs',
|
||||
'TestMacroForEach',
|
||||
'TestMathAlgorithms',
|
||||
|
Loading…
Reference in New Issue
Block a user