Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(619)

Side by Side Diff: src/heap/spaces.cc

Issue 1389293005: [heap] Fix searching for a node in FreeListCategory (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« src/heap/mark-compact.cc ('K') | « src/heap/spaces.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 2107 matching lines...) Expand 10 before | Expand all | Expand 10 after
2118 while (node != NULL) { 2118 while (node != NULL) {
2119 if (Page::FromAddress(node->address()) == p) return true; 2119 if (Page::FromAddress(node->address()) == p) return true;
2120 node = node->next(); 2120 node = node->next();
2121 } 2121 }
2122 return false; 2122 return false;
2123 } 2123 }
2124 2124
2125 2125
2126 FreeSpace* FreeListCategory::PickNodeFromList(int* node_size) { 2126 FreeSpace* FreeListCategory::PickNodeFromList(int* node_size) {
2127 FreeSpace* node = top(); 2127 FreeSpace* node = top();
2128 if (node == nullptr) return nullptr;
2128 2129
2129 if (node == NULL) return NULL; 2130 while ((node != nullptr) &&
2130
2131 while (node != NULL &&
2132 Page::FromAddress(node->address())->IsEvacuationCandidate()) { 2131 Page::FromAddress(node->address())->IsEvacuationCandidate()) {
Hannes Payer (out of office) 2015/10/15 12:45:10 Let's re-write this piece of code. Create a local
Michael Lippautz 2015/10/15 12:53:21 Done.
2133 available_ -= node->Size(); 2132 available_ -= node->Size();
2133 Page::FromAddress(node->address())
Michael Lippautz 2015/10/15 12:23:32 This was a bug, as we did not remove the size when
Hannes Payer (out of office) 2015/10/15 12:45:10 Acknowledged.
2134 ->add_available_in_free_list(type_, -(node->Size()));
2134 node = node->next(); 2135 node = node->next();
2135 } 2136 }
2136 2137
2137 if (node != NULL) { 2138 if (node != nullptr) {
2138 set_top(node->next()); 2139 set_top(node->next());
2139 *node_size = node->Size(); 2140 *node_size = node->Size();
2140 available_ -= *node_size; 2141 available_ -= *node_size;
2141 } else { 2142 } else {
2142 set_top(NULL); 2143 set_top(nullptr);
2143 } 2144 }
2144 2145
2145 if (top() == NULL) { 2146 if (top() == nullptr) {
2146 set_end(NULL); 2147 set_end(nullptr);
2147 } 2148 }
2148 2149
2149 return node; 2150 return node;
2150 } 2151 }
2151 2152
2152 2153
2153 FreeSpace* FreeListCategory::PickNodeFromList(int size_in_bytes, 2154 FreeSpace* FreeListCategory::PickNodeFromList(int size_in_bytes,
2154 int* node_size) { 2155 int* node_size) {
2155 FreeSpace* node = PickNodeFromList(node_size); 2156 FreeSpace* node = PickNodeFromList(node_size);
2156 if (node != NULL && *node_size < size_in_bytes) { 2157 if ((node != nullptr) && (*node_size < size_in_bytes)) {
2157 Free(node, *node_size); 2158 Free(node, *node_size);
2158 *node_size = 0; 2159 *node_size = 0;
2159 return NULL; 2160 return nullptr;
2160 } 2161 }
2161 return node; 2162 return node;
2162 } 2163 }
2163 2164
2164 2165
2165 FreeSpace* FreeListCategory::SearchForNodeInList(int size_in_bytes, 2166 FreeSpace* FreeListCategory::SearchForNodeInList(int size_in_bytes,
2166 int* node_size) { 2167 int* node_size) {
2167 FreeSpace* return_node = nullptr; 2168 FreeSpace* prev_non_evac_node = nullptr;
2168 FreeSpace* top_node = top(); 2169 for (FreeSpace* cur_node = top(); cur_node != nullptr;
2170 cur_node = cur_node->next()) {
2171 int size = cur_node->size();
2172 Page* page_for_node = Page::FromAddress(cur_node->address());
2169 2173
2170 for (FreeSpace** node_it = &top_node; *node_it != NULL; 2174 if ((size >= size_in_bytes) || page_for_node->IsEvacuationCandidate()) {
2171 node_it = (*node_it)->next_address()) { 2175 // The node is either large enough or contained in an evacuation
2172 FreeSpace* cur_node = *node_it; 2176 // candidate. In both cases we need to unlink it from the list.
2173 while (cur_node != NULL &&
2174 Page::FromAddress(cur_node->address())->IsEvacuationCandidate()) {
2175 int size = cur_node->Size();
2176 available_ -= size; 2177 available_ -= size;
2177 Page::FromAddress(cur_node->address()) 2178 if (cur_node == top()) {
2178 ->add_available_in_free_list(type_, -size); 2179 set_top(cur_node->next());
2179 cur_node = cur_node->next(); 2180 }
2181 if (cur_node == end()) {
Michael Lippautz 2015/10/15 12:23:32 Bug: end() was not handled properly. The bug flush
Hannes Payer (out of office) 2015/10/15 12:45:10 Acknowledged.
2182 set_end(prev_non_evac_node);
2183 }
2184 if (prev_non_evac_node != nullptr) {
2185 prev_non_evac_node->set_next(cur_node->next());
2186 }
2187 // For evacuation candidates we continue.
2188 if (page_for_node->IsEvacuationCandidate()) {
2189 page_for_node->add_available_in_free_list(type_, -size);
Hannes Payer (out of office) 2015/10/15 12:45:10 I like it that this counter is updated here, since
Michael Lippautz 2015/10/15 12:53:21 Acknowledged.
2190 continue;
2191 }
2192 // Otherwise we have a large enough node and can return.
2193 *node_size = size;
2194 return cur_node;
2180 } 2195 }
2181 2196
2182 // Update iterator. 2197 prev_non_evac_node = cur_node;
2183 *node_it = cur_node;
2184
2185 if (cur_node == nullptr) {
2186 set_end(nullptr);
2187 break;
2188 }
2189
2190 int size = cur_node->Size();
2191 if (size >= size_in_bytes) {
2192 // Large enough node found. Unlink it from the list.
2193 return_node = cur_node;
2194 *node_it = cur_node->next();
2195 *node_size = size;
2196 available_ -= size;
2197 Page::FromAddress(return_node->address())
2198 ->add_available_in_free_list(type_, -size);
2199 break;
2200 }
2201 } 2198 }
2202 2199 return nullptr;
2203 // Top could've changed if we took the first node. Update top and end
2204 // accordingly.
2205 set_top(top_node);
2206 if (top() == nullptr) {
2207 set_end(nullptr);
2208 }
2209
2210 return return_node;
2211 } 2200 }
2212 2201
2213 2202
2214 void FreeListCategory::Free(FreeSpace* free_space, int size_in_bytes) { 2203 void FreeListCategory::Free(FreeSpace* free_space, int size_in_bytes) {
2215 free_space->set_next(top()); 2204 free_space->set_next(top());
2216 set_top(free_space); 2205 set_top(free_space);
2217 if (end_ == NULL) { 2206 if (end_ == NULL) {
2218 end_ = free_space; 2207 end_ = free_space;
2219 } 2208 }
2220 available_ += size_in_bytes; 2209 available_ += size_in_bytes;
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
2323 if (node != nullptr) { 2312 if (node != nullptr) {
2324 Page::FromAddress(node->address()) 2313 Page::FromAddress(node->address())
2325 ->add_available_in_free_list(category, -(*node_size)); 2314 ->add_available_in_free_list(category, -(*node_size));
2326 DCHECK(IsVeryLong() || available() == SumFreeLists()); 2315 DCHECK(IsVeryLong() || available() == SumFreeLists());
2327 } 2316 }
2328 return node; 2317 return node;
2329 } 2318 }
2330 2319
2331 2320
2332 FreeSpace* FreeList::FindNodeFor(int size_in_bytes, int* node_size) { 2321 FreeSpace* FreeList::FindNodeFor(int size_in_bytes, int* node_size) {
2333 FreeSpace* node = NULL; 2322 FreeSpace* node = nullptr;
2334 Page* page = NULL; 2323 Page* page = nullptr;
2335 2324
2336 if (size_in_bytes <= kSmallAllocationMax) { 2325 if (size_in_bytes <= kSmallAllocationMax) {
2337 node = FindNodeIn(kSmall, node_size); 2326 node = FindNodeIn(kSmall, node_size);
2338 if (node != NULL) { 2327 if (node != nullptr) return node;
2339 DCHECK(IsVeryLong() || available() == SumFreeLists());
2340 return node;
2341 }
2342 } 2328 }
2343 2329
2344 if (size_in_bytes <= kMediumAllocationMax) { 2330 if (size_in_bytes <= kMediumAllocationMax) {
2345 node = FindNodeIn(kMedium, node_size); 2331 node = FindNodeIn(kMedium, node_size);
2346 if (node != NULL) { 2332 if (node != nullptr) return node;
2347 DCHECK(IsVeryLong() || available() == SumFreeLists());
2348 return node;
2349 }
2350 } 2333 }
2351 2334
2352 if (size_in_bytes <= kLargeAllocationMax) { 2335 if (size_in_bytes <= kLargeAllocationMax) {
2353 node = FindNodeIn(kLarge, node_size); 2336 node = FindNodeIn(kLarge, node_size);
2354 if (node != NULL) { 2337 if (node != nullptr) return node;
2355 DCHECK(IsVeryLong() || available() == SumFreeLists());
2356 return node;
2357 }
2358 } 2338 }
2359 2339
2360 node = huge_list_.SearchForNodeInList(size_in_bytes, node_size); 2340 node = huge_list_.SearchForNodeInList(size_in_bytes, node_size);
2361 2341 if (node != nullptr) {
2362 if (node != NULL) { 2342 page = Page::FromAddress(node->address());
2343 page->add_available_in_large_free_list(-(*node_size));
2363 DCHECK(IsVeryLong() || available() == SumFreeLists()); 2344 DCHECK(IsVeryLong() || available() == SumFreeLists());
2364 return node; 2345 return node;
2365 } 2346 }
2366 2347
2367 if (size_in_bytes <= kSmallListMax) { 2348 if (size_in_bytes <= kSmallListMax) {
2368 node = small_list_.PickNodeFromList(size_in_bytes, node_size); 2349 node = small_list_.PickNodeFromList(size_in_bytes, node_size);
2369 if (node != NULL) { 2350 if (node != NULL) {
2370 DCHECK(size_in_bytes <= *node_size); 2351 DCHECK(size_in_bytes <= *node_size);
2371 page = Page::FromAddress(node->address()); 2352 page = Page::FromAddress(node->address());
2372 page->add_available_in_small_free_list(-(*node_size)); 2353 page->add_available_in_small_free_list(-(*node_size));
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
2581 while (iterator.has_next()) { 2562 while (iterator.has_next()) {
2582 Page* page = iterator.next(); 2563 Page* page = iterator.next();
2583 int size = static_cast<int>(page->non_available_small_blocks()); 2564 int size = static_cast<int>(page->non_available_small_blocks());
2584 if (size == 0) continue; 2565 if (size == 0) continue;
2585 Address address = page->OffsetToAddress(Page::kPageSize - size); 2566 Address address = page->OffsetToAddress(Page::kPageSize - size);
2586 heap()->CreateFillerObjectAt(address, size); 2567 heap()->CreateFillerObjectAt(address, size);
2587 } 2568 }
2588 } 2569 }
2589 2570
2590 2571
2591 void PagedSpace::EvictEvacuationCandidatesFromFreeLists() { 2572 void PagedSpace::EvictEvacuationCandidatesFromLinearAllocationArea() {
2592 if (allocation_info_.top() >= allocation_info_.limit()) return; 2573 if (allocation_info_.top() >= allocation_info_.limit()) return;
2593 2574
2594 if (Page::FromAllocationTop(allocation_info_.top()) 2575 if (Page::FromAllocationTop(allocation_info_.top())
2595 ->IsEvacuationCandidate()) { 2576 ->IsEvacuationCandidate()) {
2596 // Create filler object to keep page iterable if it was iterable. 2577 // Create filler object to keep page iterable if it was iterable.
2597 int remaining = 2578 int remaining =
2598 static_cast<int>(allocation_info_.limit() - allocation_info_.top()); 2579 static_cast<int>(allocation_info_.limit() - allocation_info_.top());
2599 heap()->CreateFillerObjectAt(allocation_info_.top(), remaining); 2580 heap()->CreateFillerObjectAt(allocation_info_.top(), remaining);
2600 2581
2601 allocation_info_.set_top(NULL); 2582 allocation_info_.set_top(nullptr);
2602 allocation_info_.set_limit(NULL); 2583 allocation_info_.set_limit(nullptr);
2603 } 2584 }
2604 } 2585 }
2605 2586
2606 2587
2607 HeapObject* PagedSpace::WaitForSweeperThreadsAndRetryAllocation( 2588 HeapObject* PagedSpace::WaitForSweeperThreadsAndRetryAllocation(
2608 int size_in_bytes) { 2589 int size_in_bytes) {
2609 MarkCompactCollector* collector = heap()->mark_compact_collector(); 2590 MarkCompactCollector* collector = heap()->mark_compact_collector();
2610 if (collector->sweeping_in_progress()) { 2591 if (collector->sweeping_in_progress()) {
2611 // Wait for the sweeper threads here and complete the sweeping phase. 2592 // Wait for the sweeper threads here and complete the sweeping phase.
2612 collector->EnsureSweepingCompleted(); 2593 collector->EnsureSweepingCompleted();
(...skipping 545 matching lines...) Expand 10 before | Expand all | Expand 10 after
3158 object->ShortPrint(); 3139 object->ShortPrint();
3159 PrintF("\n"); 3140 PrintF("\n");
3160 } 3141 }
3161 printf(" --------------------------------------\n"); 3142 printf(" --------------------------------------\n");
3162 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes()); 3143 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes());
3163 } 3144 }
3164 3145
3165 #endif // DEBUG 3146 #endif // DEBUG
3166 } // namespace internal 3147 } // namespace internal
3167 } // namespace v8 3148 } // namespace v8
OLDNEW
« src/heap/mark-compact.cc ('K') | « src/heap/spaces.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698