| 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, | 21 DEFINE_FLAG(bool, print_free_list_before_gc, false, |
| 22 "Print free list statistics before a GC"); | 22 "Print free list statistics before a GC"); |
| 23 DEFINE_FLAG(bool, print_free_list_after_gc, false, | 23 DEFINE_FLAG(bool, print_free_list_after_gc, false, |
| 24 "Print free list statistics after a GC"); | 24 "Print free list statistics after a GC"); |
| 25 | 25 |
| 26 HeapPage* HeapPage::Initialize(VirtualMemory* memory, bool is_executable) { | 26 HeapPage* HeapPage::Initialize(VirtualMemory* memory, PageType type) { |
| 27 ASSERT(memory->size() > VirtualMemory::PageSize()); | 27 ASSERT(memory->size() > VirtualMemory::PageSize()); |
| 28 bool is_executable = (type == kExecutable); |
| 28 memory->Commit(is_executable); | 29 memory->Commit(is_executable); |
| 29 | 30 |
| 30 HeapPage* result = reinterpret_cast<HeapPage*>(memory->address()); | 31 HeapPage* result = reinterpret_cast<HeapPage*>(memory->address()); |
| 31 result->memory_ = memory; | 32 result->memory_ = memory; |
| 32 result->next_ = NULL; | 33 result->next_ = NULL; |
| 33 result->used_ = 0; | 34 result->used_ = 0; |
| 35 result->executable_ = is_executable; |
| 34 return result; | 36 return result; |
| 35 } | 37 } |
| 36 | 38 |
| 37 | 39 |
| 38 HeapPage* HeapPage::Allocate(intptr_t size, bool is_executable) { | 40 HeapPage* HeapPage::Allocate(intptr_t size, PageType type) { |
| 39 VirtualMemory* memory = | 41 VirtualMemory* memory = |
| 40 VirtualMemory::ReserveAligned(size, PageSpace::kPageAlignment); | 42 VirtualMemory::ReserveAligned(size, PageSpace::kPageAlignment); |
| 41 return Initialize(memory, is_executable); | 43 return Initialize(memory, type); |
| 42 } | 44 } |
| 43 | 45 |
| 44 | 46 |
| 45 void HeapPage::Deallocate() { | 47 void HeapPage::Deallocate() { |
| 46 // The memory for this object will become unavailable after the delete below. | 48 // The memory for this object will become unavailable after the delete below. |
| 47 delete memory_; | 49 delete memory_; |
| 48 } | 50 } |
| 49 | 51 |
| 50 | 52 |
| 51 void HeapPage::VisitObjects(ObjectVisitor* visitor) const { | 53 void HeapPage::VisitObjects(ObjectVisitor* visitor) const { |
| (...skipping 28 matching lines...) Expand all Loading... |
| 80 return raw_obj; // Found object, return it. | 82 return raw_obj; // Found object, return it. |
| 81 } | 83 } |
| 82 obj_addr += raw_obj->Size(); | 84 obj_addr += raw_obj->Size(); |
| 83 } | 85 } |
| 84 ASSERT(obj_addr == end_addr); | 86 ASSERT(obj_addr == end_addr); |
| 85 return Object::null(); | 87 return Object::null(); |
| 86 } | 88 } |
| 87 | 89 |
| 88 | 90 |
| 89 void HeapPage::WriteProtect(bool read_only) { | 91 void HeapPage::WriteProtect(bool read_only) { |
| 90 memory_->Protect( | 92 VirtualMemory::Protection prot; |
| 91 read_only ? VirtualMemory::kReadOnly : VirtualMemory::kReadWrite); | 93 if (read_only) { |
| 94 if (executable_) { |
| 95 prot = VirtualMemory::kReadExecute; |
| 96 } else { |
| 97 prot = VirtualMemory::kReadOnly; |
| 98 } |
| 99 } else { |
| 100 if (executable_) { |
| 101 prot = VirtualMemory::kReadWriteExecute; |
| 102 } else { |
| 103 prot = VirtualMemory::kReadWrite; |
| 104 } |
| 105 } |
| 106 memory_->Protect(prot); |
| 92 } | 107 } |
| 93 | 108 |
| 94 | 109 |
| 95 PageSpace::PageSpace(Heap* heap, intptr_t max_capacity, bool is_executable) | 110 PageSpace::PageSpace(Heap* heap, intptr_t max_capacity) |
| 96 : freelist_(), | 111 : freelist_(), |
| 97 heap_(heap), | 112 heap_(heap), |
| 98 pages_(NULL), | 113 pages_(NULL), |
| 99 pages_tail_(NULL), | 114 pages_tail_(NULL), |
| 100 large_pages_(NULL), | 115 large_pages_(NULL), |
| 101 max_capacity_(max_capacity), | 116 max_capacity_(max_capacity), |
| 102 capacity_(0), | 117 capacity_(0), |
| 103 in_use_(0), | 118 in_use_(0), |
| 104 count_(0), | 119 count_(0), |
| 105 is_executable_(is_executable), | |
| 106 sweeping_(false), | 120 sweeping_(false), |
| 107 page_space_controller_(FLAG_heap_growth_space_ratio, | 121 page_space_controller_(FLAG_heap_growth_space_ratio, |
| 108 FLAG_heap_growth_rate, | 122 FLAG_heap_growth_rate, |
| 109 FLAG_heap_growth_time_ratio) { | 123 FLAG_heap_growth_time_ratio) { |
| 110 } | 124 } |
| 111 | 125 |
| 112 | 126 |
| 113 PageSpace::~PageSpace() { | 127 PageSpace::~PageSpace() { |
| 114 FreePages(pages_); | 128 FreePages(pages_); |
| 115 FreePages(large_pages_); | 129 FreePages(large_pages_); |
| 116 } | 130 } |
| 117 | 131 |
| 118 | 132 |
| 119 intptr_t PageSpace::LargePageSizeFor(intptr_t size) { | 133 intptr_t PageSpace::LargePageSizeFor(intptr_t size) { |
| 120 intptr_t page_size = Utils::RoundUp(size + sizeof(HeapPage), | 134 intptr_t page_size = Utils::RoundUp(size + sizeof(HeapPage), |
| 121 VirtualMemory::PageSize()); | 135 VirtualMemory::PageSize()); |
| 122 return page_size; | 136 return page_size; |
| 123 } | 137 } |
| 124 | 138 |
| 125 | 139 |
| 126 HeapPage* PageSpace::AllocatePage() { | 140 HeapPage* PageSpace::AllocatePage(HeapPage::PageType type) { |
| 127 HeapPage* page = HeapPage::Allocate(kPageSize, is_executable_); | 141 HeapPage* page = HeapPage::Allocate(kPageSize, type); |
| 128 if (pages_ == NULL) { | 142 if (pages_ == NULL) { |
| 129 pages_ = page; | 143 pages_ = page; |
| 130 } else { | 144 } else { |
| 131 pages_tail_->set_next(page); | 145 pages_tail_->set_next(page); |
| 132 } | 146 } |
| 133 pages_tail_ = page; | 147 pages_tail_ = page; |
| 134 capacity_ += kPageSize; | 148 capacity_ += kPageSize; |
| 135 page->set_object_end(page->memory_->end()); | 149 page->set_object_end(page->memory_->end()); |
| 136 return page; | 150 return page; |
| 137 } | 151 } |
| 138 | 152 |
| 139 | 153 |
| 140 HeapPage* PageSpace::AllocateLargePage(intptr_t size) { | 154 HeapPage* PageSpace::AllocateLargePage(intptr_t size, HeapPage::PageType type) { |
| 141 intptr_t page_size = LargePageSizeFor(size); | 155 intptr_t page_size = LargePageSizeFor(size); |
| 142 HeapPage* page = HeapPage::Allocate(page_size, is_executable_); | 156 HeapPage* page = HeapPage::Allocate(page_size, type); |
| 143 page->set_next(large_pages_); | 157 page->set_next(large_pages_); |
| 144 large_pages_ = page; | 158 large_pages_ = page; |
| 145 capacity_ += page_size; | 159 capacity_ += page_size; |
| 146 // Only one object in this page. | 160 // Only one object in this page. |
| 147 page->set_object_end(page->object_start() + size); | 161 page->set_object_end(page->object_start() + size); |
| 148 return page; | 162 return page; |
| 149 } | 163 } |
| 150 | 164 |
| 151 | 165 |
| 152 void PageSpace::FreePage(HeapPage* page, HeapPage* previous_page) { | 166 void PageSpace::FreePage(HeapPage* page, HeapPage* previous_page) { |
| (...skipping 27 matching lines...) Expand all Loading... |
| 180 void PageSpace::FreePages(HeapPage* pages) { | 194 void PageSpace::FreePages(HeapPage* pages) { |
| 181 HeapPage* page = pages; | 195 HeapPage* page = pages; |
| 182 while (page != NULL) { | 196 while (page != NULL) { |
| 183 HeapPage* next = page->next(); | 197 HeapPage* next = page->next(); |
| 184 page->Deallocate(); | 198 page->Deallocate(); |
| 185 page = next; | 199 page = next; |
| 186 } | 200 } |
| 187 } | 201 } |
| 188 | 202 |
| 189 | 203 |
| 190 uword PageSpace::TryAllocate(intptr_t size) { | 204 uword PageSpace::TryAllocate(intptr_t size, |
| 191 return TryAllocate(size, kControlGrowth); | 205 HeapPage::PageType type, |
| 192 } | 206 GrowthPolicy growth_policy) { |
| 193 | |
| 194 | |
| 195 uword PageSpace::TryAllocate(intptr_t size, GrowthPolicy growth_policy) { | |
| 196 ASSERT(size >= kObjectAlignment); | 207 ASSERT(size >= kObjectAlignment); |
| 197 ASSERT(Utils::IsAligned(size, kObjectAlignment)); | 208 ASSERT(Utils::IsAligned(size, kObjectAlignment)); |
| 198 uword result = 0; | 209 uword result = 0; |
| 199 if (size < kAllocatablePageSize) { | 210 if (size < kAllocatablePageSize) { |
| 200 result = freelist_.TryAllocate(size); | 211 result = freelist_[type].TryAllocate(size); |
| 201 if ((result == 0) && | 212 if ((result == 0) && |
| 202 (page_space_controller_.CanGrowPageSpace(size) || | 213 (page_space_controller_.CanGrowPageSpace(size) || |
| 203 growth_policy == kForceGrowth) && | 214 growth_policy == kForceGrowth) && |
| 204 CanIncreaseCapacity(kPageSize)) { | 215 CanIncreaseCapacity(kPageSize)) { |
| 205 HeapPage* page = AllocatePage(); | 216 HeapPage* page = AllocatePage(type); |
| 206 ASSERT(page != NULL); | 217 ASSERT(page != NULL); |
| 207 // Start of the newly allocated page is the allocated object. | 218 // Start of the newly allocated page is the allocated object. |
| 208 result = page->object_start(); | 219 result = page->object_start(); |
| 209 // Enqueue the remainder in the free list. | 220 // Enqueue the remainder in the free list. |
| 210 uword free_start = result + size; | 221 uword free_start = result + size; |
| 211 freelist_.Free(free_start, page->object_end() - free_start); | 222 freelist_[type].Free(free_start, page->object_end() - free_start); |
| 212 } | 223 } |
| 213 } else { | 224 } else { |
| 214 // Large page allocation. | 225 // Large page allocation. |
| 215 intptr_t page_size = LargePageSizeFor(size); | 226 intptr_t page_size = LargePageSizeFor(size); |
| 216 if (page_size < size) { | 227 if (page_size < size) { |
| 217 // On overflow we fail to allocate. | 228 // On overflow we fail to allocate. |
| 218 return 0; | 229 return 0; |
| 219 } | 230 } |
| 220 if (CanIncreaseCapacity(page_size)) { | 231 if (CanIncreaseCapacity(page_size)) { |
| 221 HeapPage* page = AllocateLargePage(size); | 232 HeapPage* page = AllocateLargePage(size, type); |
| 222 if (page != NULL) { | 233 if (page != NULL) { |
| 223 result = page->object_start(); | 234 result = page->object_start(); |
| 224 } | 235 } |
| 225 } | 236 } |
| 226 } | 237 } |
| 227 if (result != 0) { | 238 if (result != 0) { |
| 228 in_use_ += size; | 239 in_use_ += size; |
| 229 } | 240 } |
| 230 ASSERT((result & kObjectAlignmentMask) == kOldObjectAlignmentOffset); | 241 ASSERT((result & kObjectAlignmentMask) == kOldObjectAlignmentOffset); |
| 231 return result; | 242 return result; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 245 while (page != NULL) { | 256 while (page != NULL) { |
| 246 if (page->Contains(addr)) { | 257 if (page->Contains(addr)) { |
| 247 return true; | 258 return true; |
| 248 } | 259 } |
| 249 page = page->next(); | 260 page = page->next(); |
| 250 } | 261 } |
| 251 return false; | 262 return false; |
| 252 } | 263 } |
| 253 | 264 |
| 254 | 265 |
| 266 bool PageSpace::Contains(uword addr, HeapPage::PageType type) const { |
| 267 HeapPage* page = pages_; |
| 268 while (page != NULL) { |
| 269 if ((page->type() == type) && page->Contains(addr)) { |
| 270 return true; |
| 271 } |
| 272 page = page->next(); |
| 273 } |
| 274 |
| 275 page = large_pages_; |
| 276 while (page != NULL) { |
| 277 if ((page->type() == type) && page->Contains(addr)) { |
| 278 return true; |
| 279 } |
| 280 page = page->next(); |
| 281 } |
| 282 return false; |
| 283 } |
| 284 |
| 285 |
| 255 void PageSpace::StartEndAddress(uword* start, uword* end) const { | 286 void PageSpace::StartEndAddress(uword* start, uword* end) const { |
| 256 ASSERT(pages_ != NULL || large_pages_ != NULL); | 287 ASSERT(pages_ != NULL || large_pages_ != NULL); |
| 257 *start = static_cast<uword>(~0); | 288 *start = static_cast<uword>(~0); |
| 258 *end = 0; | 289 *end = 0; |
| 259 for (HeapPage* page = pages_; page != NULL; page = page->next()) { | 290 for (HeapPage* page = pages_; page != NULL; page = page->next()) { |
| 260 *start = Utils::Minimum(*start, page->object_start()); | 291 *start = Utils::Minimum(*start, page->object_start()); |
| 261 *end = Utils::Maximum(*end, page->object_end()); | 292 *end = Utils::Maximum(*end, page->object_end()); |
| 262 } | 293 } |
| 263 for (HeapPage* page = large_pages_; page != NULL; page = page->next()) { | 294 for (HeapPage* page = large_pages_; page != NULL; page = page->next()) { |
| 264 *start = Utils::Minimum(*start, page->object_start()); | 295 *start = Utils::Minimum(*start, page->object_start()); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 312 } | 343 } |
| 313 | 344 |
| 314 page = large_pages_; | 345 page = large_pages_; |
| 315 while (page != NULL) { | 346 while (page != NULL) { |
| 316 page->VisitObjectPointers(visitor); | 347 page->VisitObjectPointers(visitor); |
| 317 page = page->next(); | 348 page = page->next(); |
| 318 } | 349 } |
| 319 } | 350 } |
| 320 | 351 |
| 321 | 352 |
| 322 RawObject* PageSpace::FindObject(FindObjectVisitor* visitor) const { | 353 RawObject* PageSpace::FindObject(FindObjectVisitor* visitor, |
| 354 HeapPage::PageType type) const { |
| 323 ASSERT(Isolate::Current()->no_gc_scope_depth() != 0); | 355 ASSERT(Isolate::Current()->no_gc_scope_depth() != 0); |
| 324 HeapPage* page = pages_; | 356 HeapPage* page = pages_; |
| 325 while (page != NULL) { | 357 while (page != NULL) { |
| 326 RawObject* obj = page->FindObject(visitor); | 358 if (page->type() == type) { |
| 327 if (obj != Object::null()) { | 359 RawObject* obj = page->FindObject(visitor); |
| 328 return obj; | 360 if (obj != Object::null()) { |
| 361 return obj; |
| 362 } |
| 329 } | 363 } |
| 330 page = page->next(); | 364 page = page->next(); |
| 331 } | 365 } |
| 332 | 366 |
| 333 page = large_pages_; | 367 page = large_pages_; |
| 334 while (page != NULL) { | 368 while (page != NULL) { |
| 335 RawObject* obj = page->FindObject(visitor); | 369 if (page->type() == type) { |
| 336 if (obj != Object::null()) { | 370 RawObject* obj = page->FindObject(visitor); |
| 337 return obj; | 371 if (obj != Object::null()) { |
| 372 return obj; |
| 373 } |
| 338 } | 374 } |
| 339 page = page->next(); | 375 page = page->next(); |
| 340 } | 376 } |
| 341 return Object::null(); | 377 return Object::null(); |
| 342 } | 378 } |
| 343 | 379 |
| 344 | 380 |
| 345 void PageSpace::WriteProtect(bool read_only) { | 381 void PageSpace::WriteProtect(bool read_only) { |
| 346 HeapPage* page = pages_; | 382 HeapPage* page = pages_; |
| 347 while (page != NULL) { | 383 while (page != NULL) { |
| 348 page->WriteProtect(read_only); | 384 page->WriteProtect(read_only); |
| 349 page = page->next(); | 385 page = page->next(); |
| 350 } | 386 } |
| 351 page = large_pages_; | 387 page = large_pages_; |
| 352 while (page != NULL) { | 388 while (page != NULL) { |
| 353 page->WriteProtect(read_only); | 389 page->WriteProtect(read_only); |
| 354 page = page->next(); | 390 page = page->next(); |
| 355 } | 391 } |
| 356 } | 392 } |
| 357 | 393 |
| 358 | 394 |
| 359 void PageSpace::MarkSweep(bool invoke_api_callbacks, const char* gc_reason) { | 395 void PageSpace::MarkSweep(bool invoke_api_callbacks, const char* gc_reason) { |
| 360 // MarkSweep is not reentrant. Make sure that is the case. | 396 // MarkSweep is not reentrant. Make sure that is the case. |
| 361 ASSERT(!sweeping_); | 397 ASSERT(!sweeping_); |
| 362 sweeping_ = true; | 398 sweeping_ = true; |
| 363 Isolate* isolate = Isolate::Current(); | 399 Isolate* isolate = Isolate::Current(); |
| 364 NoHandleScope no_handles(isolate); | 400 NoHandleScope no_handles(isolate); |
| 365 | 401 |
| 366 if (FLAG_print_free_list_before_gc) { | 402 if (FLAG_print_free_list_before_gc) { |
| 367 freelist_.Print(); | 403 OS::Print("Data Freelist:\n"); |
| 404 freelist_[HeapPage::kData].Print(); |
| 405 OS::Print("Executable Freelist:\n"); |
| 406 freelist_[HeapPage::kExecutable].Print(); |
| 368 } | 407 } |
| 369 | 408 |
| 370 if (FLAG_verify_before_gc) { | 409 if (FLAG_verify_before_gc) { |
| 371 OS::PrintErr("Verifying before MarkSweep..."); | 410 OS::PrintErr("Verifying before MarkSweep..."); |
| 372 heap_->Verify(); | 411 heap_->Verify(); |
| 373 OS::PrintErr(" done.\n"); | 412 OS::PrintErr(" done.\n"); |
| 374 } | 413 } |
| 375 | 414 |
| 376 if (FLAG_verbose_gc) { | 415 if (FLAG_verbose_gc) { |
| 377 OS::PrintErr("Start mark sweep for %s collection\n", gc_reason); | 416 OS::PrintErr("Start mark sweep for %s collection\n", gc_reason); |
| 378 } | 417 } |
| 379 Timer timer(true, "MarkSweep"); | 418 Timer timer(true, "MarkSweep"); |
| 380 timer.Start(); | 419 timer.Start(); |
| 381 int64_t start = OS::GetCurrentTimeMillis(); | 420 int64_t start = OS::GetCurrentTimeMillis(); |
| 382 | 421 |
| 383 // Mark all reachable old-gen objects. | 422 // Mark all reachable old-gen objects. |
| 384 GCMarker marker(heap_); | 423 GCMarker marker(heap_); |
| 385 marker.MarkObjects(isolate, this, invoke_api_callbacks); | 424 marker.MarkObjects(isolate, this, invoke_api_callbacks); |
| 386 | 425 |
| 387 // Reset the bump allocation page to unused. | 426 // Reset the bump allocation page to unused. |
| 388 // Reset the freelists and setup sweeping. | 427 // Reset the freelists and setup sweeping. |
| 389 freelist_.Reset(); | 428 freelist_[HeapPage::kData].Reset(); |
| 429 freelist_[HeapPage::kExecutable].Reset(); |
| 390 GCSweeper sweeper(heap_); | 430 GCSweeper sweeper(heap_); |
| 391 intptr_t in_use = 0; | 431 intptr_t in_use = 0; |
| 392 | 432 |
| 393 HeapPage* prev_page = NULL; | 433 HeapPage* prev_page = NULL; |
| 394 HeapPage* page = pages_; | 434 HeapPage* page = pages_; |
| 395 while (page != NULL) { | 435 while (page != NULL) { |
| 396 intptr_t page_in_use = sweeper.SweepPage(page, &freelist_); | |
| 397 HeapPage* next_page = page->next(); | 436 HeapPage* next_page = page->next(); |
| 437 intptr_t page_in_use = sweeper.SweepPage(page, &freelist_[page->type()]); |
| 398 if (page_in_use == 0) { | 438 if (page_in_use == 0) { |
| 399 FreePage(page, prev_page); | 439 FreePage(page, prev_page); |
| 400 } else { | 440 } else { |
| 401 in_use += page_in_use; | 441 in_use += page_in_use; |
| 402 prev_page = page; | 442 prev_page = page; |
| 403 } | 443 } |
| 404 // Advance to the next page. | 444 // Advance to the next page. |
| 405 page = next_page; | 445 page = next_page; |
| 406 } | 446 } |
| 407 | 447 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 435 const intptr_t KB2 = KB / 2; | 475 const intptr_t KB2 = KB / 2; |
| 436 OS::PrintErr("Mark-Sweep[%d]: %"Pd64"us (%"Pd"K -> %"Pd"K, %"Pd"K)\n", | 476 OS::PrintErr("Mark-Sweep[%d]: %"Pd64"us (%"Pd"K -> %"Pd"K, %"Pd"K)\n", |
| 437 count_, | 477 count_, |
| 438 timer.TotalElapsedTime(), | 478 timer.TotalElapsedTime(), |
| 439 (in_use_before + (KB2)) / KB, | 479 (in_use_before + (KB2)) / KB, |
| 440 (in_use + (KB2)) / KB, | 480 (in_use + (KB2)) / KB, |
| 441 (capacity_ + KB2) / KB); | 481 (capacity_ + KB2) / KB); |
| 442 } | 482 } |
| 443 | 483 |
| 444 if (FLAG_print_free_list_after_gc) { | 484 if (FLAG_print_free_list_after_gc) { |
| 445 freelist_.Print(); | 485 OS::Print("Data Freelist:\n"); |
| 486 freelist_[HeapPage::kData].Print(); |
| 487 OS::Print("Executable Freelist:\n"); |
| 488 freelist_[HeapPage::kExecutable].Print(); |
| 446 } | 489 } |
| 447 | 490 |
| 448 if (FLAG_verify_after_gc) { | 491 if (FLAG_verify_after_gc) { |
| 449 OS::PrintErr("Verifying after MarkSweep..."); | 492 OS::PrintErr("Verifying after MarkSweep..."); |
| 450 heap_->Verify(); | 493 heap_->Verify(); |
| 451 OS::PrintErr(" done.\n"); | 494 OS::PrintErr(" done.\n"); |
| 452 } | 495 } |
| 453 | 496 |
| 454 count_++; | 497 count_++; |
| 455 // Done, reset the marker. | 498 // Done, reset the marker. |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 576 return 0; | 619 return 0; |
| 577 } else { | 620 } else { |
| 578 ASSERT(total_time >= gc_time); | 621 ASSERT(total_time >= gc_time); |
| 579 int result= static_cast<int>((static_cast<double>(gc_time) / | 622 int result= static_cast<int>((static_cast<double>(gc_time) / |
| 580 static_cast<double>(total_time)) * 100); | 623 static_cast<double>(total_time)) * 100); |
| 581 return result; | 624 return result; |
| 582 } | 625 } |
| 583 } | 626 } |
| 584 | 627 |
| 585 } // namespace dart | 628 } // namespace dart |
| OLD | NEW |