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 |