OLD | NEW |
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" |
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
200 intptr_t ObjectGraph::SizeRetainedByClass(intptr_t class_id) { | 200 intptr_t ObjectGraph::SizeRetainedByClass(intptr_t class_id) { |
201 SizeVisitor total; | 201 SizeVisitor total; |
202 IterateObjects(&total); | 202 IterateObjects(&total); |
203 intptr_t size_total = total.size(); | 203 intptr_t size_total = total.size(); |
204 SizeExcludingClassVisitor excluding_class(class_id); | 204 SizeExcludingClassVisitor excluding_class(class_id); |
205 IterateObjects(&excluding_class); | 205 IterateObjects(&excluding_class); |
206 intptr_t size_excluding_class = excluding_class.size(); | 206 intptr_t size_excluding_class = excluding_class.size(); |
207 return size_total - size_excluding_class; | 207 return size_total - size_excluding_class; |
208 } | 208 } |
209 | 209 |
| 210 |
| 211 class RetainingPathVisitor : public ObjectGraph::Visitor { |
| 212 public: |
| 213 // We cannot use a GrowableObjectArray, since we must not trigger GC. |
| 214 RetainingPathVisitor(RawObject* obj, const Array& path) |
| 215 : obj_(obj), path_(path), length_(0) { |
| 216 ASSERT(Isolate::Current()->no_gc_scope_depth() != 0); |
| 217 } |
| 218 |
| 219 intptr_t length() const { return length_; } |
| 220 |
| 221 virtual Direction VisitObject(ObjectGraph::StackIterator* it) { |
| 222 if (it->Get() != obj_) { |
| 223 return kProceed; |
| 224 } else { |
| 225 HANDLESCOPE(Isolate::Current()); |
| 226 Object& parent = Object::Handle(); |
| 227 for (length_ = 0; it->MoveToParent(); ++length_) { |
| 228 if (!path_.IsNull() && length_ < path_.Length()) { |
| 229 parent = it->Get(); |
| 230 path_.SetAt(length_, parent); |
| 231 } |
| 232 } |
| 233 return kAbort; |
| 234 } |
| 235 } |
| 236 |
| 237 private: |
| 238 RawObject* obj_; |
| 239 const Array& path_; |
| 240 intptr_t length_; |
| 241 }; |
| 242 |
| 243 |
| 244 intptr_t ObjectGraph::RetainingPath(Object* obj, const Array& path) { |
| 245 NoGCScope no_gc_scope_; |
| 246 // To break the trivial path, the handle 'obj' is temporarily cleared during |
| 247 // the search, but restored before returning. |
| 248 RawObject* raw = obj->raw(); |
| 249 *obj = Object::null(); |
| 250 RetainingPathVisitor visitor(raw, path); |
| 251 IterateObjects(&visitor); |
| 252 *obj = raw; |
| 253 return visitor.length(); |
| 254 } |
| 255 |
210 } // namespace dart | 256 } // namespace dart |
OLD | NEW |