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

Reply via email to