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 2048 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2059 return size; | 2059 return size; |
2060 } | 2060 } |
2061 | 2061 |
2062 | 2062 |
2063 // ----------------------------------------------------------------------------- | 2063 // ----------------------------------------------------------------------------- |
2064 // Free lists for old object spaces implementation | 2064 // Free lists for old object spaces implementation |
2065 | 2065 |
2066 intptr_t FreeListCategory::Concatenate(FreeListCategory* category) { | 2066 intptr_t FreeListCategory::Concatenate(FreeListCategory* category) { |
2067 intptr_t free_bytes = 0; | 2067 intptr_t free_bytes = 0; |
2068 if (category->top() != NULL) { | 2068 if (category->top() != NULL) { |
2069 // This is safe (not going to deadlock) since Concatenate operations | |
2070 // are never performed on the same free lists at the same time in | |
2071 // reverse order. Furthermore, we only lock if the PagedSpace containing | |
2072 // the free list is know to be globally available, i.e., not local. | |
2073 if (!this->owner()->owner()->is_local()) mutex()->Lock(); | |
2074 if (!category->owner()->owner()->is_local()) category->mutex()->Lock(); | |
2075 DCHECK(category->end_ != NULL); | 2069 DCHECK(category->end_ != NULL); |
2076 free_bytes = category->available(); | 2070 free_bytes = category->available(); |
2077 if (end_ == NULL) { | 2071 if (end_ == NULL) { |
2078 end_ = category->end(); | 2072 end_ = category->end(); |
2079 } else { | 2073 } else { |
2080 category->end()->set_next(top()); | 2074 category->end()->set_next(top()); |
2081 } | 2075 } |
2082 set_top(category->top()); | 2076 set_top(category->top()); |
2083 base::NoBarrier_Store(&top_, category->top_); | 2077 base::NoBarrier_Store(&top_, category->top_); |
2084 available_ += category->available(); | 2078 available_ += category->available(); |
2085 category->Reset(); | 2079 category->Reset(); |
2086 if (!category->owner()->owner()->is_local()) category->mutex()->Unlock(); | |
2087 if (!this->owner()->owner()->is_local()) mutex()->Unlock(); | |
2088 } | 2080 } |
2089 return free_bytes; | 2081 return free_bytes; |
2090 } | 2082 } |
2091 | 2083 |
2092 | 2084 |
2093 void FreeListCategory::Reset() { | 2085 void FreeListCategory::Reset() { |
2094 set_top(NULL); | 2086 set_top(NULL); |
2095 set_end(NULL); | 2087 set_end(NULL); |
2096 set_available(0); | 2088 set_available(0); |
2097 } | 2089 } |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2188 DCHECK(*map_location == heap->free_space_map()); | 2180 DCHECK(*map_location == heap->free_space_map()); |
2189 } | 2181 } |
2190 n = n->next(); | 2182 n = n->next(); |
2191 } | 2183 } |
2192 } | 2184 } |
2193 | 2185 |
2194 | 2186 |
2195 FreeList::FreeList(PagedSpace* owner) | 2187 FreeList::FreeList(PagedSpace* owner) |
2196 : owner_(owner), | 2188 : owner_(owner), |
2197 heap_(owner->heap()), | 2189 heap_(owner->heap()), |
| 2190 wasted_bytes_(0), |
2198 small_list_(this), | 2191 small_list_(this), |
2199 medium_list_(this), | 2192 medium_list_(this), |
2200 large_list_(this), | 2193 large_list_(this), |
2201 huge_list_(this) { | 2194 huge_list_(this) { |
2202 Reset(); | 2195 Reset(); |
2203 } | 2196 } |
2204 | 2197 |
2205 | 2198 |
2206 intptr_t FreeList::Concatenate(FreeList* free_list) { | 2199 intptr_t FreeList::Concatenate(FreeList* other) { |
2207 intptr_t free_bytes = 0; | 2200 intptr_t free_bytes = 0; |
2208 free_bytes += small_list_.Concatenate(free_list->small_list()); | 2201 |
2209 free_bytes += medium_list_.Concatenate(free_list->medium_list()); | 2202 // This is safe (not going to deadlock) since Concatenate operations |
2210 free_bytes += large_list_.Concatenate(free_list->large_list()); | 2203 // are never performed on the same free lists at the same time in |
2211 free_bytes += huge_list_.Concatenate(free_list->huge_list()); | 2204 // reverse order. Furthermore, we only lock if the PagedSpace containing |
| 2205 // the free list is know to be globally available, i.e., not local. |
| 2206 if (!owner()->is_local()) mutex_.Lock(); |
| 2207 if (!other->owner()->is_local()) other->mutex()->Lock(); |
| 2208 |
| 2209 wasted_bytes_ += other->wasted_bytes_; |
| 2210 other->wasted_bytes_ = 0; |
| 2211 |
| 2212 free_bytes += small_list_.Concatenate(other->small_list()); |
| 2213 free_bytes += medium_list_.Concatenate(other->medium_list()); |
| 2214 free_bytes += large_list_.Concatenate(other->large_list()); |
| 2215 free_bytes += huge_list_.Concatenate(other->huge_list()); |
| 2216 |
| 2217 if (!other->owner()->is_local()) other->mutex()->Unlock(); |
| 2218 if (!owner()->is_local()) mutex_.Unlock(); |
2212 return free_bytes; | 2219 return free_bytes; |
2213 } | 2220 } |
2214 | 2221 |
2215 | 2222 |
2216 void FreeList::Reset() { | 2223 void FreeList::Reset() { |
2217 small_list_.Reset(); | 2224 small_list_.Reset(); |
2218 medium_list_.Reset(); | 2225 medium_list_.Reset(); |
2219 large_list_.Reset(); | 2226 large_list_.Reset(); |
2220 huge_list_.Reset(); | 2227 huge_list_.Reset(); |
| 2228 ResetStats(); |
2221 } | 2229 } |
2222 | 2230 |
2223 | 2231 |
2224 int FreeList::Free(Address start, int size_in_bytes) { | 2232 int FreeList::Free(Address start, int size_in_bytes) { |
2225 if (size_in_bytes == 0) return 0; | 2233 if (size_in_bytes == 0) return 0; |
2226 | 2234 |
2227 heap_->CreateFillerObjectAt(start, size_in_bytes); | 2235 heap_->CreateFillerObjectAt(start, size_in_bytes); |
2228 | 2236 |
2229 Page* page = Page::FromAddress(start); | 2237 Page* page = Page::FromAddress(start); |
2230 | 2238 |
2231 // Early return to drop too-small blocks on the floor. | 2239 // Early return to drop too-small blocks on the floor. |
2232 if (size_in_bytes <= kSmallListMin) { | 2240 if (size_in_bytes <= kSmallListMin) { |
2233 page->add_non_available_small_blocks(size_in_bytes); | 2241 page->add_non_available_small_blocks(size_in_bytes); |
| 2242 wasted_bytes_ += size_in_bytes; |
2234 return size_in_bytes; | 2243 return size_in_bytes; |
2235 } | 2244 } |
2236 | 2245 |
2237 FreeSpace* free_space = FreeSpace::cast(HeapObject::FromAddress(start)); | 2246 FreeSpace* free_space = FreeSpace::cast(HeapObject::FromAddress(start)); |
2238 // Insert other blocks at the head of a free list of the appropriate | 2247 // Insert other blocks at the head of a free list of the appropriate |
2239 // magnitude. | 2248 // magnitude. |
2240 if (size_in_bytes <= kSmallListMax) { | 2249 if (size_in_bytes <= kSmallListMax) { |
2241 small_list_.Free(free_space, size_in_bytes); | 2250 small_list_.Free(free_space, size_in_bytes); |
2242 page->add_available_in_small_free_list(size_in_bytes); | 2251 page->add_available_in_small_free_list(size_in_bytes); |
2243 } else if (size_in_bytes <= kMediumListMax) { | 2252 } else if (size_in_bytes <= kMediumListMax) { |
(...skipping 897 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3141 object->ShortPrint(); | 3150 object->ShortPrint(); |
3142 PrintF("\n"); | 3151 PrintF("\n"); |
3143 } | 3152 } |
3144 printf(" --------------------------------------\n"); | 3153 printf(" --------------------------------------\n"); |
3145 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes()); | 3154 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes()); |
3146 } | 3155 } |
3147 | 3156 |
3148 #endif // DEBUG | 3157 #endif // DEBUG |
3149 } // namespace internal | 3158 } // namespace internal |
3150 } // namespace v8 | 3159 } // namespace v8 |
OLD | NEW |