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

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

Issue 27604002: - Add more data collection to the scavenger. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 2 months 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 | Annotate | Revision Log
« no previous file with comments | « runtime/vm/scavenger.h ('k') | no next file » | 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) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, 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/scavenger.h" 5 #include "vm/scavenger.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <map> 8 #include <map>
9 #include <utility> 9 #include <utility>
10 10
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
66 }; 66 };
67 67
68 68
69 class ScavengerVisitor : public ObjectPointerVisitor { 69 class ScavengerVisitor : public ObjectPointerVisitor {
70 public: 70 public:
71 explicit ScavengerVisitor(Isolate* isolate, Scavenger* scavenger) 71 explicit ScavengerVisitor(Isolate* isolate, Scavenger* scavenger)
72 : ObjectPointerVisitor(isolate), 72 : ObjectPointerVisitor(isolate),
73 scavenger_(scavenger), 73 scavenger_(scavenger),
74 heap_(scavenger->heap_), 74 heap_(scavenger->heap_),
75 vm_heap_(Dart::vm_isolate()->heap()), 75 vm_heap_(Dart::vm_isolate()->heap()),
76 visited_count_(0),
77 handled_count_(0),
76 delayed_weak_stack_(), 78 delayed_weak_stack_(),
77 growth_policy_(PageSpace::kControlGrowth), 79 growth_policy_(PageSpace::kControlGrowth),
78 bytes_promoted_(0), 80 bytes_promoted_(0),
79 visiting_old_object_(NULL), 81 visiting_old_object_(NULL),
80 in_scavenge_pointer_(false) { } 82 in_scavenge_pointer_(false) { }
81 83
82 void VisitPointers(RawObject** first, RawObject** last) { 84 void VisitPointers(RawObject** first, RawObject** last) {
83 for (RawObject** current = first; current <= last; current++) { 85 for (RawObject** current = first; current <= last; current++) {
84 ScavengePointer(current); 86 ScavengePointer(current);
85 } 87 }
(...skipping 20 matching lines...) Expand all
106 delay_set_.insert(std::make_pair(raw_key, raw_weak)); 108 delay_set_.insert(std::make_pair(raw_key, raw_weak));
107 } 109 }
108 110
109 void Finalize() { 111 void Finalize() {
110 DelaySet::iterator it = delay_set_.begin(); 112 DelaySet::iterator it = delay_set_.begin();
111 for (; it != delay_set_.end(); ++it) { 113 for (; it != delay_set_.end(); ++it) {
112 WeakProperty::Clear(it->second); 114 WeakProperty::Clear(it->second);
113 } 115 }
114 } 116 }
115 117
118 intptr_t visited_count() const { return visited_count_; }
119 intptr_t handled_count() const { return handled_count_; }
116 intptr_t bytes_promoted() const { return bytes_promoted_; } 120 intptr_t bytes_promoted() const { return bytes_promoted_; }
117 121
118 private: 122 private:
119 void UpdateStoreBuffer(RawObject** p, RawObject* obj) { 123 void UpdateStoreBuffer(RawObject** p, RawObject* obj) {
120 uword ptr = reinterpret_cast<uword>(p); 124 uword ptr = reinterpret_cast<uword>(p);
121 ASSERT(obj->IsHeapObject()); 125 ASSERT(obj->IsHeapObject());
122 ASSERT(!scavenger_->Contains(ptr)); 126 ASSERT(!scavenger_->Contains(ptr));
123 ASSERT(!heap_->CodeContains(ptr)); 127 ASSERT(!heap_->CodeContains(ptr));
124 ASSERT(heap_->Contains(ptr)); 128 ASSERT(heap_->Contains(ptr));
125 // If the newly written object is not a new object, drop it immediately. 129 // If the newly written object is not a new object, drop it immediately.
126 if (!obj->IsNewObject() || visiting_old_object_->IsRemembered()) { 130 if (!obj->IsNewObject() || visiting_old_object_->IsRemembered()) {
127 return; 131 return;
128 } 132 }
129 visiting_old_object_->SetRememberedBit(); 133 visiting_old_object_->SetRememberedBit();
130 isolate()->store_buffer()->AddObjectGC(visiting_old_object_); 134 isolate()->store_buffer()->AddObjectGC(visiting_old_object_);
131 } 135 }
132 136
133 void ScavengePointer(RawObject** p) { 137 void ScavengePointer(RawObject** p) {
134 // ScavengePointer cannot be called recursively. 138 // ScavengePointer cannot be called recursively.
135 #ifdef DEBUG 139 #ifdef DEBUG
136 ASSERT(!in_scavenge_pointer_); 140 ASSERT(!in_scavenge_pointer_);
137 BoolScope bs(&in_scavenge_pointer_, true); 141 BoolScope bs(&in_scavenge_pointer_, true);
138 #endif 142 #endif
139 143
144 visited_count_++;
140 RawObject* raw_obj = *p; 145 RawObject* raw_obj = *p;
141 146
142 // Fast exit if the raw object is a Smi or an old object. 147 // Fast exit if the raw object is a Smi or an old object.
143 if (!raw_obj->IsHeapObject() || raw_obj->IsOldObject()) { 148 if (!raw_obj->IsHeapObject() || raw_obj->IsOldObject()) {
144 return; 149 return;
145 } 150 }
146 151
147 uword raw_addr = RawObject::ToAddr(raw_obj); 152 uword raw_addr = RawObject::ToAddr(raw_obj);
148 // Objects should be contained in the heap. 153 // Objects should be contained in the heap.
149 // TODO(iposva): Add an appropriate assert here or in the return block 154 // TODO(iposva): Add an appropriate assert here or in the return block
150 // below. 155 // below.
151 // The scavenger is only interested in objects located in the from space. 156 // The scavenger is only interested in objects located in the from space.
152 if (!scavenger_->from_->Contains(raw_addr)) { 157 if (!scavenger_->from_->Contains(raw_addr)) {
153 return; 158 return;
154 } 159 }
155 160
161 handled_count_++;
156 // Read the header word of the object and determine if the object has 162 // Read the header word of the object and determine if the object has
157 // already been copied. 163 // already been copied.
158 uword header = *reinterpret_cast<uword*>(raw_addr); 164 uword header = *reinterpret_cast<uword*>(raw_addr);
159 uword new_addr = 0; 165 uword new_addr = 0;
160 if (IsForwarding(header)) { 166 if (IsForwarding(header)) {
161 // Get the new location of the object. 167 // Get the new location of the object.
162 new_addr = ForwardedAddr(header); 168 new_addr = ForwardedAddr(header);
163 } else { 169 } else {
164 if (raw_obj->IsWatched()) { 170 if (raw_obj->IsWatched()) {
165 raw_obj->ClearWatchedBit(); 171 raw_obj->ClearWatchedBit();
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
230 *p = new_obj; 236 *p = new_obj;
231 // Update the store buffer as needed. 237 // Update the store buffer as needed.
232 if (visiting_old_object_ != NULL) { 238 if (visiting_old_object_ != NULL) {
233 UpdateStoreBuffer(p, new_obj); 239 UpdateStoreBuffer(p, new_obj);
234 } 240 }
235 } 241 }
236 242
237 Scavenger* scavenger_; 243 Scavenger* scavenger_;
238 Heap* heap_; 244 Heap* heap_;
239 Heap* vm_heap_; 245 Heap* vm_heap_;
246 intptr_t visited_count_;
247 intptr_t handled_count_;
240 typedef std::multimap<RawObject*, RawWeakProperty*> DelaySet; 248 typedef std::multimap<RawObject*, RawWeakProperty*> DelaySet;
241 DelaySet delay_set_; 249 DelaySet delay_set_;
242 GrowableArray<RawObject*> delayed_weak_stack_; 250 GrowableArray<RawObject*> delayed_weak_stack_;
243 PageSpace::GrowthPolicy growth_policy_; 251 PageSpace::GrowthPolicy growth_policy_;
244 // TODO(cshapiro): use this value to compute survival statistics for 252 // TODO(cshapiro): use this value to compute survival statistics for
245 // new space growth policy. 253 // new space growth policy.
246 intptr_t bytes_promoted_; 254 intptr_t bytes_promoted_;
247 RawObject* visiting_old_object_; 255 RawObject* visiting_old_object_;
248 bool in_scavenge_pointer_; 256 bool in_scavenge_pointer_;
249 257
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
372 #endif // defined(DEBUG) 380 #endif // defined(DEBUG)
373 if (invoke_api_callbacks) { 381 if (invoke_api_callbacks) {
374 isolate->gc_epilogue_callbacks().Invoke(); 382 isolate->gc_epilogue_callbacks().Invoke();
375 } 383 }
376 } 384 }
377 385
378 386
379 void Scavenger::IterateStoreBuffers(Isolate* isolate, 387 void Scavenger::IterateStoreBuffers(Isolate* isolate,
380 ScavengerVisitor* visitor) { 388 ScavengerVisitor* visitor) {
381 StoreBuffer* buffer = isolate->store_buffer(); 389 StoreBuffer* buffer = isolate->store_buffer();
382 heap_->RecordData(kStoreBufferBlockEntries, buffer->Count()); 390 heap_->RecordData(kStoreBufferEntries, buffer->Count());
383 391
384 // Iterating through the store buffers. 392 // Iterating through the store buffers.
385 // Grab the deduplication sets out of the store buffer. 393 // Grab the deduplication sets out of the store buffer.
386 StoreBufferBlock* pending = isolate->store_buffer()->Blocks(); 394 StoreBufferBlock* pending = isolate->store_buffer()->Blocks();
387 intptr_t entries = 0; 395 intptr_t visited_count_before = visitor->visited_count();
396 intptr_t handled_count_before = visitor->handled_count();
388 while (pending != NULL) { 397 while (pending != NULL) {
389 StoreBufferBlock* next = pending->next(); 398 StoreBufferBlock* next = pending->next();
390 intptr_t count = pending->Count(); 399 intptr_t count = pending->Count();
391 entries += count;
392 for (intptr_t i = 0; i < count; i++) { 400 for (intptr_t i = 0; i < count; i++) {
393 RawObject* raw_object = pending->At(i); 401 RawObject* raw_object = pending->At(i);
394 ASSERT(raw_object->IsRemembered()); 402 ASSERT(raw_object->IsRemembered());
395 raw_object->ClearRememberedBit(); 403 raw_object->ClearRememberedBit();
396 visitor->VisitingOldObject(raw_object); 404 visitor->VisitingOldObject(raw_object);
397 raw_object->VisitPointers(visitor); 405 raw_object->VisitPointers(visitor);
398 } 406 }
399 delete pending; 407 delete pending;
400 pending = next; 408 pending = next;
401 } 409 }
402 heap_->RecordData(kStoreBufferEntries, entries); 410 heap_->RecordData(kStoreBufferVisited,
411 visitor->visited_count() - visited_count_before);
412 heap_->RecordData(kStoreBufferPointers,
413 visitor->handled_count() - handled_count_before);
403 // Done iterating through old objects remembered in the store buffers. 414 // Done iterating through old objects remembered in the store buffers.
404 visitor->VisitingOldObject(NULL); 415 visitor->VisitingOldObject(NULL);
405 } 416 }
406 417
407 418
408 void Scavenger::IterateObjectIdTable(Isolate* isolate, 419 void Scavenger::IterateObjectIdTable(Isolate* isolate,
409 ScavengerVisitor* visitor) { 420 ScavengerVisitor* visitor) {
410 ObjectIdRing* ring = isolate->object_id_ring(); 421 ObjectIdRing* ring = isolate->object_id_ring();
411 if (ring == NULL) { 422 if (ring == NULL) {
412 // --gc_at_alloc can get us here before the ring has been initialized. 423 // --gc_at_alloc can get us here before the ring has been initialized.
413 ASSERT(FLAG_gc_at_alloc); 424 ASSERT(FLAG_gc_at_alloc);
414 return; 425 return;
415 } 426 }
416 ring->VisitPointers(visitor); 427 ring->VisitPointers(visitor);
417 } 428 }
418 429
419 430
420 void Scavenger::IterateRoots(Isolate* isolate, 431 void Scavenger::IterateRoots(Isolate* isolate,
421 ScavengerVisitor* visitor, 432 ScavengerVisitor* visitor,
422 bool visit_prologue_weak_persistent_handles) { 433 bool visit_prologue_weak_persistent_handles) {
423 int64_t start = OS::GetCurrentTimeMicros(); 434 int64_t start = OS::GetCurrentTimeMicros();
424 isolate->VisitObjectPointers(visitor, 435 isolate->VisitObjectPointers(visitor,
425 visit_prologue_weak_persistent_handles, 436 visit_prologue_weak_persistent_handles,
426 StackFrameIterator::kDontValidateFrames); 437 StackFrameIterator::kDontValidateFrames);
427 int64_t middle = OS::GetCurrentTimeMicros(); 438 int64_t middle = OS::GetCurrentTimeMicros();
428 IterateStoreBuffers(isolate, visitor); 439 IterateStoreBuffers(isolate, visitor);
429 IterateObjectIdTable(isolate, visitor); 440 IterateObjectIdTable(isolate, visitor);
430 int64_t end = OS::GetCurrentTimeMicros(); 441 int64_t end = OS::GetCurrentTimeMicros();
442 heap_->RecordData(kToKBAfterStoreBuffer, (in_use() + (KB >> 1)) >> KBLog2);
431 heap_->RecordTime(kVisitIsolateRoots, middle - start); 443 heap_->RecordTime(kVisitIsolateRoots, middle - start);
432 heap_->RecordTime(kIterateStoreBuffers, end - middle); 444 heap_->RecordTime(kIterateStoreBuffers, end - middle);
433 } 445 }
434 446
435 447
436 bool Scavenger::IsUnreachable(RawObject** p) { 448 bool Scavenger::IsUnreachable(RawObject** p) {
437 RawObject* raw_obj = *p; 449 RawObject* raw_obj = *p;
438 if (!raw_obj->IsHeapObject()) { 450 if (!raw_obj->IsHeapObject()) {
439 return false; 451 return false;
440 } 452 }
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
673 } 685 }
674 686
675 687
676 void Scavenger::WriteProtect(bool read_only) { 688 void Scavenger::WriteProtect(bool read_only) {
677 space_->Protect( 689 space_->Protect(
678 read_only ? VirtualMemory::kReadOnly : VirtualMemory::kReadWrite); 690 read_only ? VirtualMemory::kReadOnly : VirtualMemory::kReadWrite);
679 } 691 }
680 692
681 693
682 } // namespace dart 694 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/scavenger.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698