mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-16 14:55:47 +00:00
Bug 1053932: Don't let Debugger.Memory.prototype.takeCensus's result be influenced by the hash table's ordering (ByUbinodeType version). r=terrence
This commit is contained in:
parent
cfc6e05991
commit
5280bfadfd
@ -500,7 +500,7 @@ class ByObjectClass {
|
||||
entries.infallibleAppend(&r.front());
|
||||
qsort(entries.begin(), entries.length(), sizeof(*entries.begin()), compareEntries);
|
||||
|
||||
// Now build the result by iterating over the vector, not the hash table.
|
||||
// Now build the result by iterating over the sorted vector.
|
||||
RootedObject obj(cx, NewBuiltinClassInstance(cx, &JSObject::class_));
|
||||
if (!obj)
|
||||
return false;
|
||||
@ -551,6 +551,7 @@ class ByUbinodeType {
|
||||
// pointer, not just any string whose contents are correct, we can use their
|
||||
// addresses as hash table keys.
|
||||
typedef HashMap<const jschar *, EachType, DefaultHasher<const jschar *>, SystemAllocPolicy> Table;
|
||||
typedef typename Table::Entry Entry;
|
||||
Table table;
|
||||
|
||||
public:
|
||||
@ -580,27 +581,52 @@ class ByUbinodeType {
|
||||
|
||||
size_t total() const { return total_; }
|
||||
|
||||
static int compareEntries(const void *lhsVoid, const void *rhsVoid) {
|
||||
size_t lhs = (*static_cast<const Entry * const *>(lhsVoid))->value().total();
|
||||
size_t rhs = (*static_cast<const Entry * const *>(rhsVoid))->value().total();
|
||||
|
||||
// qsort sorts in "ascending" order, so we should describe entries with
|
||||
// smaller counts as being "greater than" entries with larger counts. We
|
||||
// don't want to just subtract the counts, as they're unsigned.
|
||||
if (lhs < rhs)
|
||||
return 1;
|
||||
if (lhs > rhs)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool report(Census &census, MutableHandleValue report) {
|
||||
JSContext *cx = census.cx;
|
||||
|
||||
// Build a vector of pointers to entries; sort by total; and then use
|
||||
// that to build the result object. This makes the ordering of entries
|
||||
// more interesting, and a little less non-deterministic.
|
||||
mozilla::Vector<Entry *> entries;
|
||||
if (!entries.reserve(table.count()))
|
||||
return false;
|
||||
for (typename Table::Range r = table.all(); !r.empty(); r.popFront())
|
||||
entries.infallibleAppend(&r.front());
|
||||
qsort(entries.begin(), entries.length(), sizeof(*entries.begin()), compareEntries);
|
||||
|
||||
// Now build the result by iterating over the sorted vector.
|
||||
RootedObject obj(cx, NewBuiltinClassInstance(cx, &JSObject::class_));
|
||||
if (!obj)
|
||||
return false;
|
||||
|
||||
for (typename Table::Range r = table.all(); !r.empty(); r.popFront()) {
|
||||
EachType &entry = r.front().value();
|
||||
RootedValue entryReport(cx);
|
||||
if (!entry.report(census, &entryReport))
|
||||
for (Entry **entryPtr = entries.begin(); entryPtr < entries.end(); entryPtr++) {
|
||||
Entry &entry = **entryPtr;
|
||||
EachType &assorter = entry.value();
|
||||
RootedValue assorterReport(cx);
|
||||
if (!assorter.report(census, &assorterReport))
|
||||
return false;
|
||||
|
||||
const jschar *name = r.front().key();
|
||||
const jschar *name = entry.key();
|
||||
MOZ_ASSERT(name);
|
||||
JSAtom *atom = AtomizeChars(cx, name, js_strlen(name));
|
||||
if (!atom)
|
||||
return false;
|
||||
RootedId entryId(cx, AtomToId(atom));
|
||||
|
||||
if (!JSObject::defineGeneric(cx, obj, entryId, entryReport))
|
||||
if (!JSObject::defineGeneric(cx, obj, entryId, assorterReport))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user