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

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

Issue 2566383002: ObjectGraph: Establish a HeapIterationScope *before* making the heap writable, least the sweeper in… (Closed)
Patch Set: . Created 4 years 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/isolate.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"
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
142 Unmarker() {} 142 Unmarker() {}
143 143
144 void VisitObject(RawObject* obj) { 144 void VisitObject(RawObject* obj) {
145 if (obj->IsMarked()) { 145 if (obj->IsMarked()) {
146 obj->ClearMarkBit(); 146 obj->ClearMarkBit();
147 } 147 }
148 } 148 }
149 149
150 static void UnmarkAll(Isolate* isolate) { 150 static void UnmarkAll(Isolate* isolate) {
151 Unmarker unmarker; 151 Unmarker unmarker;
152 isolate->heap()->IterateObjects(&unmarker); 152 isolate->heap()->VisitObjects(&unmarker);
153 } 153 }
154 154
155 private: 155 private:
156 DISALLOW_COPY_AND_ASSIGN(Unmarker); 156 DISALLOW_COPY_AND_ASSIGN(Unmarker);
157 }; 157 };
158 158
159 159
160 ObjectGraph::ObjectGraph(Thread* thread) : StackResource(thread) { 160 ObjectGraph::ObjectGraph(Thread* thread) : StackResource(thread) {
161 // The VM isolate has all its objects pre-marked, so iterating over it 161 // The VM isolate has all its objects pre-marked, so iterating over it
162 // would be a no-op. 162 // would be a no-op.
163 ASSERT(thread->isolate() != Dart::vm_isolate()); 163 ASSERT(thread->isolate() != Dart::vm_isolate());
164 thread->isolate()->heap()->WriteProtectCode(false);
165 } 164 }
166 165
167 166
168 ObjectGraph::~ObjectGraph() { 167 ObjectGraph::~ObjectGraph() {}
169 isolate()->heap()->WriteProtectCode(true);
170 }
171 168
172 169
173 void ObjectGraph::IterateObjects(ObjectGraph::Visitor* visitor) { 170 void ObjectGraph::IterateObjects(ObjectGraph::Visitor* visitor) {
174 NoSafepointScope no_safepoint_scope_; 171 NoSafepointScope no_safepoint_scope_;
175 Stack stack(isolate()); 172 Stack stack(isolate());
176 isolate()->IterateObjectPointers(&stack, false); 173 isolate()->VisitObjectPointers(&stack, false);
177 stack.TraverseGraph(visitor); 174 stack.TraverseGraph(visitor);
178 Unmarker::UnmarkAll(isolate()); 175 Unmarker::UnmarkAll(isolate());
179 } 176 }
180 177
181 178
182 void ObjectGraph::IterateObjectsFrom(const Object& root, 179 void ObjectGraph::IterateObjectsFrom(const Object& root,
183 ObjectGraph::Visitor* visitor) { 180 ObjectGraph::Visitor* visitor) {
184 NoSafepointScope no_safepoint_scope_; 181 NoSafepointScope no_safepoint_scope_;
185 Stack stack(isolate()); 182 Stack stack(isolate());
186 RawObject* root_raw = root.raw(); 183 RawObject* root_raw = root.raw();
(...skipping 22 matching lines...) Expand all
209 DISALLOW_COPY_AND_ASSIGN(InstanceAccumulator); 206 DISALLOW_COPY_AND_ASSIGN(InstanceAccumulator);
210 }; 207 };
211 208
212 209
213 void ObjectGraph::IterateObjectsFrom(intptr_t class_id, 210 void ObjectGraph::IterateObjectsFrom(intptr_t class_id,
214 ObjectGraph::Visitor* visitor) { 211 ObjectGraph::Visitor* visitor) {
215 NoSafepointScope no_safepoint_scope_; 212 NoSafepointScope no_safepoint_scope_;
216 Stack stack(isolate()); 213 Stack stack(isolate());
217 214
218 InstanceAccumulator accumulator(&stack, class_id); 215 InstanceAccumulator accumulator(&stack, class_id);
219 isolate()->heap()->IterateObjects(&accumulator); 216 isolate()->heap()->VisitObjects(&accumulator);
220 217
221 stack.TraverseGraph(visitor); 218 stack.TraverseGraph(visitor);
222 Unmarker::UnmarkAll(isolate()); 219 Unmarker::UnmarkAll(isolate());
223 } 220 }
224 221
225 222
226 class SizeVisitor : public ObjectGraph::Visitor { 223 class SizeVisitor : public ObjectGraph::Visitor {
227 public: 224 public:
228 SizeVisitor() : size_(0) {} 225 SizeVisitor() : size_(0) {}
229 intptr_t size() const { return size_; } 226 intptr_t size() const { return size_; }
(...skipping 28 matching lines...) Expand all
258 virtual bool ShouldSkip(RawObject* obj) const { 255 virtual bool ShouldSkip(RawObject* obj) const {
259 return obj->GetClassId() == skip_; 256 return obj->GetClassId() == skip_;
260 } 257 }
261 258
262 private: 259 private:
263 const intptr_t skip_; 260 const intptr_t skip_;
264 }; 261 };
265 262
266 263
267 intptr_t ObjectGraph::SizeRetainedByInstance(const Object& obj) { 264 intptr_t ObjectGraph::SizeRetainedByInstance(const Object& obj) {
265 HeapIterationScope iteration_scope(true);
268 SizeVisitor total; 266 SizeVisitor total;
269 IterateObjects(&total); 267 IterateObjects(&total);
270 intptr_t size_total = total.size(); 268 intptr_t size_total = total.size();
271 SizeExcludingObjectVisitor excluding_obj(obj); 269 SizeExcludingObjectVisitor excluding_obj(obj);
272 IterateObjects(&excluding_obj); 270 IterateObjects(&excluding_obj);
273 intptr_t size_excluding_obj = excluding_obj.size(); 271 intptr_t size_excluding_obj = excluding_obj.size();
274 return size_total - size_excluding_obj; 272 return size_total - size_excluding_obj;
275 } 273 }
276 274
277 275
278 intptr_t ObjectGraph::SizeReachableByInstance(const Object& obj) { 276 intptr_t ObjectGraph::SizeReachableByInstance(const Object& obj) {
277 HeapIterationScope iteration_scope(true);
279 SizeVisitor total; 278 SizeVisitor total;
280 IterateObjectsFrom(obj, &total); 279 IterateObjectsFrom(obj, &total);
281 return total.size(); 280 return total.size();
282 } 281 }
283 282
284 283
285 intptr_t ObjectGraph::SizeRetainedByClass(intptr_t class_id) { 284 intptr_t ObjectGraph::SizeRetainedByClass(intptr_t class_id) {
285 HeapIterationScope iteration_scope(true);
286 SizeVisitor total; 286 SizeVisitor total;
287 IterateObjects(&total); 287 IterateObjects(&total);
288 intptr_t size_total = total.size(); 288 intptr_t size_total = total.size();
289 SizeExcludingClassVisitor excluding_class(class_id); 289 SizeExcludingClassVisitor excluding_class(class_id);
290 IterateObjects(&excluding_class); 290 IterateObjects(&excluding_class);
291 intptr_t size_excluding_class = excluding_class.size(); 291 intptr_t size_excluding_class = excluding_class.size();
292 return size_total - size_excluding_class; 292 return size_total - size_excluding_class;
293 } 293 }
294 294
295 295
296 intptr_t ObjectGraph::SizeReachableByClass(intptr_t class_id) { 296 intptr_t ObjectGraph::SizeReachableByClass(intptr_t class_id) {
297 HeapIterationScope iteration_scope(true);
297 SizeVisitor total; 298 SizeVisitor total;
298 IterateObjectsFrom(class_id, &total); 299 IterateObjectsFrom(class_id, &total);
299 return total.size(); 300 return total.size();
300 } 301 }
301 302
302 303
303 class RetainingPathVisitor : public ObjectGraph::Visitor { 304 class RetainingPathVisitor : public ObjectGraph::Visitor {
304 public: 305 public:
305 // We cannot use a GrowableObjectArray, since we must not trigger GC. 306 // We cannot use a GrowableObjectArray, since we must not trigger GC.
306 RetainingPathVisitor(RawObject* obj, const Array& path) 307 RetainingPathVisitor(RawObject* obj, const Array& path)
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
383 Thread* thread_; 384 Thread* thread_;
384 RawObject* obj_; 385 RawObject* obj_;
385 const Array& path_; 386 const Array& path_;
386 intptr_t length_; 387 intptr_t length_;
387 bool was_last_array_; 388 bool was_last_array_;
388 }; 389 };
389 390
390 391
391 intptr_t ObjectGraph::RetainingPath(Object* obj, const Array& path) { 392 intptr_t ObjectGraph::RetainingPath(Object* obj, const Array& path) {
392 NoSafepointScope no_safepoint_scope_; 393 NoSafepointScope no_safepoint_scope_;
394 HeapIterationScope iteration_scope(true);
393 // To break the trivial path, the handle 'obj' is temporarily cleared during 395 // To break the trivial path, the handle 'obj' is temporarily cleared during
394 // the search, but restored before returning. 396 // the search, but restored before returning.
395 RawObject* raw = obj->raw(); 397 RawObject* raw = obj->raw();
396 *obj = Object::null(); 398 *obj = Object::null();
397 RetainingPathVisitor visitor(raw, path); 399 RetainingPathVisitor visitor(raw, path);
398 IterateObjects(&visitor); 400 IterateObjects(&visitor);
399 *obj = raw; 401 *obj = raw;
400 return visitor.length(); 402 return visitor.length();
401 } 403 }
402 404
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
460 RawObject* source_; 462 RawObject* source_;
461 RawObject* target_; 463 RawObject* target_;
462 const Array& references_; 464 const Array& references_;
463 Object* scratch_; 465 Object* scratch_;
464 intptr_t length_; 466 intptr_t length_;
465 }; 467 };
466 468
467 469
468 intptr_t ObjectGraph::InboundReferences(Object* obj, const Array& references) { 470 intptr_t ObjectGraph::InboundReferences(Object* obj, const Array& references) {
469 Object& scratch = Object::Handle(); 471 Object& scratch = Object::Handle();
470 NoSafepointScope no_safepoint_scope_; 472 NoSafepointScope no_safepoint_scope;
471 InboundReferencesVisitor visitor(isolate(), obj->raw(), references, &scratch); 473 InboundReferencesVisitor visitor(isolate(), obj->raw(), references, &scratch);
472 isolate()->heap()->IterateObjects(&visitor); 474 isolate()->heap()->IterateObjects(&visitor);
473 return visitor.length(); 475 return visitor.length();
474 } 476 }
475 477
476 478
477 static void WritePtr(RawObject* raw, WriteStream* stream) { 479 static void WritePtr(RawObject* raw, WriteStream* stream) {
478 ASSERT(raw->IsHeapObject()); 480 ASSERT(raw->IsHeapObject());
479 ASSERT(raw->IsOldObject()); 481 ASSERT(raw->IsOldObject());
480 uword addr = RawObject::ToAddr(raw); 482 uword addr = RawObject::ToAddr(raw);
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
604 606
605 607
606 intptr_t ObjectGraph::Serialize(WriteStream* stream, 608 intptr_t ObjectGraph::Serialize(WriteStream* stream,
607 SnapshotRoots roots, 609 SnapshotRoots roots,
608 bool collect_garbage) { 610 bool collect_garbage) {
609 if (collect_garbage) { 611 if (collect_garbage) {
610 isolate()->heap()->CollectAllGarbage(); 612 isolate()->heap()->CollectAllGarbage();
611 } 613 }
612 // Current encoding assumes objects do not move, so promote everything to old. 614 // Current encoding assumes objects do not move, so promote everything to old.
613 isolate()->heap()->new_space()->Evacuate(); 615 isolate()->heap()->new_space()->Evacuate();
616 HeapIterationScope iteration_scope(true);
614 617
615 RawObject* kRootAddress = reinterpret_cast<RawObject*>(kHeapObjectTag); 618 RawObject* kRootAddress = reinterpret_cast<RawObject*>(kHeapObjectTag);
616 const intptr_t kRootCid = kIllegalCid; 619 const intptr_t kRootCid = kIllegalCid;
617 RawObject* kStackAddress = 620 RawObject* kStackAddress =
618 reinterpret_cast<RawObject*>(kObjectAlignment + kHeapObjectTag); 621 reinterpret_cast<RawObject*>(kObjectAlignment + kHeapObjectTag);
619 622
620 stream->WriteUnsigned(kObjectAlignment); 623 stream->WriteUnsigned(kObjectAlignment);
621 stream->WriteUnsigned(kStackCid); 624 stream->WriteUnsigned(kStackCid);
622 625
623 if (roots == kVM) { 626 if (roots == kVM) {
624 // Write root "object". 627 // Write root "object".
625 WriteHeader(kRootAddress, 0, kRootCid, stream); 628 WriteHeader(kRootAddress, 0, kRootCid, stream);
626 WritePointerVisitor ptr_writer(isolate(), stream, false); 629 WritePointerVisitor ptr_writer(isolate(), stream, false);
627 isolate()->IterateObjectPointers(&ptr_writer, false); 630 isolate()->VisitObjectPointers(&ptr_writer, false);
628 stream->WriteUnsigned(0); 631 stream->WriteUnsigned(0);
629 } else { 632 } else {
630 { 633 {
631 // Write root "object". 634 // Write root "object".
632 WriteHeader(kRootAddress, 0, kRootCid, stream); 635 WriteHeader(kRootAddress, 0, kRootCid, stream);
633 WritePointerVisitor ptr_writer(isolate(), stream, false); 636 WritePointerVisitor ptr_writer(isolate(), stream, false);
634 IterateUserFields(&ptr_writer); 637 IterateUserFields(&ptr_writer);
635 WritePtr(kStackAddress, stream); 638 WritePtr(kStackAddress, stream);
636 stream->WriteUnsigned(0); 639 stream->WriteUnsigned(0);
637 } 640 }
638 641
639 { 642 {
640 // Write stack "object". 643 // Write stack "object".
641 WriteHeader(kStackAddress, 0, kStackCid, stream); 644 WriteHeader(kStackAddress, 0, kStackCid, stream);
642 WritePointerVisitor ptr_writer(isolate(), stream, true); 645 WritePointerVisitor ptr_writer(isolate(), stream, true);
643 isolate()->IterateStackPointers(&ptr_writer, false); 646 isolate()->VisitStackPointers(&ptr_writer, false);
644 stream->WriteUnsigned(0); 647 stream->WriteUnsigned(0);
645 } 648 }
646 } 649 }
647 650
648 WriteGraphVisitor visitor(isolate(), stream, roots); 651 WriteGraphVisitor visitor(isolate(), stream, roots);
649 IterateObjects(&visitor); 652 IterateObjects(&visitor);
650 653
651 intptr_t object_count = visitor.count(); 654 intptr_t object_count = visitor.count();
652 if (roots == kVM) { 655 if (roots == kVM) {
653 object_count += 1; // root 656 object_count += 1; // root
654 } else { 657 } else {
655 object_count += 2; // root and stack 658 object_count += 2; // root and stack
656 } 659 }
657 return object_count; 660 return object_count;
658 } 661 }
659 662
660 } // namespace dart 663 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/isolate.h ('k') | runtime/vm/object_graph_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698