| 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/pages.h" | 5 #include "vm/pages.h" |
| 6 | 6 |
| 7 #include "platform/assert.h" | 7 #include "platform/assert.h" |
| 8 #include "vm/gc_marker.h" | 8 #include "vm/gc_marker.h" |
| 9 #include "vm/gc_sweeper.h" | 9 #include "vm/gc_sweeper.h" |
| 10 #include "vm/object.h" | 10 #include "vm/object.h" |
| 11 #include "vm/virtual_memory.h" | 11 #include "vm/virtual_memory.h" |
| 12 | 12 |
| 13 namespace dart { | 13 namespace dart { |
| 14 | 14 |
| 15 DEFINE_FLAG(int, heap_growth_space_ratio, 10, | 15 DEFINE_FLAG(int, heap_growth_space_ratio, 10, |
| 16 "The desired maximum percentage of free space after GC"); | 16 "The desired maximum percentage of free space after GC"); |
| 17 DEFINE_FLAG(int, heap_growth_time_ratio, 3, | 17 DEFINE_FLAG(int, heap_growth_time_ratio, 3, |
| 18 "The desired maximum percentage of time spent in GC"); | 18 "The desired maximum percentage of time spent in GC"); |
| 19 DEFINE_FLAG(int, heap_growth_rate, 4, | 19 DEFINE_FLAG(int, heap_growth_rate, 4, |
| 20 "The size the heap is grown, in heap pages"); | 20 "The size the heap is grown, in heap pages"); |
| 21 DEFINE_FLAG(bool, print_free_list_before_gc, false, | |
| 22 "Print free list statistics before a GC"); | |
| 23 DEFINE_FLAG(bool, print_free_list_after_gc, false, | |
| 24 "Print free list statistics after a GC"); | |
| 25 | 21 |
| 26 HeapPage* HeapPage::Initialize(VirtualMemory* memory, bool is_executable) { | 22 HeapPage* HeapPage::Initialize(VirtualMemory* memory, bool is_executable) { |
| 27 ASSERT(memory->size() > VirtualMemory::PageSize()); | 23 ASSERT(memory->size() > VirtualMemory::PageSize()); |
| 28 memory->Commit(is_executable); | 24 memory->Commit(is_executable); |
| 29 | 25 |
| 30 HeapPage* result = reinterpret_cast<HeapPage*>(memory->address()); | 26 HeapPage* result = reinterpret_cast<HeapPage*>(memory->address()); |
| 31 result->memory_ = memory; | 27 result->memory_ = memory; |
| 32 result->next_ = NULL; | 28 result->next_ = NULL; |
| 33 result->used_ = 0; | 29 result->used_ = 0; |
| 34 result->top_ = result->first_object_start(); | 30 result->top_ = result->first_object_start(); |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 209 uword PageSpace::TryAllocate(intptr_t size) { | 205 uword PageSpace::TryAllocate(intptr_t size) { |
| 210 return TryAllocate(size, kControlGrowth); | 206 return TryAllocate(size, kControlGrowth); |
| 211 } | 207 } |
| 212 | 208 |
| 213 | 209 |
| 214 uword PageSpace::TryAllocate(intptr_t size, GrowthPolicy growth_policy) { | 210 uword PageSpace::TryAllocate(intptr_t size, GrowthPolicy growth_policy) { |
| 215 ASSERT(size >= kObjectAlignment); | 211 ASSERT(size >= kObjectAlignment); |
| 216 ASSERT(Utils::IsAligned(size, kObjectAlignment)); | 212 ASSERT(Utils::IsAligned(size, kObjectAlignment)); |
| 217 uword result = 0; | 213 uword result = 0; |
| 218 if (size < kAllocatablePageSize) { | 214 if (size < kAllocatablePageSize) { |
| 219 result = freelist_.TryAllocate(size); | 215 result = TryBumpAllocate(size); |
| 220 if (result == 0) { | 216 if (result == 0) { |
| 221 result = TryBumpAllocate(size); | 217 result = freelist_.TryAllocate(size); |
| 222 if ((result == 0) && | 218 if ((result == 0) && |
| 223 (page_space_controller_.CanGrowPageSpace(size) || | 219 (page_space_controller_.CanGrowPageSpace(size) || |
| 224 growth_policy == kForceGrowth) && | 220 growth_policy == kForceGrowth) && |
| 225 CanIncreaseCapacity(kPageSize)) { | 221 CanIncreaseCapacity(kPageSize)) { |
| 226 AllocatePage(); | 222 AllocatePage(); |
| 227 result = TryBumpAllocate(size); | 223 result = TryBumpAllocate(size); |
| 228 ASSERT(result != 0); | 224 ASSERT(result != 0); |
| 229 } | 225 } |
| 230 } | 226 } |
| 231 } else { | 227 } else { |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 340 } | 336 } |
| 341 | 337 |
| 342 | 338 |
| 343 void PageSpace::MarkSweep(bool invoke_api_callbacks) { | 339 void PageSpace::MarkSweep(bool invoke_api_callbacks) { |
| 344 // MarkSweep is not reentrant. Make sure that is the case. | 340 // MarkSweep is not reentrant. Make sure that is the case. |
| 345 ASSERT(!sweeping_); | 341 ASSERT(!sweeping_); |
| 346 sweeping_ = true; | 342 sweeping_ = true; |
| 347 Isolate* isolate = Isolate::Current(); | 343 Isolate* isolate = Isolate::Current(); |
| 348 NoHandleScope no_handles(isolate); | 344 NoHandleScope no_handles(isolate); |
| 349 | 345 |
| 350 if (FLAG_print_free_list_before_gc) { | |
| 351 freelist_.Print(); | |
| 352 } | |
| 353 | |
| 354 if (FLAG_verify_before_gc) { | 346 if (FLAG_verify_before_gc) { |
| 355 OS::PrintErr("Verifying before MarkSweep..."); | 347 OS::PrintErr("Verifying before MarkSweep..."); |
| 356 heap_->Verify(); | 348 heap_->Verify(); |
| 357 OS::PrintErr(" done.\n"); | 349 OS::PrintErr(" done.\n"); |
| 358 } | 350 } |
| 359 | 351 |
| 360 Timer timer(true, "MarkSweep"); | 352 Timer timer(true, "MarkSweep"); |
| 361 timer.Start(); | 353 timer.Start(); |
| 362 int64_t start = OS::GetCurrentTimeMillis(); | 354 int64_t start = OS::GetCurrentTimeMillis(); |
| 363 | 355 |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 416 if (FLAG_verbose_gc) { | 408 if (FLAG_verbose_gc) { |
| 417 const intptr_t KB2 = KB / 2; | 409 const intptr_t KB2 = KB / 2; |
| 418 OS::PrintErr("Mark-Sweep[%d]: %lldus (%dK -> %dK, %dK)\n", | 410 OS::PrintErr("Mark-Sweep[%d]: %lldus (%dK -> %dK, %dK)\n", |
| 419 count_, | 411 count_, |
| 420 timer.TotalElapsedTime(), | 412 timer.TotalElapsedTime(), |
| 421 (in_use_before + (KB2)) / KB, | 413 (in_use_before + (KB2)) / KB, |
| 422 (in_use + (KB2)) / KB, | 414 (in_use + (KB2)) / KB, |
| 423 (capacity_ + KB2) / KB); | 415 (capacity_ + KB2) / KB); |
| 424 } | 416 } |
| 425 | 417 |
| 426 if (FLAG_print_free_list_after_gc) { | |
| 427 freelist_.Print(); | |
| 428 } | |
| 429 | |
| 430 if (FLAG_verify_after_gc) { | 418 if (FLAG_verify_after_gc) { |
| 431 OS::PrintErr("Verifying after MarkSweep..."); | 419 OS::PrintErr("Verifying after MarkSweep..."); |
| 432 heap_->Verify(); | 420 heap_->Verify(); |
| 433 OS::PrintErr(" done.\n"); | 421 OS::PrintErr(" done.\n"); |
| 434 } | 422 } |
| 435 | 423 |
| 436 count_++; | 424 count_++; |
| 437 // Done, reset the marker. | 425 // Done, reset the marker. |
| 438 ASSERT(sweeping_); | 426 ASSERT(sweeping_); |
| 439 sweeping_ = false; | 427 sweeping_ = false; |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 547 return 0; | 535 return 0; |
| 548 } else { | 536 } else { |
| 549 ASSERT(total_time >= gc_time); | 537 ASSERT(total_time >= gc_time); |
| 550 int result= static_cast<int>((static_cast<double>(gc_time) / | 538 int result= static_cast<int>((static_cast<double>(gc_time) / |
| 551 static_cast<double>(total_time)) * 100); | 539 static_cast<double>(total_time)) * 100); |
| 552 return result; | 540 return result; |
| 553 } | 541 } |
| 554 } | 542 } |
| 555 | 543 |
| 556 } // namespace dart | 544 } // namespace dart |
| OLD | NEW |