Bug 1199219 - Implement JS::ubi::Node::size for js::Shape referents; r=sfink

This commit is contained in:
Nick Fitzgerald 2015-09-22 12:15:24 -07:00
parent 6d81eb63cc
commit ca3f10d7ba
4 changed files with 45 additions and 10 deletions

View File

@ -4,7 +4,7 @@ const Census = {};
(function () {
// Census.walkCensus(subject, name, walker)
// Census.walkCensus(subject, name, walker[, ignore])
//
// Use |walker| to check |subject|, a census object of the sort returned by
// Debugger.Memory.prototype.takeCensus: a tree of objects with integers at the
@ -17,24 +17,34 @@ const Census = {};
// subject census named |prop|. This is for recursing into the subobjects of
// the subject.
//
// - done(): Called after we have called 'enter' on every property of the
// subject.
// - done(ignore): Called after we have called 'enter' on every property of
// the subject. Passed the |ignore| set of properties.
//
// - check(value): Check |value|, a leaf in the subject.
//
// Walker methods are expected to simply throw if a node we visit doesn't look
// right.
Census.walkCensus = (subject, name, walker) => walk(subject, name, walker, 0);
function walk(subject, name, walker, count) {
//
// The optional |ignore| parameter allows you to specify a |Set| of property
// names which should be ignored. The walker will not traverse such
// properties.
Census.walkCensus = (subject, name, walker, ignore = new Set()) =>
walk(subject, name, walker, ignore, 0);
function walk(subject, name, walker, ignore, count) {
if (typeof subject === 'object') {
print(name);
for (let prop in subject) {
if (ignore.has(prop)) {
continue;
}
count = walk(subject[prop],
name + "[" + uneval(prop) + "]",
walker.enter(prop),
ignore,
count);
}
walker.done();
walker.done(ignore);
} else {
print(name + " = " + uneval(subject));
walker.check(subject);
@ -93,7 +103,7 @@ const Census = {};
}
},
done: () => unvisited.forEach(prop => missing(prop, basis[prop])),
done: ignore => [...unvisited].filter(p => !ignore.has(p)).forEach(p => missing(p, basis[p])),
check: expectedObject
};
} else {

View File

@ -15,11 +15,11 @@ Census.walkCensus(census1, "census1", Census.assertAllNotLessThan(census0));
var g2 = newGlobal();
dbg.addDebuggee(g2);
var census2 = dbg.memory.takeCensus();
Census.walkCensus(census2, "census2", Census.assertAllNotLessThan(census1));
Census.walkCensus(census2, "census2", Census.assertAllNotLessThan(census1), new Set(["bytes"]));
dbg.removeDebuggee(g2);
var census3 = dbg.memory.takeCensus();
Census.walkCensus(census3, "census3", Census.assertAllEqual(census1));
Census.walkCensus(census3, "census3", Census.assertAllEqual(census1), new Set(["bytes"]));
dbg.removeDebuggee(g1);
var census4 = dbg.memory.takeCensus();

View File

@ -1649,3 +1649,17 @@ AutoRooterGetterSetter::Inner::trace(JSTracer* trc)
if ((attrs & JSPROP_SETTER) && *psetter)
TraceRoot(trc, (JSObject**) psetter, "AutoRooterGetterSetter setter");
}
JS::ubi::Node::Size
JS::ubi::Concrete<js::Shape>::size(mozilla::MallocSizeOf mallocSizeOf) const
{
Size size = js::gc::Arena::thingSize(get().asTenured().getAllocKind());
if (get().hasTable())
size += get().table().sizeOfIncludingThis(mallocSizeOf);
if (!get().inDictionary() && get().kids.isHash())
size += get().kids.toHash()->sizeOfIncludingThis(mallocSizeOf);
return size;
}

View File

@ -532,6 +532,7 @@ class Shape : public gc::TenuredCell
friend class TenuringTracer;
friend struct StackBaseShape;
friend struct StackShape;
friend struct JS::ubi::Concrete<Shape>;
protected:
HeapPtrBaseShape base_;
@ -1433,7 +1434,17 @@ ReshapeForAllocKind(JSContext* cx, Shape* shape, TaggedProto proto,
// instances that occupy a compartment.
namespace JS {
namespace ubi {
template<> struct Concrete<js::Shape> : TracerConcreteWithCompartment<js::Shape> { };
template<> struct Concrete<js::Shape> : TracerConcreteWithCompartment<js::Shape> {
Size size(mozilla::MallocSizeOf mallocSizeOf) const override;
protected:
explicit Concrete(js::Shape *ptr) : TracerConcreteWithCompartment<js::Shape>(ptr) { }
public:
static void construct(void *storage, js::Shape *ptr) { new (storage) Concrete(ptr); }
};
template<> struct Concrete<js::BaseShape> : TracerConcreteWithCompartment<js::BaseShape> { };
} // namespace ubi
} // namespace JS