Chromium Code Reviews| 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 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 312 // and it is less informative than its alternatives. | 312 // and it is less informative than its alternatives. |
| 313 intptr_t cid = obj->GetClassId(); | 313 intptr_t cid = obj->GetClassId(); |
| 314 switch (cid) { | 314 switch (cid) { |
| 315 case kICDataCid: | 315 case kICDataCid: |
| 316 return true; | 316 return true; |
| 317 default: | 317 default: |
| 318 return false; | 318 return false; |
| 319 } | 319 } |
| 320 } | 320 } |
| 321 | 321 |
| 322 bool ShouldStop(RawObject* obj) { | |
| 323 // A static field is considered a root from a language point of view. | |
| 324 if (obj->IsField()) { | |
| 325 const Field& field = Field::Handle(static_cast<RawField*>(obj)); | |
| 326 return field.is_static(); | |
| 327 } | |
| 328 return false; | |
| 329 } | |
| 330 | |
| 331 void StartList() { | |
| 332 wasLastArray_ = false; | |
|
Cutch
2016/08/12 14:23:39
C++ style guide says variables are lower_case_like
cbernaschina
2016/08/12 17:28:24
Done.
| |
| 333 } | |
| 334 | |
| 335 bool ShouldOverwrite(RawObject* obj) { | |
|
Cutch
2016/08/12 14:23:40
ShouldReplace?
cbernaschina
2016/08/12 17:28:24
Changed approach, and name
| |
| 336 // A GrowableObjectArray overwrites its internal storage. | |
| 337 // Keeping both of them in the list is redundant. | |
| 338 if (wasLastArray_ && obj->IsGrowableObjectArray()) { | |
| 339 wasLastArray_ = false; | |
| 340 return true; | |
| 341 } | |
| 342 wasLastArray_ = obj->IsArray(); | |
| 343 return false; | |
| 344 } | |
| 345 | |
| 322 virtual Direction VisitObject(ObjectGraph::StackIterator* it) { | 346 virtual Direction VisitObject(ObjectGraph::StackIterator* it) { |
| 323 if (it->Get() != obj_) { | 347 if (it->Get() != obj_) { |
| 324 if (ShouldSkip(it->Get())) { | 348 if (ShouldSkip(it->Get())) { |
| 325 return kBacktrack; | 349 return kBacktrack; |
| 326 } else { | 350 } else { |
| 327 return kProceed; | 351 return kProceed; |
| 328 } | 352 } |
| 329 } else { | 353 } else { |
| 330 HANDLESCOPE(thread_); | 354 HANDLESCOPE(thread_); |
| 331 Object& current = Object::Handle(); | 355 Object& current = Object::Handle(); |
| 332 Smi& offset_from_parent = Smi::Handle(); | 356 Smi& offset_from_parent = Smi::Handle(); |
| 357 StartList(); | |
| 333 do { | 358 do { |
| 359 if (ShouldOverwrite(it->Get())) { | |
| 360 --length_; | |
| 361 } | |
| 334 intptr_t obj_index = length_ * 2; | 362 intptr_t obj_index = length_ * 2; |
| 335 intptr_t offset_index = obj_index + 1; | 363 intptr_t offset_index = obj_index + 1; |
| 336 if (!path_.IsNull() && offset_index < path_.Length()) { | 364 if (!path_.IsNull() && offset_index < path_.Length()) { |
| 337 current = it->Get(); | 365 current = it->Get(); |
| 338 path_.SetAt(obj_index, current); | 366 path_.SetAt(obj_index, current); |
| 339 offset_from_parent = Smi::New(it->OffsetFromParentInWords()); | 367 offset_from_parent = Smi::New(it->OffsetFromParentInWords()); |
| 340 path_.SetAt(offset_index, offset_from_parent); | 368 path_.SetAt(offset_index, offset_from_parent); |
| 341 } | 369 } |
| 342 ++length_; | 370 ++length_; |
| 343 } while (it->MoveToParent()); | 371 } while (!ShouldStop(it->Get()) && it->MoveToParent()); |
| 344 return kAbort; | 372 return kAbort; |
| 345 } | 373 } |
| 346 } | 374 } |
| 347 | 375 |
| 348 private: | 376 private: |
| 349 Thread* thread_; | 377 Thread* thread_; |
| 350 RawObject* obj_; | 378 RawObject* obj_; |
| 351 const Array& path_; | 379 const Array& path_; |
| 352 intptr_t length_; | 380 intptr_t length_; |
| 381 bool wasLastArray_; | |
| 353 }; | 382 }; |
| 354 | 383 |
| 355 | 384 |
| 356 intptr_t ObjectGraph::RetainingPath(Object* obj, const Array& path) { | 385 intptr_t ObjectGraph::RetainingPath(Object* obj, const Array& path) { |
| 357 NoSafepointScope no_safepoint_scope_; | 386 NoSafepointScope no_safepoint_scope_; |
| 358 // To break the trivial path, the handle 'obj' is temporarily cleared during | 387 // To break the trivial path, the handle 'obj' is temporarily cleared during |
| 359 // the search, but restored before returning. | 388 // the search, but restored before returning. |
| 360 RawObject* raw = obj->raw(); | 389 RawObject* raw = obj->raw(); |
| 361 *obj = Object::null(); | 390 *obj = Object::null(); |
| 362 RetainingPathVisitor visitor(raw, path); | 391 RetainingPathVisitor visitor(raw, path); |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 524 { | 553 { |
| 525 WritePointerVisitor ptr_writer(isolate(), stream); | 554 WritePointerVisitor ptr_writer(isolate(), stream); |
| 526 isolate()->IterateObjectPointers(&ptr_writer, false); | 555 isolate()->IterateObjectPointers(&ptr_writer, false); |
| 527 } | 556 } |
| 528 stream->WriteUnsigned(0); | 557 stream->WriteUnsigned(0); |
| 529 IterateObjects(&visitor); | 558 IterateObjects(&visitor); |
| 530 return visitor.count() + 1; // + root | 559 return visitor.count() + 1; // + root |
| 531 } | 560 } |
| 532 | 561 |
| 533 } // namespace dart | 562 } // namespace dart |
| OLD | NEW |