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

Side by Side Diff: src/spaces.cc

Issue 13958004: Revert "On-the-fly bookkeeping of PagedSpace memory kept in free-lists." (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 8 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 | Annotate | Revision Log
« no previous file with comments | « src/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 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 679 matching lines...) Expand 10 before | Expand all | Expand 10 after
690 chunk_size, 690 chunk_size,
691 area_start, 691 area_start,
692 area_end, 692 area_end,
693 executable, 693 executable,
694 owner); 694 owner);
695 result->set_reserved_memory(&reservation); 695 result->set_reserved_memory(&reservation);
696 return result; 696 return result;
697 } 697 }
698 698
699 699
700 void Page::ResetFreeListStatistics() {
701 non_available_small_blocks_ = 0;
702 available_in_small_free_list_ = 0;
703 available_in_medium_free_list_ = 0;
704 available_in_large_free_list_ = 0;
705 available_in_huge_free_list_ = 0;
706 }
707
708
709 Page* MemoryAllocator::AllocatePage(intptr_t size, 700 Page* MemoryAllocator::AllocatePage(intptr_t size,
710 PagedSpace* owner, 701 PagedSpace* owner,
711 Executability executable) { 702 Executability executable) {
712 MemoryChunk* chunk = AllocateChunk(size, size, executable, owner); 703 MemoryChunk* chunk = AllocateChunk(size, size, executable, owner);
713 704
714 if (chunk == NULL) return NULL; 705 if (chunk == NULL) return NULL;
715 706
716 return Page::Initialize(isolate_->heap(), chunk, executable, owner); 707 return Page::Initialize(isolate_->heap(), chunk, executable, owner);
717 } 708 }
718 709
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after
1059 PageIterator it(this); 1050 PageIterator it(this);
1060 int count = 0; 1051 int count = 0;
1061 while (it.has_next()) { 1052 while (it.has_next()) {
1062 it.next(); 1053 it.next();
1063 count++; 1054 count++;
1064 } 1055 }
1065 return count; 1056 return count;
1066 } 1057 }
1067 1058
1068 1059
1069 void PagedSpace::ObtainFreeListStatistics(Page* page, SizeStats* sizes) {
1070 sizes->huge_size_ = page->available_in_huge_free_list();
1071 sizes->small_size_ = page->available_in_small_free_list();
1072 sizes->medium_size_ = page->available_in_medium_free_list();
1073 sizes->large_size_ = page->available_in_large_free_list();
1074 }
1075
1076
1077 void PagedSpace::ResetFreeListStatistics() {
1078 PageIterator page_iterator(this);
1079 while (page_iterator.has_next()) {
1080 Page* page = page_iterator.next();
1081 page->ResetFreeListStatistics();
1082 }
1083 }
1084
1085
1086 void PagedSpace::ReleasePage(Page* page, bool unlink) { 1060 void PagedSpace::ReleasePage(Page* page, bool unlink) {
1087 ASSERT(page->LiveBytes() == 0); 1061 ASSERT(page->LiveBytes() == 0);
1088 ASSERT(AreaSize() == page->area_size()); 1062 ASSERT(AreaSize() == page->area_size());
1089 1063
1090 // Adjust list of unswept pages if the page is the head of the list. 1064 // Adjust list of unswept pages if the page is the head of the list.
1091 if (first_unswept_page_ == page) { 1065 if (first_unswept_page_ == page) {
1092 first_unswept_page_ = page->next_page(); 1066 first_unswept_page_ = page->next_page();
1093 if (first_unswept_page_ == anchor()) { 1067 if (first_unswept_page_ == anchor()) {
1094 first_unswept_page_ = Page::FromAddress(NULL); 1068 first_unswept_page_ = Page::FromAddress(NULL);
1095 } 1069 }
(...skipping 979 matching lines...) Expand 10 before | Expand all | Expand 10 after
2075 } 2049 }
2076 2050
2077 2051
2078 void FreeListCategory::Reset() { 2052 void FreeListCategory::Reset() {
2079 top_ = NULL; 2053 top_ = NULL;
2080 end_ = NULL; 2054 end_ = NULL;
2081 available_ = 0; 2055 available_ = 0;
2082 } 2056 }
2083 2057
2084 2058
2059 intptr_t FreeListCategory::CountFreeListItemsInList(Page* p) {
2060 int sum = 0;
2061 FreeListNode* n = top_;
2062 while (n != NULL) {
2063 if (Page::FromAddress(n->address()) == p) {
2064 FreeSpace* free_space = reinterpret_cast<FreeSpace*>(n);
2065 sum += free_space->Size();
2066 }
2067 n = n->next();
2068 }
2069 return sum;
2070 }
2071
2072
2085 intptr_t FreeListCategory::EvictFreeListItemsInList(Page* p) { 2073 intptr_t FreeListCategory::EvictFreeListItemsInList(Page* p) {
2086 int sum = 0; 2074 int sum = 0;
2087 FreeListNode** n = &top_; 2075 FreeListNode** n = &top_;
2088 while (*n != NULL) { 2076 while (*n != NULL) {
2089 if (Page::FromAddress((*n)->address()) == p) { 2077 if (Page::FromAddress((*n)->address()) == p) {
2090 FreeSpace* free_space = reinterpret_cast<FreeSpace*>(*n); 2078 FreeSpace* free_space = reinterpret_cast<FreeSpace*>(*n);
2091 sum += free_space->Size(); 2079 sum += free_space->Size();
2092 *n = (*n)->next(); 2080 *n = (*n)->next();
2093 } else { 2081 } else {
2094 n = (*n)->next_address(); 2082 n = (*n)->next_address();
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
2175 large_list_.Reset(); 2163 large_list_.Reset();
2176 huge_list_.Reset(); 2164 huge_list_.Reset();
2177 } 2165 }
2178 2166
2179 2167
2180 int FreeList::Free(Address start, int size_in_bytes) { 2168 int FreeList::Free(Address start, int size_in_bytes) {
2181 if (size_in_bytes == 0) return 0; 2169 if (size_in_bytes == 0) return 0;
2182 2170
2183 FreeListNode* node = FreeListNode::FromAddress(start); 2171 FreeListNode* node = FreeListNode::FromAddress(start);
2184 node->set_size(heap_, size_in_bytes); 2172 node->set_size(heap_, size_in_bytes);
2185 Page* page = Page::FromAddress(start);
2186 2173
2187 // Early return to drop too-small blocks on the floor. 2174 // Early return to drop too-small blocks on the floor.
2188 if (size_in_bytes < kSmallListMin) { 2175 if (size_in_bytes < kSmallListMin) return size_in_bytes;
2189 page->add_non_available_small_blocks(size_in_bytes);
2190 return size_in_bytes;
2191 }
2192 2176
2193 // Insert other blocks at the head of a free list of the appropriate 2177 // Insert other blocks at the head of a free list of the appropriate
2194 // magnitude. 2178 // magnitude.
2195 if (size_in_bytes <= kSmallListMax) { 2179 if (size_in_bytes <= kSmallListMax) {
2196 small_list_.Free(node, size_in_bytes); 2180 small_list_.Free(node, size_in_bytes);
2197 page->add_available_in_small_free_list(size_in_bytes);
2198 } else if (size_in_bytes <= kMediumListMax) { 2181 } else if (size_in_bytes <= kMediumListMax) {
2199 medium_list_.Free(node, size_in_bytes); 2182 medium_list_.Free(node, size_in_bytes);
2200 page->add_available_in_medium_free_list(size_in_bytes);
2201 } else if (size_in_bytes <= kLargeListMax) { 2183 } else if (size_in_bytes <= kLargeListMax) {
2202 large_list_.Free(node, size_in_bytes); 2184 large_list_.Free(node, size_in_bytes);
2203 page->add_available_in_large_free_list(size_in_bytes);
2204 } else { 2185 } else {
2205 huge_list_.Free(node, size_in_bytes); 2186 huge_list_.Free(node, size_in_bytes);
2206 page->add_available_in_huge_free_list(size_in_bytes);
2207 } 2187 }
2208 2188
2209 ASSERT(IsVeryLong() || available() == SumFreeLists()); 2189 ASSERT(IsVeryLong() || available() == SumFreeLists());
2210 return 0; 2190 return 0;
2211 } 2191 }
2212 2192
2213 2193
2214 FreeListNode* FreeList::FindNodeFor(int size_in_bytes, int* node_size) { 2194 FreeListNode* FreeList::FindNodeFor(int size_in_bytes, int* node_size) {
2215 FreeListNode* node = NULL; 2195 FreeListNode* node = NULL;
2216 Page* page = NULL;
2217 2196
2218 if (size_in_bytes <= kSmallAllocationMax) { 2197 if (size_in_bytes <= kSmallAllocationMax) {
2219 node = small_list_.PickNodeFromList(node_size); 2198 node = small_list_.PickNodeFromList(node_size);
2220 if (node != NULL) { 2199 if (node != NULL) return node;
2221 page = Page::FromAddress(node->address());
2222 page->add_available_in_small_free_list(-(*node_size));
2223 return node;
2224 }
2225 } 2200 }
2226 2201
2227 if (size_in_bytes <= kMediumAllocationMax) { 2202 if (size_in_bytes <= kMediumAllocationMax) {
2228 node = medium_list_.PickNodeFromList(node_size); 2203 node = medium_list_.PickNodeFromList(node_size);
2229 if (node != NULL) { 2204 if (node != NULL) return node;
2230 page = Page::FromAddress(node->address());
2231 page->add_available_in_medium_free_list(-(*node_size));
2232 return node;
2233 }
2234 } 2205 }
2235 2206
2236 if (size_in_bytes <= kLargeAllocationMax) { 2207 if (size_in_bytes <= kLargeAllocationMax) {
2237 node = large_list_.PickNodeFromList(node_size); 2208 node = large_list_.PickNodeFromList(node_size);
2238 if (node != NULL) { 2209 if (node != NULL) return node;
2239 page = Page::FromAddress(node->address());
2240 page->add_available_in_large_free_list(-(*node_size));
2241 return node;
2242 }
2243 } 2210 }
2244 2211
2245 int huge_list_available = huge_list_.available(); 2212 int huge_list_available = huge_list_.available();
2246 for (FreeListNode** cur = huge_list_.GetTopAddress(); 2213 for (FreeListNode** cur = huge_list_.GetTopAddress();
2247 *cur != NULL; 2214 *cur != NULL;
2248 cur = (*cur)->next_address()) { 2215 cur = (*cur)->next_address()) {
2249 FreeListNode* cur_node = *cur; 2216 FreeListNode* cur_node = *cur;
2250 while (cur_node != NULL && 2217 while (cur_node != NULL &&
2251 Page::FromAddress(cur_node->address())->IsEvacuationCandidate()) { 2218 Page::FromAddress(cur_node->address())->IsEvacuationCandidate()) {
2252 int size = reinterpret_cast<FreeSpace*>(cur_node)->Size(); 2219 huge_list_available -= reinterpret_cast<FreeSpace*>(cur_node)->Size();
2253 huge_list_available -= size;
2254 page = Page::FromAddress(node->address());
2255 page->add_available_in_huge_free_list(-size);
2256 cur_node = cur_node->next(); 2220 cur_node = cur_node->next();
2257 } 2221 }
2258 2222
2259 *cur = cur_node; 2223 *cur = cur_node;
2260 if (cur_node == NULL) { 2224 if (cur_node == NULL) {
2261 huge_list_.set_end(NULL); 2225 huge_list_.set_end(NULL);
2262 break; 2226 break;
2263 } 2227 }
2264 2228
2265 ASSERT((*cur)->map() == heap_->raw_unchecked_free_space_map()); 2229 ASSERT((*cur)->map() == heap_->raw_unchecked_free_space_map());
2266 FreeSpace* cur_as_free_space = reinterpret_cast<FreeSpace*>(*cur); 2230 FreeSpace* cur_as_free_space = reinterpret_cast<FreeSpace*>(*cur);
2267 int size = cur_as_free_space->Size(); 2231 int size = cur_as_free_space->Size();
2268 if (size >= size_in_bytes) { 2232 if (size >= size_in_bytes) {
2269 // Large enough node found. Unlink it from the list. 2233 // Large enough node found. Unlink it from the list.
2270 node = *cur; 2234 node = *cur;
2271 *cur = node->next(); 2235 *cur = node->next();
2272 *node_size = size; 2236 *node_size = size;
2273 huge_list_available -= size; 2237 huge_list_available -= size;
2274 page = Page::FromAddress(node->address());
2275 page->add_available_in_huge_free_list(-size);
2276 break; 2238 break;
2277 } 2239 }
2278 } 2240 }
2279 2241
2280 if (huge_list_.top() == NULL) { 2242 if (huge_list_.top() == NULL) {
2281 huge_list_.set_end(NULL); 2243 huge_list_.set_end(NULL);
2282 } 2244 }
2283 2245
2284 huge_list_.set_available(huge_list_available); 2246 huge_list_.set_available(huge_list_available);
2285 ASSERT(IsVeryLong() || available() == SumFreeLists()); 2247 ASSERT(IsVeryLong() || available() == SumFreeLists());
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
2353 } else { 2315 } else {
2354 // TODO(gc) Try not freeing linear allocation region when bytes_left 2316 // TODO(gc) Try not freeing linear allocation region when bytes_left
2355 // are zero. 2317 // are zero.
2356 owner_->SetTop(NULL, NULL); 2318 owner_->SetTop(NULL, NULL);
2357 } 2319 }
2358 2320
2359 return new_node; 2321 return new_node;
2360 } 2322 }
2361 2323
2362 2324
2325 void FreeList::CountFreeListItems(Page* p, SizeStats* sizes) {
2326 sizes->huge_size_ = huge_list_.CountFreeListItemsInList(p);
2327 if (sizes->huge_size_ < p->area_size()) {
2328 sizes->small_size_ = small_list_.CountFreeListItemsInList(p);
2329 sizes->medium_size_ = medium_list_.CountFreeListItemsInList(p);
2330 sizes->large_size_ = large_list_.CountFreeListItemsInList(p);
2331 } else {
2332 sizes->small_size_ = 0;
2333 sizes->medium_size_ = 0;
2334 sizes->large_size_ = 0;
2335 }
2336 }
2337
2338
2363 intptr_t FreeList::EvictFreeListItems(Page* p) { 2339 intptr_t FreeList::EvictFreeListItems(Page* p) {
2364 intptr_t sum = huge_list_.EvictFreeListItemsInList(p); 2340 intptr_t sum = huge_list_.EvictFreeListItemsInList(p);
2365 p->set_available_in_huge_free_list(0);
2366 2341
2367 if (sum < p->area_size()) { 2342 if (sum < p->area_size()) {
2368 sum += small_list_.EvictFreeListItemsInList(p) + 2343 sum += small_list_.EvictFreeListItemsInList(p) +
2369 medium_list_.EvictFreeListItemsInList(p) + 2344 medium_list_.EvictFreeListItemsInList(p) +
2370 large_list_.EvictFreeListItemsInList(p); 2345 large_list_.EvictFreeListItemsInList(p);
2371 p->set_available_in_small_free_list(0);
2372 p->set_available_in_medium_free_list(0);
2373 p->set_available_in_large_free_list(0);
2374 } 2346 }
2375 2347
2376 return sum; 2348 return sum;
2377 } 2349 }
2378 2350
2379 2351
2380 void FreeList::RepairLists(Heap* heap) { 2352 void FreeList::RepairLists(Heap* heap) {
2381 small_list_.RepairFreeList(heap); 2353 small_list_.RepairFreeList(heap);
2382 medium_list_.RepairFreeList(heap); 2354 medium_list_.RepairFreeList(heap);
2383 large_list_.RepairFreeList(heap); 2355 large_list_.RepairFreeList(heap);
(...skipping 787 matching lines...) Expand 10 before | Expand all | Expand 10 after
3171 object->ShortPrint(); 3143 object->ShortPrint();
3172 PrintF("\n"); 3144 PrintF("\n");
3173 } 3145 }
3174 printf(" --------------------------------------\n"); 3146 printf(" --------------------------------------\n");
3175 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes()); 3147 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes());
3176 } 3148 }
3177 3149
3178 #endif // DEBUG 3150 #endif // DEBUG
3179 3151
3180 } } // namespace v8::internal 3152 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/spaces.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698