Hi,
In bug 972712 I implemented class-based memory reporting. An example:
│ │ │ │ ├───0.69 MB (00.64%) -- compartment([System Principal],
resource://gre/modules/addons/XPIProvider.jsm)
│ │ │ │ │ ├──0.45 MB (00.42%) -- classes
│ │ │ │ │ │ ├──0.21 MB (00.20%) -- class(Function)
│ │ │ │ │ │ │ ├──0.16 MB (00.15%) -- objects
│ │ │ │ │ │ │ │ ├──0.16 MB (00.15%) ── gc-heap
│ │ │ │ │ │ │ │ └──0.00 MB (00.00%) ── malloc-heap/slots
│ │ │ │ │ │ │ └──0.05 MB (00.04%) -- shapes
│ │ │ │ │ │ │ ├──0.05 MB (00.04%) -- gc-heap
│ │ │ │ │ │ │ │ ├──0.03 MB (00.03%) ── base
│ │ │ │ │ │ │ │ └──0.02 MB (00.02%) ── tree
│ │ │ │ │ │ │ └──0.00 MB (00.00%) -- malloc-heap
│ │ │ │ │ │ │ ├──0.00 MB (00.00%) ── tree-kids
│ │ │ │ │ │ │ └──0.00 MB (00.00%) ── tree-tables
This is pretty nice, but I had to back it out a while ago due to
intermittent complaints from ASAN.
Here is the code that ASAN complains about:
case JSTRACE_SHAPE: {
Shape *shape = static_cast<Shape *>(thing);
CompartmentStats *cStats = GetCompartmentStats(shape->compartment());
JS::ClassInfo info; // This zeroes all the sizes.
if (shape->inDictionary())
info.shapesGCHeapDict += thingSize;
else
info.shapesGCHeapTree += thingSize;
shape->addSizeOfExcludingThis(rtStats->mallocSizeOf_, &info);
cStats->classInfo.add(info);
const BaseShape *base = shape->base();
const Class *clasp = base->clasp(); // <-- ASAN complains
const char *className = clasp->name;
AddClassInfo(granularity, cStats, className, info);
break;
}
The code being complained about is just getting the shape's classname.
Here's example ASAN output (note that the first ASAN complaint is a
red herring; it's the second one that's relevant):
https://tbpl.mozilla.org/php/getParsedLog.php?id=37913274&tree=Try&full=1#error1
ASAN indicates that the memory access is wild, e.g. possibly a heap
buffer overflow. (I.e. it's not a use-after-free.) I don't think I'm
doing anything unreasonable here. Are shape->base() and base->clasp()
and clasp->name always safe to call? It might be worth mentioning that
this is a full JS heap traversal, so it's possible that |shape| is
non-reachable but hasn't yet been collected.
It only happens on about 1 in 20 runs, which is annoying.
Any insights appreciated. Thanks!
Nick
_______________________________________________
dev-tech-js-engine-internals mailing list
[email protected]
https://lists.mozilla.org/listinfo/dev-tech-js-engine-internals