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 2057 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2068 reinterpret_cast<Address>(next); | 2068 reinterpret_cast<Address>(next); |
2069 } else { | 2069 } else { |
2070 Memory::Address_at(address() + kPointerSize) = | 2070 Memory::Address_at(address() + kPointerSize) = |
2071 reinterpret_cast<Address>(next); | 2071 reinterpret_cast<Address>(next); |
2072 } | 2072 } |
2073 } | 2073 } |
2074 | 2074 |
2075 | 2075 |
2076 intptr_t FreeListCategory::Concatenate(FreeListCategory* category) { | 2076 intptr_t FreeListCategory::Concatenate(FreeListCategory* category) { |
2077 intptr_t free_bytes = 0; | 2077 intptr_t free_bytes = 0; |
2078 if (category->top_ != NULL) { | 2078 if (category->top() != NULL) { |
2079 ASSERT(category->end_ != NULL); | |
2080 // This is safe (not going to deadlock) since Concatenate operations | 2079 // This is safe (not going to deadlock) since Concatenate operations |
2081 // are never performed on the same free lists at the same time in | 2080 // are never performed on the same free lists at the same time in |
2082 // reverse order. | 2081 // reverse order. |
2083 LockGuard<Mutex> target_lock_guard(mutex()); | 2082 LockGuard<Mutex> target_lock_guard(mutex()); |
2084 LockGuard<Mutex> source_lock_guard(category->mutex()); | 2083 LockGuard<Mutex> source_lock_guard(category->mutex()); |
| 2084 ASSERT(category->end_ != NULL); |
2085 free_bytes = category->available(); | 2085 free_bytes = category->available(); |
2086 if (end_ == NULL) { | 2086 if (end_ == NULL) { |
2087 end_ = category->end(); | 2087 end_ = category->end(); |
2088 } else { | 2088 } else { |
2089 category->end()->set_next(top_); | 2089 category->end()->set_next(top()); |
2090 } | 2090 } |
2091 top_ = category->top(); | 2091 set_top(category->top()); |
| 2092 NoBarrier_Store(&top_, category->top_); |
2092 available_ += category->available(); | 2093 available_ += category->available(); |
2093 category->Reset(); | 2094 category->Reset(); |
2094 } | 2095 } |
2095 return free_bytes; | 2096 return free_bytes; |
2096 } | 2097 } |
2097 | 2098 |
2098 | 2099 |
2099 void FreeListCategory::Reset() { | 2100 void FreeListCategory::Reset() { |
2100 top_ = NULL; | 2101 set_top(NULL); |
2101 end_ = NULL; | 2102 set_end(NULL); |
2102 available_ = 0; | 2103 set_available(0); |
2103 } | 2104 } |
2104 | 2105 |
2105 | 2106 |
2106 intptr_t FreeListCategory::EvictFreeListItemsInList(Page* p) { | 2107 intptr_t FreeListCategory::EvictFreeListItemsInList(Page* p) { |
2107 int sum = 0; | 2108 int sum = 0; |
2108 FreeListNode** n = &top_; | 2109 FreeListNode* t = top(); |
| 2110 FreeListNode** n = &t; |
2109 while (*n != NULL) { | 2111 while (*n != NULL) { |
2110 if (Page::FromAddress((*n)->address()) == p) { | 2112 if (Page::FromAddress((*n)->address()) == p) { |
2111 FreeSpace* free_space = reinterpret_cast<FreeSpace*>(*n); | 2113 FreeSpace* free_space = reinterpret_cast<FreeSpace*>(*n); |
2112 sum += free_space->Size(); | 2114 sum += free_space->Size(); |
2113 *n = (*n)->next(); | 2115 *n = (*n)->next(); |
2114 } else { | 2116 } else { |
2115 n = (*n)->next_address(); | 2117 n = (*n)->next_address(); |
2116 } | 2118 } |
2117 } | 2119 } |
2118 if (top_ == NULL) { | 2120 set_top(t); |
2119 end_ = NULL; | 2121 if (top() == NULL) { |
| 2122 set_end(NULL); |
2120 } | 2123 } |
2121 available_ -= sum; | 2124 available_ -= sum; |
2122 return sum; | 2125 return sum; |
2123 } | 2126 } |
2124 | 2127 |
2125 | 2128 |
2126 bool FreeListCategory::ContainsPageFreeListItemsInList(Page* p) { | 2129 bool FreeListCategory::ContainsPageFreeListItemsInList(Page* p) { |
2127 FreeListNode** n = &top_; | 2130 FreeListNode* node = top(); |
2128 while (*n != NULL) { | 2131 while (node != NULL) { |
2129 if (Page::FromAddress((*n)->address()) == p) return true; | 2132 if (Page::FromAddress(node->address()) == p) return true; |
2130 n = (*n)->next_address(); | 2133 node = node->next(); |
2131 } | 2134 } |
2132 return false; | 2135 return false; |
2133 } | 2136 } |
2134 | 2137 |
2135 | 2138 |
2136 FreeListNode* FreeListCategory::PickNodeFromList(int *node_size) { | 2139 FreeListNode* FreeListCategory::PickNodeFromList(int *node_size) { |
2137 FreeListNode* node = top_; | 2140 FreeListNode* node = top(); |
2138 | 2141 |
2139 if (node == NULL) return NULL; | 2142 if (node == NULL) return NULL; |
2140 | 2143 |
2141 while (node != NULL && | 2144 while (node != NULL && |
2142 Page::FromAddress(node->address())->IsEvacuationCandidate()) { | 2145 Page::FromAddress(node->address())->IsEvacuationCandidate()) { |
2143 available_ -= reinterpret_cast<FreeSpace*>(node)->Size(); | 2146 available_ -= reinterpret_cast<FreeSpace*>(node)->Size(); |
2144 node = node->next(); | 2147 node = node->next(); |
2145 } | 2148 } |
2146 | 2149 |
2147 if (node != NULL) { | 2150 if (node != NULL) { |
(...skipping 18 matching lines...) Expand all Loading... |
2166 if (node != NULL && *node_size < size_in_bytes) { | 2169 if (node != NULL && *node_size < size_in_bytes) { |
2167 Free(node, *node_size); | 2170 Free(node, *node_size); |
2168 *node_size = 0; | 2171 *node_size = 0; |
2169 return NULL; | 2172 return NULL; |
2170 } | 2173 } |
2171 return node; | 2174 return node; |
2172 } | 2175 } |
2173 | 2176 |
2174 | 2177 |
2175 void FreeListCategory::Free(FreeListNode* node, int size_in_bytes) { | 2178 void FreeListCategory::Free(FreeListNode* node, int size_in_bytes) { |
2176 node->set_next(top_); | 2179 node->set_next(top()); |
2177 top_ = node; | 2180 set_top(node); |
2178 if (end_ == NULL) { | 2181 if (end_ == NULL) { |
2179 end_ = node; | 2182 end_ = node; |
2180 } | 2183 } |
2181 available_ += size_in_bytes; | 2184 available_ += size_in_bytes; |
2182 } | 2185 } |
2183 | 2186 |
2184 | 2187 |
2185 void FreeListCategory::RepairFreeList(Heap* heap) { | 2188 void FreeListCategory::RepairFreeList(Heap* heap) { |
2186 FreeListNode* n = top_; | 2189 FreeListNode* n = top(); |
2187 while (n != NULL) { | 2190 while (n != NULL) { |
2188 Map** map_location = reinterpret_cast<Map**>(n->address()); | 2191 Map** map_location = reinterpret_cast<Map**>(n->address()); |
2189 if (*map_location == NULL) { | 2192 if (*map_location == NULL) { |
2190 *map_location = heap->free_space_map(); | 2193 *map_location = heap->free_space_map(); |
2191 } else { | 2194 } else { |
2192 ASSERT(*map_location == heap->free_space_map()); | 2195 ASSERT(*map_location == heap->free_space_map()); |
2193 } | 2196 } |
2194 n = n->next(); | 2197 n = n->next(); |
2195 } | 2198 } |
2196 } | 2199 } |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2285 if (node != NULL) { | 2288 if (node != NULL) { |
2286 ASSERT(size_in_bytes <= *node_size); | 2289 ASSERT(size_in_bytes <= *node_size); |
2287 page = Page::FromAddress(node->address()); | 2290 page = Page::FromAddress(node->address()); |
2288 page->add_available_in_large_free_list(-(*node_size)); | 2291 page->add_available_in_large_free_list(-(*node_size)); |
2289 ASSERT(IsVeryLong() || available() == SumFreeLists()); | 2292 ASSERT(IsVeryLong() || available() == SumFreeLists()); |
2290 return node; | 2293 return node; |
2291 } | 2294 } |
2292 } | 2295 } |
2293 | 2296 |
2294 int huge_list_available = huge_list_.available(); | 2297 int huge_list_available = huge_list_.available(); |
2295 for (FreeListNode** cur = huge_list_.GetTopAddress(); | 2298 FreeListNode* top_node = huge_list_.top(); |
| 2299 for (FreeListNode** cur = &top_node; |
2296 *cur != NULL; | 2300 *cur != NULL; |
2297 cur = (*cur)->next_address()) { | 2301 cur = (*cur)->next_address()) { |
2298 FreeListNode* cur_node = *cur; | 2302 FreeListNode* cur_node = *cur; |
2299 while (cur_node != NULL && | 2303 while (cur_node != NULL && |
2300 Page::FromAddress(cur_node->address())->IsEvacuationCandidate()) { | 2304 Page::FromAddress(cur_node->address())->IsEvacuationCandidate()) { |
2301 int size = reinterpret_cast<FreeSpace*>(cur_node)->Size(); | 2305 int size = reinterpret_cast<FreeSpace*>(cur_node)->Size(); |
2302 huge_list_available -= size; | 2306 huge_list_available -= size; |
2303 page = Page::FromAddress(cur_node->address()); | 2307 page = Page::FromAddress(cur_node->address()); |
2304 page->add_available_in_huge_free_list(-size); | 2308 page->add_available_in_huge_free_list(-size); |
2305 cur_node = cur_node->next(); | 2309 cur_node = cur_node->next(); |
(...skipping 13 matching lines...) Expand all Loading... |
2319 node = *cur; | 2323 node = *cur; |
2320 *cur = node->next(); | 2324 *cur = node->next(); |
2321 *node_size = size; | 2325 *node_size = size; |
2322 huge_list_available -= size; | 2326 huge_list_available -= size; |
2323 page = Page::FromAddress(node->address()); | 2327 page = Page::FromAddress(node->address()); |
2324 page->add_available_in_huge_free_list(-size); | 2328 page->add_available_in_huge_free_list(-size); |
2325 break; | 2329 break; |
2326 } | 2330 } |
2327 } | 2331 } |
2328 | 2332 |
| 2333 huge_list_.set_top(top_node); |
2329 if (huge_list_.top() == NULL) { | 2334 if (huge_list_.top() == NULL) { |
2330 huge_list_.set_end(NULL); | 2335 huge_list_.set_end(NULL); |
2331 } | 2336 } |
2332 huge_list_.set_available(huge_list_available); | 2337 huge_list_.set_available(huge_list_available); |
2333 | 2338 |
2334 if (node != NULL) { | 2339 if (node != NULL) { |
2335 ASSERT(IsVeryLong() || available() == SumFreeLists()); | 2340 ASSERT(IsVeryLong() || available() == SumFreeLists()); |
2336 return node; | 2341 return node; |
2337 } | 2342 } |
2338 | 2343 |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2472 small_list_.RepairFreeList(heap); | 2477 small_list_.RepairFreeList(heap); |
2473 medium_list_.RepairFreeList(heap); | 2478 medium_list_.RepairFreeList(heap); |
2474 large_list_.RepairFreeList(heap); | 2479 large_list_.RepairFreeList(heap); |
2475 huge_list_.RepairFreeList(heap); | 2480 huge_list_.RepairFreeList(heap); |
2476 } | 2481 } |
2477 | 2482 |
2478 | 2483 |
2479 #ifdef DEBUG | 2484 #ifdef DEBUG |
2480 intptr_t FreeListCategory::SumFreeList() { | 2485 intptr_t FreeListCategory::SumFreeList() { |
2481 intptr_t sum = 0; | 2486 intptr_t sum = 0; |
2482 FreeListNode* cur = top_; | 2487 FreeListNode* cur = top(); |
2483 while (cur != NULL) { | 2488 while (cur != NULL) { |
2484 ASSERT(cur->map() == cur->GetHeap()->raw_unchecked_free_space_map()); | 2489 ASSERT(cur->map() == cur->GetHeap()->raw_unchecked_free_space_map()); |
2485 FreeSpace* cur_as_free_space = reinterpret_cast<FreeSpace*>(cur); | 2490 FreeSpace* cur_as_free_space = reinterpret_cast<FreeSpace*>(cur); |
2486 sum += cur_as_free_space->Size(); | 2491 sum += cur_as_free_space->Size(); |
2487 cur = cur->next(); | 2492 cur = cur->next(); |
2488 } | 2493 } |
2489 return sum; | 2494 return sum; |
2490 } | 2495 } |
2491 | 2496 |
2492 | 2497 |
2493 static const int kVeryLongFreeList = 500; | 2498 static const int kVeryLongFreeList = 500; |
2494 | 2499 |
2495 | 2500 |
2496 int FreeListCategory::FreeListLength() { | 2501 int FreeListCategory::FreeListLength() { |
2497 int length = 0; | 2502 int length = 0; |
2498 FreeListNode* cur = top_; | 2503 FreeListNode* cur = top(); |
2499 while (cur != NULL) { | 2504 while (cur != NULL) { |
2500 length++; | 2505 length++; |
2501 cur = cur->next(); | 2506 cur = cur->next(); |
2502 if (length == kVeryLongFreeList) return length; | 2507 if (length == kVeryLongFreeList) return length; |
2503 } | 2508 } |
2504 return length; | 2509 return length; |
2505 } | 2510 } |
2506 | 2511 |
2507 | 2512 |
2508 bool FreeList::IsVeryLong() { | 2513 bool FreeList::IsVeryLong() { |
(...skipping 685 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3194 object->ShortPrint(); | 3199 object->ShortPrint(); |
3195 PrintF("\n"); | 3200 PrintF("\n"); |
3196 } | 3201 } |
3197 printf(" --------------------------------------\n"); | 3202 printf(" --------------------------------------\n"); |
3198 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes()); | 3203 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes()); |
3199 } | 3204 } |
3200 | 3205 |
3201 #endif // DEBUG | 3206 #endif // DEBUG |
3202 | 3207 |
3203 } } // namespace v8::internal | 3208 } } // namespace v8::internal |
OLD | NEW |