| 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 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 131 // Some internal VM objects visit pointers not contained within the parent. | 131 // Some internal VM objects visit pointers not contained within the parent. |
| 132 // For instance, RawCode::VisitCodePointers visits pointers in instructions. | 132 // For instance, RawCode::VisitCodePointers visits pointers in instructions. |
| 133 ASSERT(!parent.obj->IsDartInstance()); | 133 ASSERT(!parent.obj->IsDartInstance()); |
| 134 return -1; | 134 return -1; |
| 135 } | 135 } |
| 136 } | 136 } |
| 137 | 137 |
| 138 | 138 |
| 139 class Unmarker : public ObjectVisitor { | 139 class Unmarker : public ObjectVisitor { |
| 140 public: | 140 public: |
| 141 explicit Unmarker(Isolate* isolate) : ObjectVisitor(isolate) { } | 141 Unmarker() { } |
| 142 | 142 |
| 143 void VisitObject(RawObject* obj) { | 143 void VisitObject(RawObject* obj) { |
| 144 if (obj->IsMarked()) { | 144 if (obj->IsMarked()) { |
| 145 obj->ClearMarkBit(); | 145 obj->ClearMarkBit(); |
| 146 } | 146 } |
| 147 } | 147 } |
| 148 | 148 |
| 149 static void UnmarkAll(Isolate* isolate) { | 149 static void UnmarkAll(Isolate* isolate) { |
| 150 Unmarker unmarker(isolate); | 150 Unmarker unmarker; |
| 151 isolate->heap()->IterateObjects(&unmarker); | 151 isolate->heap()->IterateObjects(&unmarker); |
| 152 } | 152 } |
| 153 | 153 |
| 154 private: | 154 private: |
| 155 DISALLOW_COPY_AND_ASSIGN(Unmarker); | 155 DISALLOW_COPY_AND_ASSIGN(Unmarker); |
| 156 }; | 156 }; |
| 157 | 157 |
| 158 | 158 |
| 159 ObjectGraph::ObjectGraph(Thread* thread) | 159 ObjectGraph::ObjectGraph(Thread* thread) |
| 160 : StackResource(thread) { | 160 : StackResource(thread) { |
| (...skipping 24 matching lines...) Expand all Loading... |
| 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 Unmarker::UnmarkAll(isolate()); | 189 Unmarker::UnmarkAll(isolate()); |
| 190 } | 190 } |
| 191 | 191 |
| 192 | 192 |
| 193 class InstanceAccumulator : public ObjectVisitor { | 193 class InstanceAccumulator : public ObjectVisitor { |
| 194 public: | 194 public: |
| 195 explicit InstanceAccumulator(ObjectGraph::Stack* stack, | 195 InstanceAccumulator(ObjectGraph::Stack* stack, intptr_t class_id) |
| 196 intptr_t class_id, | 196 : stack_(stack), class_id_(class_id) { } |
| 197 Isolate* isolate) | |
| 198 : ObjectVisitor(isolate), stack_(stack), class_id_(class_id) { } | |
| 199 | 197 |
| 200 void VisitObject(RawObject* obj) { | 198 void VisitObject(RawObject* obj) { |
| 201 if (obj->GetClassId() == class_id_) { | 199 if (obj->GetClassId() == class_id_) { |
| 202 RawObject* rawobj = obj; | 200 RawObject* rawobj = obj; |
| 203 stack_->VisitPointer(&rawobj); | 201 stack_->VisitPointer(&rawobj); |
| 204 } | 202 } |
| 205 } | 203 } |
| 206 | 204 |
| 207 private: | 205 private: |
| 208 ObjectGraph::Stack* stack_; | 206 ObjectGraph::Stack* stack_; |
| 209 const intptr_t class_id_; | 207 const intptr_t class_id_; |
| 210 | 208 |
| 211 DISALLOW_COPY_AND_ASSIGN(InstanceAccumulator); | 209 DISALLOW_COPY_AND_ASSIGN(InstanceAccumulator); |
| 212 }; | 210 }; |
| 213 | 211 |
| 214 | 212 |
| 215 void ObjectGraph::IterateObjectsFrom(intptr_t class_id, | 213 void ObjectGraph::IterateObjectsFrom(intptr_t class_id, |
| 216 ObjectGraph::Visitor* visitor) { | 214 ObjectGraph::Visitor* visitor) { |
| 217 NoSafepointScope no_safepoint_scope_; | 215 NoSafepointScope no_safepoint_scope_; |
| 218 Stack stack(isolate()); | 216 Stack stack(isolate()); |
| 219 | 217 |
| 220 InstanceAccumulator accumulator(&stack, class_id, isolate()); | 218 InstanceAccumulator accumulator(&stack, class_id); |
| 221 isolate()->heap()->IterateObjects(&accumulator); | 219 isolate()->heap()->IterateObjects(&accumulator); |
| 222 | 220 |
| 223 stack.TraverseGraph(visitor); | 221 stack.TraverseGraph(visitor); |
| 224 Unmarker::UnmarkAll(isolate()); | 222 Unmarker::UnmarkAll(isolate()); |
| 225 } | 223 } |
| 226 | 224 |
| 227 | 225 |
| 228 class SizeVisitor : public ObjectGraph::Visitor { | 226 class SizeVisitor : public ObjectGraph::Visitor { |
| 229 public: | 227 public: |
| 230 SizeVisitor() : size_(0) { } | 228 SizeVisitor() : size_(0) { } |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 369 | 367 |
| 370 | 368 |
| 371 class InboundReferencesVisitor : public ObjectVisitor, | 369 class InboundReferencesVisitor : public ObjectVisitor, |
| 372 public ObjectPointerVisitor { | 370 public ObjectPointerVisitor { |
| 373 public: | 371 public: |
| 374 // We cannot use a GrowableObjectArray, since we must not trigger GC. | 372 // We cannot use a GrowableObjectArray, since we must not trigger GC. |
| 375 InboundReferencesVisitor(Isolate* isolate, | 373 InboundReferencesVisitor(Isolate* isolate, |
| 376 RawObject* target, | 374 RawObject* target, |
| 377 const Array& references, | 375 const Array& references, |
| 378 Object* scratch) | 376 Object* scratch) |
| 379 : ObjectVisitor(isolate), ObjectPointerVisitor(isolate), source_(NULL), | 377 : ObjectPointerVisitor(isolate), source_(NULL), |
| 380 target_(target), references_(references), scratch_(scratch), length_(0) { | 378 target_(target), references_(references), scratch_(scratch), length_(0) { |
| 381 ASSERT(Thread::Current()->no_safepoint_scope_depth() != 0); | 379 ASSERT(Thread::Current()->no_safepoint_scope_depth() != 0); |
| 382 } | 380 } |
| 383 | 381 |
| 384 intptr_t length() const { return length_; } | 382 intptr_t length() const { return length_; } |
| 385 | 383 |
| 386 virtual void VisitObject(RawObject* raw_obj) { | 384 virtual void VisitObject(RawObject* raw_obj) { |
| 387 source_ = raw_obj; | 385 source_ = raw_obj; |
| 388 raw_obj->VisitPointers(this); | 386 raw_obj->VisitPointers(this); |
| 389 } | 387 } |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 526 { | 524 { |
| 527 WritePointerVisitor ptr_writer(isolate(), stream); | 525 WritePointerVisitor ptr_writer(isolate(), stream); |
| 528 isolate()->IterateObjectPointers(&ptr_writer, false); | 526 isolate()->IterateObjectPointers(&ptr_writer, false); |
| 529 } | 527 } |
| 530 stream->WriteUnsigned(0); | 528 stream->WriteUnsigned(0); |
| 531 IterateObjects(&visitor); | 529 IterateObjects(&visitor); |
| 532 return visitor.count() + 1; // + root | 530 return visitor.count() + 1; // + root |
| 533 } | 531 } |
| 534 | 532 |
| 535 } // namespace dart | 533 } // namespace dart |
| OLD | NEW |