Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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/heap.h" | 5 #include "vm/heap.h" |
| 6 | 6 |
| 7 #include "platform/assert.h" | 7 #include "platform/assert.h" |
| 8 #include "platform/utils.h" | 8 #include "platform/utils.h" |
| 9 #include "vm/flags.h" | 9 #include "vm/flags.h" |
| 10 #include "vm/isolate.h" | 10 #include "vm/isolate.h" |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 44 | 44 |
| 45 | 45 |
| 46 Heap::Heap(Isolate* isolate, | 46 Heap::Heap(Isolate* isolate, |
| 47 intptr_t max_new_gen_semi_words, | 47 intptr_t max_new_gen_semi_words, |
| 48 intptr_t max_old_gen_words, | 48 intptr_t max_old_gen_words, |
| 49 intptr_t max_external_words) | 49 intptr_t max_external_words) |
| 50 : isolate_(isolate), | 50 : isolate_(isolate), |
| 51 new_space_(this, max_new_gen_semi_words, kNewObjectAlignmentOffset), | 51 new_space_(this, max_new_gen_semi_words, kNewObjectAlignmentOffset), |
| 52 old_space_(this, max_old_gen_words, max_external_words), | 52 old_space_(this, max_old_gen_words, max_external_words), |
| 53 read_only_(false), | 53 read_only_(false), |
| 54 gc_in_progress_(false), | 54 gc_new_space_in_progress_(false), |
| 55 gc_old_space_in_progress_(false), | |
| 55 pretenure_policy_(0) { | 56 pretenure_policy_(0) { |
| 56 for (int sel = 0; | 57 for (int sel = 0; |
| 57 sel < kNumWeakSelectors; | 58 sel < kNumWeakSelectors; |
| 58 sel++) { | 59 sel++) { |
| 59 new_weak_tables_[sel] = new WeakTable(); | 60 new_weak_tables_[sel] = new WeakTable(); |
| 60 old_weak_tables_[sel] = new WeakTable(); | 61 old_weak_tables_[sel] = new WeakTable(); |
| 61 } | 62 } |
| 62 stats_.num_ = 0; | 63 stats_.num_ = 0; |
| 63 } | 64 } |
| 64 | 65 |
| 65 | 66 |
| 66 Heap::~Heap() { | 67 Heap::~Heap() { |
| 67 for (int sel = 0; | 68 for (int sel = 0; |
| 68 sel < kNumWeakSelectors; | 69 sel < kNumWeakSelectors; |
| 69 sel++) { | 70 sel++) { |
| 70 delete new_weak_tables_[sel]; | 71 delete new_weak_tables_[sel]; |
| 71 delete old_weak_tables_[sel]; | 72 delete old_weak_tables_[sel]; |
| 72 } | 73 } |
| 73 } | 74 } |
| 74 | 75 |
| 75 | 76 |
| 76 uword Heap::AllocateNew(intptr_t size) { | 77 uword Heap::AllocateNew(intptr_t size) { |
| 77 ASSERT(Thread::Current()->no_safepoint_scope_depth() == 0); | 78 ASSERT(Thread::Current()->no_safepoint_scope_depth() == 0); |
| 78 // Currently, only the Dart thread may allocate in new space. | 79 // Currently, only the Dart thread may allocate in new space. |
| 79 isolate()->AssertCurrentThreadIsMutator(); | 80 isolate()->AssertCurrentThreadIsMutator(); |
| 80 uword addr = new_space_.TryAllocate(size); | 81 uword addr = new_space_.TryAllocate(size); |
| 81 if (addr == 0) { | 82 if (addr == 0) { |
| 82 CollectGarbage(kNew); | 83 CollectGarbage(kNew); |
|
Ivan Posva
2016/01/11 06:14:09
Please add a comment that the CollectGarbage(kNew)
siva
2016/01/11 18:27:47
Added a comment.
If a new space collection happen
| |
| 83 addr = new_space_.TryAllocate(size); | 84 addr = new_space_.TryAllocate(size); |
| 84 if (addr == 0) { | 85 if (addr == 0) { |
| 85 return AllocateOld(size, HeapPage::kData); | 86 return AllocateOld(size, HeapPage::kData); |
| 86 } | 87 } |
| 87 } | 88 } |
| 88 return addr; | 89 return addr; |
| 89 } | 90 } |
| 90 | 91 |
| 91 | 92 |
| 92 uword Heap::AllocateOld(intptr_t size, HeapPage::PageType type) { | 93 uword Heap::AllocateOld(intptr_t size, HeapPage::PageType type) { |
| 93 ASSERT(Thread::Current()->no_safepoint_scope_depth() == 0); | 94 ASSERT(Thread::Current()->no_safepoint_scope_depth() == 0); |
| 94 uword addr = old_space_.TryAllocate(size, type); | 95 uword addr = old_space_.TryAllocate(size, type); |
| 95 if (addr != 0) { | 96 if (addr != 0) { |
| 96 return addr; | 97 return addr; |
| 97 } | 98 } |
| 98 // If we are in the process of running a sweep wait for the sweeper to free | 99 // If we are in the process of running a sweep wait for the sweeper to free |
| 99 // memory. | 100 // memory. |
| 100 { | 101 { |
| 101 MonitorLocker ml(old_space_.tasks_lock()); | 102 MonitorLocker ml(old_space_.tasks_lock()); |
| 102 addr = old_space_.TryAllocate(size, type); | 103 addr = old_space_.TryAllocate(size, type); |
| 103 while ((addr == 0) && (old_space_.tasks() > 0)) { | 104 while ((addr == 0) && (old_space_.tasks() > 0)) { |
| 104 ml.Wait(); | 105 ml.Wait(); |
| 105 addr = old_space_.TryAllocate(size, type); | 106 addr = old_space_.TryAllocate(size, type); |
| 106 } | 107 } |
| 107 } | 108 } |
| 108 if (addr != 0) { | 109 if (addr != 0) { |
| 109 return addr; | 110 return addr; |
| 110 } | 111 } |
| 111 // All GC tasks finished without allocating successfully. Run a full GC. | 112 Thread* thread = Thread::Current(); |
| 112 CollectAllGarbage(); | 113 if (thread->CanCollectGarbage()) { |
| 113 addr = old_space_.TryAllocate(size, type); | 114 // All GC tasks finished without allocating successfully. Run a full GC. |
| 114 if (addr != 0) { | 115 CollectAllGarbage(); |
| 115 return addr; | |
| 116 } | |
| 117 // Wait for all of the concurrent tasks to finish before giving up. | |
| 118 { | |
| 119 MonitorLocker ml(old_space_.tasks_lock()); | |
| 120 addr = old_space_.TryAllocate(size, type); | 116 addr = old_space_.TryAllocate(size, type); |
| 121 while ((addr == 0) && (old_space_.tasks() > 0)) { | 117 if (addr != 0) { |
| 122 ml.Wait(); | 118 return addr; |
| 119 } | |
| 120 // Wait for all of the concurrent tasks to finish before giving up. | |
| 121 { | |
| 122 MonitorLocker ml(old_space_.tasks_lock()); | |
| 123 addr = old_space_.TryAllocate(size, type); | 123 addr = old_space_.TryAllocate(size, type); |
| 124 while ((addr == 0) && (old_space_.tasks() > 0)) { | |
| 125 ml.Wait(); | |
| 126 addr = old_space_.TryAllocate(size, type); | |
| 127 } | |
| 124 } | 128 } |
| 125 } | 129 if (addr != 0) { |
| 126 if (addr != 0) { | 130 return addr; |
| 127 return addr; | 131 } |
| 128 } | 132 // Force growth before attempting a synchronous GC. |
|
Ivan Posva
2016/01/11 06:14:09
a -> another
siva
2016/01/11 18:27:47
Done.
| |
| 129 // Force growth before attempting a synchronous GC. | 133 addr = old_space_.TryAllocate(size, type, PageSpace::kForceGrowth); |
| 130 addr = old_space_.TryAllocate(size, type, PageSpace::kForceGrowth); | 134 if (addr != 0) { |
| 131 if (addr != 0) { | 135 return addr; |
| 132 return addr; | 136 } |
| 133 } | 137 // Before throwing an out-of-memory error try a synchronous GC. |
| 134 // Before throwing an out-of-memory error try a synchronous GC. | 138 CollectAllGarbage(); |
| 135 CollectAllGarbage(); | 139 { |
| 136 { | 140 MonitorLocker ml(old_space_.tasks_lock()); |
| 137 MonitorLocker ml(old_space_.tasks_lock()); | 141 while (old_space_.tasks() > 0) { |
| 138 while (old_space_.tasks() > 0) { | 142 ml.Wait(); |
| 139 ml.Wait(); | 143 } |
| 140 } | 144 } |
| 141 } | 145 } |
| 142 addr = old_space_.TryAllocate(size, type, PageSpace::kForceGrowth); | 146 addr = old_space_.TryAllocate(size, type, PageSpace::kForceGrowth); |
| 143 if (addr != 0) { | 147 if (addr != 0) { |
| 144 return addr; | 148 return addr; |
| 145 } | 149 } |
| 146 // Give up allocating this object. | 150 // Give up allocating this object. |
| 147 OS::PrintErr( | 151 OS::PrintErr( |
| 148 "Exhausted heap space, trying to allocate %" Pd " bytes.\n", size); | 152 "Exhausted heap space, trying to allocate %" Pd " bytes.\n", size); |
| 149 return 0; | 153 return 0; |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 300 } | 304 } |
| 301 raw_obj = FindOldObject(visitor); | 305 raw_obj = FindOldObject(visitor); |
| 302 if (raw_obj != Object::null()) { | 306 if (raw_obj != Object::null()) { |
| 303 return raw_obj; | 307 return raw_obj; |
| 304 } | 308 } |
| 305 raw_obj = FindObjectInCodeSpace(visitor); | 309 raw_obj = FindObjectInCodeSpace(visitor); |
| 306 return raw_obj; | 310 return raw_obj; |
| 307 } | 311 } |
| 308 | 312 |
| 309 | 313 |
| 310 bool Heap::gc_in_progress() { | 314 bool Heap::BeginNewSpaceGC() { |
| 311 MutexLocker ml(&gc_in_progress_mutex_); | 315 MonitorLocker ml(&gc_in_progress_monitor_); |
| 312 return gc_in_progress_; | 316 bool start_gc_on_thread = true; |
| 317 while (gc_new_space_in_progress_ || | |
| 318 gc_old_space_in_progress_) { | |
| 319 start_gc_on_thread = !gc_new_space_in_progress_; | |
| 320 ml.Wait(); | |
| 321 } | |
| 322 if (start_gc_on_thread) { | |
| 323 gc_new_space_in_progress_ = true; | |
| 324 return true; | |
| 325 } | |
| 326 return false; | |
| 313 } | 327 } |
| 314 | 328 |
| 315 | 329 |
| 316 void Heap::BeginGC() { | 330 void Heap::EndNewSpaceGC() { |
| 317 MutexLocker ml(&gc_in_progress_mutex_); | 331 MonitorLocker ml(&gc_in_progress_monitor_); |
| 318 ASSERT(!gc_in_progress_); | 332 ASSERT(gc_new_space_in_progress_); |
| 319 gc_in_progress_ = true; | 333 gc_new_space_in_progress_ = false; |
| 334 ml.NotifyAll(); | |
| 320 } | 335 } |
| 321 | 336 |
| 322 | 337 |
| 323 void Heap::EndGC() { | 338 bool Heap::BeginOldSpaceGC() { |
| 324 MutexLocker ml(&gc_in_progress_mutex_); | 339 MonitorLocker ml(&gc_in_progress_monitor_); |
| 325 ASSERT(gc_in_progress_); | 340 bool start_gc_on_thread = true; |
| 326 gc_in_progress_ = false; | 341 while (gc_new_space_in_progress_ || |
| 342 gc_old_space_in_progress_) { | |
| 343 start_gc_on_thread = !gc_old_space_in_progress_; | |
| 344 ml.Wait(); | |
| 345 } | |
| 346 if (start_gc_on_thread) { | |
| 347 gc_old_space_in_progress_ = true; | |
| 348 return true; | |
| 349 } | |
| 350 return false; | |
| 327 } | 351 } |
| 328 | 352 |
| 329 | 353 |
| 330 void Heap::CollectGarbage(Space space, | 354 void Heap::EndOldSpaceGC() { |
| 331 ApiCallbacks api_callbacks, | 355 MonitorLocker ml(&gc_in_progress_monitor_); |
| 332 GCReason reason) { | 356 ASSERT(gc_old_space_in_progress_); |
| 333 Thread* thread = Thread::Current(); | 357 gc_old_space_in_progress_ = false; |
| 334 bool invoke_api_callbacks = (api_callbacks == kInvokeApiCallbacks); | 358 ml.NotifyAll(); |
| 335 switch (space) { | |
| 336 case kNew: { | |
| 337 RecordBeforeGC(kNew, reason); | |
| 338 VMTagScope tagScope(thread, VMTag::kGCNewSpaceTagId); | |
| 339 TimelineDurationScope tds(thread, | |
| 340 isolate()->GetGCStream(), | |
| 341 "CollectNewGeneration"); | |
| 342 UpdateClassHeapStatsBeforeGC(kNew); | |
| 343 new_space_.Scavenge(invoke_api_callbacks); | |
| 344 isolate()->class_table()->UpdatePromoted(); | |
| 345 UpdatePretenurePolicy(); | |
| 346 RecordAfterGC(); | |
| 347 PrintStats(); | |
| 348 if (old_space_.NeedsGarbageCollection()) { | |
| 349 // Old collections should call the API callbacks. | |
| 350 CollectGarbage(kOld, kInvokeApiCallbacks, kPromotion); | |
| 351 } | |
| 352 break; | |
| 353 } | |
| 354 case kOld: | |
| 355 case kCode: { | |
| 356 RecordBeforeGC(kOld, reason); | |
| 357 VMTagScope tagScope(thread, VMTag::kGCOldSpaceTagId); | |
| 358 TimelineDurationScope tds(thread, | |
| 359 isolate()->GetGCStream(), | |
| 360 "CollectOldGeneration"); | |
| 361 UpdateClassHeapStatsBeforeGC(kOld); | |
| 362 old_space_.MarkSweep(invoke_api_callbacks); | |
| 363 RecordAfterGC(); | |
| 364 PrintStats(); | |
| 365 break; | |
| 366 } | |
| 367 default: | |
| 368 UNREACHABLE(); | |
| 369 } | |
| 370 } | 359 } |
| 371 | 360 |
| 372 | 361 |
| 373 void Heap::UpdateClassHeapStatsBeforeGC(Heap::Space space) { | 362 void Heap::UpdateClassHeapStatsBeforeGC(Heap::Space space) { |
| 374 ClassTable* class_table = isolate()->class_table(); | 363 ClassTable* class_table = isolate()->class_table(); |
| 375 if (space == kNew) { | 364 if (space == kNew) { |
| 376 class_table->ResetCountersNew(); | 365 class_table->ResetCountersNew(); |
| 377 } else { | 366 } else { |
| 378 class_table->ResetCountersOld(); | 367 class_table->ResetCountersOld(); |
| 379 } | 368 } |
| 380 } | 369 } |
| 381 | 370 |
| 382 | 371 |
| 372 void Heap::CollectNewSpaceGarbage(Thread* thread, | |
| 373 ApiCallbacks api_callbacks, | |
| 374 GCReason reason) { | |
| 375 if (BeginNewSpaceGC()) { | |
| 376 bool invoke_api_callbacks = (api_callbacks == kInvokeApiCallbacks); | |
| 377 RecordBeforeGC(kNew, reason); | |
| 378 VMTagScope tagScope(thread, VMTag::kGCNewSpaceTagId); | |
| 379 TimelineDurationScope tds(thread, | |
| 380 isolate()->GetGCStream(), | |
| 381 "CollectNewGeneration"); | |
| 382 UpdateClassHeapStatsBeforeGC(kNew); | |
| 383 new_space_.Scavenge(invoke_api_callbacks); | |
| 384 isolate()->class_table()->UpdatePromoted(); | |
| 385 UpdatePretenurePolicy(); | |
| 386 RecordAfterGC(kNew); | |
| 387 PrintStats(); | |
| 388 EndNewSpaceGC(); | |
| 389 if (old_space_.NeedsGarbageCollection()) { | |
| 390 // Old collections should call the API callbacks. | |
| 391 CollectOldSpaceGarbage(thread, kInvokeApiCallbacks, kPromotion); | |
| 392 } | |
| 393 } | |
| 394 } | |
| 395 | |
| 396 | |
| 397 void Heap::CollectOldSpaceGarbage(Thread* thread, | |
| 398 ApiCallbacks api_callbacks, | |
| 399 GCReason reason) { | |
| 400 if (BeginOldSpaceGC()) { | |
| 401 bool invoke_api_callbacks = (api_callbacks == kInvokeApiCallbacks); | |
| 402 RecordBeforeGC(kOld, reason); | |
| 403 VMTagScope tagScope(thread, VMTag::kGCOldSpaceTagId); | |
| 404 TimelineDurationScope tds(thread, | |
| 405 isolate()->GetGCStream(), | |
| 406 "CollectOldGeneration"); | |
| 407 UpdateClassHeapStatsBeforeGC(kOld); | |
| 408 old_space_.MarkSweep(invoke_api_callbacks); | |
| 409 RecordAfterGC(kOld); | |
| 410 PrintStats(); | |
| 411 EndOldSpaceGC(); | |
| 412 } | |
| 413 } | |
| 414 | |
| 415 | |
| 416 void Heap::CollectGarbage(Space space, | |
| 417 ApiCallbacks api_callbacks, | |
| 418 GCReason reason) { | |
| 419 Thread* thread = Thread::Current(); | |
| 420 switch (space) { | |
| 421 case kNew: { | |
| 422 CollectNewSpaceGarbage(thread, api_callbacks, reason); | |
| 423 break; | |
| 424 } | |
| 425 case kOld: | |
| 426 case kCode: { | |
| 427 CollectOldSpaceGarbage(thread, api_callbacks, reason); | |
| 428 break; | |
| 429 } | |
| 430 default: | |
| 431 UNREACHABLE(); | |
| 432 } | |
| 433 } | |
| 434 | |
| 435 | |
| 383 void Heap::CollectGarbage(Space space) { | 436 void Heap::CollectGarbage(Space space) { |
| 437 Thread* thread = Thread::Current(); | |
| 384 if (space == kOld) { | 438 if (space == kOld) { |
| 385 CollectGarbage(space, kInvokeApiCallbacks, kOldSpace); | 439 CollectOldSpaceGarbage(thread, kInvokeApiCallbacks, kOldSpace); |
| 386 } else { | 440 } else { |
| 387 ASSERT(space == kNew); | 441 ASSERT(space == kNew); |
| 388 CollectGarbage(space, kInvokeApiCallbacks, kNewSpace); | 442 CollectNewSpaceGarbage(thread, kInvokeApiCallbacks, kNewSpace); |
| 389 } | 443 } |
| 390 } | 444 } |
| 391 | 445 |
| 392 | 446 |
| 393 void Heap::CollectAllGarbage() { | 447 void Heap::CollectAllGarbage() { |
| 394 Thread* thread = Thread::Current(); | 448 Thread* thread = Thread::Current(); |
| 395 { | 449 CollectNewSpaceGarbage(thread, kInvokeApiCallbacks, kFull); |
| 396 RecordBeforeGC(kNew, kFull); | 450 CollectOldSpaceGarbage(thread, kInvokeApiCallbacks, kFull); |
| 397 VMTagScope tagScope(thread, VMTag::kGCNewSpaceTagId); | |
| 398 TimelineDurationScope tds(thread, | |
| 399 isolate()->GetGCStream(), | |
| 400 "CollectNewGeneration"); | |
| 401 UpdateClassHeapStatsBeforeGC(kNew); | |
| 402 new_space_.Scavenge(kInvokeApiCallbacks); | |
| 403 isolate()->class_table()->UpdatePromoted(); | |
| 404 UpdatePretenurePolicy(); | |
| 405 RecordAfterGC(); | |
| 406 PrintStats(); | |
| 407 } | |
| 408 { | |
| 409 RecordBeforeGC(kOld, kFull); | |
| 410 VMTagScope tagScope(thread, VMTag::kGCOldSpaceTagId); | |
| 411 TimelineDurationScope tds(thread, | |
| 412 isolate()->GetGCStream(), | |
| 413 "CollectOldGeneration"); | |
| 414 UpdateClassHeapStatsBeforeGC(kOld); | |
| 415 old_space_.MarkSweep(kInvokeApiCallbacks); | |
| 416 RecordAfterGC(); | |
| 417 PrintStats(); | |
| 418 } | |
| 419 } | 451 } |
| 420 | 452 |
| 421 | 453 |
| 422 bool Heap::ShouldPretenure(intptr_t class_id) const { | 454 bool Heap::ShouldPretenure(intptr_t class_id) const { |
| 423 if (class_id == kOneByteStringCid) { | 455 if (class_id == kOneByteStringCid) { |
| 424 return pretenure_policy_ > 0; | 456 return pretenure_policy_ > 0; |
| 425 } else { | 457 } else { |
| 426 return false; | 458 return false; |
| 427 } | 459 } |
| 428 } | 460 } |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 687 void Heap::PrintToJSONObject(Space space, JSONObject* object) const { | 719 void Heap::PrintToJSONObject(Space space, JSONObject* object) const { |
| 688 if (space == kNew) { | 720 if (space == kNew) { |
| 689 new_space_.PrintToJSONObject(object); | 721 new_space_.PrintToJSONObject(object); |
| 690 } else { | 722 } else { |
| 691 old_space_.PrintToJSONObject(object); | 723 old_space_.PrintToJSONObject(object); |
| 692 } | 724 } |
| 693 } | 725 } |
| 694 | 726 |
| 695 | 727 |
| 696 void Heap::RecordBeforeGC(Space space, GCReason reason) { | 728 void Heap::RecordBeforeGC(Space space, GCReason reason) { |
| 697 BeginGC(); | 729 ASSERT((space == kNew && gc_new_space_in_progress_) || |
| 730 (space == kOld && gc_old_space_in_progress_)); | |
| 698 stats_.num_++; | 731 stats_.num_++; |
| 699 stats_.space_ = space; | 732 stats_.space_ = space; |
| 700 stats_.reason_ = reason; | 733 stats_.reason_ = reason; |
| 701 stats_.before_.micros_ = OS::GetCurrentTimeMicros(); | 734 stats_.before_.micros_ = OS::GetCurrentTimeMicros(); |
| 702 stats_.before_.new_ = new_space_.GetCurrentUsage(); | 735 stats_.before_.new_ = new_space_.GetCurrentUsage(); |
| 703 stats_.before_.old_ = old_space_.GetCurrentUsage(); | 736 stats_.before_.old_ = old_space_.GetCurrentUsage(); |
| 704 stats_.times_[0] = 0; | 737 stats_.times_[0] = 0; |
| 705 stats_.times_[1] = 0; | 738 stats_.times_[1] = 0; |
| 706 stats_.times_[2] = 0; | 739 stats_.times_[2] = 0; |
| 707 stats_.times_[3] = 0; | 740 stats_.times_[3] = 0; |
| 708 stats_.data_[0] = 0; | 741 stats_.data_[0] = 0; |
| 709 stats_.data_[1] = 0; | 742 stats_.data_[1] = 0; |
| 710 stats_.data_[2] = 0; | 743 stats_.data_[2] = 0; |
| 711 stats_.data_[3] = 0; | 744 stats_.data_[3] = 0; |
| 712 } | 745 } |
| 713 | 746 |
| 714 | 747 |
| 715 void Heap::RecordAfterGC() { | 748 void Heap::RecordAfterGC(Space space) { |
| 716 stats_.after_.micros_ = OS::GetCurrentTimeMicros(); | 749 stats_.after_.micros_ = OS::GetCurrentTimeMicros(); |
| 717 int64_t delta = stats_.after_.micros_ - stats_.before_.micros_; | 750 int64_t delta = stats_.after_.micros_ - stats_.before_.micros_; |
| 718 if (stats_.space_ == kNew) { | 751 if (stats_.space_ == kNew) { |
| 719 new_space_.AddGCTime(delta); | 752 new_space_.AddGCTime(delta); |
| 720 new_space_.IncrementCollections(); | 753 new_space_.IncrementCollections(); |
| 721 } else { | 754 } else { |
| 722 old_space_.AddGCTime(delta); | 755 old_space_.AddGCTime(delta); |
| 723 old_space_.IncrementCollections(); | 756 old_space_.IncrementCollections(); |
| 724 } | 757 } |
| 725 stats_.after_.new_ = new_space_.GetCurrentUsage(); | 758 stats_.after_.new_ = new_space_.GetCurrentUsage(); |
| 726 stats_.after_.old_ = old_space_.GetCurrentUsage(); | 759 stats_.after_.old_ = old_space_.GetCurrentUsage(); |
| 727 EndGC(); | 760 ASSERT((space == kNew && gc_new_space_in_progress_) || |
| 761 (space == kOld && gc_old_space_in_progress_)); | |
| 728 if (Service::gc_stream.enabled()) { | 762 if (Service::gc_stream.enabled()) { |
| 729 ServiceEvent event(Isolate::Current(), ServiceEvent::kGC); | 763 ServiceEvent event(Isolate::Current(), ServiceEvent::kGC); |
| 730 event.set_gc_stats(&stats_); | 764 event.set_gc_stats(&stats_); |
| 731 Service::HandleEvent(&event); | 765 Service::HandleEvent(&event); |
| 732 } | 766 } |
| 733 } | 767 } |
| 734 | 768 |
| 735 | 769 |
| 736 void Heap::PrintStats() { | 770 void Heap::PrintStats() { |
| 737 if (!FLAG_verbose_gc) return; | 771 if (!FLAG_verbose_gc) return; |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 807 Dart::vm_isolate()->heap()->WriteProtect(false, include_code_pages_); | 841 Dart::vm_isolate()->heap()->WriteProtect(false, include_code_pages_); |
| 808 } | 842 } |
| 809 | 843 |
| 810 | 844 |
| 811 WritableVMIsolateScope::~WritableVMIsolateScope() { | 845 WritableVMIsolateScope::~WritableVMIsolateScope() { |
| 812 ASSERT(Dart::vm_isolate()->heap()->UsedInWords(Heap::kNew) == 0); | 846 ASSERT(Dart::vm_isolate()->heap()->UsedInWords(Heap::kNew) == 0); |
| 813 Dart::vm_isolate()->heap()->WriteProtect(true, include_code_pages_); | 847 Dart::vm_isolate()->heap()->WriteProtect(true, include_code_pages_); |
| 814 } | 848 } |
| 815 | 849 |
| 816 } // namespace dart | 850 } // namespace dart |
| OLD | NEW |