Chromium Code Reviews| 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 1911 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1922 ASSERT(map() == NULL || Size() >= kNextOffset + kPointerSize); | 1922 ASSERT(map() == NULL || Size() >= kNextOffset + kPointerSize); |
| 1923 Memory::Address_at(address() + kNextOffset) = | 1923 Memory::Address_at(address() + kNextOffset) = |
| 1924 reinterpret_cast<Address>(next); | 1924 reinterpret_cast<Address>(next); |
| 1925 } else { | 1925 } else { |
| 1926 Memory::Address_at(address() + kPointerSize) = | 1926 Memory::Address_at(address() + kPointerSize) = |
| 1927 reinterpret_cast<Address>(next); | 1927 reinterpret_cast<Address>(next); |
| 1928 } | 1928 } |
| 1929 } | 1929 } |
| 1930 | 1930 |
| 1931 | 1931 |
| 1932 FreeList::FreeList(PagedSpace* owner) | 1932 void FreeListCategory::ConcatenateFreeLists(FreeListCategory* category) { |
| 1933 : owner_(owner), heap_(owner->heap()) { | 1933 ScopedLock lock_target(mutex_); |
| 1934 Reset(); | 1934 ScopedLock lock_source(category->mutex()); |
|
Michael Starzinger
2012/12/11 10:50:41
This operation is grabbing two mutexes in sequence
Hannes Payer (out of office)
2012/12/11 17:10:15
OK, I removed it. The code is not going to deadloc
| |
| 1935 if (end_ == NULL) { | |
| 1936 end_ = category->end(); | |
| 1937 } else { | |
| 1938 category->end()->set_next(top_); | |
| 1939 } | |
| 1940 top_ = category->top(); | |
| 1941 available_ += category->available(); | |
| 1942 category->Reset(); | |
| 1935 } | 1943 } |
| 1936 | 1944 |
| 1937 | 1945 |
| 1938 void FreeList::Reset() { | 1946 void FreeListCategory::Reset() { |
| 1947 top_ = NULL; | |
| 1948 end_ = NULL; | |
| 1939 available_ = 0; | 1949 available_ = 0; |
| 1940 small_list_ = NULL; | |
| 1941 medium_list_ = NULL; | |
| 1942 large_list_ = NULL; | |
| 1943 huge_list_ = NULL; | |
| 1944 } | 1950 } |
| 1945 | 1951 |
| 1946 | 1952 |
| 1947 int FreeList::Free(Address start, int size_in_bytes) { | 1953 intptr_t FreeListCategory::CountFreeListItemsInList(Page* p) { |
| 1948 if (size_in_bytes == 0) return 0; | 1954 intptr_t sum = 0; |
| 1949 FreeListNode* node = FreeListNode::FromAddress(start); | 1955 FreeListNode* n = top_; |
| 1950 node->set_size(heap_, size_in_bytes); | 1956 while (n != NULL) { |
| 1951 | 1957 if (Page::FromAddress(n->address()) == p) { |
| 1952 // Early return to drop too-small blocks on the floor. | 1958 FreeSpace* free_space = reinterpret_cast<FreeSpace*>(n); |
| 1953 if (size_in_bytes < kSmallListMin) return size_in_bytes; | 1959 sum += free_space->Size(); |
| 1954 | 1960 } |
| 1955 // Insert other blocks at the head of a free list of the appropriate | 1961 n = n->next(); |
| 1956 // magnitude. | |
| 1957 if (size_in_bytes <= kSmallListMax) { | |
| 1958 node->set_next(small_list_); | |
| 1959 small_list_ = node; | |
| 1960 } else if (size_in_bytes <= kMediumListMax) { | |
| 1961 node->set_next(medium_list_); | |
| 1962 medium_list_ = node; | |
| 1963 } else if (size_in_bytes <= kLargeListMax) { | |
| 1964 node->set_next(large_list_); | |
| 1965 large_list_ = node; | |
| 1966 } else { | |
| 1967 node->set_next(huge_list_); | |
| 1968 huge_list_ = node; | |
| 1969 } | 1962 } |
| 1970 available_ += size_in_bytes; | 1963 return sum; |
| 1971 ASSERT(IsVeryLong() || available_ == SumFreeLists()); | |
| 1972 return 0; | |
| 1973 } | 1964 } |
| 1974 | 1965 |
| 1975 | 1966 |
| 1976 FreeListNode* FreeList::PickNodeFromList(FreeListNode** list, int* node_size) { | 1967 intptr_t FreeListCategory::EvictFreeListItemsInList(Page* p) { |
| 1977 FreeListNode* node = *list; | 1968 intptr_t sum = 0; |
| 1969 FreeListNode** n = &top_; | |
| 1970 while (*n != NULL) { | |
| 1971 if (Page::FromAddress((*n)->address()) == p) { | |
| 1972 FreeSpace* free_space = reinterpret_cast<FreeSpace*>(*n); | |
| 1973 sum += free_space->Size(); | |
| 1974 *n = (*n)->next(); | |
| 1975 } else { | |
| 1976 n = (*n)->next_address(); | |
| 1977 } | |
| 1978 } | |
| 1979 if (top_ == NULL) { | |
| 1980 end_ = NULL; | |
| 1981 } | |
| 1982 available_ -= sum; | |
| 1983 return sum; | |
| 1984 } | |
| 1985 | |
| 1986 | |
| 1987 FreeListNode* FreeListCategory::PickNodeFromList(int *node_size) { | |
| 1988 FreeListNode* node = top_; | |
| 1978 | 1989 |
| 1979 if (node == NULL) return NULL; | 1990 if (node == NULL) return NULL; |
| 1980 | 1991 |
| 1981 while (node != NULL && | 1992 while (node != NULL && |
| 1982 Page::FromAddress(node->address())->IsEvacuationCandidate()) { | 1993 Page::FromAddress(node->address())->IsEvacuationCandidate()) { |
| 1983 available_ -= node->Size(); | 1994 available_ -= node->Size(); |
| 1984 node = node->next(); | 1995 node = node->next(); |
| 1985 } | 1996 } |
| 1986 | 1997 |
| 1987 if (node != NULL) { | 1998 if (node != NULL) { |
| 1999 set_top(node->next()); | |
| 1988 *node_size = node->Size(); | 2000 *node_size = node->Size(); |
| 1989 *list = node->next(); | 2001 available_ -= *node_size; |
| 1990 } else { | 2002 } else { |
| 1991 *list = NULL; | 2003 set_top(NULL); |
| 2004 } | |
| 2005 | |
| 2006 if (top() == NULL) { | |
| 2007 set_end(NULL); | |
| 1992 } | 2008 } |
| 1993 | 2009 |
| 1994 return node; | 2010 return node; |
| 1995 } | 2011 } |
| 1996 | 2012 |
| 1997 | 2013 |
| 2014 void FreeListCategory::Free(FreeListNode* node, int size_in_bytes) { | |
| 2015 node->set_next(top_); | |
| 2016 top_ = node; | |
| 2017 if (end_ == NULL) { | |
| 2018 end_ = node; | |
| 2019 } | |
| 2020 available_ += size_in_bytes; | |
| 2021 } | |
| 2022 | |
| 2023 | |
| 2024 void FreeListCategory::RepairFreeList(Heap* heap) { | |
| 2025 FreeListNode* n = top_; | |
| 2026 while (n != NULL) { | |
| 2027 Map** map_location = reinterpret_cast<Map**>(n->address()); | |
| 2028 if (*map_location == NULL) { | |
| 2029 *map_location = heap->free_space_map(); | |
| 2030 } else { | |
| 2031 ASSERT(*map_location == heap->free_space_map()); | |
| 2032 } | |
| 2033 n = n->next(); | |
| 2034 } | |
| 2035 } | |
| 2036 | |
| 2037 | |
| 2038 FreeList::FreeList(PagedSpace* owner) | |
| 2039 : owner_(owner), heap_(owner->heap()) { | |
| 2040 Reset(); | |
| 2041 } | |
| 2042 | |
| 2043 | |
| 2044 void FreeList::Reset() { | |
| 2045 small_list_.Reset(); | |
| 2046 medium_list_.Reset(); | |
| 2047 large_list_.Reset(); | |
| 2048 huge_list_.Reset(); | |
| 2049 } | |
| 2050 | |
| 2051 | |
| 2052 int FreeList::Free(Address start, int size_in_bytes) { | |
| 2053 if (size_in_bytes == 0) return 0; | |
| 2054 | |
| 2055 FreeListNode* node = FreeListNode::FromAddress(start); | |
| 2056 node->set_size(heap_, size_in_bytes); | |
| 2057 | |
| 2058 // Early return to drop too-small blocks on the floor. | |
| 2059 if (size_in_bytes < kSmallListMin) return size_in_bytes; | |
| 2060 | |
| 2061 // Insert other blocks at the head of a free list of the appropriate | |
| 2062 // magnitude. | |
| 2063 if (size_in_bytes <= kSmallListMax) { | |
| 2064 small_list_.Free(node, size_in_bytes); | |
| 2065 } else if (size_in_bytes <= kMediumListMax) { | |
| 2066 medium_list_.Free(node, size_in_bytes); | |
| 2067 } else if (size_in_bytes <= kLargeListMax) { | |
| 2068 large_list_.Free(node, size_in_bytes); | |
| 2069 } else { | |
| 2070 huge_list_.Free(node, size_in_bytes); | |
| 2071 } | |
| 2072 | |
| 2073 ASSERT(IsVeryLong() || available() == SumFreeLists()); | |
| 2074 return 0; | |
| 2075 } | |
| 2076 | |
| 2077 | |
| 1998 FreeListNode* FreeList::FindNodeFor(int size_in_bytes, int* node_size) { | 2078 FreeListNode* FreeList::FindNodeFor(int size_in_bytes, int* node_size) { |
| 1999 FreeListNode* node = NULL; | 2079 FreeListNode* node = NULL; |
| 2000 | 2080 |
| 2001 if (size_in_bytes <= kSmallAllocationMax) { | 2081 if (size_in_bytes <= kSmallAllocationMax) { |
| 2002 node = PickNodeFromList(&small_list_, node_size); | 2082 node = small_list_.PickNodeFromList(node_size); |
| 2003 if (node != NULL) return node; | 2083 if (node != NULL) return node; |
| 2004 } | 2084 } |
| 2005 | 2085 |
| 2006 if (size_in_bytes <= kMediumAllocationMax) { | 2086 if (size_in_bytes <= kMediumAllocationMax) { |
| 2007 node = PickNodeFromList(&medium_list_, node_size); | 2087 node = medium_list_.PickNodeFromList(node_size); |
| 2008 if (node != NULL) return node; | 2088 if (node != NULL) return node; |
| 2009 } | 2089 } |
| 2010 | 2090 |
| 2011 if (size_in_bytes <= kLargeAllocationMax) { | 2091 if (size_in_bytes <= kLargeAllocationMax) { |
| 2012 node = PickNodeFromList(&large_list_, node_size); | 2092 node = large_list_.PickNodeFromList(node_size); |
| 2013 if (node != NULL) return node; | 2093 if (node != NULL) return node; |
| 2014 } | 2094 } |
| 2015 | 2095 |
| 2016 for (FreeListNode** cur = &huge_list_; | 2096 int huge_list_available = huge_list_.available(); |
| 2097 for (FreeListNode** cur = huge_list_.GetTopAddress(); | |
| 2017 *cur != NULL; | 2098 *cur != NULL; |
| 2018 cur = (*cur)->next_address()) { | 2099 cur = (*cur)->next_address()) { |
| 2019 FreeListNode* cur_node = *cur; | 2100 FreeListNode* cur_node = *cur; |
| 2020 while (cur_node != NULL && | 2101 while (cur_node != NULL && |
| 2021 Page::FromAddress(cur_node->address())->IsEvacuationCandidate()) { | 2102 Page::FromAddress(cur_node->address())->IsEvacuationCandidate()) { |
| 2022 available_ -= reinterpret_cast<FreeSpace*>(cur_node)->Size(); | 2103 huge_list_available -= reinterpret_cast<FreeSpace*>(cur_node)->Size(); |
| 2023 cur_node = cur_node->next(); | 2104 cur_node = cur_node->next(); |
| 2024 } | 2105 } |
| 2025 | 2106 |
| 2026 *cur = cur_node; | 2107 *cur = cur_node; |
| 2027 if (cur_node == NULL) break; | 2108 if (cur_node == NULL) { |
| 2109 huge_list_.set_end(NULL); | |
| 2110 break; | |
| 2111 } | |
| 2028 | 2112 |
| 2029 ASSERT((*cur)->map() == HEAP->raw_unchecked_free_space_map()); | 2113 ASSERT((*cur)->map() == HEAP->raw_unchecked_free_space_map()); |
| 2030 FreeSpace* cur_as_free_space = reinterpret_cast<FreeSpace*>(*cur); | 2114 FreeSpace* cur_as_free_space = reinterpret_cast<FreeSpace*>(*cur); |
| 2031 int size = cur_as_free_space->Size(); | 2115 int size = cur_as_free_space->Size(); |
| 2032 if (size >= size_in_bytes) { | 2116 if (size >= size_in_bytes) { |
| 2033 // Large enough node found. Unlink it from the list. | 2117 // Large enough node found. Unlink it from the list. |
| 2034 node = *cur; | 2118 node = *cur; |
| 2119 *cur = node->next(); | |
| 2035 *node_size = size; | 2120 *node_size = size; |
| 2036 *cur = node->next(); | 2121 huge_list_available -= size; |
| 2037 break; | 2122 break; |
| 2038 } | 2123 } |
| 2039 } | 2124 } |
| 2040 | 2125 |
| 2126 if (huge_list_.top() == NULL) { | |
| 2127 huge_list_.set_end(NULL); | |
| 2128 } | |
| 2129 | |
| 2130 huge_list_.set_available(huge_list_available); | |
| 2131 ASSERT(IsVeryLong() || available() == SumFreeLists()); | |
| 2132 | |
| 2041 return node; | 2133 return node; |
| 2042 } | 2134 } |
| 2043 | 2135 |
| 2044 | 2136 |
| 2045 // Allocation on the old space free list. If it succeeds then a new linear | 2137 // Allocation on the old space free list. If it succeeds then a new linear |
| 2046 // allocation space has been set up with the top and limit of the space. If | 2138 // allocation space has been set up with the top and limit of the space. If |
| 2047 // the allocation fails then NULL is returned, and the caller can perform a GC | 2139 // the allocation fails then NULL is returned, and the caller can perform a GC |
| 2048 // or allocate a new page before retrying. | 2140 // or allocate a new page before retrying. |
| 2049 HeapObject* FreeList::Allocate(int size_in_bytes) { | 2141 HeapObject* FreeList::Allocate(int size_in_bytes) { |
| 2050 ASSERT(0 < size_in_bytes); | 2142 ASSERT(0 < size_in_bytes); |
| 2051 ASSERT(size_in_bytes <= kMaxBlockSize); | 2143 ASSERT(size_in_bytes <= kMaxBlockSize); |
| 2052 ASSERT(IsAligned(size_in_bytes, kPointerSize)); | 2144 ASSERT(IsAligned(size_in_bytes, kPointerSize)); |
| 2053 // Don't free list allocate if there is linear space available. | 2145 // Don't free list allocate if there is linear space available. |
| 2054 ASSERT(owner_->limit() - owner_->top() < size_in_bytes); | 2146 ASSERT(owner_->limit() - owner_->top() < size_in_bytes); |
| 2055 | 2147 |
| 2056 int new_node_size = 0; | 2148 int new_node_size = 0; |
| 2057 FreeListNode* new_node = FindNodeFor(size_in_bytes, &new_node_size); | 2149 FreeListNode* new_node = FindNodeFor(size_in_bytes, &new_node_size); |
| 2058 if (new_node == NULL) return NULL; | 2150 if (new_node == NULL) return NULL; |
| 2059 | 2151 |
| 2060 available_ -= new_node_size; | |
| 2061 ASSERT(IsVeryLong() || available_ == SumFreeLists()); | |
| 2062 | 2152 |
| 2063 int bytes_left = new_node_size - size_in_bytes; | 2153 int bytes_left = new_node_size - size_in_bytes; |
| 2064 ASSERT(bytes_left >= 0); | 2154 ASSERT(bytes_left >= 0); |
| 2065 | 2155 |
| 2066 int old_linear_size = static_cast<int>(owner_->limit() - owner_->top()); | 2156 int old_linear_size = static_cast<int>(owner_->limit() - owner_->top()); |
| 2067 // Mark the old linear allocation area with a free space map so it can be | 2157 // Mark the old linear allocation area with a free space map so it can be |
| 2068 // skipped when scanning the heap. This also puts it back in the free list | 2158 // skipped when scanning the heap. This also puts it back in the free list |
| 2069 // if it is big enough. | 2159 // if it is big enough. |
| 2070 owner_->Free(owner_->top(), old_linear_size); | 2160 owner_->Free(owner_->top(), old_linear_size); |
| 2071 | 2161 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2109 } else { | 2199 } else { |
| 2110 // TODO(gc) Try not freeing linear allocation region when bytes_left | 2200 // TODO(gc) Try not freeing linear allocation region when bytes_left |
| 2111 // are zero. | 2201 // are zero. |
| 2112 owner_->SetTop(NULL, NULL); | 2202 owner_->SetTop(NULL, NULL); |
| 2113 } | 2203 } |
| 2114 | 2204 |
| 2115 return new_node; | 2205 return new_node; |
| 2116 } | 2206 } |
| 2117 | 2207 |
| 2118 | 2208 |
| 2119 static intptr_t CountFreeListItemsInList(FreeListNode* n, Page* p) { | |
| 2120 intptr_t sum = 0; | |
| 2121 while (n != NULL) { | |
| 2122 if (Page::FromAddress(n->address()) == p) { | |
| 2123 FreeSpace* free_space = reinterpret_cast<FreeSpace*>(n); | |
| 2124 sum += free_space->Size(); | |
| 2125 } | |
| 2126 n = n->next(); | |
| 2127 } | |
| 2128 return sum; | |
| 2129 } | |
| 2130 | |
| 2131 | |
| 2132 void FreeList::CountFreeListItems(Page* p, SizeStats* sizes) { | 2209 void FreeList::CountFreeListItems(Page* p, SizeStats* sizes) { |
| 2133 sizes->huge_size_ = CountFreeListItemsInList(huge_list_, p); | 2210 sizes->huge_size_ = huge_list_.CountFreeListItemsInList(p); |
| 2134 if (sizes->huge_size_ < p->area_size()) { | 2211 if (sizes->huge_size_ < p->area_size()) { |
| 2135 sizes->small_size_ = CountFreeListItemsInList(small_list_, p); | 2212 sizes->small_size_ = small_list_.CountFreeListItemsInList(p); |
| 2136 sizes->medium_size_ = CountFreeListItemsInList(medium_list_, p); | 2213 sizes->medium_size_ = medium_list_.CountFreeListItemsInList(p); |
| 2137 sizes->large_size_ = CountFreeListItemsInList(large_list_, p); | 2214 sizes->large_size_ = large_list_.CountFreeListItemsInList(p); |
| 2138 } else { | 2215 } else { |
| 2139 sizes->small_size_ = 0; | 2216 sizes->small_size_ = 0; |
| 2140 sizes->medium_size_ = 0; | 2217 sizes->medium_size_ = 0; |
| 2141 sizes->large_size_ = 0; | 2218 sizes->large_size_ = 0; |
| 2142 } | 2219 } |
| 2143 } | 2220 } |
| 2144 | 2221 |
| 2145 | 2222 |
| 2146 static intptr_t EvictFreeListItemsInList(FreeListNode** n, Page* p) { | |
| 2147 intptr_t sum = 0; | |
| 2148 while (*n != NULL) { | |
| 2149 if (Page::FromAddress((*n)->address()) == p) { | |
| 2150 FreeSpace* free_space = reinterpret_cast<FreeSpace*>(*n); | |
| 2151 sum += free_space->Size(); | |
| 2152 *n = (*n)->next(); | |
| 2153 } else { | |
| 2154 n = (*n)->next_address(); | |
| 2155 } | |
| 2156 } | |
| 2157 return sum; | |
| 2158 } | |
| 2159 | |
| 2160 | |
| 2161 intptr_t FreeList::EvictFreeListItems(Page* p) { | 2223 intptr_t FreeList::EvictFreeListItems(Page* p) { |
| 2162 intptr_t sum = EvictFreeListItemsInList(&huge_list_, p); | 2224 intptr_t sum = huge_list_.EvictFreeListItemsInList(p); |
| 2163 | 2225 |
| 2164 if (sum < p->area_size()) { | 2226 if (sum < p->area_size()) { |
| 2165 sum += EvictFreeListItemsInList(&small_list_, p) + | 2227 sum += small_list_.EvictFreeListItemsInList(p) + |
| 2166 EvictFreeListItemsInList(&medium_list_, p) + | 2228 medium_list_.EvictFreeListItemsInList(p) + |
| 2167 EvictFreeListItemsInList(&large_list_, p); | 2229 large_list_.EvictFreeListItemsInList(p); |
| 2168 } | 2230 } |
| 2169 | 2231 |
| 2170 available_ -= static_cast<int>(sum); | |
| 2171 | |
| 2172 return sum; | 2232 return sum; |
| 2173 } | 2233 } |
| 2174 | 2234 |
| 2175 | 2235 |
| 2236 void FreeList::RepairLists(Heap* heap) { | |
| 2237 small_list_.RepairFreeList(heap); | |
| 2238 medium_list_.RepairFreeList(heap); | |
| 2239 large_list_.RepairFreeList(heap); | |
| 2240 huge_list_.RepairFreeList(heap); | |
| 2241 } | |
| 2242 | |
| 2243 | |
| 2176 #ifdef DEBUG | 2244 #ifdef DEBUG |
| 2177 intptr_t FreeList::SumFreeList(FreeListNode* cur) { | 2245 intptr_t FreeListCategory::SumFreeList() { |
| 2178 intptr_t sum = 0; | 2246 intptr_t sum = 0; |
| 2247 FreeListNode* cur = top_; | |
| 2179 while (cur != NULL) { | 2248 while (cur != NULL) { |
| 2180 ASSERT(cur->map() == HEAP->raw_unchecked_free_space_map()); | 2249 ASSERT(cur->map() == HEAP->raw_unchecked_free_space_map()); |
| 2181 FreeSpace* cur_as_free_space = reinterpret_cast<FreeSpace*>(cur); | 2250 FreeSpace* cur_as_free_space = reinterpret_cast<FreeSpace*>(cur); |
| 2182 sum += cur_as_free_space->Size(); | 2251 sum += cur_as_free_space->Size(); |
| 2183 cur = cur->next(); | 2252 cur = cur->next(); |
| 2184 } | 2253 } |
| 2185 return sum; | 2254 return sum; |
| 2186 } | 2255 } |
| 2187 | 2256 |
| 2188 | 2257 |
| 2189 static const int kVeryLongFreeList = 500; | 2258 static const int kVeryLongFreeList = 500; |
| 2190 | 2259 |
| 2191 | 2260 |
| 2192 int FreeList::FreeListLength(FreeListNode* cur) { | 2261 int FreeListCategory::FreeListLength() { |
| 2193 int length = 0; | 2262 int length = 0; |
| 2263 FreeListNode* cur = top_; | |
| 2194 while (cur != NULL) { | 2264 while (cur != NULL) { |
| 2195 length++; | 2265 length++; |
| 2196 cur = cur->next(); | 2266 cur = cur->next(); |
| 2197 if (length == kVeryLongFreeList) return length; | 2267 if (length == kVeryLongFreeList) return length; |
| 2198 } | 2268 } |
| 2199 return length; | 2269 return length; |
| 2200 } | 2270 } |
| 2201 | 2271 |
| 2202 | 2272 |
| 2203 bool FreeList::IsVeryLong() { | 2273 bool FreeList::IsVeryLong() { |
| 2204 if (FreeListLength(small_list_) == kVeryLongFreeList) return true; | 2274 if (small_list_.FreeListLength() == kVeryLongFreeList) return true; |
| 2205 if (FreeListLength(medium_list_) == kVeryLongFreeList) return true; | 2275 if (medium_list_.FreeListLength() == kVeryLongFreeList) return true; |
| 2206 if (FreeListLength(large_list_) == kVeryLongFreeList) return true; | 2276 if (large_list_.FreeListLength() == kVeryLongFreeList) return true; |
| 2207 if (FreeListLength(huge_list_) == kVeryLongFreeList) return true; | 2277 if (huge_list_.FreeListLength() == kVeryLongFreeList) return true; |
| 2208 return false; | 2278 return false; |
| 2209 } | 2279 } |
| 2210 | 2280 |
| 2211 | 2281 |
| 2212 // This can take a very long time because it is linear in the number of entries | 2282 // This can take a very long time because it is linear in the number of entries |
| 2213 // on the free list, so it should not be called if FreeListLength returns | 2283 // on the free list, so it should not be called if FreeListLength returns |
| 2214 // kVeryLongFreeList. | 2284 // kVeryLongFreeList. |
| 2215 intptr_t FreeList::SumFreeLists() { | 2285 intptr_t FreeList::SumFreeLists() { |
| 2216 intptr_t sum = SumFreeList(small_list_); | 2286 intptr_t sum = small_list_.SumFreeList(); |
| 2217 sum += SumFreeList(medium_list_); | 2287 sum += medium_list_.SumFreeList(); |
| 2218 sum += SumFreeList(large_list_); | 2288 sum += large_list_.SumFreeList(); |
| 2219 sum += SumFreeList(huge_list_); | 2289 sum += huge_list_.SumFreeList(); |
| 2220 return sum; | 2290 return sum; |
| 2221 } | 2291 } |
| 2222 #endif | 2292 #endif |
| 2223 | 2293 |
| 2224 | 2294 |
| 2225 // ----------------------------------------------------------------------------- | 2295 // ----------------------------------------------------------------------------- |
| 2226 // OldSpace implementation | 2296 // OldSpace implementation |
| 2227 | 2297 |
| 2228 bool NewSpace::ReserveSpace(int bytes) { | 2298 bool NewSpace::ReserveSpace(int bytes) { |
| 2229 // We can't reliably unpack a partial snapshot that needs more new space | 2299 // We can't reliably unpack a partial snapshot that needs more new space |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2297 // Mark the old linear allocation area with a free space so it can be | 2367 // Mark the old linear allocation area with a free space so it can be |
| 2298 // skipped when scanning the heap. This also puts it back in the free list | 2368 // skipped when scanning the heap. This also puts it back in the free list |
| 2299 // if it is big enough. | 2369 // if it is big enough. |
| 2300 Free(top(), old_linear_size); | 2370 Free(top(), old_linear_size); |
| 2301 | 2371 |
| 2302 SetTop(new_area->address(), new_area->address() + size_in_bytes); | 2372 SetTop(new_area->address(), new_area->address() + size_in_bytes); |
| 2303 return true; | 2373 return true; |
| 2304 } | 2374 } |
| 2305 | 2375 |
| 2306 | 2376 |
| 2307 static void RepairFreeList(Heap* heap, FreeListNode* n) { | |
| 2308 while (n != NULL) { | |
| 2309 Map** map_location = reinterpret_cast<Map**>(n->address()); | |
| 2310 if (*map_location == NULL) { | |
| 2311 *map_location = heap->free_space_map(); | |
| 2312 } else { | |
| 2313 ASSERT(*map_location == heap->free_space_map()); | |
| 2314 } | |
| 2315 n = n->next(); | |
| 2316 } | |
| 2317 } | |
| 2318 | |
| 2319 | |
| 2320 void FreeList::RepairLists(Heap* heap) { | |
| 2321 RepairFreeList(heap, small_list_); | |
| 2322 RepairFreeList(heap, medium_list_); | |
| 2323 RepairFreeList(heap, large_list_); | |
| 2324 RepairFreeList(heap, huge_list_); | |
| 2325 } | |
| 2326 | |
| 2327 | |
| 2328 // After we have booted, we have created a map which represents free space | 2377 // After we have booted, we have created a map which represents free space |
| 2329 // on the heap. If there was already a free list then the elements on it | 2378 // on the heap. If there was already a free list then the elements on it |
| 2330 // were created with the wrong FreeSpaceMap (normally NULL), so we need to | 2379 // were created with the wrong FreeSpaceMap (normally NULL), so we need to |
| 2331 // fix them. | 2380 // fix them. |
| 2332 void PagedSpace::RepairFreeListsAfterBoot() { | 2381 void PagedSpace::RepairFreeListsAfterBoot() { |
| 2333 free_list_.RepairLists(heap()); | 2382 free_list_.RepairLists(heap()); |
| 2334 } | 2383 } |
| 2335 | 2384 |
| 2336 | 2385 |
| 2337 // You have to call this last, since the implementation from PagedSpace | 2386 // You have to call this last, since the implementation from PagedSpace |
| (...skipping 612 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2950 object->ShortPrint(); | 2999 object->ShortPrint(); |
| 2951 PrintF("\n"); | 3000 PrintF("\n"); |
| 2952 } | 3001 } |
| 2953 printf(" --------------------------------------\n"); | 3002 printf(" --------------------------------------\n"); |
| 2954 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes()); | 3003 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes()); |
| 2955 } | 3004 } |
| 2956 | 3005 |
| 2957 #endif // DEBUG | 3006 #endif // DEBUG |
| 2958 | 3007 |
| 2959 } } // namespace v8::internal | 3008 } } // namespace v8::internal |
| OLD | NEW |