Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(69)

Side by Side Diff: runtime/vm/object_graph.cc

Issue 2481873005: clang-format runtime/vm (Closed)
Patch Set: Merge Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/object_graph.h ('k') | runtime/vm/object_graph_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/reusable_handles.h"
13 #include "vm/visitor.h" 13 #include "vm/visitor.h"
14 14
15 namespace dart { 15 namespace dart {
16 16
17 // 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.
18 // 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.
19 // 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
20 // 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
21 // 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.
22 // 22 //
23 // TODO(koda): Potential optimizations: 23 // TODO(koda): Potential optimizations:
24 // - Use tag bits for compact Node and sentinel representations. 24 // - Use tag bits for compact Node and sentinel representations.
25 class ObjectGraph::Stack : public ObjectPointerVisitor { 25 class ObjectGraph::Stack : public ObjectPointerVisitor {
26 public: 26 public:
27 explicit Stack(Isolate* isolate) 27 explicit Stack(Isolate* isolate)
28 : ObjectPointerVisitor(isolate), data_(kInitialCapacity) { } 28 : ObjectPointerVisitor(isolate), data_(kInitialCapacity) {}
29 29
30 // Marks and pushes. Used to initialize this stack with roots. 30 // Marks and pushes. Used to initialize this stack with roots.
31 virtual void VisitPointers(RawObject** first, RawObject** last) { 31 virtual void VisitPointers(RawObject** first, RawObject** last) {
32 for (RawObject** current = first; current <= last; ++current) { 32 for (RawObject** current = first; current <= last; ++current) {
33 if ((*current)->IsHeapObject() && !(*current)->IsMarked()) { 33 if ((*current)->IsHeapObject() && !(*current)->IsMarked()) {
34 (*current)->SetMarkBit(); 34 (*current)->SetMarkBit();
35 Node node; 35 Node node;
36 node.ptr = current; 36 node.ptr = current;
37 node.obj = *current; 37 node.obj = *current;
38 data_.Add(node); 38 data_.Add(node);
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 Unmarker() { } 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; 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) : StackResource(thread) {
160 : StackResource(thread) {
161 // The VM isolate has all its objects pre-marked, so iterating over it 160 // The VM isolate has all its objects pre-marked, so iterating over it
162 // would be a no-op. 161 // would be a no-op.
163 ASSERT(thread->isolate() != Dart::vm_isolate()); 162 ASSERT(thread->isolate() != Dart::vm_isolate());
164 thread->isolate()->heap()->WriteProtectCode(false); 163 thread->isolate()->heap()->WriteProtectCode(false);
165 } 164 }
166 165
167 166
168 ObjectGraph::~ObjectGraph() { 167 ObjectGraph::~ObjectGraph() {
169 isolate()->heap()->WriteProtectCode(true); 168 isolate()->heap()->WriteProtectCode(true);
170 } 169 }
(...skipping 15 matching lines...) Expand all
186 RawObject* root_raw = root.raw(); 185 RawObject* root_raw = root.raw();
187 stack.VisitPointer(&root_raw); 186 stack.VisitPointer(&root_raw);
188 stack.TraverseGraph(visitor); 187 stack.TraverseGraph(visitor);
189 Unmarker::UnmarkAll(isolate()); 188 Unmarker::UnmarkAll(isolate());
190 } 189 }
191 190
192 191
193 class InstanceAccumulator : public ObjectVisitor { 192 class InstanceAccumulator : public ObjectVisitor {
194 public: 193 public:
195 InstanceAccumulator(ObjectGraph::Stack* stack, intptr_t class_id) 194 InstanceAccumulator(ObjectGraph::Stack* stack, intptr_t class_id)
196 : stack_(stack), class_id_(class_id) { } 195 : stack_(stack), class_id_(class_id) {}
197 196
198 void VisitObject(RawObject* obj) { 197 void VisitObject(RawObject* obj) {
199 if (obj->GetClassId() == class_id_) { 198 if (obj->GetClassId() == class_id_) {
200 RawObject* rawobj = obj; 199 RawObject* rawobj = obj;
201 stack_->VisitPointer(&rawobj); 200 stack_->VisitPointer(&rawobj);
202 } 201 }
203 } 202 }
204 203
205 private: 204 private:
206 ObjectGraph::Stack* stack_; 205 ObjectGraph::Stack* stack_;
(...skipping 11 matching lines...) Expand all
218 InstanceAccumulator accumulator(&stack, class_id); 217 InstanceAccumulator accumulator(&stack, class_id);
219 isolate()->heap()->IterateObjects(&accumulator); 218 isolate()->heap()->IterateObjects(&accumulator);
220 219
221 stack.TraverseGraph(visitor); 220 stack.TraverseGraph(visitor);
222 Unmarker::UnmarkAll(isolate()); 221 Unmarker::UnmarkAll(isolate());
223 } 222 }
224 223
225 224
226 class SizeVisitor : public ObjectGraph::Visitor { 225 class SizeVisitor : public ObjectGraph::Visitor {
227 public: 226 public:
228 SizeVisitor() : size_(0) { } 227 SizeVisitor() : size_(0) {}
229 intptr_t size() const { return size_; } 228 intptr_t size() const { return size_; }
230 virtual bool ShouldSkip(RawObject* obj) const { return false; } 229 virtual bool ShouldSkip(RawObject* obj) const { return false; }
231 virtual Direction VisitObject(ObjectGraph::StackIterator* it) { 230 virtual Direction VisitObject(ObjectGraph::StackIterator* it) {
232 RawObject* obj = it->Get(); 231 RawObject* obj = it->Get();
233 if (ShouldSkip(obj)) { 232 if (ShouldSkip(obj)) {
234 return kBacktrack; 233 return kBacktrack;
235 } 234 }
236 size_ += obj->Size(); 235 size_ += obj->Size();
237 return kProceed; 236 return kProceed;
238 } 237 }
238
239 private: 239 private:
240 intptr_t size_; 240 intptr_t size_;
241 }; 241 };
242 242
243 243
244 class SizeExcludingObjectVisitor : public SizeVisitor { 244 class SizeExcludingObjectVisitor : public SizeVisitor {
245 public: 245 public:
246 explicit SizeExcludingObjectVisitor(const Object& skip) : skip_(skip) { } 246 explicit SizeExcludingObjectVisitor(const Object& skip) : skip_(skip) {}
247 virtual bool ShouldSkip(RawObject* obj) const { return obj == skip_.raw(); } 247 virtual bool ShouldSkip(RawObject* obj) const { return obj == skip_.raw(); }
248
248 private: 249 private:
249 const Object& skip_; 250 const Object& skip_;
250 }; 251 };
251 252
252 253
253 class SizeExcludingClassVisitor : public SizeVisitor { 254 class SizeExcludingClassVisitor : public SizeVisitor {
254 public: 255 public:
255 explicit SizeExcludingClassVisitor(intptr_t skip) : skip_(skip) { } 256 explicit SizeExcludingClassVisitor(intptr_t skip) : skip_(skip) {}
256 virtual bool ShouldSkip(RawObject* obj) const { 257 virtual bool ShouldSkip(RawObject* obj) const {
257 return obj->GetClassId() == skip_; 258 return obj->GetClassId() == skip_;
258 } 259 }
260
259 private: 261 private:
260 const intptr_t skip_; 262 const intptr_t skip_;
261 }; 263 };
262 264
263 265
264 intptr_t ObjectGraph::SizeRetainedByInstance(const Object& obj) { 266 intptr_t ObjectGraph::SizeRetainedByInstance(const Object& obj) {
265 SizeVisitor total; 267 SizeVisitor total;
266 IterateObjects(&total); 268 IterateObjects(&total);
267 intptr_t size_total = total.size(); 269 intptr_t size_total = total.size();
268 SizeExcludingObjectVisitor excluding_obj(obj); 270 SizeExcludingObjectVisitor excluding_obj(obj);
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
305 ASSERT(Thread::Current()->no_safepoint_scope_depth() != 0); 307 ASSERT(Thread::Current()->no_safepoint_scope_depth() != 0);
306 } 308 }
307 309
308 intptr_t length() const { return length_; } 310 intptr_t length() const { return length_; }
309 311
310 bool ShouldSkip(RawObject* obj) { 312 bool ShouldSkip(RawObject* obj) {
311 // A retaining path through ICData is never the only retaining path, 313 // A retaining path through ICData is never the only retaining path,
312 // and it is less informative than its alternatives. 314 // and it is less informative than its alternatives.
313 intptr_t cid = obj->GetClassId(); 315 intptr_t cid = obj->GetClassId();
314 switch (cid) { 316 switch (cid) {
315 case kICDataCid: 317 case kICDataCid:
316 return true; 318 return true;
317 default: 319 default:
318 return false; 320 return false;
319 } 321 }
320 } 322 }
321 323
322 bool ShouldStop(RawObject* obj) { 324 bool ShouldStop(RawObject* obj) {
323 // A static field is considered a root from a language point of view. 325 // A static field is considered a root from a language point of view.
324 if (obj->IsField()) { 326 if (obj->IsField()) {
325 const Field& field = Field::Handle(static_cast<RawField*>(obj)); 327 const Field& field = Field::Handle(static_cast<RawField*>(obj));
326 return field.is_static(); 328 return field.is_static();
327 } 329 }
328 return false; 330 return false;
329 } 331 }
330 332
331 void StartList() { 333 void StartList() { was_last_array_ = false; }
332 was_last_array_ = false;
333 }
334 334
335 intptr_t HideNDescendant(RawObject* obj) { 335 intptr_t HideNDescendant(RawObject* obj) {
336 // A GrowableObjectArray overwrites its internal storage. 336 // A GrowableObjectArray overwrites its internal storage.
337 // Keeping both of them in the list is redundant. 337 // Keeping both of them in the list is redundant.
338 if (was_last_array_ && obj->IsGrowableObjectArray()) { 338 if (was_last_array_ && obj->IsGrowableObjectArray()) {
339 was_last_array_ = false; 339 was_last_array_ = false;
340 return 1; 340 return 1;
341 } 341 }
342 // A LinkedHasMap overwrites its internal storage. 342 // A LinkedHasMap overwrites its internal storage.
343 // Keeping both of them in the list is redundant. 343 // Keeping both of them in the list is redundant.
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
401 401
402 402
403 class InboundReferencesVisitor : public ObjectVisitor, 403 class InboundReferencesVisitor : public ObjectVisitor,
404 public ObjectPointerVisitor { 404 public ObjectPointerVisitor {
405 public: 405 public:
406 // We cannot use a GrowableObjectArray, since we must not trigger GC. 406 // We cannot use a GrowableObjectArray, since we must not trigger GC.
407 InboundReferencesVisitor(Isolate* isolate, 407 InboundReferencesVisitor(Isolate* isolate,
408 RawObject* target, 408 RawObject* target,
409 const Array& references, 409 const Array& references,
410 Object* scratch) 410 Object* scratch)
411 : ObjectPointerVisitor(isolate), source_(NULL), 411 : ObjectPointerVisitor(isolate),
412 target_(target), references_(references), scratch_(scratch), length_(0) { 412 source_(NULL),
413 target_(target),
414 references_(references),
415 scratch_(scratch),
416 length_(0) {
413 ASSERT(Thread::Current()->no_safepoint_scope_depth() != 0); 417 ASSERT(Thread::Current()->no_safepoint_scope_depth() != 0);
414 } 418 }
415 419
416 intptr_t length() const { return length_; } 420 intptr_t length() const { return length_; }
417 421
418 virtual void VisitObject(RawObject* raw_obj) { 422 virtual void VisitObject(RawObject* raw_obj) {
419 source_ = raw_obj; 423 source_ = raw_obj;
420 raw_obj->VisitPointers(this); 424 raw_obj->VisitPointers(this);
421 } 425 }
422 426
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
499 } 503 }
500 504
501 intptr_t count() const { return count_; } 505 intptr_t count() const { return count_; }
502 506
503 private: 507 private:
504 WriteStream* stream_; 508 WriteStream* stream_;
505 intptr_t count_; 509 intptr_t count_;
506 }; 510 };
507 511
508 512
509 static void WriteHeader(RawObject* raw, intptr_t size, intptr_t cid, 513 static void WriteHeader(RawObject* raw,
510 WriteStream* stream) { 514 intptr_t size,
515 intptr_t cid,
516 WriteStream* stream) {
511 WritePtr(raw, stream); 517 WritePtr(raw, stream);
512 ASSERT(Utils::IsAligned(size, kObjectAlignment)); 518 ASSERT(Utils::IsAligned(size, kObjectAlignment));
513 stream->WriteUnsigned(size); 519 stream->WriteUnsigned(size);
514 stream->WriteUnsigned(cid); 520 stream->WriteUnsigned(cid);
515 } 521 }
516 522
517 523
518 class WriteGraphVisitor : public ObjectGraph::Visitor { 524 class WriteGraphVisitor : public ObjectGraph::Visitor {
519 public: 525 public:
520 WriteGraphVisitor(Isolate* isolate, WriteStream* stream) 526 WriteGraphVisitor(Isolate* isolate, WriteStream* stream)
521 : stream_(stream), ptr_writer_(isolate, stream), count_(0) {} 527 : stream_(stream), ptr_writer_(isolate, stream), count_(0) {}
522 528
523 virtual Direction VisitObject(ObjectGraph::StackIterator* it) { 529 virtual Direction VisitObject(ObjectGraph::StackIterator* it) {
524 RawObject* raw_obj = it->Get(); 530 RawObject* raw_obj = it->Get();
525 Thread* thread = Thread::Current(); 531 Thread* thread = Thread::Current();
526 REUSABLE_OBJECT_HANDLESCOPE(thread); 532 REUSABLE_OBJECT_HANDLESCOPE(thread);
527 Object& obj = thread->ObjectHandle(); 533 Object& obj = thread->ObjectHandle();
528 obj = raw_obj; 534 obj = raw_obj;
529 // Each object is a header + a zero-terminated list of its neighbors. 535 // Each object is a header + a zero-terminated list of its neighbors.
530 WriteHeader(raw_obj, raw_obj->Size(), obj.GetClassId(), stream_); 536 WriteHeader(raw_obj, raw_obj->Size(), obj.GetClassId(), stream_);
531 raw_obj->VisitPointers(&ptr_writer_); 537 raw_obj->VisitPointers(&ptr_writer_);
(...skipping 26 matching lines...) Expand all
558 { 564 {
559 WritePointerVisitor ptr_writer(isolate(), stream); 565 WritePointerVisitor ptr_writer(isolate(), stream);
560 isolate()->IterateObjectPointers(&ptr_writer, false); 566 isolate()->IterateObjectPointers(&ptr_writer, false);
561 } 567 }
562 stream->WriteUnsigned(0); 568 stream->WriteUnsigned(0);
563 IterateObjects(&visitor); 569 IterateObjects(&visitor);
564 return visitor.count() + 1; // + root 570 return visitor.count() + 1; // + root
565 } 571 }
566 572
567 } // namespace dart 573 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/object_graph.h ('k') | runtime/vm/object_graph_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698