| OLD | NEW |
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 2077 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2088 | 2088 |
| 2089 | 2089 |
| 2090 // Iterate the live objects in a range of addresses (eg, a page or a | 2090 // Iterate the live objects in a range of addresses (eg, a page or a |
| 2091 // semispace). The live regions of the range have been linked into a list. | 2091 // semispace). The live regions of the range have been linked into a list. |
| 2092 // The first live region is [first_live_start, first_live_end), and the last | 2092 // The first live region is [first_live_start, first_live_end), and the last |
| 2093 // address in the range is top. The callback function is used to get the | 2093 // address in the range is top. The callback function is used to get the |
| 2094 // size of each live object. | 2094 // size of each live object. |
| 2095 int MarkCompactCollector::IterateLiveObjectsInRange( | 2095 int MarkCompactCollector::IterateLiveObjectsInRange( |
| 2096 Address start, | 2096 Address start, |
| 2097 Address end, | 2097 Address end, |
| 2098 HeapObjectCallback size_func) { | 2098 LiveObjectCallback size_func) { |
| 2099 int live_objects_size = 0; | 2099 int live_objects_size = 0; |
| 2100 Address current = start; | 2100 Address current = start; |
| 2101 while (current < end) { | 2101 while (current < end) { |
| 2102 uint32_t encoded_map = Memory::uint32_at(current); | 2102 uint32_t encoded_map = Memory::uint32_at(current); |
| 2103 if (encoded_map == kSingleFreeEncoding) { | 2103 if (encoded_map == kSingleFreeEncoding) { |
| 2104 current += kPointerSize; | 2104 current += kPointerSize; |
| 2105 } else if (encoded_map == kMultiFreeEncoding) { | 2105 } else if (encoded_map == kMultiFreeEncoding) { |
| 2106 current += Memory::int_at(current + kIntSize); | 2106 current += Memory::int_at(current + kIntSize); |
| 2107 } else { | 2107 } else { |
| 2108 int size = size_func(HeapObject::FromAddress(current)); | 2108 int size = (this->*size_func)(HeapObject::FromAddress(current)); |
| 2109 current += size; | 2109 current += size; |
| 2110 live_objects_size += size; | 2110 live_objects_size += size; |
| 2111 } | 2111 } |
| 2112 } | 2112 } |
| 2113 return live_objects_size; | 2113 return live_objects_size; |
| 2114 } | 2114 } |
| 2115 | 2115 |
| 2116 | 2116 |
| 2117 int MarkCompactCollector::IterateLiveObjects(NewSpace* space, | 2117 int MarkCompactCollector::IterateLiveObjects( |
| 2118 HeapObjectCallback size_f) { | 2118 NewSpace* space, LiveObjectCallback size_f) { |
| 2119 ASSERT(MARK_LIVE_OBJECTS < state_ && state_ <= RELOCATE_OBJECTS); | 2119 ASSERT(MARK_LIVE_OBJECTS < state_ && state_ <= RELOCATE_OBJECTS); |
| 2120 return IterateLiveObjectsInRange(space->bottom(), space->top(), size_f); | 2120 return IterateLiveObjectsInRange(space->bottom(), space->top(), size_f); |
| 2121 } | 2121 } |
| 2122 | 2122 |
| 2123 | 2123 |
| 2124 int MarkCompactCollector::IterateLiveObjects(PagedSpace* space, | 2124 int MarkCompactCollector::IterateLiveObjects( |
| 2125 HeapObjectCallback size_f) { | 2125 PagedSpace* space, LiveObjectCallback size_f) { |
| 2126 ASSERT(MARK_LIVE_OBJECTS < state_ && state_ <= RELOCATE_OBJECTS); | 2126 ASSERT(MARK_LIVE_OBJECTS < state_ && state_ <= RELOCATE_OBJECTS); |
| 2127 int total = 0; | 2127 int total = 0; |
| 2128 PageIterator it(space, PageIterator::PAGES_IN_USE); | 2128 PageIterator it(space, PageIterator::PAGES_IN_USE); |
| 2129 while (it.has_next()) { | 2129 while (it.has_next()) { |
| 2130 Page* p = it.next(); | 2130 Page* p = it.next(); |
| 2131 total += IterateLiveObjectsInRange(p->ObjectAreaStart(), | 2131 total += IterateLiveObjectsInRange(p->ObjectAreaStart(), |
| 2132 p->AllocationTop(), | 2132 p->AllocationTop(), |
| 2133 size_f); | 2133 size_f); |
| 2134 } | 2134 } |
| 2135 return total; | 2135 return total; |
| 2136 } | 2136 } |
| 2137 | 2137 |
| 2138 | 2138 |
| 2139 // ------------------------------------------------------------------------- | 2139 // ------------------------------------------------------------------------- |
| 2140 // Phase 3: Update pointers | 2140 // Phase 3: Update pointers |
| 2141 | 2141 |
| 2142 // Helper class for updating pointers in HeapObjects. | 2142 // Helper class for updating pointers in HeapObjects. |
| 2143 class UpdatingVisitor: public ObjectVisitor { | 2143 class UpdatingVisitor: public ObjectVisitor { |
| 2144 public: | 2144 public: |
| 2145 UpdatingVisitor() {} | 2145 explicit UpdatingVisitor(Heap* heap) : heap_(heap) {} |
| 2146 | 2146 |
| 2147 void VisitPointer(Object** p) { | 2147 void VisitPointer(Object** p) { |
| 2148 UpdatePointer(p); | 2148 UpdatePointer(p); |
| 2149 } | 2149 } |
| 2150 | 2150 |
| 2151 void VisitPointers(Object** start, Object** end) { | 2151 void VisitPointers(Object** start, Object** end) { |
| 2152 // Mark all HeapObject pointers in [start, end) | 2152 // Mark all HeapObject pointers in [start, end) |
| 2153 for (Object** p = start; p < end; p++) UpdatePointer(p); | 2153 for (Object** p = start; p < end; p++) UpdatePointer(p); |
| 2154 } | 2154 } |
| 2155 | 2155 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 2172 reinterpret_cast<Code*>(target)->instruction_start()); | 2172 reinterpret_cast<Code*>(target)->instruction_start()); |
| 2173 } | 2173 } |
| 2174 | 2174 |
| 2175 private: | 2175 private: |
| 2176 void UpdatePointer(Object** p) { | 2176 void UpdatePointer(Object** p) { |
| 2177 if (!(*p)->IsHeapObject()) return; | 2177 if (!(*p)->IsHeapObject()) return; |
| 2178 | 2178 |
| 2179 HeapObject* obj = HeapObject::cast(*p); | 2179 HeapObject* obj = HeapObject::cast(*p); |
| 2180 Address old_addr = obj->address(); | 2180 Address old_addr = obj->address(); |
| 2181 Address new_addr; | 2181 Address new_addr; |
| 2182 ASSERT(!HEAP->InFromSpace(obj)); | 2182 ASSERT(!heap_->InFromSpace(obj)); |
| 2183 | 2183 |
| 2184 if (HEAP->new_space()->Contains(obj)) { | 2184 if (heap_->new_space()->Contains(obj)) { |
| 2185 Address forwarding_pointer_addr = | 2185 Address forwarding_pointer_addr = |
| 2186 HEAP->new_space()->FromSpaceLow() + | 2186 heap_->new_space()->FromSpaceLow() + |
| 2187 HEAP->new_space()->ToSpaceOffsetForAddress(old_addr); | 2187 heap_->new_space()->ToSpaceOffsetForAddress(old_addr); |
| 2188 new_addr = Memory::Address_at(forwarding_pointer_addr); | 2188 new_addr = Memory::Address_at(forwarding_pointer_addr); |
| 2189 | 2189 |
| 2190 #ifdef DEBUG | 2190 #ifdef DEBUG |
| 2191 ASSERT(HEAP->old_pointer_space()->Contains(new_addr) || | 2191 ASSERT(heap_->old_pointer_space()->Contains(new_addr) || |
| 2192 HEAP->old_data_space()->Contains(new_addr) || | 2192 heap_->old_data_space()->Contains(new_addr) || |
| 2193 HEAP->new_space()->FromSpaceContains(new_addr) || | 2193 heap_->new_space()->FromSpaceContains(new_addr) || |
| 2194 HEAP->lo_space()->Contains(HeapObject::FromAddress(new_addr))); | 2194 heap_->lo_space()->Contains(HeapObject::FromAddress(new_addr))); |
| 2195 | 2195 |
| 2196 if (HEAP->new_space()->FromSpaceContains(new_addr)) { | 2196 if (heap_->new_space()->FromSpaceContains(new_addr)) { |
| 2197 ASSERT(HEAP->new_space()->FromSpaceOffsetForAddress(new_addr) <= | 2197 ASSERT(heap_->new_space()->FromSpaceOffsetForAddress(new_addr) <= |
| 2198 HEAP->new_space()->ToSpaceOffsetForAddress(old_addr)); | 2198 heap_->new_space()->ToSpaceOffsetForAddress(old_addr)); |
| 2199 } | 2199 } |
| 2200 #endif | 2200 #endif |
| 2201 | 2201 |
| 2202 } else if (HEAP->lo_space()->Contains(obj)) { | 2202 } else if (heap_->lo_space()->Contains(obj)) { |
| 2203 // Don't move objects in the large object space. | 2203 // Don't move objects in the large object space. |
| 2204 return; | 2204 return; |
| 2205 | 2205 |
| 2206 } else { | 2206 } else { |
| 2207 #ifdef DEBUG | 2207 #ifdef DEBUG |
| 2208 PagedSpaces spaces; | 2208 PagedSpaces spaces; |
| 2209 PagedSpace* original_space = spaces.next(); | 2209 PagedSpace* original_space = spaces.next(); |
| 2210 while (original_space != NULL) { | 2210 while (original_space != NULL) { |
| 2211 if (original_space->Contains(obj)) break; | 2211 if (original_space->Contains(obj)) break; |
| 2212 original_space = spaces.next(); | 2212 original_space = spaces.next(); |
| 2213 } | 2213 } |
| 2214 ASSERT(original_space != NULL); | 2214 ASSERT(original_space != NULL); |
| 2215 #endif | 2215 #endif |
| 2216 new_addr = MarkCompactCollector::GetForwardingAddressInOldSpace(obj); | 2216 new_addr = MarkCompactCollector::GetForwardingAddressInOldSpace(obj); |
| 2217 ASSERT(original_space->Contains(new_addr)); | 2217 ASSERT(original_space->Contains(new_addr)); |
| 2218 ASSERT(original_space->MCSpaceOffsetForAddress(new_addr) <= | 2218 ASSERT(original_space->MCSpaceOffsetForAddress(new_addr) <= |
| 2219 original_space->MCSpaceOffsetForAddress(old_addr)); | 2219 original_space->MCSpaceOffsetForAddress(old_addr)); |
| 2220 } | 2220 } |
| 2221 | 2221 |
| 2222 *p = HeapObject::FromAddress(new_addr); | 2222 *p = HeapObject::FromAddress(new_addr); |
| 2223 | 2223 |
| 2224 #ifdef DEBUG | 2224 #ifdef DEBUG |
| 2225 if (FLAG_gc_verbose) { | 2225 if (FLAG_gc_verbose) { |
| 2226 PrintF("update %p : %p -> %p\n", | 2226 PrintF("update %p : %p -> %p\n", |
| 2227 reinterpret_cast<Address>(p), old_addr, new_addr); | 2227 reinterpret_cast<Address>(p), old_addr, new_addr); |
| 2228 } | 2228 } |
| 2229 #endif | 2229 #endif |
| 2230 } | 2230 } |
| 2231 |
| 2232 Heap* heap_; |
| 2231 }; | 2233 }; |
| 2232 | 2234 |
| 2233 | 2235 |
| 2234 void MarkCompactCollector::UpdatePointers() { | 2236 void MarkCompactCollector::UpdatePointers() { |
| 2235 #ifdef DEBUG | 2237 #ifdef DEBUG |
| 2236 ASSERT(state_ == ENCODE_FORWARDING_ADDRESSES); | 2238 ASSERT(state_ == ENCODE_FORWARDING_ADDRESSES); |
| 2237 state_ = UPDATE_POINTERS; | 2239 state_ = UPDATE_POINTERS; |
| 2238 #endif | 2240 #endif |
| 2239 UpdatingVisitor updating_visitor; | 2241 UpdatingVisitor updating_visitor(heap_); |
| 2240 heap_->IterateRoots(&updating_visitor, VISIT_ONLY_STRONG); | 2242 heap_->IterateRoots(&updating_visitor, VISIT_ONLY_STRONG); |
| 2241 heap_->isolate_->global_handles()->IterateWeakRoots(&updating_visitor); | 2243 heap_->isolate_->global_handles()->IterateWeakRoots(&updating_visitor); |
| 2242 | 2244 |
| 2243 int live_maps_size = IterateLiveObjects(heap_->map_space(), | 2245 int live_maps_size = IterateLiveObjects( |
| 2244 &UpdatePointersInOldObject); | 2246 heap_->map_space(), &MarkCompactCollector::UpdatePointersInOldObject); |
| 2245 int live_pointer_olds_size = IterateLiveObjects(heap_->old_pointer_space(), | 2247 int live_pointer_olds_size = IterateLiveObjects( |
| 2246 &UpdatePointersInOldObject); | 2248 heap_->old_pointer_space(), |
| 2247 int live_data_olds_size = IterateLiveObjects(heap_->old_data_space(), | 2249 &MarkCompactCollector::UpdatePointersInOldObject); |
| 2248 &UpdatePointersInOldObject); | 2250 int live_data_olds_size = IterateLiveObjects( |
| 2249 int live_codes_size = IterateLiveObjects(heap_->code_space(), | 2251 heap_->old_data_space(), |
| 2250 &UpdatePointersInOldObject); | 2252 &MarkCompactCollector::UpdatePointersInOldObject); |
| 2251 int live_cells_size = IterateLiveObjects(heap_->cell_space(), | 2253 int live_codes_size = IterateLiveObjects( |
| 2252 &UpdatePointersInOldObject); | 2254 heap_->code_space(), &MarkCompactCollector::UpdatePointersInOldObject); |
| 2253 int live_news_size = IterateLiveObjects(heap_->new_space(), | 2255 int live_cells_size = IterateLiveObjects( |
| 2254 &UpdatePointersInNewObject); | 2256 heap_->cell_space(), &MarkCompactCollector::UpdatePointersInOldObject); |
| 2257 int live_news_size = IterateLiveObjects( |
| 2258 heap_->new_space(), &MarkCompactCollector::UpdatePointersInNewObject); |
| 2255 | 2259 |
| 2256 // Large objects do not move, the map word can be updated directly. | 2260 // Large objects do not move, the map word can be updated directly. |
| 2257 LargeObjectIterator it(heap_->lo_space()); | 2261 LargeObjectIterator it(heap_->lo_space()); |
| 2258 for (HeapObject* obj = it.next(); obj != NULL; obj = it.next()) | 2262 for (HeapObject* obj = it.next(); obj != NULL; obj = it.next()) |
| 2259 UpdatePointersInNewObject(obj); | 2263 UpdatePointersInNewObject(obj); |
| 2260 | 2264 |
| 2261 USE(live_maps_size); | 2265 USE(live_maps_size); |
| 2262 USE(live_pointer_olds_size); | 2266 USE(live_pointer_olds_size); |
| 2263 USE(live_data_olds_size); | 2267 USE(live_data_olds_size); |
| 2264 USE(live_codes_size); | 2268 USE(live_codes_size); |
| 2265 USE(live_cells_size); | 2269 USE(live_cells_size); |
| 2266 USE(live_news_size); | 2270 USE(live_news_size); |
| 2267 ASSERT(live_maps_size == live_map_objects_size_); | 2271 ASSERT(live_maps_size == live_map_objects_size_); |
| 2268 ASSERT(live_data_olds_size == live_old_data_objects_size_); | 2272 ASSERT(live_data_olds_size == live_old_data_objects_size_); |
| 2269 ASSERT(live_pointer_olds_size == live_old_pointer_objects_size_); | 2273 ASSERT(live_pointer_olds_size == live_old_pointer_objects_size_); |
| 2270 ASSERT(live_codes_size == live_code_objects_size_); | 2274 ASSERT(live_codes_size == live_code_objects_size_); |
| 2271 ASSERT(live_cells_size == live_cell_objects_size_); | 2275 ASSERT(live_cells_size == live_cell_objects_size_); |
| 2272 ASSERT(live_news_size == live_young_objects_size_); | 2276 ASSERT(live_news_size == live_young_objects_size_); |
| 2273 } | 2277 } |
| 2274 | 2278 |
| 2275 | 2279 |
| 2276 int MarkCompactCollector::UpdatePointersInNewObject(HeapObject* obj) { | 2280 int MarkCompactCollector::UpdatePointersInNewObject(HeapObject* obj) { |
| 2277 // Keep old map pointers | 2281 // Keep old map pointers |
| 2278 Map* old_map = obj->map(); | 2282 Map* old_map = obj->map(); |
| 2279 ASSERT(old_map->IsHeapObject()); | 2283 ASSERT(old_map->IsHeapObject()); |
| 2280 | 2284 |
| 2281 Address forwarded = GetForwardingAddressInOldSpace(old_map); | 2285 Address forwarded = GetForwardingAddressInOldSpace(old_map); |
| 2282 | 2286 |
| 2283 ASSERT(HEAP->map_space()->Contains(old_map)); | 2287 ASSERT(heap_->map_space()->Contains(old_map)); |
| 2284 ASSERT(HEAP->map_space()->Contains(forwarded)); | 2288 ASSERT(heap_->map_space()->Contains(forwarded)); |
| 2285 #ifdef DEBUG | 2289 #ifdef DEBUG |
| 2286 if (FLAG_gc_verbose) { | 2290 if (FLAG_gc_verbose) { |
| 2287 PrintF("update %p : %p -> %p\n", obj->address(), old_map->address(), | 2291 PrintF("update %p : %p -> %p\n", obj->address(), old_map->address(), |
| 2288 forwarded); | 2292 forwarded); |
| 2289 } | 2293 } |
| 2290 #endif | 2294 #endif |
| 2291 // Update the map pointer. | 2295 // Update the map pointer. |
| 2292 obj->set_map(reinterpret_cast<Map*>(HeapObject::FromAddress(forwarded))); | 2296 obj->set_map(reinterpret_cast<Map*>(HeapObject::FromAddress(forwarded))); |
| 2293 | 2297 |
| 2294 // We have to compute the object size relying on the old map because | 2298 // We have to compute the object size relying on the old map because |
| 2295 // map objects are not relocated yet. | 2299 // map objects are not relocated yet. |
| 2296 int obj_size = obj->SizeFromMap(old_map); | 2300 int obj_size = obj->SizeFromMap(old_map); |
| 2297 | 2301 |
| 2298 // Update pointers in the object body. | 2302 // Update pointers in the object body. |
| 2299 UpdatingVisitor updating_visitor; | 2303 UpdatingVisitor updating_visitor(heap_); |
| 2300 obj->IterateBody(old_map->instance_type(), obj_size, &updating_visitor); | 2304 obj->IterateBody(old_map->instance_type(), obj_size, &updating_visitor); |
| 2301 return obj_size; | 2305 return obj_size; |
| 2302 } | 2306 } |
| 2303 | 2307 |
| 2304 | 2308 |
| 2305 int MarkCompactCollector::UpdatePointersInOldObject(HeapObject* obj) { | 2309 int MarkCompactCollector::UpdatePointersInOldObject(HeapObject* obj) { |
| 2306 // Decode the map pointer. | 2310 // Decode the map pointer. |
| 2307 MapWord encoding = obj->map_word(); | 2311 MapWord encoding = obj->map_word(); |
| 2308 Address map_addr = encoding.DecodeMapAddress(HEAP->map_space()); | 2312 Address map_addr = encoding.DecodeMapAddress(heap_->map_space()); |
| 2309 ASSERT(HEAP->map_space()->Contains(HeapObject::FromAddress(map_addr))); | 2313 ASSERT(heap_->map_space()->Contains(HeapObject::FromAddress(map_addr))); |
| 2310 | 2314 |
| 2311 // At this point, the first word of map_addr is also encoded, cannot | 2315 // At this point, the first word of map_addr is also encoded, cannot |
| 2312 // cast it to Map* using Map::cast. | 2316 // cast it to Map* using Map::cast. |
| 2313 Map* map = reinterpret_cast<Map*>(HeapObject::FromAddress(map_addr)); | 2317 Map* map = reinterpret_cast<Map*>(HeapObject::FromAddress(map_addr)); |
| 2314 int obj_size = obj->SizeFromMap(map); | 2318 int obj_size = obj->SizeFromMap(map); |
| 2315 InstanceType type = map->instance_type(); | 2319 InstanceType type = map->instance_type(); |
| 2316 | 2320 |
| 2317 // Update map pointer. | 2321 // Update map pointer. |
| 2318 Address new_map_addr = GetForwardingAddressInOldSpace(map); | 2322 Address new_map_addr = GetForwardingAddressInOldSpace(map); |
| 2319 int offset = encoding.DecodeOffset(); | 2323 int offset = encoding.DecodeOffset(); |
| 2320 obj->set_map_word(MapWord::EncodeAddress(new_map_addr, offset)); | 2324 obj->set_map_word(MapWord::EncodeAddress(new_map_addr, offset)); |
| 2321 | 2325 |
| 2322 #ifdef DEBUG | 2326 #ifdef DEBUG |
| 2323 if (FLAG_gc_verbose) { | 2327 if (FLAG_gc_verbose) { |
| 2324 PrintF("update %p : %p -> %p\n", obj->address(), | 2328 PrintF("update %p : %p -> %p\n", obj->address(), |
| 2325 map_addr, new_map_addr); | 2329 map_addr, new_map_addr); |
| 2326 } | 2330 } |
| 2327 #endif | 2331 #endif |
| 2328 | 2332 |
| 2329 // Update pointers in the object body. | 2333 // Update pointers in the object body. |
| 2330 UpdatingVisitor updating_visitor; | 2334 UpdatingVisitor updating_visitor(heap_); |
| 2331 obj->IterateBody(type, obj_size, &updating_visitor); | 2335 obj->IterateBody(type, obj_size, &updating_visitor); |
| 2332 return obj_size; | 2336 return obj_size; |
| 2333 } | 2337 } |
| 2334 | 2338 |
| 2335 | 2339 |
| 2336 Address MarkCompactCollector::GetForwardingAddressInOldSpace(HeapObject* obj) { | 2340 Address MarkCompactCollector::GetForwardingAddressInOldSpace(HeapObject* obj) { |
| 2337 // Object should either in old or map space. | 2341 // Object should either in old or map space. |
| 2338 MapWord encoding = obj->map_word(); | 2342 MapWord encoding = obj->map_word(); |
| 2339 | 2343 |
| 2340 // Offset to the first live object's forwarding address. | 2344 // Offset to the first live object's forwarding address. |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2376 // ------------------------------------------------------------------------- | 2380 // ------------------------------------------------------------------------- |
| 2377 // Phase 4: Relocate objects | 2381 // Phase 4: Relocate objects |
| 2378 | 2382 |
| 2379 void MarkCompactCollector::RelocateObjects() { | 2383 void MarkCompactCollector::RelocateObjects() { |
| 2380 #ifdef DEBUG | 2384 #ifdef DEBUG |
| 2381 ASSERT(state_ == UPDATE_POINTERS); | 2385 ASSERT(state_ == UPDATE_POINTERS); |
| 2382 state_ = RELOCATE_OBJECTS; | 2386 state_ = RELOCATE_OBJECTS; |
| 2383 #endif | 2387 #endif |
| 2384 // Relocates objects, always relocate map objects first. Relocating | 2388 // Relocates objects, always relocate map objects first. Relocating |
| 2385 // objects in other space relies on map objects to get object size. | 2389 // objects in other space relies on map objects to get object size. |
| 2386 int live_maps_size = IterateLiveObjects(heap_->map_space(), | 2390 int live_maps_size = IterateLiveObjects( |
| 2387 &RelocateMapObject); | 2391 heap_->map_space(), &MarkCompactCollector::RelocateMapObject); |
| 2388 int live_pointer_olds_size = IterateLiveObjects(heap_->old_pointer_space(), | 2392 int live_pointer_olds_size = IterateLiveObjects( |
| 2389 &RelocateOldPointerObject); | 2393 heap_->old_pointer_space(), |
| 2390 int live_data_olds_size = IterateLiveObjects(heap_->old_data_space(), | 2394 &MarkCompactCollector::RelocateOldPointerObject); |
| 2391 &RelocateOldDataObject); | 2395 int live_data_olds_size = IterateLiveObjects( |
| 2392 int live_codes_size = IterateLiveObjects(heap_->code_space(), | 2396 heap_->old_data_space(), &MarkCompactCollector::RelocateOldDataObject); |
| 2393 &RelocateCodeObject); | 2397 int live_codes_size = IterateLiveObjects( |
| 2394 int live_cells_size = IterateLiveObjects(heap_->cell_space(), | 2398 heap_->code_space(), &MarkCompactCollector::RelocateCodeObject); |
| 2395 &RelocateCellObject); | 2399 int live_cells_size = IterateLiveObjects( |
| 2396 int live_news_size = IterateLiveObjects(heap_->new_space(), | 2400 heap_->cell_space(), &MarkCompactCollector::RelocateCellObject); |
| 2397 &RelocateNewObject); | 2401 int live_news_size = IterateLiveObjects( |
| 2402 heap_->new_space(), &MarkCompactCollector::RelocateNewObject); |
| 2398 | 2403 |
| 2399 USE(live_maps_size); | 2404 USE(live_maps_size); |
| 2400 USE(live_pointer_olds_size); | 2405 USE(live_pointer_olds_size); |
| 2401 USE(live_data_olds_size); | 2406 USE(live_data_olds_size); |
| 2402 USE(live_codes_size); | 2407 USE(live_codes_size); |
| 2403 USE(live_cells_size); | 2408 USE(live_cells_size); |
| 2404 USE(live_news_size); | 2409 USE(live_news_size); |
| 2405 ASSERT(live_maps_size == live_map_objects_size_); | 2410 ASSERT(live_maps_size == live_map_objects_size_); |
| 2406 ASSERT(live_data_olds_size == live_old_data_objects_size_); | 2411 ASSERT(live_data_olds_size == live_old_data_objects_size_); |
| 2407 ASSERT(live_pointer_olds_size == live_old_pointer_objects_size_); | 2412 ASSERT(live_pointer_olds_size == live_old_pointer_objects_size_); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 2423 space->MCCommitRelocationInfo(); | 2428 space->MCCommitRelocationInfo(); |
| 2424 | 2429 |
| 2425 heap_->CheckNewSpaceExpansionCriteria(); | 2430 heap_->CheckNewSpaceExpansionCriteria(); |
| 2426 heap_->IncrementYoungSurvivorsCounter(live_news_size); | 2431 heap_->IncrementYoungSurvivorsCounter(live_news_size); |
| 2427 } | 2432 } |
| 2428 | 2433 |
| 2429 | 2434 |
| 2430 int MarkCompactCollector::RelocateMapObject(HeapObject* obj) { | 2435 int MarkCompactCollector::RelocateMapObject(HeapObject* obj) { |
| 2431 // Recover map pointer. | 2436 // Recover map pointer. |
| 2432 MapWord encoding = obj->map_word(); | 2437 MapWord encoding = obj->map_word(); |
| 2433 Address map_addr = encoding.DecodeMapAddress(HEAP->map_space()); | 2438 Address map_addr = encoding.DecodeMapAddress(heap_->map_space()); |
| 2434 ASSERT(HEAP->map_space()->Contains(HeapObject::FromAddress(map_addr))); | 2439 ASSERT(heap_->map_space()->Contains(HeapObject::FromAddress(map_addr))); |
| 2435 | 2440 |
| 2436 // Get forwarding address before resetting map pointer | 2441 // Get forwarding address before resetting map pointer |
| 2437 Address new_addr = GetForwardingAddressInOldSpace(obj); | 2442 Address new_addr = GetForwardingAddressInOldSpace(obj); |
| 2438 | 2443 |
| 2439 // Reset map pointer. The meta map object may not be copied yet so | 2444 // Reset map pointer. The meta map object may not be copied yet so |
| 2440 // Map::cast does not yet work. | 2445 // Map::cast does not yet work. |
| 2441 obj->set_map(reinterpret_cast<Map*>(HeapObject::FromAddress(map_addr))); | 2446 obj->set_map(reinterpret_cast<Map*>(HeapObject::FromAddress(map_addr))); |
| 2442 | 2447 |
| 2443 Address old_addr = obj->address(); | 2448 Address old_addr = obj->address(); |
| 2444 | 2449 |
| 2445 if (new_addr != old_addr) { | 2450 if (new_addr != old_addr) { |
| 2446 // Move contents. | 2451 // Move contents. |
| 2447 HEAP->MoveBlockToOldSpaceAndUpdateRegionMarks(new_addr, | 2452 heap_->MoveBlockToOldSpaceAndUpdateRegionMarks(new_addr, |
| 2448 old_addr, | 2453 old_addr, |
| 2449 Map::kSize); | 2454 Map::kSize); |
| 2450 } | 2455 } |
| 2451 | 2456 |
| 2452 #ifdef DEBUG | 2457 #ifdef DEBUG |
| 2453 if (FLAG_gc_verbose) { | 2458 if (FLAG_gc_verbose) { |
| 2454 PrintF("relocate %p -> %p\n", old_addr, new_addr); | 2459 PrintF("relocate %p -> %p\n", old_addr, new_addr); |
| 2455 } | 2460 } |
| 2456 #endif | 2461 #endif |
| 2457 | 2462 |
| 2458 return Map::kSize; | 2463 return Map::kSize; |
| 2459 } | 2464 } |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2518 if (copied_to->IsJSFunction()) { | 2523 if (copied_to->IsJSFunction()) { |
| 2519 PROFILE(FunctionMoveEvent(old_addr, new_addr)); | 2524 PROFILE(FunctionMoveEvent(old_addr, new_addr)); |
| 2520 } | 2525 } |
| 2521 HEAP_PROFILE(heap_, ObjectMoveEvent(old_addr, new_addr)); | 2526 HEAP_PROFILE(heap_, ObjectMoveEvent(old_addr, new_addr)); |
| 2522 | 2527 |
| 2523 return obj_size; | 2528 return obj_size; |
| 2524 } | 2529 } |
| 2525 | 2530 |
| 2526 | 2531 |
| 2527 int MarkCompactCollector::RelocateOldPointerObject(HeapObject* obj) { | 2532 int MarkCompactCollector::RelocateOldPointerObject(HeapObject* obj) { |
| 2528 Heap* heap = HEAP; | 2533 return RelocateOldNonCodeObject(obj, heap_->old_pointer_space()); |
| 2529 return heap->mark_compact_collector()->RelocateOldNonCodeObject( | |
| 2530 obj, heap->old_pointer_space()); | |
| 2531 } | 2534 } |
| 2532 | 2535 |
| 2533 | 2536 |
| 2534 int MarkCompactCollector::RelocateOldDataObject(HeapObject* obj) { | 2537 int MarkCompactCollector::RelocateOldDataObject(HeapObject* obj) { |
| 2535 Heap* heap = HEAP; | 2538 return RelocateOldNonCodeObject(obj, heap_->old_data_space()); |
| 2536 return heap->mark_compact_collector()->RelocateOldNonCodeObject( | |
| 2537 obj, heap->old_data_space()); | |
| 2538 } | 2539 } |
| 2539 | 2540 |
| 2540 | 2541 |
| 2541 int MarkCompactCollector::RelocateCellObject(HeapObject* obj) { | 2542 int MarkCompactCollector::RelocateCellObject(HeapObject* obj) { |
| 2542 Heap* heap = HEAP; | 2543 return RelocateOldNonCodeObject(obj, heap_->cell_space()); |
| 2543 return heap->mark_compact_collector()->RelocateOldNonCodeObject( | |
| 2544 obj, heap->cell_space()); | |
| 2545 } | 2544 } |
| 2546 | 2545 |
| 2547 | 2546 |
| 2548 int MarkCompactCollector::RelocateCodeObject(HeapObject* obj) { | 2547 int MarkCompactCollector::RelocateCodeObject(HeapObject* obj) { |
| 2549 // Recover map pointer. | 2548 // Recover map pointer. |
| 2550 MapWord encoding = obj->map_word(); | 2549 MapWord encoding = obj->map_word(); |
| 2551 Heap* heap = HEAP; | 2550 Address map_addr = encoding.DecodeMapAddress(heap_->map_space()); |
| 2552 Address map_addr = encoding.DecodeMapAddress(heap->map_space()); | 2551 ASSERT(heap_->map_space()->Contains(HeapObject::FromAddress(map_addr))); |
| 2553 ASSERT(heap->map_space()->Contains(HeapObject::FromAddress(map_addr))); | |
| 2554 | 2552 |
| 2555 // Get forwarding address before resetting map pointer | 2553 // Get forwarding address before resetting map pointer |
| 2556 Address new_addr = GetForwardingAddressInOldSpace(obj); | 2554 Address new_addr = GetForwardingAddressInOldSpace(obj); |
| 2557 | 2555 |
| 2558 // Reset the map pointer. | 2556 // Reset the map pointer. |
| 2559 int obj_size = RestoreMap(obj, heap->code_space(), new_addr, map_addr); | 2557 int obj_size = RestoreMap(obj, heap_->code_space(), new_addr, map_addr); |
| 2560 | 2558 |
| 2561 Address old_addr = obj->address(); | 2559 Address old_addr = obj->address(); |
| 2562 | 2560 |
| 2563 if (new_addr != old_addr) { | 2561 if (new_addr != old_addr) { |
| 2564 // Move contents. | 2562 // Move contents. |
| 2565 heap->MoveBlock(new_addr, old_addr, obj_size); | 2563 heap_->MoveBlock(new_addr, old_addr, obj_size); |
| 2566 } | 2564 } |
| 2567 | 2565 |
| 2568 HeapObject* copied_to = HeapObject::FromAddress(new_addr); | 2566 HeapObject* copied_to = HeapObject::FromAddress(new_addr); |
| 2569 if (copied_to->IsCode()) { | 2567 if (copied_to->IsCode()) { |
| 2570 // May also update inline cache target. | 2568 // May also update inline cache target. |
| 2571 Code::cast(copied_to)->Relocate(new_addr - old_addr); | 2569 Code::cast(copied_to)->Relocate(new_addr - old_addr); |
| 2572 // Notify the logger that compiled code has moved. | 2570 // Notify the logger that compiled code has moved. |
| 2573 PROFILE(CodeMoveEvent(old_addr, new_addr)); | 2571 PROFILE(CodeMoveEvent(old_addr, new_addr)); |
| 2574 } | 2572 } |
| 2575 HEAP_PROFILE(heap, ObjectMoveEvent(old_addr, new_addr)); | 2573 HEAP_PROFILE(heap_, ObjectMoveEvent(old_addr, new_addr)); |
| 2576 | 2574 |
| 2577 return obj_size; | 2575 return obj_size; |
| 2578 } | 2576 } |
| 2579 | 2577 |
| 2580 | 2578 |
| 2581 int MarkCompactCollector::RelocateNewObject(HeapObject* obj) { | 2579 int MarkCompactCollector::RelocateNewObject(HeapObject* obj) { |
| 2582 int obj_size = obj->Size(); | 2580 int obj_size = obj->Size(); |
| 2583 | 2581 |
| 2584 // Get forwarding address | 2582 // Get forwarding address |
| 2585 Address old_addr = obj->address(); | 2583 Address old_addr = obj->address(); |
| 2586 Heap* heap = HEAP; | 2584 int offset = heap_->new_space()->ToSpaceOffsetForAddress(old_addr); |
| 2587 int offset = heap->new_space()->ToSpaceOffsetForAddress(old_addr); | |
| 2588 | 2585 |
| 2589 Address new_addr = | 2586 Address new_addr = |
| 2590 Memory::Address_at(heap->new_space()->FromSpaceLow() + offset); | 2587 Memory::Address_at(heap_->new_space()->FromSpaceLow() + offset); |
| 2591 | 2588 |
| 2592 #ifdef DEBUG | 2589 #ifdef DEBUG |
| 2593 if (heap->new_space()->FromSpaceContains(new_addr)) { | 2590 if (heap_->new_space()->FromSpaceContains(new_addr)) { |
| 2594 ASSERT(heap->new_space()->FromSpaceOffsetForAddress(new_addr) <= | 2591 ASSERT(heap_->new_space()->FromSpaceOffsetForAddress(new_addr) <= |
| 2595 heap->new_space()->ToSpaceOffsetForAddress(old_addr)); | 2592 heap_->new_space()->ToSpaceOffsetForAddress(old_addr)); |
| 2596 } else { | 2593 } else { |
| 2597 ASSERT(heap->TargetSpace(obj) == heap->old_pointer_space() || | 2594 ASSERT(heap_->TargetSpace(obj) == heap_->old_pointer_space() || |
| 2598 heap->TargetSpace(obj) == heap->old_data_space()); | 2595 heap_->TargetSpace(obj) == heap_->old_data_space()); |
| 2599 } | 2596 } |
| 2600 #endif | 2597 #endif |
| 2601 | 2598 |
| 2602 // New and old addresses cannot overlap. | 2599 // New and old addresses cannot overlap. |
| 2603 if (heap->InNewSpace(HeapObject::FromAddress(new_addr))) { | 2600 if (heap_->InNewSpace(HeapObject::FromAddress(new_addr))) { |
| 2604 heap->CopyBlock(new_addr, old_addr, obj_size); | 2601 heap_->CopyBlock(new_addr, old_addr, obj_size); |
| 2605 } else { | 2602 } else { |
| 2606 heap->CopyBlockToOldSpaceAndUpdateRegionMarks(new_addr, | 2603 heap_->CopyBlockToOldSpaceAndUpdateRegionMarks(new_addr, |
| 2607 old_addr, | 2604 old_addr, |
| 2608 obj_size); | 2605 obj_size); |
| 2609 } | 2606 } |
| 2610 | 2607 |
| 2611 #ifdef DEBUG | 2608 #ifdef DEBUG |
| 2612 if (FLAG_gc_verbose) { | 2609 if (FLAG_gc_verbose) { |
| 2613 PrintF("relocate %p -> %p\n", old_addr, new_addr); | 2610 PrintF("relocate %p -> %p\n", old_addr, new_addr); |
| 2614 } | 2611 } |
| 2615 #endif | 2612 #endif |
| 2616 | 2613 |
| 2617 HeapObject* copied_to = HeapObject::FromAddress(new_addr); | 2614 HeapObject* copied_to = HeapObject::FromAddress(new_addr); |
| 2618 if (copied_to->IsJSFunction()) { | 2615 if (copied_to->IsJSFunction()) { |
| 2619 PROFILE(FunctionMoveEvent(old_addr, new_addr)); | 2616 PROFILE(FunctionMoveEvent(old_addr, new_addr)); |
| 2620 } | 2617 } |
| 2621 HEAP_PROFILE(heap, ObjectMoveEvent(old_addr, new_addr)); | 2618 HEAP_PROFILE(heap_, ObjectMoveEvent(old_addr, new_addr)); |
| 2622 | 2619 |
| 2623 return obj_size; | 2620 return obj_size; |
| 2624 } | 2621 } |
| 2625 | 2622 |
| 2626 | 2623 |
| 2627 void MarkCompactCollector::ReportDeleteIfNeeded(HeapObject* obj) { | 2624 void MarkCompactCollector::ReportDeleteIfNeeded(HeapObject* obj) { |
| 2628 #ifdef ENABLE_LOGGING_AND_PROFILING | 2625 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 2629 if (obj->IsCode()) { | 2626 if (obj->IsCode()) { |
| 2630 PROFILE(CodeDeleteEvent(obj->address())); | 2627 PROFILE(CodeDeleteEvent(obj->address())); |
| 2631 } else if (obj->IsJSFunction()) { | 2628 } else if (obj->IsJSFunction()) { |
| 2632 PROFILE(FunctionDeleteEvent(obj->address())); | 2629 PROFILE(FunctionDeleteEvent(obj->address())); |
| 2633 } | 2630 } |
| 2634 #endif | 2631 #endif |
| 2635 } | 2632 } |
| 2636 | 2633 |
| 2637 | 2634 |
| 2638 void MarkCompactCollector::Initialize() { | 2635 void MarkCompactCollector::Initialize() { |
| 2639 StaticPointersToNewGenUpdatingVisitor::Initialize(); | 2636 StaticPointersToNewGenUpdatingVisitor::Initialize(); |
| 2640 StaticMarkingVisitor::Initialize(); | 2637 StaticMarkingVisitor::Initialize(); |
| 2641 } | 2638 } |
| 2642 | 2639 |
| 2643 | 2640 |
| 2644 } } // namespace v8::internal | 2641 } } // namespace v8::internal |
| OLD | NEW |