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 1483 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1494 // or because incremental marking wants to get a chance to do a step. Set | 1494 // or because incremental marking wants to get a chance to do a step. Set |
1495 // the new limit accordingly. | 1495 // the new limit accordingly. |
1496 Address new_top = old_top + aligned_size_in_bytes; | 1496 Address new_top = old_top + aligned_size_in_bytes; |
1497 InlineAllocationStep(new_top, new_top); | 1497 InlineAllocationStep(new_top, new_top); |
1498 UpdateInlineAllocationLimit(aligned_size_in_bytes); | 1498 UpdateInlineAllocationLimit(aligned_size_in_bytes); |
1499 } | 1499 } |
1500 return true; | 1500 return true; |
1501 } | 1501 } |
1502 | 1502 |
1503 | 1503 |
1504 void NewSpace::InlineAllocationStep(Address top, Address new_top) { | 1504 void NewSpace::InlineAllocationStep(Address top, Address new_top) { |
Hannes Payer (out of office)
2015/09/25 13:04:51
Uh, looks like you added another CL to your CL.
Hannes Payer (out of office)
2015/09/25 13:07:38
Ah, wrong diff view. Thanks for pointing this out.
Michael Lippautz
2015/09/25 13:28:49
Acknowledged.
Michael Lippautz
2015/09/25 13:28:50
Acknowledged.
| |
1505 if (top_on_previous_step_) { | 1505 if (top_on_previous_step_) { |
1506 int bytes_allocated = static_cast<int>(top - top_on_previous_step_); | 1506 int bytes_allocated = static_cast<int>(top - top_on_previous_step_); |
1507 heap()->incremental_marking()->Step(bytes_allocated, | 1507 heap()->incremental_marking()->Step(bytes_allocated, |
1508 IncrementalMarking::GC_VIA_STACK_GUARD); | 1508 IncrementalMarking::GC_VIA_STACK_GUARD); |
1509 top_on_previous_step_ = new_top; | 1509 top_on_previous_step_ = new_top; |
1510 } | 1510 } |
1511 } | 1511 } |
1512 | 1512 |
1513 #ifdef VERIFY_HEAP | 1513 #ifdef VERIFY_HEAP |
1514 // We do not use the SemiSpaceIterator because verification doesn't assume | 1514 // We do not use the SemiSpaceIterator because verification doesn't assume |
(...skipping 689 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 | |
2214 void FreeList::Reset() { | 2252 void FreeList::Reset() { |
2215 small_list_.Reset(); | 2253 small_list_.Reset(); |
2216 medium_list_.Reset(); | 2254 medium_list_.Reset(); |
2217 large_list_.Reset(); | 2255 large_list_.Reset(); |
2218 huge_list_.Reset(); | 2256 huge_list_.Reset(); |
2219 } | 2257 } |
2220 | 2258 |
2221 | 2259 |
2222 int FreeList::Free(Address start, int size_in_bytes) { | 2260 int FreeList::Free(Address start, int size_in_bytes) { |
2223 if (size_in_bytes == 0) return 0; | 2261 if (size_in_bytes == 0) return 0; |
(...skipping 23 matching lines...) Expand all Loading... | |
2247 } else { | 2285 } else { |
2248 huge_list_.Free(free_space, size_in_bytes); | 2286 huge_list_.Free(free_space, size_in_bytes); |
2249 page->add_available_in_huge_free_list(size_in_bytes); | 2287 page->add_available_in_huge_free_list(size_in_bytes); |
2250 } | 2288 } |
2251 | 2289 |
2252 DCHECK(IsVeryLong() || available() == SumFreeLists()); | 2290 DCHECK(IsVeryLong() || available() == SumFreeLists()); |
2253 return 0; | 2291 return 0; |
2254 } | 2292 } |
2255 | 2293 |
2256 | 2294 |
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 | |
2257 FreeSpace* FreeList::FindNodeFor(int size_in_bytes, int* node_size) { | 2327 FreeSpace* FreeList::FindNodeFor(int size_in_bytes, int* node_size) { |
2258 FreeSpace* node = NULL; | 2328 FreeSpace* node = NULL; |
2259 Page* page = NULL; | 2329 Page* page = NULL; |
2260 | 2330 |
2261 if (size_in_bytes <= kSmallAllocationMax) { | 2331 if (size_in_bytes <= kSmallAllocationMax) { |
2262 node = small_list_.PickNodeFromList(node_size); | 2332 node = FindNodeIn(kSmall, node_size); |
2263 if (node != NULL) { | 2333 if (node != nullptr) { |
2264 DCHECK(size_in_bytes <= *node_size); | 2334 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()); | |
2268 return node; | 2335 return node; |
2269 } | 2336 } |
2270 } | 2337 } |
2271 | 2338 |
2272 if (size_in_bytes <= kMediumAllocationMax) { | 2339 if (size_in_bytes <= kMediumAllocationMax) { |
2273 node = medium_list_.PickNodeFromList(node_size); | 2340 node = FindNodeIn(kMedium, node_size); |
2274 if (node != NULL) { | 2341 if (node != nullptr) { |
2275 DCHECK(size_in_bytes <= *node_size); | 2342 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()); | |
2279 return node; | 2343 return node; |
2280 } | 2344 } |
2281 } | 2345 } |
2282 | 2346 |
2283 if (size_in_bytes <= kLargeAllocationMax) { | 2347 if (size_in_bytes <= kLargeAllocationMax) { |
2284 node = large_list_.PickNodeFromList(node_size); | 2348 node = FindNodeIn(kLarge, node_size); |
2285 if (node != NULL) { | 2349 if (node != nullptr) { |
2286 DCHECK(size_in_bytes <= *node_size); | 2350 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()); | |
2290 return node; | 2351 return node; |
2291 } | 2352 } |
2292 } | 2353 } |
2293 | 2354 |
2294 int huge_list_available = huge_list_.available(); | 2355 int huge_list_available = huge_list_.available(); |
2295 FreeSpace* top_node = huge_list_.top(); | 2356 FreeSpace* top_node = huge_list_.top(); |
2296 for (FreeSpace** cur = &top_node; *cur != NULL; | 2357 for (FreeSpace** cur = &top_node; *cur != NULL; |
2297 cur = (*cur)->next_address()) { | 2358 cur = (*cur)->next_address()) { |
2298 FreeSpace* cur_node = *cur; | 2359 FreeSpace* cur_node = *cur; |
2299 while (cur_node != NULL && | 2360 while (cur_node != NULL && |
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2535 free_list_.Reset(); | 2596 free_list_.Reset(); |
2536 } | 2597 } |
2537 | 2598 |
2538 | 2599 |
2539 intptr_t PagedSpace::SizeOfObjects() { | 2600 intptr_t PagedSpace::SizeOfObjects() { |
2540 DCHECK(!FLAG_concurrent_sweeping || | 2601 DCHECK(!FLAG_concurrent_sweeping || |
2541 heap()->mark_compact_collector()->sweeping_in_progress() || | 2602 heap()->mark_compact_collector()->sweeping_in_progress() || |
2542 (unswept_free_bytes_ == 0)); | 2603 (unswept_free_bytes_ == 0)); |
2543 const intptr_t size = Size() - unswept_free_bytes_ - (limit() - top()); | 2604 const intptr_t size = Size() - unswept_free_bytes_ - (limit() - top()); |
2544 DCHECK_GE(size, 0); | 2605 DCHECK_GE(size, 0); |
2545 USE(size); | |
2546 return size; | 2606 return size; |
2547 } | 2607 } |
2548 | 2608 |
2549 | 2609 |
2550 // After we have booted, we have created a map which represents free space | 2610 // After we have booted, we have created a map which represents free space |
2551 // on the heap. If there was already a free list then the elements on it | 2611 // on the heap. If there was already a free list then the elements on it |
2552 // were created with the wrong FreeSpaceMap (normally NULL), so we need to | 2612 // were created with the wrong FreeSpaceMap (normally NULL), so we need to |
2553 // fix them. | 2613 // fix them. |
2554 void PagedSpace::RepairFreeListsAfterDeserialization() { | 2614 void PagedSpace::RepairFreeListsAfterDeserialization() { |
2555 free_list_.RepairLists(heap()); | 2615 free_list_.RepairLists(heap()); |
(...skipping 583 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3139 object->ShortPrint(); | 3199 object->ShortPrint(); |
3140 PrintF("\n"); | 3200 PrintF("\n"); |
3141 } | 3201 } |
3142 printf(" --------------------------------------\n"); | 3202 printf(" --------------------------------------\n"); |
3143 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes()); | 3203 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes()); |
3144 } | 3204 } |
3145 | 3205 |
3146 #endif // DEBUG | 3206 #endif // DEBUG |
3147 } // namespace internal | 3207 } // namespace internal |
3148 } // namespace v8 | 3208 } // namespace v8 |
OLD | NEW |