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/slots-buffer.h" | 10 #include "src/heap/slots-buffer.h" |
(...skipping 996 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1007 // area_size_ | 1007 // area_size_ |
1008 // allocation_info_ | 1008 // allocation_info_ |
1009 // end_of_unswept_pages_ | 1009 // end_of_unswept_pages_ |
1010 // unswept_free_bytes_ | 1010 // unswept_free_bytes_ |
1011 // anchor_ | 1011 // anchor_ |
1012 | 1012 |
1013 MoveOverFreeMemory(other); | 1013 MoveOverFreeMemory(other); |
1014 | 1014 |
1015 // Update and clear accounting statistics. | 1015 // Update and clear accounting statistics. |
1016 accounting_stats_.Merge(other->accounting_stats_); | 1016 accounting_stats_.Merge(other->accounting_stats_); |
1017 other->accounting_stats_.Clear(); | 1017 other->accounting_stats_.Reset(); |
1018 | 1018 |
1019 // Move over pages. | 1019 // Move over pages. |
1020 PageIterator it(other); | 1020 PageIterator it(other); |
1021 Page* p = nullptr; | 1021 Page* p = nullptr; |
1022 while (it.has_next()) { | 1022 while (it.has_next()) { |
1023 p = it.next(); | 1023 p = it.next(); |
1024 p->Unlink(); | 1024 p->Unlink(); |
1025 p->set_owner(this); | 1025 p->set_owner(this); |
1026 p->InsertAfter(anchor_.prev_page()); | 1026 p->InsertAfter(anchor_.prev_page()); |
1027 } | 1027 } |
(...skipping 1176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2204 intptr_t FreeList::Concatenate(FreeList* free_list) { | 2204 intptr_t FreeList::Concatenate(FreeList* free_list) { |
2205 intptr_t free_bytes = 0; | 2205 intptr_t free_bytes = 0; |
2206 free_bytes += small_list_.Concatenate(free_list->small_list()); | 2206 free_bytes += small_list_.Concatenate(free_list->small_list()); |
2207 free_bytes += medium_list_.Concatenate(free_list->medium_list()); | 2207 free_bytes += medium_list_.Concatenate(free_list->medium_list()); |
2208 free_bytes += large_list_.Concatenate(free_list->large_list()); | 2208 free_bytes += large_list_.Concatenate(free_list->large_list()); |
2209 free_bytes += huge_list_.Concatenate(free_list->huge_list()); | 2209 free_bytes += huge_list_.Concatenate(free_list->huge_list()); |
2210 return free_bytes; | 2210 return free_bytes; |
2211 } | 2211 } |
2212 | 2212 |
2213 | 2213 |
2214 FreeSpace* PagedSpace::TryRemoveMemory() { | |
2215 FreeSpace* space = nullptr; | |
2216 int node_size = 0; | |
2217 space = free_list()->FindNodeIn(FreeList::kHuge, &node_size); | |
2218 if (space == nullptr) | |
2219 space = free_list()->FindNodeIn(FreeList::kLarge, &node_size); | |
2220 if (space == nullptr) | |
2221 space = free_list()->FindNodeIn(FreeList::kMedium, &node_size); | |
2222 if (space == nullptr) | |
2223 space = free_list()->FindNodeIn(FreeList::kSmall, &node_size); | |
2224 if (space != nullptr) { | |
2225 accounting_stats_.AllocateBytes(node_size); | |
2226 } | |
2227 return space; | |
2228 } | |
2229 | |
2230 | |
2231 void PagedSpace::DivideMemory(CompactionSpaceCollection** other, int num, | |
2232 intptr_t limit) { | |
2233 CHECK(num > 0); | |
2234 CHECK(other != nullptr); | |
2235 | |
2236 if (limit == 0) limit = std::numeric_limits<intptr_t>::max(); | |
2237 | |
2238 EmptyAllocationInfo(); | |
2239 | |
2240 int index = 0; | |
2241 FreeSpace* node = nullptr; | |
2242 for (CompactionSpace* space = other[index]->Get(identity()); | |
2243 ((node = TryRemoveMemory()) != nullptr) && | |
2244 (space->free_list()->available() < limit); | |
2245 space = other[++index % num]->Get(identity())) { | |
2246 CHECK(space->identity() == identity()); | |
2247 space->AddMemory(node->address(), node->size()); | |
2248 } | |
2249 } | |
2250 | |
2251 | |
2252 void FreeList::Reset() { | 2214 void FreeList::Reset() { |
2253 small_list_.Reset(); | 2215 small_list_.Reset(); |
2254 medium_list_.Reset(); | 2216 medium_list_.Reset(); |
2255 large_list_.Reset(); | 2217 large_list_.Reset(); |
2256 huge_list_.Reset(); | 2218 huge_list_.Reset(); |
2257 } | 2219 } |
2258 | 2220 |
2259 | 2221 |
2260 int FreeList::Free(Address start, int size_in_bytes) { | 2222 int FreeList::Free(Address start, int size_in_bytes) { |
2261 if (size_in_bytes == 0) return 0; | 2223 if (size_in_bytes == 0) return 0; |
(...skipping 23 matching lines...) Expand all Loading... |
2285 } else { | 2247 } else { |
2286 huge_list_.Free(free_space, size_in_bytes); | 2248 huge_list_.Free(free_space, size_in_bytes); |
2287 page->add_available_in_huge_free_list(size_in_bytes); | 2249 page->add_available_in_huge_free_list(size_in_bytes); |
2288 } | 2250 } |
2289 | 2251 |
2290 DCHECK(IsVeryLong() || available() == SumFreeLists()); | 2252 DCHECK(IsVeryLong() || available() == SumFreeLists()); |
2291 return 0; | 2253 return 0; |
2292 } | 2254 } |
2293 | 2255 |
2294 | 2256 |
2295 void FreeList::UpdateFragmentationStats(FreeListCategoryType category, | |
2296 Address address, int size) { | |
2297 Page* page = Page::FromAddress(address); | |
2298 switch (category) { | |
2299 case kSmall: | |
2300 page->add_available_in_small_free_list(size); | |
2301 break; | |
2302 case kMedium: | |
2303 page->add_available_in_medium_free_list(size); | |
2304 break; | |
2305 case kLarge: | |
2306 page->add_available_in_large_free_list(size); | |
2307 break; | |
2308 case kHuge: | |
2309 page->add_available_in_huge_free_list(size); | |
2310 break; | |
2311 default: | |
2312 UNREACHABLE(); | |
2313 } | |
2314 } | |
2315 | |
2316 | |
2317 FreeSpace* FreeList::FindNodeIn(FreeListCategoryType category, int* node_size) { | |
2318 FreeSpace* node = GetFreeListCategory(category)->PickNodeFromList(node_size); | |
2319 if (node != nullptr) { | |
2320 UpdateFragmentationStats(category, node->address(), -(*node_size)); | |
2321 DCHECK(IsVeryLong() || available() == SumFreeLists()); | |
2322 } | |
2323 return node; | |
2324 } | |
2325 | |
2326 | |
2327 FreeSpace* FreeList::FindNodeFor(int size_in_bytes, int* node_size) { | 2257 FreeSpace* FreeList::FindNodeFor(int size_in_bytes, int* node_size) { |
2328 FreeSpace* node = NULL; | 2258 FreeSpace* node = NULL; |
2329 Page* page = NULL; | 2259 Page* page = NULL; |
2330 | 2260 |
2331 if (size_in_bytes <= kSmallAllocationMax) { | 2261 if (size_in_bytes <= kSmallAllocationMax) { |
2332 node = FindNodeIn(kSmall, node_size); | 2262 node = small_list_.PickNodeFromList(node_size); |
2333 if (node != nullptr) { | 2263 if (node != NULL) { |
2334 DCHECK(size_in_bytes <= node->size()); | 2264 DCHECK(size_in_bytes <= *node_size); |
| 2265 page = Page::FromAddress(node->address()); |
| 2266 page->add_available_in_small_free_list(-(*node_size)); |
| 2267 DCHECK(IsVeryLong() || available() == SumFreeLists()); |
2335 return node; | 2268 return node; |
2336 } | 2269 } |
2337 } | 2270 } |
2338 | 2271 |
2339 if (size_in_bytes <= kMediumAllocationMax) { | 2272 if (size_in_bytes <= kMediumAllocationMax) { |
2340 node = FindNodeIn(kMedium, node_size); | 2273 node = medium_list_.PickNodeFromList(node_size); |
2341 if (node != nullptr) { | 2274 if (node != NULL) { |
2342 DCHECK(size_in_bytes <= node->size()); | 2275 DCHECK(size_in_bytes <= *node_size); |
| 2276 page = Page::FromAddress(node->address()); |
| 2277 page->add_available_in_medium_free_list(-(*node_size)); |
| 2278 DCHECK(IsVeryLong() || available() == SumFreeLists()); |
2343 return node; | 2279 return node; |
2344 } | 2280 } |
2345 } | 2281 } |
2346 | 2282 |
2347 if (size_in_bytes <= kLargeAllocationMax) { | 2283 if (size_in_bytes <= kLargeAllocationMax) { |
2348 node = FindNodeIn(kLarge, node_size); | 2284 node = large_list_.PickNodeFromList(node_size); |
2349 if (node != nullptr) { | 2285 if (node != NULL) { |
2350 DCHECK(size_in_bytes <= node->size()); | 2286 DCHECK(size_in_bytes <= *node_size); |
| 2287 page = Page::FromAddress(node->address()); |
| 2288 page->add_available_in_large_free_list(-(*node_size)); |
| 2289 DCHECK(IsVeryLong() || available() == SumFreeLists()); |
2351 return node; | 2290 return node; |
2352 } | 2291 } |
2353 } | 2292 } |
2354 | 2293 |
2355 int huge_list_available = huge_list_.available(); | 2294 int huge_list_available = huge_list_.available(); |
2356 FreeSpace* top_node = huge_list_.top(); | 2295 FreeSpace* top_node = huge_list_.top(); |
2357 for (FreeSpace** cur = &top_node; *cur != NULL; | 2296 for (FreeSpace** cur = &top_node; *cur != NULL; |
2358 cur = (*cur)->next_address()) { | 2297 cur = (*cur)->next_address()) { |
2359 FreeSpace* cur_node = *cur; | 2298 FreeSpace* cur_node = *cur; |
2360 while (cur_node != NULL && | 2299 while (cur_node != NULL && |
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2596 free_list_.Reset(); | 2535 free_list_.Reset(); |
2597 } | 2536 } |
2598 | 2537 |
2599 | 2538 |
2600 intptr_t PagedSpace::SizeOfObjects() { | 2539 intptr_t PagedSpace::SizeOfObjects() { |
2601 DCHECK(!FLAG_concurrent_sweeping || | 2540 DCHECK(!FLAG_concurrent_sweeping || |
2602 heap()->mark_compact_collector()->sweeping_in_progress() || | 2541 heap()->mark_compact_collector()->sweeping_in_progress() || |
2603 (unswept_free_bytes_ == 0)); | 2542 (unswept_free_bytes_ == 0)); |
2604 const intptr_t size = Size() - unswept_free_bytes_ - (limit() - top()); | 2543 const intptr_t size = Size() - unswept_free_bytes_ - (limit() - top()); |
2605 DCHECK_GE(size, 0); | 2544 DCHECK_GE(size, 0); |
| 2545 USE(size); |
2606 return size; | 2546 return size; |
2607 } | 2547 } |
2608 | 2548 |
2609 | 2549 |
2610 // After we have booted, we have created a map which represents free space | 2550 // After we have booted, we have created a map which represents free space |
2611 // on the heap. If there was already a free list then the elements on it | 2551 // on the heap. If there was already a free list then the elements on it |
2612 // were created with the wrong FreeSpaceMap (normally NULL), so we need to | 2552 // were created with the wrong FreeSpaceMap (normally NULL), so we need to |
2613 // fix them. | 2553 // fix them. |
2614 void PagedSpace::RepairFreeListsAfterDeserialization() { | 2554 void PagedSpace::RepairFreeListsAfterDeserialization() { |
2615 free_list_.RepairLists(heap()); | 2555 free_list_.RepairLists(heap()); |
(...skipping 583 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3199 object->ShortPrint(); | 3139 object->ShortPrint(); |
3200 PrintF("\n"); | 3140 PrintF("\n"); |
3201 } | 3141 } |
3202 printf(" --------------------------------------\n"); | 3142 printf(" --------------------------------------\n"); |
3203 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes()); | 3143 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes()); |
3204 } | 3144 } |
3205 | 3145 |
3206 #endif // DEBUG | 3146 #endif // DEBUG |
3207 } // namespace internal | 3147 } // namespace internal |
3208 } // namespace v8 | 3148 } // namespace v8 |
OLD | NEW |