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" |
| 11 #include "vm/raw_object.h" | 11 #include "vm/raw_object.h" |
| 12 #include "vm/reusable_handles.h" | |
| 12 #include "vm/visitor.h" | 13 #include "vm/visitor.h" |
| 13 | 14 |
| 14 namespace dart { | 15 namespace dart { |
| 15 | 16 |
| 16 // The state of a pre-order, depth-first traversal of an object graph. | 17 // The state of a pre-order, depth-first traversal of an object graph. |
| 17 // When a node is visited, *all* its children are pushed to the stack at once. | 18 // When a node is visited, *all* its children are pushed to the stack at once. |
| 18 // We insert a sentinel between the node and its children on the stack, to | 19 // We insert a sentinel between the node and its children on the stack, to |
| 19 // remember that the node has been visited. The node is kept on the stack while | 20 // remember that the node has been visited. The node is kept on the stack while |
| 20 // its children are processed, to give the visitor a complete chain of parents. | 21 // its children are processed, to give the visitor a complete chain of parents. |
| 21 // | 22 // |
| (...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 363 | 364 |
| 364 | 365 |
| 365 intptr_t ObjectGraph::InboundReferences(Object* obj, const Array& references) { | 366 intptr_t ObjectGraph::InboundReferences(Object* obj, const Array& references) { |
| 366 Object& scratch = Object::Handle(); | 367 Object& scratch = Object::Handle(); |
| 367 NoGCScope no_gc_scope_; | 368 NoGCScope no_gc_scope_; |
| 368 InboundReferencesVisitor visitor(isolate(), obj->raw(), references, &scratch); | 369 InboundReferencesVisitor visitor(isolate(), obj->raw(), references, &scratch); |
| 369 isolate()->heap()->IterateObjects(&visitor); | 370 isolate()->heap()->IterateObjects(&visitor); |
| 370 return visitor.length(); | 371 return visitor.length(); |
| 371 } | 372 } |
| 372 | 373 |
| 374 | |
| 375 void WritePtr(RawObject* raw, WriteStream* stream) { | |
| 376 ASSERT(raw->IsHeapObject()); | |
| 377 ASSERT(raw->IsOldObject()); | |
| 378 uword addr = RawObject::ToAddr(raw); | |
| 379 ASSERT(Utils::IsAligned(addr, kObjectAlignment)); | |
| 380 // TODO(koda): Use delta-encoding/back-references to compress this. | |
| 381 stream->WriteUnsigned(addr / kObjectAlignment); | |
| 382 } | |
| 383 | |
| 384 | |
| 385 class WritePointerVisitor : public ObjectPointerVisitor { | |
| 386 public: | |
| 387 WritePointerVisitor(Isolate* isolate, WriteStream* stream) | |
| 388 : ObjectPointerVisitor(isolate), stream_(stream), count_(0) {} | |
| 389 virtual void VisitPointers(RawObject** first, RawObject** last) { | |
| 390 for (RawObject** current = first; current <= last; ++current) { | |
| 391 if (!(*current)->IsHeapObject() || (*current == Object::null())) { | |
| 392 // Ignore smis and nulls for now. | |
| 393 // TODO(koda): To track which field each pointer corresponds to, | |
| 394 // we'll need to encode which fields were omitted here. | |
|
Cutch
2014/12/02 16:46:26
Just curious: Why not send tagged pointers over th
koda
2014/12/02 18:47:12
1. For now, we mainly care about the graph shape a
| |
| 395 continue; | |
| 396 } | |
| 397 WritePtr(*current, stream_); | |
| 398 ++count_; | |
| 399 } | |
| 400 } | |
| 401 | |
| 402 intptr_t count() const { return count_; } | |
| 403 | |
| 404 private: | |
| 405 WriteStream* stream_; | |
| 406 intptr_t count_; | |
| 407 }; | |
| 408 | |
| 409 | |
| 410 void WriteHeader(RawObject* raw, intptr_t size, intptr_t cid, | |
| 411 WriteStream* stream) { | |
| 412 WritePtr(raw, stream); | |
| 413 ASSERT(Utils::IsAligned(size, kObjectAlignment)); | |
| 414 stream->WriteUnsigned(size); | |
| 415 stream->WriteUnsigned(cid); | |
| 416 } | |
| 417 | |
| 418 | |
| 419 class WriteGraphVisitor : public ObjectGraph::Visitor { | |
| 420 public: | |
| 421 WriteGraphVisitor(Isolate* isolate, WriteStream* stream) | |
| 422 : stream_(stream), ptr_writer_(isolate, stream), count_(0) {} | |
| 423 | |
| 424 virtual Direction VisitObject(ObjectGraph::StackIterator* it) { | |
| 425 RawObject* raw_obj = it->Get(); | |
| 426 Isolate* isolate = Isolate::Current(); | |
| 427 REUSABLE_OBJECT_HANDLESCOPE(isolate); | |
| 428 Object& obj = isolate->ObjectHandle(); | |
| 429 obj = raw_obj; | |
| 430 // Each object is a header + a zero-terminated list of its neighbors. | |
| 431 WriteHeader(raw_obj, raw_obj->Size(), obj.GetClassId(), stream_); | |
| 432 raw_obj->VisitPointers(&ptr_writer_); | |
| 433 stream_->WriteUnsigned(0); | |
| 434 ++count_; | |
| 435 return kProceed; | |
| 436 } | |
| 437 | |
| 438 intptr_t count() const { return count_; } | |
| 439 | |
| 440 private: | |
| 441 WriteStream* stream_; | |
| 442 WritePointerVisitor ptr_writer_; | |
| 443 intptr_t count_; | |
| 444 }; | |
| 445 | |
| 446 | |
| 447 void ObjectGraph::Serialize(WriteStream* stream) { | |
| 448 // Current encoding assumes objects do not move, so promote everything to old. | |
| 449 isolate()->heap()->new_space()->Evacuate(); | |
| 450 WriteGraphVisitor visitor(isolate(), stream); | |
| 451 stream->WriteUnsigned(0); | |
| 452 stream->WriteUnsigned(0); | |
| 453 stream->WriteUnsigned(0); | |
| 454 { | |
| 455 WritePointerVisitor ptr_writer(isolate(), stream); | |
| 456 isolate()->VisitObjectPointers(&ptr_writer, false, false); | |
| 457 } | |
| 458 stream->WriteUnsigned(0); | |
| 459 IterateObjects(&visitor); | |
| 460 OS::PrintErr("%" Pd "\n", visitor.count()); | |
|
Cutch
2014/12/02 16:46:26
Remove before submitting
koda
2014/12/02 18:47:12
Done.
| |
| 461 } | |
| 462 | |
| 373 } // namespace dart | 463 } // namespace dart |
| OLD | NEW |