| 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 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 164 isolate->heap()->WriteProtectCode(false); | 164 isolate->heap()->WriteProtectCode(false); |
| 165 } | 165 } |
| 166 | 166 |
| 167 | 167 |
| 168 ObjectGraph::~ObjectGraph() { | 168 ObjectGraph::~ObjectGraph() { |
| 169 isolate()->heap()->WriteProtectCode(true); | 169 isolate()->heap()->WriteProtectCode(true); |
| 170 } | 170 } |
| 171 | 171 |
| 172 | 172 |
| 173 void ObjectGraph::IterateObjects(ObjectGraph::Visitor* visitor) { | 173 void ObjectGraph::IterateObjects(ObjectGraph::Visitor* visitor) { |
| 174 NoGCScope no_gc_scope_; | 174 NoSafepointScope no_safepoint_scope_; |
| 175 Stack stack(isolate()); | 175 Stack stack(isolate()); |
| 176 isolate()->VisitObjectPointers(&stack, false, false); | 176 isolate()->VisitObjectPointers(&stack, false, false); |
| 177 stack.TraverseGraph(visitor); | 177 stack.TraverseGraph(visitor); |
| 178 Unmarker::UnmarkAll(isolate()); | 178 Unmarker::UnmarkAll(isolate()); |
| 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 NoGCScope no_gc_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. | 189 // TODO(koda): Optimize if we only visited a small subgraph. |
| 190 Unmarker::UnmarkAll(isolate()); | 190 Unmarker::UnmarkAll(isolate()); |
| 191 } | 191 } |
| 192 | 192 |
| 193 | 193 |
| 194 class SizeVisitor : public ObjectGraph::Visitor { | 194 class SizeVisitor : public ObjectGraph::Visitor { |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 249 intptr_t size_excluding_class = excluding_class.size(); | 249 intptr_t size_excluding_class = excluding_class.size(); |
| 250 return size_total - size_excluding_class; | 250 return size_total - size_excluding_class; |
| 251 } | 251 } |
| 252 | 252 |
| 253 | 253 |
| 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(Isolate::Current()->no_gc_scope_depth() != 0); | 259 ASSERT(Isolate::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 virtual Direction VisitObject(ObjectGraph::StackIterator* it) { | 264 virtual Direction VisitObject(ObjectGraph::StackIterator* it) { |
| 265 if (it->Get() != obj_) { | 265 if (it->Get() != obj_) { |
| 266 return kProceed; | 266 return kProceed; |
| 267 } else { | 267 } else { |
| 268 HANDLESCOPE(Isolate::Current()); | 268 HANDLESCOPE(Isolate::Current()); |
| 269 Object& current = Object::Handle(); | 269 Object& current = Object::Handle(); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 284 } | 284 } |
| 285 | 285 |
| 286 private: | 286 private: |
| 287 RawObject* obj_; | 287 RawObject* obj_; |
| 288 const Array& path_; | 288 const Array& path_; |
| 289 intptr_t length_; | 289 intptr_t length_; |
| 290 }; | 290 }; |
| 291 | 291 |
| 292 | 292 |
| 293 intptr_t ObjectGraph::RetainingPath(Object* obj, const Array& path) { | 293 intptr_t ObjectGraph::RetainingPath(Object* obj, const Array& path) { |
| 294 NoGCScope no_gc_scope_; | 294 NoSafepointScope no_safepoint_scope_; |
| 295 // To break the trivial path, the handle 'obj' is temporarily cleared during | 295 // To break the trivial path, the handle 'obj' is temporarily cleared during |
| 296 // the search, but restored before returning. | 296 // the search, but restored before returning. |
| 297 RawObject* raw = obj->raw(); | 297 RawObject* raw = obj->raw(); |
| 298 *obj = Object::null(); | 298 *obj = Object::null(); |
| 299 RetainingPathVisitor visitor(raw, path); | 299 RetainingPathVisitor visitor(raw, path); |
| 300 IterateObjects(&visitor); | 300 IterateObjects(&visitor); |
| 301 *obj = raw; | 301 *obj = raw; |
| 302 return visitor.length(); | 302 return visitor.length(); |
| 303 } | 303 } |
| 304 | 304 |
| 305 | 305 |
| 306 class InboundReferencesVisitor : public ObjectVisitor, | 306 class InboundReferencesVisitor : public ObjectVisitor, |
| 307 public ObjectPointerVisitor { | 307 public ObjectPointerVisitor { |
| 308 public: | 308 public: |
| 309 // We cannot use a GrowableObjectArray, since we must not trigger GC. | 309 // We cannot use a GrowableObjectArray, since we must not trigger GC. |
| 310 InboundReferencesVisitor(Isolate* isolate, | 310 InboundReferencesVisitor(Isolate* isolate, |
| 311 RawObject* target, | 311 RawObject* target, |
| 312 const Array& references, | 312 const Array& references, |
| 313 Object* scratch) | 313 Object* scratch) |
| 314 : ObjectVisitor(isolate), ObjectPointerVisitor(isolate), source_(NULL), | 314 : ObjectVisitor(isolate), ObjectPointerVisitor(isolate), source_(NULL), |
| 315 target_(target), references_(references), scratch_(scratch), length_(0) { | 315 target_(target), references_(references), scratch_(scratch), length_(0) { |
| 316 ASSERT(Isolate::Current()->no_gc_scope_depth() != 0); | 316 ASSERT(Isolate::Current()->no_safepoint_scope_depth() != 0); |
| 317 } | 317 } |
| 318 | 318 |
| 319 intptr_t length() const { return length_; } | 319 intptr_t length() const { return length_; } |
| 320 | 320 |
| 321 virtual void VisitObject(RawObject* raw_obj) { | 321 virtual void VisitObject(RawObject* raw_obj) { |
| 322 source_ = raw_obj; | 322 source_ = raw_obj; |
| 323 raw_obj->VisitPointers(this); | 323 raw_obj->VisitPointers(this); |
| 324 } | 324 } |
| 325 | 325 |
| 326 virtual void VisitPointers(RawObject** first, RawObject** last) { | 326 virtual void VisitPointers(RawObject** first, RawObject** last) { |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 358 RawObject* source_; | 358 RawObject* source_; |
| 359 RawObject* target_; | 359 RawObject* target_; |
| 360 const Array& references_; | 360 const Array& references_; |
| 361 Object* scratch_; | 361 Object* scratch_; |
| 362 intptr_t length_; | 362 intptr_t length_; |
| 363 }; | 363 }; |
| 364 | 364 |
| 365 | 365 |
| 366 intptr_t ObjectGraph::InboundReferences(Object* obj, const Array& references) { | 366 intptr_t ObjectGraph::InboundReferences(Object* obj, const Array& references) { |
| 367 Object& scratch = Object::Handle(); | 367 Object& scratch = Object::Handle(); |
| 368 NoGCScope no_gc_scope_; | 368 NoSafepointScope no_safepoint_scope_; |
| 369 InboundReferencesVisitor visitor(isolate(), obj->raw(), references, &scratch); | 369 InboundReferencesVisitor visitor(isolate(), obj->raw(), references, &scratch); |
| 370 isolate()->heap()->IterateObjects(&visitor); | 370 isolate()->heap()->IterateObjects(&visitor); |
| 371 return visitor.length(); | 371 return visitor.length(); |
| 372 } | 372 } |
| 373 | 373 |
| 374 | 374 |
| 375 static void WritePtr(RawObject* raw, WriteStream* stream) { | 375 static void WritePtr(RawObject* raw, WriteStream* stream) { |
| 376 ASSERT(raw->IsHeapObject()); | 376 ASSERT(raw->IsHeapObject()); |
| 377 ASSERT(raw->IsOldObject()); | 377 ASSERT(raw->IsOldObject()); |
| 378 uword addr = RawObject::ToAddr(raw); | 378 uword addr = RawObject::ToAddr(raw); |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 455 stream->WriteUnsigned(0); | 455 stream->WriteUnsigned(0); |
| 456 { | 456 { |
| 457 WritePointerVisitor ptr_writer(isolate(), stream); | 457 WritePointerVisitor ptr_writer(isolate(), stream); |
| 458 isolate()->VisitObjectPointers(&ptr_writer, false, false); | 458 isolate()->VisitObjectPointers(&ptr_writer, false, false); |
| 459 } | 459 } |
| 460 stream->WriteUnsigned(0); | 460 stream->WriteUnsigned(0); |
| 461 IterateObjects(&visitor); | 461 IterateObjects(&visitor); |
| 462 } | 462 } |
| 463 | 463 |
| 464 } // namespace dart | 464 } // namespace dart |
| OLD | NEW |