OLD | NEW |
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 2100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2111 } | 2111 } |
2112 | 2112 |
2113 | 2113 |
2114 FreeListNode* FreeListCategory::PickNodeFromList(int *node_size) { | 2114 FreeListNode* FreeListCategory::PickNodeFromList(int *node_size) { |
2115 FreeListNode* node = top_; | 2115 FreeListNode* node = top_; |
2116 | 2116 |
2117 if (node == NULL) return NULL; | 2117 if (node == NULL) return NULL; |
2118 | 2118 |
2119 while (node != NULL && | 2119 while (node != NULL && |
2120 Page::FromAddress(node->address())->IsEvacuationCandidate()) { | 2120 Page::FromAddress(node->address())->IsEvacuationCandidate()) { |
2121 available_ -= node->Size(); | 2121 available_ -= reinterpret_cast<FreeSpace*>(node)->Size(); |
2122 node = node->next(); | 2122 node = node->next(); |
2123 } | 2123 } |
2124 | 2124 |
2125 if (node != NULL) { | 2125 if (node != NULL) { |
2126 set_top(node->next()); | 2126 set_top(node->next()); |
2127 *node_size = node->Size(); | 2127 *node_size = reinterpret_cast<FreeSpace*>(node)->Size(); |
2128 available_ -= *node_size; | 2128 available_ -= *node_size; |
2129 } else { | 2129 } else { |
2130 set_top(NULL); | 2130 set_top(NULL); |
2131 } | 2131 } |
2132 | 2132 |
2133 if (top() == NULL) { | 2133 if (top() == NULL) { |
2134 set_end(NULL); | 2134 set_end(NULL); |
2135 } | 2135 } |
2136 | 2136 |
2137 return node; | 2137 return node; |
2138 } | 2138 } |
2139 | 2139 |
2140 | 2140 |
| 2141 FreeListNode* FreeListCategory::PickNodeFromList(int size_in_bytes, |
| 2142 int *node_size) { |
| 2143 FreeListNode* node = PickNodeFromList(node_size); |
| 2144 if (node != NULL && *node_size < size_in_bytes) { |
| 2145 Free(node, *node_size); |
| 2146 *node_size = 0; |
| 2147 return NULL; |
| 2148 } |
| 2149 return node; |
| 2150 } |
| 2151 |
| 2152 |
2141 void FreeListCategory::Free(FreeListNode* node, int size_in_bytes) { | 2153 void FreeListCategory::Free(FreeListNode* node, int size_in_bytes) { |
2142 node->set_next(top_); | 2154 node->set_next(top_); |
2143 top_ = node; | 2155 top_ = node; |
2144 if (end_ == NULL) { | 2156 if (end_ == NULL) { |
2145 end_ = node; | 2157 end_ = node; |
2146 } | 2158 } |
2147 available_ += size_in_bytes; | 2159 available_ += size_in_bytes; |
2148 } | 2160 } |
2149 | 2161 |
2150 | 2162 |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2195 | 2207 |
2196 // Early return to drop too-small blocks on the floor. | 2208 // Early return to drop too-small blocks on the floor. |
2197 if (size_in_bytes < kSmallListMin) { | 2209 if (size_in_bytes < kSmallListMin) { |
2198 page->add_non_available_small_blocks(size_in_bytes); | 2210 page->add_non_available_small_blocks(size_in_bytes); |
2199 return size_in_bytes; | 2211 return size_in_bytes; |
2200 } | 2212 } |
2201 | 2213 |
2202 // Insert other blocks at the head of a free list of the appropriate | 2214 // Insert other blocks at the head of a free list of the appropriate |
2203 // magnitude. | 2215 // magnitude. |
2204 if (size_in_bytes <= kSmallListMax) { | 2216 if (size_in_bytes <= kSmallListMax) { |
2205 ASSERT(!owner_->ConstantAllocationSize() || | |
2206 (owner_->identity() == MAP_SPACE && size_in_bytes >= Map::kSize) || | |
2207 (owner_->identity() == CELL_SPACE && size_in_bytes >= Cell::kSize) || | |
2208 (owner_->identity() == PROPERTY_CELL_SPACE && | |
2209 size_in_bytes >= JSGlobalPropertyCell::kSize)); | |
2210 small_list_.Free(node, size_in_bytes); | 2217 small_list_.Free(node, size_in_bytes); |
2211 page->add_available_in_small_free_list(size_in_bytes); | 2218 page->add_available_in_small_free_list(size_in_bytes); |
2212 } else if (size_in_bytes <= kMediumListMax) { | 2219 } else if (size_in_bytes <= kMediumListMax) { |
2213 medium_list_.Free(node, size_in_bytes); | 2220 medium_list_.Free(node, size_in_bytes); |
2214 page->add_available_in_medium_free_list(size_in_bytes); | 2221 page->add_available_in_medium_free_list(size_in_bytes); |
2215 } else if (size_in_bytes <= kLargeListMax) { | 2222 } else if (size_in_bytes <= kLargeListMax) { |
2216 large_list_.Free(node, size_in_bytes); | 2223 large_list_.Free(node, size_in_bytes); |
2217 page->add_available_in_large_free_list(size_in_bytes); | 2224 page->add_available_in_large_free_list(size_in_bytes); |
2218 } else { | 2225 } else { |
2219 huge_list_.Free(node, size_in_bytes); | 2226 huge_list_.Free(node, size_in_bytes); |
2220 page->add_available_in_huge_free_list(size_in_bytes); | 2227 page->add_available_in_huge_free_list(size_in_bytes); |
2221 } | 2228 } |
2222 | 2229 |
2223 ASSERT(IsVeryLong() || available() == SumFreeLists()); | 2230 ASSERT(IsVeryLong() || available() == SumFreeLists()); |
2224 return 0; | 2231 return 0; |
2225 } | 2232 } |
2226 | 2233 |
2227 | 2234 |
2228 FreeListNode* FreeList::FindNodeFor(int size_in_bytes, int* node_size) { | 2235 FreeListNode* FreeList::FindNodeFor(int size_in_bytes, int* node_size) { |
2229 FreeListNode* node = NULL; | 2236 FreeListNode* node = NULL; |
2230 Page* page = NULL; | 2237 Page* page = NULL; |
2231 | 2238 |
2232 if ((owner_->ConstantAllocationSize() && size_in_bytes <= kSmallListMax) || | 2239 if (size_in_bytes <= kSmallAllocationMax) { |
2233 size_in_bytes <= kSmallAllocationMax) { | |
2234 node = small_list_.PickNodeFromList(node_size); | 2240 node = small_list_.PickNodeFromList(node_size); |
2235 if (node != NULL) { | 2241 if (node != NULL) { |
2236 ASSERT(size_in_bytes <= *node_size); | 2242 ASSERT(size_in_bytes <= *node_size); |
2237 page = Page::FromAddress(node->address()); | 2243 page = Page::FromAddress(node->address()); |
2238 page->add_available_in_small_free_list(-(*node_size)); | 2244 page->add_available_in_small_free_list(-(*node_size)); |
| 2245 ASSERT(IsVeryLong() || available() == SumFreeLists()); |
2239 return node; | 2246 return node; |
2240 } | 2247 } |
2241 } | 2248 } |
2242 | 2249 |
2243 if (size_in_bytes <= kMediumAllocationMax) { | 2250 if (size_in_bytes <= kMediumAllocationMax) { |
2244 node = medium_list_.PickNodeFromList(node_size); | 2251 node = medium_list_.PickNodeFromList(node_size); |
2245 if (node != NULL) { | 2252 if (node != NULL) { |
2246 ASSERT(size_in_bytes <= *node_size); | 2253 ASSERT(size_in_bytes <= *node_size); |
2247 page = Page::FromAddress(node->address()); | 2254 page = Page::FromAddress(node->address()); |
2248 page->add_available_in_medium_free_list(-(*node_size)); | 2255 page->add_available_in_medium_free_list(-(*node_size)); |
| 2256 ASSERT(IsVeryLong() || available() == SumFreeLists()); |
2249 return node; | 2257 return node; |
2250 } | 2258 } |
2251 } | 2259 } |
2252 | 2260 |
2253 if (size_in_bytes <= kLargeAllocationMax) { | 2261 if (size_in_bytes <= kLargeAllocationMax) { |
2254 node = large_list_.PickNodeFromList(node_size); | 2262 node = large_list_.PickNodeFromList(node_size); |
2255 if (node != NULL) { | 2263 if (node != NULL) { |
2256 ASSERT(size_in_bytes <= *node_size); | 2264 ASSERT(size_in_bytes <= *node_size); |
2257 page = Page::FromAddress(node->address()); | 2265 page = Page::FromAddress(node->address()); |
2258 page->add_available_in_large_free_list(-(*node_size)); | 2266 page->add_available_in_large_free_list(-(*node_size)); |
| 2267 ASSERT(IsVeryLong() || available() == SumFreeLists()); |
2259 return node; | 2268 return node; |
2260 } | 2269 } |
2261 } | 2270 } |
2262 | 2271 |
2263 int huge_list_available = huge_list_.available(); | 2272 int huge_list_available = huge_list_.available(); |
2264 for (FreeListNode** cur = huge_list_.GetTopAddress(); | 2273 for (FreeListNode** cur = huge_list_.GetTopAddress(); |
2265 *cur != NULL; | 2274 *cur != NULL; |
2266 cur = (*cur)->next_address()) { | 2275 cur = (*cur)->next_address()) { |
2267 FreeListNode* cur_node = *cur; | 2276 FreeListNode* cur_node = *cur; |
2268 while (cur_node != NULL && | 2277 while (cur_node != NULL && |
(...skipping 22 matching lines...) Expand all Loading... |
2291 huge_list_available -= size; | 2300 huge_list_available -= size; |
2292 page = Page::FromAddress(node->address()); | 2301 page = Page::FromAddress(node->address()); |
2293 page->add_available_in_huge_free_list(-size); | 2302 page->add_available_in_huge_free_list(-size); |
2294 break; | 2303 break; |
2295 } | 2304 } |
2296 } | 2305 } |
2297 | 2306 |
2298 if (huge_list_.top() == NULL) { | 2307 if (huge_list_.top() == NULL) { |
2299 huge_list_.set_end(NULL); | 2308 huge_list_.set_end(NULL); |
2300 } | 2309 } |
| 2310 huge_list_.set_available(huge_list_available); |
2301 | 2311 |
2302 huge_list_.set_available(huge_list_available); | 2312 if (node != NULL) { |
| 2313 ASSERT(IsVeryLong() || available() == SumFreeLists()); |
| 2314 return node; |
| 2315 } |
| 2316 |
| 2317 if (size_in_bytes <= kSmallListMax) { |
| 2318 node = small_list_.PickNodeFromList(size_in_bytes, node_size); |
| 2319 if (node != NULL) { |
| 2320 ASSERT(size_in_bytes <= *node_size); |
| 2321 page = Page::FromAddress(node->address()); |
| 2322 page->add_available_in_small_free_list(-(*node_size)); |
| 2323 } |
| 2324 } else if (size_in_bytes <= kMediumListMax) { |
| 2325 node = medium_list_.PickNodeFromList(size_in_bytes, node_size); |
| 2326 if (node != NULL) { |
| 2327 ASSERT(size_in_bytes <= *node_size); |
| 2328 page = Page::FromAddress(node->address()); |
| 2329 page->add_available_in_medium_free_list(-(*node_size)); |
| 2330 } |
| 2331 } else if (size_in_bytes <= kLargeListMax) { |
| 2332 node = large_list_.PickNodeFromList(size_in_bytes, node_size); |
| 2333 if (node != NULL) { |
| 2334 ASSERT(size_in_bytes <= *node_size); |
| 2335 page = Page::FromAddress(node->address()); |
| 2336 page->add_available_in_large_free_list(-(*node_size)); |
| 2337 } |
| 2338 } |
| 2339 |
2303 ASSERT(IsVeryLong() || available() == SumFreeLists()); | 2340 ASSERT(IsVeryLong() || available() == SumFreeLists()); |
2304 | |
2305 return node; | 2341 return node; |
2306 } | 2342 } |
2307 | 2343 |
2308 | 2344 |
2309 // Allocation on the old space free list. If it succeeds then a new linear | 2345 // Allocation on the old space free list. If it succeeds then a new linear |
2310 // allocation space has been set up with the top and limit of the space. If | 2346 // allocation space has been set up with the top and limit of the space. If |
2311 // the allocation fails then NULL is returned, and the caller can perform a GC | 2347 // the allocation fails then NULL is returned, and the caller can perform a GC |
2312 // or allocate a new page before retrying. | 2348 // or allocate a new page before retrying. |
2313 HeapObject* FreeList::Allocate(int size_in_bytes) { | 2349 HeapObject* FreeList::Allocate(int size_in_bytes) { |
2314 ASSERT(0 < size_in_bytes); | 2350 ASSERT(0 < size_in_bytes); |
(...skipping 883 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3198 object->ShortPrint(); | 3234 object->ShortPrint(); |
3199 PrintF("\n"); | 3235 PrintF("\n"); |
3200 } | 3236 } |
3201 printf(" --------------------------------------\n"); | 3237 printf(" --------------------------------------\n"); |
3202 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes()); | 3238 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes()); |
3203 } | 3239 } |
3204 | 3240 |
3205 #endif // DEBUG | 3241 #endif // DEBUG |
3206 | 3242 |
3207 } } // namespace v8::internal | 3243 } } // namespace v8::internal |
OLD | NEW |