| 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 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 179 } | 179 } |
| 180 | 180 |
| 181 | 181 |
| 182 void ObjectGraph::IterateObjectsFrom(const Object& root, | 182 void ObjectGraph::IterateObjectsFrom(const Object& root, |
| 183 ObjectGraph::Visitor* visitor) { | 183 ObjectGraph::Visitor* visitor) { |
| 184 NoSafepointScope no_safepoint_scope_; | 184 NoSafepointScope no_safepoint_scope_; |
| 185 Stack stack(isolate()); | 185 Stack stack(isolate()); |
| 186 RawObject* root_raw = root.raw(); | 186 RawObject* root_raw = root.raw(); |
| 187 stack.VisitPointer(&root_raw); | 187 stack.VisitPointer(&root_raw); |
| 188 stack.TraverseGraph(visitor); | 188 stack.TraverseGraph(visitor); |
| 189 // TODO(koda): Optimize if we only visited a small subgraph. | |
| 190 Unmarker::UnmarkAll(isolate()); | 189 Unmarker::UnmarkAll(isolate()); |
| 191 } | 190 } |
| 192 | 191 |
| 192 |
| 193 class InstanceAccumulator : public ObjectVisitor { |
| 194 public: |
| 195 explicit InstanceAccumulator(ObjectGraph::Stack* stack, |
| 196 intptr_t class_id, |
| 197 Isolate* isolate) |
| 198 : ObjectVisitor(isolate), stack_(stack), class_id_(class_id) { } |
| 199 |
| 200 void VisitObject(RawObject* obj) { |
| 201 if (obj->GetClassId() == class_id_) { |
| 202 RawObject* rawobj = obj; |
| 203 stack_->VisitPointer(&rawobj); |
| 204 } |
| 205 } |
| 206 |
| 207 private: |
| 208 ObjectGraph::Stack* stack_; |
| 209 const intptr_t class_id_; |
| 210 |
| 211 DISALLOW_COPY_AND_ASSIGN(InstanceAccumulator); |
| 212 }; |
| 213 |
| 214 |
| 215 void ObjectGraph::IterateObjectsFrom(intptr_t class_id, |
| 216 ObjectGraph::Visitor* visitor) { |
| 217 NoSafepointScope no_safepoint_scope_; |
| 218 Stack stack(isolate()); |
| 219 |
| 220 InstanceAccumulator accumulator(&stack, class_id, isolate()); |
| 221 isolate()->heap()->IterateObjects(&accumulator); |
| 222 |
| 223 stack.TraverseGraph(visitor); |
| 224 Unmarker::UnmarkAll(isolate()); |
| 225 } |
| 226 |
| 193 | 227 |
| 194 class SizeVisitor : public ObjectGraph::Visitor { | 228 class SizeVisitor : public ObjectGraph::Visitor { |
| 195 public: | 229 public: |
| 196 SizeVisitor() : size_(0) { } | 230 SizeVisitor() : size_(0) { } |
| 197 intptr_t size() const { return size_; } | 231 intptr_t size() const { return size_; } |
| 198 virtual bool ShouldSkip(RawObject* obj) const { return false; } | 232 virtual bool ShouldSkip(RawObject* obj) const { return false; } |
| 199 virtual Direction VisitObject(ObjectGraph::StackIterator* it) { | 233 virtual Direction VisitObject(ObjectGraph::StackIterator* it) { |
| 200 RawObject* obj = it->Get(); | 234 RawObject* obj = it->Get(); |
| 201 if (ShouldSkip(obj)) { | 235 if (ShouldSkip(obj)) { |
| 202 return kBacktrack; | 236 return kBacktrack; |
| (...skipping 30 matching lines...) Expand all Loading... |
| 233 SizeVisitor total; | 267 SizeVisitor total; |
| 234 IterateObjects(&total); | 268 IterateObjects(&total); |
| 235 intptr_t size_total = total.size(); | 269 intptr_t size_total = total.size(); |
| 236 SizeExcludingObjectVisitor excluding_obj(obj); | 270 SizeExcludingObjectVisitor excluding_obj(obj); |
| 237 IterateObjects(&excluding_obj); | 271 IterateObjects(&excluding_obj); |
| 238 intptr_t size_excluding_obj = excluding_obj.size(); | 272 intptr_t size_excluding_obj = excluding_obj.size(); |
| 239 return size_total - size_excluding_obj; | 273 return size_total - size_excluding_obj; |
| 240 } | 274 } |
| 241 | 275 |
| 242 | 276 |
| 277 intptr_t ObjectGraph::SizeReachableByInstance(const Object& obj) { |
| 278 SizeVisitor total; |
| 279 IterateObjectsFrom(obj, &total); |
| 280 return total.size(); |
| 281 } |
| 282 |
| 283 |
| 243 intptr_t ObjectGraph::SizeRetainedByClass(intptr_t class_id) { | 284 intptr_t ObjectGraph::SizeRetainedByClass(intptr_t class_id) { |
| 244 SizeVisitor total; | 285 SizeVisitor total; |
| 245 IterateObjects(&total); | 286 IterateObjects(&total); |
| 246 intptr_t size_total = total.size(); | 287 intptr_t size_total = total.size(); |
| 247 SizeExcludingClassVisitor excluding_class(class_id); | 288 SizeExcludingClassVisitor excluding_class(class_id); |
| 248 IterateObjects(&excluding_class); | 289 IterateObjects(&excluding_class); |
| 249 intptr_t size_excluding_class = excluding_class.size(); | 290 intptr_t size_excluding_class = excluding_class.size(); |
| 250 return size_total - size_excluding_class; | 291 return size_total - size_excluding_class; |
| 251 } | 292 } |
| 252 | 293 |
| 253 | 294 |
| 295 intptr_t ObjectGraph::SizeReachableByClass(intptr_t class_id) { |
| 296 SizeVisitor total; |
| 297 IterateObjectsFrom(class_id, &total); |
| 298 return total.size(); |
| 299 } |
| 300 |
| 301 |
| 254 class RetainingPathVisitor : public ObjectGraph::Visitor { | 302 class RetainingPathVisitor : public ObjectGraph::Visitor { |
| 255 public: | 303 public: |
| 256 // We cannot use a GrowableObjectArray, since we must not trigger GC. | 304 // We cannot use a GrowableObjectArray, since we must not trigger GC. |
| 257 RetainingPathVisitor(RawObject* obj, const Array& path) | 305 RetainingPathVisitor(RawObject* obj, const Array& path) |
| 258 : thread_(Thread::Current()), obj_(obj), path_(path), length_(0) { | 306 : thread_(Thread::Current()), obj_(obj), path_(path), length_(0) { |
| 259 ASSERT(Thread::Current()->no_safepoint_scope_depth() != 0); | 307 ASSERT(Thread::Current()->no_safepoint_scope_depth() != 0); |
| 260 } | 308 } |
| 261 | 309 |
| 262 intptr_t length() const { return length_; } | 310 intptr_t length() const { return length_; } |
| 263 | 311 |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 474 { | 522 { |
| 475 WritePointerVisitor ptr_writer(isolate(), stream); | 523 WritePointerVisitor ptr_writer(isolate(), stream); |
| 476 isolate()->IterateObjectPointers(&ptr_writer, false, false); | 524 isolate()->IterateObjectPointers(&ptr_writer, false, false); |
| 477 } | 525 } |
| 478 stream->WriteUnsigned(0); | 526 stream->WriteUnsigned(0); |
| 479 IterateObjects(&visitor); | 527 IterateObjects(&visitor); |
| 480 return visitor.count() + 1; // + root | 528 return visitor.count() + 1; // + root |
| 481 } | 529 } |
| 482 | 530 |
| 483 } // namespace dart | 531 } // namespace dart |
| OLD | NEW |