| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/heap/spaces.h" | 5 #include "src/heap/spaces.h" |
| 6 | 6 |
| 7 #include "src/base/bits.h" | 7 #include "src/base/bits.h" |
| 8 #include "src/base/platform/platform.h" | 8 #include "src/base/platform/platform.h" |
| 9 #include "src/full-codegen/full-codegen.h" | 9 #include "src/full-codegen/full-codegen.h" |
| 10 #include "src/heap/slot-set.h" | 10 #include "src/heap/slot-set.h" |
| (...skipping 2361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2372 | 2372 |
| 2373 | 2373 |
| 2374 int FreeList::Free(Address start, int size_in_bytes) { | 2374 int FreeList::Free(Address start, int size_in_bytes) { |
| 2375 if (size_in_bytes == 0) return 0; | 2375 if (size_in_bytes == 0) return 0; |
| 2376 | 2376 |
| 2377 owner()->heap()->CreateFillerObjectAt(start, size_in_bytes, | 2377 owner()->heap()->CreateFillerObjectAt(start, size_in_bytes, |
| 2378 ClearRecordedSlots::kNo); | 2378 ClearRecordedSlots::kNo); |
| 2379 | 2379 |
| 2380 Page* page = Page::FromAddress(start); | 2380 Page* page = Page::FromAddress(start); |
| 2381 | 2381 |
| 2382 // Early return to drop too-small blocks on the floor. | 2382 // Blocks have to be a minimum size to hold free list items. |
| 2383 if (size_in_bytes <= kSmallListMin) { | 2383 if (size_in_bytes < kMinBlockSize) { |
| 2384 page->add_wasted_memory(size_in_bytes); | 2384 page->add_wasted_memory(size_in_bytes); |
| 2385 wasted_bytes_ += size_in_bytes; | 2385 wasted_bytes_ += size_in_bytes; |
| 2386 return size_in_bytes; | 2386 return size_in_bytes; |
| 2387 } | 2387 } |
| 2388 | 2388 |
| 2389 FreeSpace* free_space = FreeSpace::cast(HeapObject::FromAddress(start)); | 2389 FreeSpace* free_space = FreeSpace::cast(HeapObject::FromAddress(start)); |
| 2390 // Insert other blocks at the head of a free list of the appropriate | 2390 // Insert other blocks at the head of a free list of the appropriate |
| 2391 // magnitude. | 2391 // magnitude. |
| 2392 FreeListCategoryType type = SelectFreeListCategoryType(size_in_bytes); | 2392 FreeListCategoryType type = SelectFreeListCategoryType(size_in_bytes); |
| 2393 category_[type].Free(free_space, size_in_bytes); | 2393 category_[type].Free(free_space, size_in_bytes); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2430 page->add_available_in_free_list(-(*node_size)); | 2430 page->add_available_in_free_list(-(*node_size)); |
| 2431 DCHECK(IsVeryLong() || Available() == SumFreeLists()); | 2431 DCHECK(IsVeryLong() || Available() == SumFreeLists()); |
| 2432 return node; | 2432 return node; |
| 2433 } | 2433 } |
| 2434 | 2434 |
| 2435 // We need a huge block of memory, but we didn't find anything in the huge | 2435 // We need a huge block of memory, but we didn't find anything in the huge |
| 2436 // list. | 2436 // list. |
| 2437 if (type == kHuge) return nullptr; | 2437 if (type == kHuge) return nullptr; |
| 2438 | 2438 |
| 2439 // Now search the best fitting free list for a node that has at least the | 2439 // Now search the best fitting free list for a node that has at least the |
| 2440 // requested size. This takes linear time in the number of elements. | 2440 // requested size. |
| 2441 type = SelectFreeListCategoryType(size_in_bytes); | 2441 type = SelectFreeListCategoryType(size_in_bytes); |
| 2442 node = category_[type].PickNodeFromList(size_in_bytes, node_size); | 2442 node = category_[type].PickNodeFromList(size_in_bytes, node_size); |
| 2443 if (node != nullptr) { | 2443 if (node != nullptr) { |
| 2444 DCHECK(size_in_bytes <= *node_size); | 2444 DCHECK(size_in_bytes <= *node_size); |
| 2445 page = Page::FromAddress(node->address()); | 2445 page = Page::FromAddress(node->address()); |
| 2446 page->add_available_in_free_list(-(*node_size)); | 2446 page->add_available_in_free_list(-(*node_size)); |
| 2447 } | 2447 } |
| 2448 | 2448 |
| 2449 DCHECK(IsVeryLong() || Available() == SumFreeLists()); | 2449 DCHECK(IsVeryLong() || Available() == SumFreeLists()); |
| 2450 return node; | 2450 return node; |
| 2451 } | 2451 } |
| 2452 | 2452 |
| 2453 | 2453 |
| 2454 FreeSpace* FreeList::TryRemoveMemory(intptr_t hint_size_in_bytes) { | 2454 FreeSpace* FreeList::TryRemoveMemory(intptr_t hint_size_in_bytes) { |
| 2455 hint_size_in_bytes = RoundDown(hint_size_in_bytes, kPointerSize); | 2455 hint_size_in_bytes = RoundDown(hint_size_in_bytes, kPointerSize); |
| 2456 base::LockGuard<base::Mutex> guard(&mutex_); | 2456 base::LockGuard<base::Mutex> guard(&mutex_); |
| 2457 FreeSpace* node = nullptr; | 2457 FreeSpace* node = nullptr; |
| 2458 int node_size = 0; | 2458 int node_size = 0; |
| 2459 // Try to find a node that fits exactly. | 2459 // Try to find a node that fits exactly. |
| 2460 node = FindNodeFor(static_cast<int>(hint_size_in_bytes), &node_size); | 2460 node = FindNodeFor(static_cast<int>(hint_size_in_bytes), &node_size); |
| 2461 // If no node could be found get as much memory as possible. | 2461 // If no node could be found get as much memory as possible. |
| 2462 if (node == nullptr) node = FindNodeIn(kHuge, &node_size); | 2462 if (node == nullptr) node = FindNodeIn(kHuge, &node_size); |
| 2463 if (node == nullptr) node = FindNodeIn(kLarge, &node_size); | 2463 if (node == nullptr) node = FindNodeIn(kLarge, &node_size); |
| 2464 if (node != nullptr) { | 2464 if (node != nullptr) { |
| 2465 // We round up the size to (kSmallListMin + kPointerSize) to (a) have a | 2465 // We round up the size to (kMinBlockSize + kPointerSize) to (a) have a |
| 2466 // size larger then the minimum size required for FreeSpace, and (b) to get | 2466 // size larger then the minimum size required for FreeSpace, and (b) to get |
| 2467 // a block that can actually be freed into some FreeList later on. | 2467 // a block that can actually be freed into some FreeList later on. |
| 2468 if (hint_size_in_bytes <= kSmallListMin) { | 2468 if (hint_size_in_bytes <= kMinBlockSize) { |
| 2469 hint_size_in_bytes = kSmallListMin + kPointerSize; | 2469 hint_size_in_bytes = kMinBlockSize + kPointerSize; |
| 2470 } | 2470 } |
| 2471 // Give back left overs that were not required by {size_in_bytes}. | 2471 // Give back left overs that were not required by {size_in_bytes}. |
| 2472 intptr_t left_over = node_size - hint_size_in_bytes; | 2472 intptr_t left_over = node_size - hint_size_in_bytes; |
| 2473 | 2473 |
| 2474 // Do not bother to return anything below {kSmallListMin} as it would be | 2474 // Do not bother to return anything below {kMinBlockSize} as it would be |
| 2475 // immediately discarded anyways. | 2475 // immediately discarded anyways. |
| 2476 if (left_over > kSmallListMin) { | 2476 if (left_over > kMinBlockSize) { |
| 2477 Free(node->address() + hint_size_in_bytes, static_cast<int>(left_over)); | 2477 Free(node->address() + hint_size_in_bytes, static_cast<int>(left_over)); |
| 2478 node->set_size(static_cast<int>(hint_size_in_bytes)); | 2478 node->set_size(static_cast<int>(hint_size_in_bytes)); |
| 2479 } | 2479 } |
| 2480 } | 2480 } |
| 2481 return node; | 2481 return node; |
| 2482 } | 2482 } |
| 2483 | 2483 |
| 2484 | 2484 |
| 2485 // Allocation on the old space free list. If it succeeds then a new linear | 2485 // Allocation on the old space free list. If it succeeds then a new linear |
| 2486 // allocation space has been set up with the top and limit of the space. If | 2486 // allocation space has been set up with the top and limit of the space. If |
| (...skipping 755 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3242 object->ShortPrint(); | 3242 object->ShortPrint(); |
| 3243 PrintF("\n"); | 3243 PrintF("\n"); |
| 3244 } | 3244 } |
| 3245 printf(" --------------------------------------\n"); | 3245 printf(" --------------------------------------\n"); |
| 3246 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes()); | 3246 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes()); |
| 3247 } | 3247 } |
| 3248 | 3248 |
| 3249 #endif // DEBUG | 3249 #endif // DEBUG |
| 3250 } // namespace internal | 3250 } // namespace internal |
| 3251 } // namespace v8 | 3251 } // namespace v8 |
| OLD | NEW |