Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1143)

Side by Side Diff: runtime/vm/object_graph.cc

Issue 2990643002: Calculates retaining paths through user fields and ignores VM objects (Closed)
Patch Set: Created 3 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« runtime/vm/object_graph.h ('K') | « runtime/vm/object_graph.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/object_graph.h" 5 #include "vm/object_graph.h"
6 6
7 #include "vm/dart.h" 7 #include "vm/dart.h"
8 #include "vm/growable_array.h" 8 #include "vm/growable_array.h"
9 #include "vm/isolate.h" 9 #include "vm/isolate.h"
10 #include "vm/object.h" 10 #include "vm/object.h"
11 #include "vm/object_store.h" 11 #include "vm/object_store.h"
12 #include "vm/raw_object.h" 12 #include "vm/raw_object.h"
13 #include "vm/reusable_handles.h" 13 #include "vm/reusable_handles.h"
14 #include "vm/visitor.h" 14 #include "vm/visitor.h"
15 15
16 namespace dart { 16 namespace dart {
17 17
18 // The state of a pre-order, depth-first traversal of an object graph. 18 // The state of a pre-order, depth-first traversal of an object graph.
19 // When a node is visited, *all* its children are pushed to the stack at once. 19 // When a node is visited, *all* its children are pushed to the stack at once.
20 // We insert a sentinel between the node and its children on the stack, to 20 // We insert a sentinel between the node and its children on the stack, to
21 // remember that the node has been visited. The node is kept on the stack while 21 // remember that the node has been visited. The node is kept on the stack while
22 // its children are processed, to give the visitor a complete chain of parents. 22 // its children are processed, to give the visitor a complete chain of parents.
23 // 23 //
24 // TODO(koda): Potential optimizations: 24 // TODO(koda): Potential optimizations:
25 // - Use tag bits for compact Node and sentinel representations. 25 // - Use tag bits for compact Node and sentinel representations.
26 class ObjectGraph::Stack : public ObjectPointerVisitor { 26 class ObjectGraph::Stack : public ObjectPointerVisitor {
27 public: 27 public:
28 explicit Stack(Isolate* isolate) 28 explicit Stack(Isolate* isolate)
29 : ObjectPointerVisitor(isolate), data_(kInitialCapacity) {} 29 : ObjectPointerVisitor(isolate),
30 include_vm_obj(true),
31 data_(kInitialCapacity) {}
30 32
31 // Marks and pushes. Used to initialize this stack with roots. 33 // Marks and pushes. Used to initialize this stack with roots.
32 virtual void VisitPointers(RawObject** first, RawObject** last) { 34 virtual void VisitPointers(RawObject** first, RawObject** last) {
33 for (RawObject** current = first; current <= last; ++current) { 35 for (RawObject** current = first; current <= last; ++current) {
34 if ((*current)->IsHeapObject() && !(*current)->IsMarked()) { 36 if ((*current)->IsHeapObject() && !(*current)->IsMarked()) {
37 if (!include_vm_obj) {
cbernaschina 2017/07/25 21:09:22 Can we make this more generic? Maybe storing a fu
danunez 2017/07/25 22:24:54 I like this idea and we discussed this a bit offli
38 Object& o = Object::Handle(*current);
rmacnak 2017/07/25 21:55:21 Allocating a handle here is too expensive. *curre
danunez 2017/07/25 22:24:54 RawObject::GetClassId() is private. I can make it
rmacnak 2017/07/26 00:25:40 Make ObjectGraph::Stack a friend instead. I'm sort
39 intptr_t cid = o.GetClassId();
40 if (cid < kInstanceCid && cid != kContextCid) {
41 continue;
42 }
43 }
35 (*current)->SetMarkBit(); 44 (*current)->SetMarkBit();
36 Node node; 45 Node node;
37 node.ptr = current; 46 node.ptr = current;
38 node.obj = *current; 47 node.obj = *current;
39 data_.Add(node); 48 data_.Add(node);
40 } 49 }
41 } 50 }
42 } 51 }
43 52
44 // Traverses the object graph from the current state. 53 // Traverses the object graph from the current state.
(...skipping 17 matching lines...) Expand all
62 obj->VisitPointers(this); 71 obj->VisitPointers(this);
63 break; 72 break;
64 case ObjectGraph::Visitor::kBacktrack: 73 case ObjectGraph::Visitor::kBacktrack:
65 break; 74 break;
66 case ObjectGraph::Visitor::kAbort: 75 case ObjectGraph::Visitor::kAbort:
67 return; 76 return;
68 } 77 }
69 } 78 }
70 } 79 }
71 80
81 bool include_vm_obj;
rmacnak 2017/07/25 21:55:21 include_vm_objects_
danunez 2017/07/25 22:24:54 Done.
82
72 private: 83 private:
73 struct Node { 84 struct Node {
74 RawObject** ptr; // kSentinel for the sentinel node. 85 RawObject** ptr; // kSentinel for the sentinel node.
75 RawObject* obj; 86 RawObject* obj;
76 }; 87 };
77 88
78 static RawObject** const kSentinel; 89 static RawObject** const kSentinel;
79 static const intptr_t kInitialCapacity = 1024; 90 static const intptr_t kInitialCapacity = 1024;
80 static const intptr_t kNoParent = -1; 91 static const intptr_t kNoParent = -1;
81 92
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after
370 }; 381 };
371 382
372 intptr_t ObjectGraph::RetainingPath(Object* obj, const Array& path) { 383 intptr_t ObjectGraph::RetainingPath(Object* obj, const Array& path) {
373 NoSafepointScope no_safepoint_scope_; 384 NoSafepointScope no_safepoint_scope_;
374 HeapIterationScope iteration_scope(true); 385 HeapIterationScope iteration_scope(true);
375 // To break the trivial path, the handle 'obj' is temporarily cleared during 386 // To break the trivial path, the handle 'obj' is temporarily cleared during
376 // the search, but restored before returning. 387 // the search, but restored before returning.
377 RawObject* raw = obj->raw(); 388 RawObject* raw = obj->raw();
378 *obj = Object::null(); 389 *obj = Object::null();
379 RetainingPathVisitor visitor(raw, path); 390 RetainingPathVisitor visitor(raw, path);
380 IterateObjects(&visitor); 391 IterateObjectsNoVM(&visitor);
392 if (visitor.length() == 0) {
393 IterateObjects(&visitor);
394 }
381 *obj = raw; 395 *obj = raw;
382 return visitor.length(); 396 return visitor.length();
383 } 397 }
384 398
385 class InboundReferencesVisitor : public ObjectVisitor, 399 class InboundReferencesVisitor : public ObjectVisitor,
386 public ObjectPointerVisitor { 400 public ObjectPointerVisitor {
387 public: 401 public:
388 // We cannot use a GrowableObjectArray, since we must not trigger GC. 402 // We cannot use a GrowableObjectArray, since we must not trigger GC.
389 InboundReferencesVisitor(Isolate* isolate, 403 InboundReferencesVisitor(Isolate* isolate,
390 RawObject* target, 404 RawObject* target,
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after
626 640
627 intptr_t object_count = visitor.count(); 641 intptr_t object_count = visitor.count();
628 if (roots == kVM) { 642 if (roots == kVM) {
629 object_count += 1; // root 643 object_count += 1; // root
630 } else { 644 } else {
631 object_count += 2; // root and stack 645 object_count += 2; // root and stack
632 } 646 }
633 return object_count; 647 return object_count;
634 } 648 }
635 649
650 void ObjectGraph::IterateObjectsNoVM(ObjectGraph::Visitor* visitor) {
rmacnak 2017/07/25 21:55:21 Place next to ObjectGraph::IterateObjects.
danunez 2017/07/25 22:24:54 I can do this, but I will also have to move Iterat
651 NoSafepointScope no_safepoint_scope_;
652 Stack stack(isolate());
653 IterateUserFields(&stack);
654 stack.include_vm_obj = false;
655 stack.TraverseGraph(visitor);
656 Unmarker::UnmarkAll(isolate());
657 }
658
636 } // namespace dart 659 } // namespace dart
OLDNEW
« runtime/vm/object_graph.h ('K') | « runtime/vm/object_graph.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698