Hi, Currently, about:memory shows data for objects separately from shapes, and there are fixed buckets, like so:
├──125.51 MB (53.64%) -- compartments │ ├───65.20 MB (27.86%) -- objects │ │ ├──48.80 MB (20.86%) -- gc-heap │ │ │ ├──18.45 MB (07.88%) ── function │ │ │ ├──15.98 MB (06.83%) ── ordinary │ │ │ ├──13.60 MB (05.81%) ── dense-array │ │ │ └───0.77 MB (00.33%) ── cross-compartment-wrapper │ │ ├──16.40 MB (07.01%) -- malloc-heap │ │ │ ├──10.58 MB (04.52%) ── slots │ │ │ ├───5.07 MB (02.17%) ── elements/non-asm.js │ │ │ └───0.74 MB (00.32%) ++ (4 tiny) │ │ └───0.00 MB (00.00%) ── non-heap/code/asm.js │ ├───46.58 MB (19.91%) -- shapes │ │ ├──28.00 MB (11.97%) -- gc-heap │ │ │ ├──11.61 MB (04.96%) -- tree │ │ │ │ ├──10.22 MB (04.37%) ── global-parented │ │ │ │ └───1.39 MB (00.60%) ── non-global-parented │ │ │ ├───8.45 MB (03.61%) ── dict │ │ │ └───7.94 MB (03.39%) ── base │ │ └──18.58 MB (07.94%) -- malloc-heap │ │ ├───7.18 MB (03.07%) ── tree-tables │ │ ├───6.77 MB (02.89%) ── compartment-tables │ │ ├───3.73 MB (01.59%) ── dict-tables │ │ └───0.90 MB (00.38%) ── tree-shape-kids This isn't all that useful. The measurements are often large, but this bucket grouping doesn't give much insight into where things might be improved. It also entirely disassociates objects and shapes, when really they're intimately linked. I'm thinking about a different bucket scheme that gives more insight into what the code is doing. The idea is to merge the "objects" and "shapes" sub-trees into a single "objects-and-shapes" sub-tree, and then group things within that by class. E.g.: - objects-and-shapes - Object - ... - Function - ... - Array - ... - Proxy - ... - RegExp - ... Within each of the class-specific sub-trees, some of the existing object and shape buckets would be used: the object/shape/base-shape GC things, and the shape tables, etc. One particularly nice thing about this is that memory used by content-defined classes would be identified as such. Also, the relationship between objects and shapes will be clearer. Now, this design depends on every JSObject, Shape, and BaseShape belonging to exactly one single class. I think this is the case, but I admit to being unsure how to handle proxies -- JSObject::className() looks like this: const char * JSObject::className(JSContext *cx, HandleObject obj) { assertSameCompartment(cx, obj); if (obj->is<ProxyObject>()) return Proxy::className(cx, obj); return obj->getClass()->name; } The memory reporting code runs without a |cx|, so in my experimental code I've just used obj->getClass()->name, and not treated proxies specially. Does this sound reasonable? Nick _______________________________________________ dev-tech-js-engine-internals mailing list dev-tech-js-engine-internals@lists.mozilla.org https://lists.mozilla.org/listinfo/dev-tech-js-engine-internals