| 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 | 
|---|