| Index: runtime/vm/object_graph.cc
|
| diff --git a/runtime/vm/object_graph.cc b/runtime/vm/object_graph.cc
|
| index 2bc0d664374374c5a5e9fcef582bf2c2c1e16bbf..ae1b1194b0d6fcb80db0a021e0407372f6357646 100644
|
| --- a/runtime/vm/object_graph.cc
|
| +++ b/runtime/vm/object_graph.cc
|
| @@ -186,7 +186,41 @@ void ObjectGraph::IterateObjectsFrom(const Object& root,
|
| RawObject* root_raw = root.raw();
|
| stack.VisitPointer(&root_raw);
|
| stack.TraverseGraph(visitor);
|
| - // TODO(koda): Optimize if we only visited a small subgraph.
|
| + Unmarker::UnmarkAll(isolate());
|
| +}
|
| +
|
| +
|
| +class InstanceAccumulator : public ObjectVisitor {
|
| + public:
|
| + explicit InstanceAccumulator(ObjectGraph::Stack* stack,
|
| + intptr_t class_id,
|
| + Isolate* isolate)
|
| + : ObjectVisitor(isolate), stack_(stack), class_id_(class_id) { }
|
| +
|
| + void VisitObject(RawObject* obj) {
|
| + if (obj->GetClassId() == class_id_) {
|
| + RawObject* rawobj = obj;
|
| + stack_->VisitPointer(&rawobj);
|
| + }
|
| + }
|
| +
|
| + private:
|
| + ObjectGraph::Stack* stack_;
|
| + const intptr_t class_id_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(InstanceAccumulator);
|
| +};
|
| +
|
| +
|
| +void ObjectGraph::IterateObjectsFrom(intptr_t class_id,
|
| + ObjectGraph::Visitor* visitor) {
|
| + NoSafepointScope no_safepoint_scope_;
|
| + Stack stack(isolate());
|
| +
|
| + InstanceAccumulator accumulator(&stack, class_id, isolate());
|
| + isolate()->heap()->IterateObjects(&accumulator);
|
| +
|
| + stack.TraverseGraph(visitor);
|
| Unmarker::UnmarkAll(isolate());
|
| }
|
|
|
| @@ -240,6 +274,13 @@ intptr_t ObjectGraph::SizeRetainedByInstance(const Object& obj) {
|
| }
|
|
|
|
|
| +intptr_t ObjectGraph::SizeReachableByInstance(const Object& obj) {
|
| + SizeVisitor total;
|
| + IterateObjectsFrom(obj, &total);
|
| + return total.size();
|
| +}
|
| +
|
| +
|
| intptr_t ObjectGraph::SizeRetainedByClass(intptr_t class_id) {
|
| SizeVisitor total;
|
| IterateObjects(&total);
|
| @@ -251,6 +292,13 @@ intptr_t ObjectGraph::SizeRetainedByClass(intptr_t class_id) {
|
| }
|
|
|
|
|
| +intptr_t ObjectGraph::SizeReachableByClass(intptr_t class_id) {
|
| + SizeVisitor total;
|
| + IterateObjectsFrom(class_id, &total);
|
| + return total.size();
|
| +}
|
| +
|
| +
|
| class RetainingPathVisitor : public ObjectGraph::Visitor {
|
| public:
|
| // We cannot use a GrowableObjectArray, since we must not trigger GC.
|
|
|