| 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 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 254 class RetainingPathVisitor : public ObjectGraph::Visitor { | 254 class RetainingPathVisitor : public ObjectGraph::Visitor { |
| 255 public: | 255 public: |
| 256 // We cannot use a GrowableObjectArray, since we must not trigger GC. | 256 // We cannot use a GrowableObjectArray, since we must not trigger GC. |
| 257 RetainingPathVisitor(RawObject* obj, const Array& path) | 257 RetainingPathVisitor(RawObject* obj, const Array& path) |
| 258 : obj_(obj), path_(path), length_(0) { | 258 : obj_(obj), path_(path), length_(0) { |
| 259 ASSERT(Thread::Current()->no_safepoint_scope_depth() != 0); | 259 ASSERT(Thread::Current()->no_safepoint_scope_depth() != 0); |
| 260 } | 260 } |
| 261 | 261 |
| 262 intptr_t length() const { return length_; } | 262 intptr_t length() const { return length_; } |
| 263 | 263 |
| 264 bool ShouldSkip(RawObject* obj) { |
| 265 // A retaining path through ICData is never the only retaining path, |
| 266 // and it is less informative than its alternatives. |
| 267 intptr_t cid = obj->GetClassId(); |
| 268 switch (cid) { |
| 269 case kICDataCid: |
| 270 return true; |
| 271 default: |
| 272 return false; |
| 273 } |
| 274 } |
| 275 |
| 264 virtual Direction VisitObject(ObjectGraph::StackIterator* it) { | 276 virtual Direction VisitObject(ObjectGraph::StackIterator* it) { |
| 265 if (it->Get() != obj_) { | 277 if (it->Get() != obj_) { |
| 266 return kProceed; | 278 if (ShouldSkip(it->Get())) { |
| 279 return kBacktrack; |
| 280 } else { |
| 281 return kProceed; |
| 282 } |
| 267 } else { | 283 } else { |
| 268 HANDLESCOPE(Isolate::Current()); | 284 HANDLESCOPE(Isolate::Current()); |
| 269 Object& current = Object::Handle(); | 285 Object& current = Object::Handle(); |
| 270 Smi& offset_from_parent = Smi::Handle(); | 286 Smi& offset_from_parent = Smi::Handle(); |
| 271 do { | 287 do { |
| 272 intptr_t obj_index = length_ * 2; | 288 intptr_t obj_index = length_ * 2; |
| 273 intptr_t offset_index = obj_index + 1; | 289 intptr_t offset_index = obj_index + 1; |
| 274 if (!path_.IsNull() && offset_index < path_.Length()) { | 290 if (!path_.IsNull() && offset_index < path_.Length()) { |
| 275 current = it->Get(); | 291 current = it->Get(); |
| 276 path_.SetAt(obj_index, current); | 292 path_.SetAt(obj_index, current); |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 457 { | 473 { |
| 458 WritePointerVisitor ptr_writer(isolate(), stream); | 474 WritePointerVisitor ptr_writer(isolate(), stream); |
| 459 isolate()->IterateObjectPointers(&ptr_writer, false, false); | 475 isolate()->IterateObjectPointers(&ptr_writer, false, false); |
| 460 } | 476 } |
| 461 stream->WriteUnsigned(0); | 477 stream->WriteUnsigned(0); |
| 462 IterateObjects(&visitor); | 478 IterateObjects(&visitor); |
| 463 return visitor.count() + 1; // + root | 479 return visitor.count() + 1; // + root |
| 464 } | 480 } |
| 465 | 481 |
| 466 } // namespace dart | 482 } // namespace dart |
| OLD | NEW |