| 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 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 65 } | 65 } |
| 66 | 66 |
| 67 | 67 |
| 68 HeapObjectIterator::HeapObjectIterator(Page* page, | 68 HeapObjectIterator::HeapObjectIterator(Page* page, |
| 69 HeapObjectCallback size_func) { | 69 HeapObjectCallback size_func) { |
| 70 Space* owner = page->owner(); | 70 Space* owner = page->owner(); |
| 71 ASSERT(owner == page->heap()->old_pointer_space() || | 71 ASSERT(owner == page->heap()->old_pointer_space() || |
| 72 owner == page->heap()->old_data_space() || | 72 owner == page->heap()->old_data_space() || |
| 73 owner == page->heap()->map_space() || | 73 owner == page->heap()->map_space() || |
| 74 owner == page->heap()->cell_space() || | 74 owner == page->heap()->cell_space() || |
| 75 owner == page->heap()->property_cell_space() || |
| 75 owner == page->heap()->code_space()); | 76 owner == page->heap()->code_space()); |
| 76 Initialize(reinterpret_cast<PagedSpace*>(owner), | 77 Initialize(reinterpret_cast<PagedSpace*>(owner), |
| 77 page->area_start(), | 78 page->area_start(), |
| 78 page->area_end(), | 79 page->area_end(), |
| 79 kOnePageOnly, | 80 kOnePageOnly, |
| 80 size_func); | 81 size_func); |
| 81 ASSERT(page->WasSweptPrecisely()); | 82 ASSERT(page->WasSweptPrecisely()); |
| 82 } | 83 } |
| 83 | 84 |
| 84 | 85 |
| (...skipping 951 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1036 break; | 1037 break; |
| 1037 case OLD_DATA_SPACE: | 1038 case OLD_DATA_SPACE: |
| 1038 size = 192 * KB; | 1039 size = 192 * KB; |
| 1039 break; | 1040 break; |
| 1040 case MAP_SPACE: | 1041 case MAP_SPACE: |
| 1041 size = 16 * kPointerSize * KB; | 1042 size = 16 * kPointerSize * KB; |
| 1042 break; | 1043 break; |
| 1043 case CELL_SPACE: | 1044 case CELL_SPACE: |
| 1044 size = 16 * kPointerSize * KB; | 1045 size = 16 * kPointerSize * KB; |
| 1045 break; | 1046 break; |
| 1047 case PROPERTY_CELL_SPACE: |
| 1048 size = 8 * kPointerSize * KB; |
| 1049 break; |
| 1046 case CODE_SPACE: | 1050 case CODE_SPACE: |
| 1047 if (heap()->isolate()->code_range()->exists()) { | 1051 if (heap()->isolate()->code_range()->exists()) { |
| 1048 // When code range exists, code pages are allocated in a special way | 1052 // When code range exists, code pages are allocated in a special way |
| 1049 // (from the reserved code range). That part of the code is not yet | 1053 // (from the reserved code range). That part of the code is not yet |
| 1050 // upgraded to handle small pages. | 1054 // upgraded to handle small pages. |
| 1051 size = AreaSize(); | 1055 size = AreaSize(); |
| 1052 } else { | 1056 } else { |
| 1053 size = 384 * KB; | 1057 size = 384 * KB; |
| 1054 } | 1058 } |
| 1055 break; | 1059 break; |
| (...skipping 1051 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2107 } | 2111 } |
| 2108 | 2112 |
| 2109 | 2113 |
| 2110 FreeListNode* FreeListCategory::PickNodeFromList(int *node_size) { | 2114 FreeListNode* FreeListCategory::PickNodeFromList(int *node_size) { |
| 2111 FreeListNode* node = top_; | 2115 FreeListNode* node = top_; |
| 2112 | 2116 |
| 2113 if (node == NULL) return NULL; | 2117 if (node == NULL) return NULL; |
| 2114 | 2118 |
| 2115 while (node != NULL && | 2119 while (node != NULL && |
| 2116 Page::FromAddress(node->address())->IsEvacuationCandidate()) { | 2120 Page::FromAddress(node->address())->IsEvacuationCandidate()) { |
| 2117 available_ -= node->Size(); | 2121 available_ -= reinterpret_cast<FreeSpace*>(node)->Size(); |
| 2118 node = node->next(); | 2122 node = node->next(); |
| 2119 } | 2123 } |
| 2120 | 2124 |
| 2121 if (node != NULL) { | 2125 if (node != NULL) { |
| 2122 set_top(node->next()); | 2126 set_top(node->next()); |
| 2123 *node_size = node->Size(); | 2127 *node_size = reinterpret_cast<FreeSpace*>(node)->Size(); |
| 2124 available_ -= *node_size; | 2128 available_ -= *node_size; |
| 2125 } else { | 2129 } else { |
| 2126 set_top(NULL); | 2130 set_top(NULL); |
| 2127 } | 2131 } |
| 2128 | 2132 |
| 2129 if (top() == NULL) { | 2133 if (top() == NULL) { |
| 2130 set_end(NULL); | 2134 set_end(NULL); |
| 2131 } | 2135 } |
| 2132 | 2136 |
| 2133 return node; | 2137 return node; |
| 2134 } | 2138 } |
| 2135 | 2139 |
| 2136 | 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 |
| 2137 void FreeListCategory::Free(FreeListNode* node, int size_in_bytes) { | 2153 void FreeListCategory::Free(FreeListNode* node, int size_in_bytes) { |
| 2138 node->set_next(top_); | 2154 node->set_next(top_); |
| 2139 top_ = node; | 2155 top_ = node; |
| 2140 if (end_ == NULL) { | 2156 if (end_ == NULL) { |
| 2141 end_ = node; | 2157 end_ = node; |
| 2142 } | 2158 } |
| 2143 available_ += size_in_bytes; | 2159 available_ += size_in_bytes; |
| 2144 } | 2160 } |
| 2145 | 2161 |
| 2146 | 2162 |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2216 } | 2232 } |
| 2217 | 2233 |
| 2218 | 2234 |
| 2219 FreeListNode* FreeList::FindNodeFor(int size_in_bytes, int* node_size) { | 2235 FreeListNode* FreeList::FindNodeFor(int size_in_bytes, int* node_size) { |
| 2220 FreeListNode* node = NULL; | 2236 FreeListNode* node = NULL; |
| 2221 Page* page = NULL; | 2237 Page* page = NULL; |
| 2222 | 2238 |
| 2223 if (size_in_bytes <= kSmallAllocationMax) { | 2239 if (size_in_bytes <= kSmallAllocationMax) { |
| 2224 node = small_list_.PickNodeFromList(node_size); | 2240 node = small_list_.PickNodeFromList(node_size); |
| 2225 if (node != NULL) { | 2241 if (node != NULL) { |
| 2242 ASSERT(size_in_bytes <= *node_size); |
| 2226 page = Page::FromAddress(node->address()); | 2243 page = Page::FromAddress(node->address()); |
| 2227 page->add_available_in_small_free_list(-(*node_size)); | 2244 page->add_available_in_small_free_list(-(*node_size)); |
| 2245 ASSERT(IsVeryLong() || available() == SumFreeLists()); |
| 2228 return node; | 2246 return node; |
| 2229 } | 2247 } |
| 2230 } | 2248 } |
| 2231 | 2249 |
| 2232 if (size_in_bytes <= kMediumAllocationMax) { | 2250 if (size_in_bytes <= kMediumAllocationMax) { |
| 2233 node = medium_list_.PickNodeFromList(node_size); | 2251 node = medium_list_.PickNodeFromList(node_size); |
| 2234 if (node != NULL) { | 2252 if (node != NULL) { |
| 2253 ASSERT(size_in_bytes <= *node_size); |
| 2235 page = Page::FromAddress(node->address()); | 2254 page = Page::FromAddress(node->address()); |
| 2236 page->add_available_in_medium_free_list(-(*node_size)); | 2255 page->add_available_in_medium_free_list(-(*node_size)); |
| 2256 ASSERT(IsVeryLong() || available() == SumFreeLists()); |
| 2237 return node; | 2257 return node; |
| 2238 } | 2258 } |
| 2239 } | 2259 } |
| 2240 | 2260 |
| 2241 if (size_in_bytes <= kLargeAllocationMax) { | 2261 if (size_in_bytes <= kLargeAllocationMax) { |
| 2242 node = large_list_.PickNodeFromList(node_size); | 2262 node = large_list_.PickNodeFromList(node_size); |
| 2243 if (node != NULL) { | 2263 if (node != NULL) { |
| 2264 ASSERT(size_in_bytes <= *node_size); |
| 2244 page = Page::FromAddress(node->address()); | 2265 page = Page::FromAddress(node->address()); |
| 2245 page->add_available_in_large_free_list(-(*node_size)); | 2266 page->add_available_in_large_free_list(-(*node_size)); |
| 2267 ASSERT(IsVeryLong() || available() == SumFreeLists()); |
| 2246 return node; | 2268 return node; |
| 2247 } | 2269 } |
| 2248 } | 2270 } |
| 2249 | 2271 |
| 2250 int huge_list_available = huge_list_.available(); | 2272 int huge_list_available = huge_list_.available(); |
| 2251 for (FreeListNode** cur = huge_list_.GetTopAddress(); | 2273 for (FreeListNode** cur = huge_list_.GetTopAddress(); |
| 2252 *cur != NULL; | 2274 *cur != NULL; |
| 2253 cur = (*cur)->next_address()) { | 2275 cur = (*cur)->next_address()) { |
| 2254 FreeListNode* cur_node = *cur; | 2276 FreeListNode* cur_node = *cur; |
| 2255 while (cur_node != NULL && | 2277 while (cur_node != NULL && |
| (...skipping 22 matching lines...) Expand all Loading... |
| 2278 huge_list_available -= size; | 2300 huge_list_available -= size; |
| 2279 page = Page::FromAddress(node->address()); | 2301 page = Page::FromAddress(node->address()); |
| 2280 page->add_available_in_huge_free_list(-size); | 2302 page->add_available_in_huge_free_list(-size); |
| 2281 break; | 2303 break; |
| 2282 } | 2304 } |
| 2283 } | 2305 } |
| 2284 | 2306 |
| 2285 if (huge_list_.top() == NULL) { | 2307 if (huge_list_.top() == NULL) { |
| 2286 huge_list_.set_end(NULL); | 2308 huge_list_.set_end(NULL); |
| 2287 } | 2309 } |
| 2310 huge_list_.set_available(huge_list_available); |
| 2288 | 2311 |
| 2289 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 |
| 2290 ASSERT(IsVeryLong() || available() == SumFreeLists()); | 2340 ASSERT(IsVeryLong() || available() == SumFreeLists()); |
| 2291 | |
| 2292 return node; | 2341 return node; |
| 2293 } | 2342 } |
| 2294 | 2343 |
| 2295 | 2344 |
| 2296 // 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 |
| 2297 // 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 |
| 2298 // 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 |
| 2299 // or allocate a new page before retrying. | 2348 // or allocate a new page before retrying. |
| 2300 HeapObject* FreeList::Allocate(int size_in_bytes) { | 2349 HeapObject* FreeList::Allocate(int size_in_bytes) { |
| 2301 ASSERT(0 < size_in_bytes); | 2350 ASSERT(0 < size_in_bytes); |
| (...skipping 525 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2827 // there is at least one non-inlined virtual function. I would prefer to hide | 2876 // there is at least one non-inlined virtual function. I would prefer to hide |
| 2828 // the VerifyObject definition behind VERIFY_HEAP. | 2877 // the VerifyObject definition behind VERIFY_HEAP. |
| 2829 | 2878 |
| 2830 void MapSpace::VerifyObject(HeapObject* object) { | 2879 void MapSpace::VerifyObject(HeapObject* object) { |
| 2831 // The object should be a map or a free-list node. | 2880 // The object should be a map or a free-list node. |
| 2832 CHECK(object->IsMap() || object->IsFreeSpace()); | 2881 CHECK(object->IsMap() || object->IsFreeSpace()); |
| 2833 } | 2882 } |
| 2834 | 2883 |
| 2835 | 2884 |
| 2836 // ----------------------------------------------------------------------------- | 2885 // ----------------------------------------------------------------------------- |
| 2837 // GlobalPropertyCellSpace implementation | 2886 // CellSpace and PropertyCellSpace implementation |
| 2838 // TODO(mvstanton): this is weird...the compiler can't make a vtable unless | 2887 // TODO(mvstanton): this is weird...the compiler can't make a vtable unless |
| 2839 // there is at least one non-inlined virtual function. I would prefer to hide | 2888 // there is at least one non-inlined virtual function. I would prefer to hide |
| 2840 // the VerifyObject definition behind VERIFY_HEAP. | 2889 // the VerifyObject definition behind VERIFY_HEAP. |
| 2841 | 2890 |
| 2842 void CellSpace::VerifyObject(HeapObject* object) { | 2891 void CellSpace::VerifyObject(HeapObject* object) { |
| 2843 // The object should be a global object property cell or a free-list node. | 2892 // The object should be a global object property cell or a free-list node. |
| 2844 CHECK(object->IsJSGlobalPropertyCell() || | 2893 CHECK(object->IsCell() || |
| 2845 object->map() == heap()->two_pointer_filler_map()); | 2894 object->map() == heap()->two_pointer_filler_map()); |
| 2846 } | 2895 } |
| 2847 | 2896 |
| 2897 |
| 2898 void PropertyCellSpace::VerifyObject(HeapObject* object) { |
| 2899 // The object should be a global object property cell or a free-list node. |
| 2900 CHECK(object->IsPropertyCell() || |
| 2901 object->map() == heap()->two_pointer_filler_map()); |
| 2902 } |
| 2903 |
| 2848 | 2904 |
| 2849 // ----------------------------------------------------------------------------- | 2905 // ----------------------------------------------------------------------------- |
| 2850 // LargeObjectIterator | 2906 // LargeObjectIterator |
| 2851 | 2907 |
| 2852 LargeObjectIterator::LargeObjectIterator(LargeObjectSpace* space) { | 2908 LargeObjectIterator::LargeObjectIterator(LargeObjectSpace* space) { |
| 2853 current_ = space->first_page_; | 2909 current_ = space->first_page_; |
| 2854 size_func_ = NULL; | 2910 size_func_ = NULL; |
| 2855 } | 2911 } |
| 2856 | 2912 |
| 2857 | 2913 |
| (...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3178 object->ShortPrint(); | 3234 object->ShortPrint(); |
| 3179 PrintF("\n"); | 3235 PrintF("\n"); |
| 3180 } | 3236 } |
| 3181 printf(" --------------------------------------\n"); | 3237 printf(" --------------------------------------\n"); |
| 3182 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes()); | 3238 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes()); |
| 3183 } | 3239 } |
| 3184 | 3240 |
| 3185 #endif // DEBUG | 3241 #endif // DEBUG |
| 3186 | 3242 |
| 3187 } } // namespace v8::internal | 3243 } } // namespace v8::internal |
| OLD | NEW |