OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
8 #include "src/api.h" | 8 #include "src/api.h" |
9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
10 #include "src/base/once.h" | 10 #include "src/base/once.h" |
(...skipping 2130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2141 heap->OnMoveEvent(target, source, size); | 2141 heap->OnMoveEvent(target, source, size); |
2142 } | 2142 } |
2143 | 2143 |
2144 if (marks_handling == TRANSFER_MARKS) { | 2144 if (marks_handling == TRANSFER_MARKS) { |
2145 if (Marking::TransferColor(source, target)) { | 2145 if (Marking::TransferColor(source, target)) { |
2146 MemoryChunk::IncrementLiveBytesFromGC(target->address(), size); | 2146 MemoryChunk::IncrementLiveBytesFromGC(target->address(), size); |
2147 } | 2147 } |
2148 } | 2148 } |
2149 } | 2149 } |
2150 | 2150 |
2151 template <int alignment> | 2151 template <AllocationAlignment alignment> |
2152 static inline bool SemiSpaceCopyObject(Map* map, HeapObject** slot, | 2152 static inline bool SemiSpaceCopyObject(Map* map, HeapObject** slot, |
2153 HeapObject* object, int object_size) { | 2153 HeapObject* object, int object_size) { |
2154 Heap* heap = map->GetHeap(); | 2154 Heap* heap = map->GetHeap(); |
2155 | 2155 |
2156 DCHECK(heap->AllowedToBeMigrated(object, NEW_SPACE)); | 2156 DCHECK(heap->AllowedToBeMigrated(object, NEW_SPACE)); |
2157 AllocationAlignment align = | |
2158 alignment == kDoubleAlignment ? kDoubleAligned : kWordAligned; | |
2159 AllocationResult allocation = | 2157 AllocationResult allocation = |
2160 heap->new_space()->AllocateRaw(object_size, align); | 2158 heap->new_space()->AllocateRaw(object_size, alignment); |
2161 | 2159 |
2162 HeapObject* target = NULL; // Initialization to please compiler. | 2160 HeapObject* target = NULL; // Initialization to please compiler. |
2163 if (allocation.To(&target)) { | 2161 if (allocation.To(&target)) { |
2164 // Order is important here: Set the promotion limit before storing a | 2162 // Order is important here: Set the promotion limit before storing a |
2165 // filler for double alignment or migrating the object. Otherwise we | 2163 // filler for double alignment or migrating the object. Otherwise we |
2166 // may end up overwriting promotion queue entries when we migrate the | 2164 // may end up overwriting promotion queue entries when we migrate the |
2167 // object. | 2165 // object. |
2168 heap->promotion_queue()->SetNewLimit(heap->new_space()->top()); | 2166 heap->promotion_queue()->SetNewLimit(heap->new_space()->top()); |
2169 | 2167 |
2170 MigrateObject(heap, object, target, object_size); | 2168 MigrateObject(heap, object, target, object_size); |
2171 | 2169 |
2172 // Update slot to new target. | 2170 // Update slot to new target. |
2173 *slot = target; | 2171 *slot = target; |
2174 | 2172 |
2175 heap->IncrementSemiSpaceCopiedObjectSize(object_size); | 2173 heap->IncrementSemiSpaceCopiedObjectSize(object_size); |
2176 return true; | 2174 return true; |
2177 } | 2175 } |
2178 return false; | 2176 return false; |
2179 } | 2177 } |
2180 | 2178 |
2181 | 2179 |
2182 template <ObjectContents object_contents, int alignment> | 2180 template <ObjectContents object_contents, AllocationAlignment alignment> |
2183 static inline bool PromoteObject(Map* map, HeapObject** slot, | 2181 static inline bool PromoteObject(Map* map, HeapObject** slot, |
2184 HeapObject* object, int object_size) { | 2182 HeapObject* object, int object_size) { |
2185 Heap* heap = map->GetHeap(); | 2183 Heap* heap = map->GetHeap(); |
2186 | 2184 |
2187 AllocationAlignment align = | |
2188 alignment == kDoubleAlignment ? kDoubleAligned : kWordAligned; | |
2189 AllocationResult allocation = | 2185 AllocationResult allocation = |
2190 heap->old_space()->AllocateRaw(object_size, align); | 2186 heap->old_space()->AllocateRaw(object_size, alignment); |
2191 | 2187 |
2192 HeapObject* target = NULL; // Initialization to please compiler. | 2188 HeapObject* target = NULL; // Initialization to please compiler. |
2193 if (allocation.To(&target)) { | 2189 if (allocation.To(&target)) { |
2194 MigrateObject(heap, object, target, object_size); | 2190 MigrateObject(heap, object, target, object_size); |
2195 | 2191 |
2196 // Update slot to new target. | 2192 // Update slot to new target. |
2197 *slot = target; | 2193 *slot = target; |
2198 | 2194 |
2199 if (object_contents == POINTER_OBJECT) { | 2195 if (object_contents == POINTER_OBJECT) { |
2200 if (map->instance_type() == JS_FUNCTION_TYPE) { | 2196 if (map->instance_type() == JS_FUNCTION_TYPE) { |
2201 heap->promotion_queue()->insert(target, | 2197 heap->promotion_queue()->insert(target, |
2202 JSFunction::kNonWeakFieldsEndOffset); | 2198 JSFunction::kNonWeakFieldsEndOffset); |
2203 } else { | 2199 } else { |
2204 heap->promotion_queue()->insert(target, object_size); | 2200 heap->promotion_queue()->insert(target, object_size); |
2205 } | 2201 } |
2206 } | 2202 } |
2207 heap->IncrementPromotedObjectsSize(object_size); | 2203 heap->IncrementPromotedObjectsSize(object_size); |
2208 return true; | 2204 return true; |
2209 } | 2205 } |
2210 return false; | 2206 return false; |
2211 } | 2207 } |
2212 | 2208 |
2213 | 2209 |
2214 template <ObjectContents object_contents, int alignment> | 2210 template <ObjectContents object_contents, AllocationAlignment alignment> |
2215 static inline void EvacuateObject(Map* map, HeapObject** slot, | 2211 static inline void EvacuateObject(Map* map, HeapObject** slot, |
2216 HeapObject* object, int object_size) { | 2212 HeapObject* object, int object_size) { |
2217 SLOW_DCHECK(object_size <= Page::kMaxRegularHeapObjectSize); | 2213 SLOW_DCHECK(object_size <= Page::kMaxRegularHeapObjectSize); |
2218 SLOW_DCHECK(object->Size() == object_size); | 2214 SLOW_DCHECK(object->Size() == object_size); |
2219 Heap* heap = map->GetHeap(); | 2215 Heap* heap = map->GetHeap(); |
2220 | 2216 |
2221 if (!heap->ShouldBePromoted(object->address(), object_size)) { | 2217 if (!heap->ShouldBePromoted(object->address(), object_size)) { |
2222 // A semi-space copy may fail due to fragmentation. In that case, we | 2218 // A semi-space copy may fail due to fragmentation. In that case, we |
2223 // try to promote the object. | 2219 // try to promote the object. |
2224 if (SemiSpaceCopyObject<alignment>(map, slot, object, object_size)) { | 2220 if (SemiSpaceCopyObject<alignment>(map, slot, object, object_size)) { |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2258 Code* code = Code::cast(Code::GetObjectFromEntryAddress(code_entry_slot)); | 2254 Code* code = Code::cast(Code::GetObjectFromEntryAddress(code_entry_slot)); |
2259 map->GetHeap()->mark_compact_collector()->RecordCodeEntrySlot( | 2255 map->GetHeap()->mark_compact_collector()->RecordCodeEntrySlot( |
2260 code_entry_slot, code); | 2256 code_entry_slot, code); |
2261 } | 2257 } |
2262 } | 2258 } |
2263 | 2259 |
2264 | 2260 |
2265 static inline void EvacuateFixedArray(Map* map, HeapObject** slot, | 2261 static inline void EvacuateFixedArray(Map* map, HeapObject** slot, |
2266 HeapObject* object) { | 2262 HeapObject* object) { |
2267 int object_size = FixedArray::BodyDescriptor::SizeOf(map, object); | 2263 int object_size = FixedArray::BodyDescriptor::SizeOf(map, object); |
2268 EvacuateObject<POINTER_OBJECT, kObjectAlignment>(map, slot, object, | 2264 EvacuateObject<POINTER_OBJECT, kWordAligned>(map, slot, object, |
2269 object_size); | 2265 object_size); |
2270 } | 2266 } |
2271 | 2267 |
2272 | 2268 |
2273 static inline void EvacuateFixedDoubleArray(Map* map, HeapObject** slot, | 2269 static inline void EvacuateFixedDoubleArray(Map* map, HeapObject** slot, |
2274 HeapObject* object) { | 2270 HeapObject* object) { |
2275 int length = reinterpret_cast<FixedDoubleArray*>(object)->length(); | 2271 int length = reinterpret_cast<FixedDoubleArray*>(object)->length(); |
2276 int object_size = FixedDoubleArray::SizeFor(length); | 2272 int object_size = FixedDoubleArray::SizeFor(length); |
2277 EvacuateObject<DATA_OBJECT, kDoubleAlignment>(map, slot, object, | 2273 EvacuateObject<DATA_OBJECT, kDoubleAligned>(map, slot, object, object_size); |
2278 object_size); | |
2279 } | 2274 } |
2280 | 2275 |
2281 | 2276 |
2282 static inline void EvacuateFixedTypedArray(Map* map, HeapObject** slot, | 2277 static inline void EvacuateFixedTypedArray(Map* map, HeapObject** slot, |
2283 HeapObject* object) { | 2278 HeapObject* object) { |
2284 int object_size = reinterpret_cast<FixedTypedArrayBase*>(object)->size(); | 2279 int object_size = reinterpret_cast<FixedTypedArrayBase*>(object)->size(); |
2285 EvacuateObject<DATA_OBJECT, kObjectAlignment>(map, slot, object, | 2280 EvacuateObject<DATA_OBJECT, kWordAligned>(map, slot, object, object_size); |
2286 object_size); | |
2287 } | 2281 } |
2288 | 2282 |
2289 | 2283 |
2290 static inline void EvacuateFixedFloat64Array(Map* map, HeapObject** slot, | 2284 static inline void EvacuateFixedFloat64Array(Map* map, HeapObject** slot, |
2291 HeapObject* object) { | 2285 HeapObject* object) { |
2292 int object_size = reinterpret_cast<FixedFloat64Array*>(object)->size(); | 2286 int object_size = reinterpret_cast<FixedFloat64Array*>(object)->size(); |
2293 EvacuateObject<DATA_OBJECT, kDoubleAlignment>(map, slot, object, | 2287 EvacuateObject<DATA_OBJECT, kDoubleAligned>(map, slot, object, object_size); |
2294 object_size); | |
2295 } | 2288 } |
2296 | 2289 |
2297 | 2290 |
2298 static inline void EvacuateByteArray(Map* map, HeapObject** slot, | 2291 static inline void EvacuateByteArray(Map* map, HeapObject** slot, |
2299 HeapObject* object) { | 2292 HeapObject* object) { |
2300 int object_size = reinterpret_cast<ByteArray*>(object)->ByteArraySize(); | 2293 int object_size = reinterpret_cast<ByteArray*>(object)->ByteArraySize(); |
2301 EvacuateObject<DATA_OBJECT, kObjectAlignment>(map, slot, object, | 2294 EvacuateObject<DATA_OBJECT, kWordAligned>(map, slot, object, object_size); |
2302 object_size); | |
2303 } | 2295 } |
2304 | 2296 |
2305 | 2297 |
2306 static inline void EvacuateSeqOneByteString(Map* map, HeapObject** slot, | 2298 static inline void EvacuateSeqOneByteString(Map* map, HeapObject** slot, |
2307 HeapObject* object) { | 2299 HeapObject* object) { |
2308 int object_size = SeqOneByteString::cast(object) | 2300 int object_size = SeqOneByteString::cast(object) |
2309 ->SeqOneByteStringSize(map->instance_type()); | 2301 ->SeqOneByteStringSize(map->instance_type()); |
2310 EvacuateObject<DATA_OBJECT, kObjectAlignment>(map, slot, object, | 2302 EvacuateObject<DATA_OBJECT, kWordAligned>(map, slot, object, object_size); |
2311 object_size); | |
2312 } | 2303 } |
2313 | 2304 |
2314 | 2305 |
2315 static inline void EvacuateSeqTwoByteString(Map* map, HeapObject** slot, | 2306 static inline void EvacuateSeqTwoByteString(Map* map, HeapObject** slot, |
2316 HeapObject* object) { | 2307 HeapObject* object) { |
2317 int object_size = SeqTwoByteString::cast(object) | 2308 int object_size = SeqTwoByteString::cast(object) |
2318 ->SeqTwoByteStringSize(map->instance_type()); | 2309 ->SeqTwoByteStringSize(map->instance_type()); |
2319 EvacuateObject<DATA_OBJECT, kObjectAlignment>(map, slot, object, | 2310 EvacuateObject<DATA_OBJECT, kWordAligned>(map, slot, object, object_size); |
2320 object_size); | |
2321 } | 2311 } |
2322 | 2312 |
2323 | 2313 |
2324 static inline void EvacuateShortcutCandidate(Map* map, HeapObject** slot, | 2314 static inline void EvacuateShortcutCandidate(Map* map, HeapObject** slot, |
2325 HeapObject* object) { | 2315 HeapObject* object) { |
2326 DCHECK(IsShortcutCandidate(map->instance_type())); | 2316 DCHECK(IsShortcutCandidate(map->instance_type())); |
2327 | 2317 |
2328 Heap* heap = map->GetHeap(); | 2318 Heap* heap = map->GetHeap(); |
2329 | 2319 |
2330 if (marks_handling == IGNORE_MARKS && | 2320 if (marks_handling == IGNORE_MARKS && |
(...skipping 16 matching lines...) Expand all Loading... |
2347 object->set_map_word(MapWord::FromForwardingAddress(target)); | 2337 object->set_map_word(MapWord::FromForwardingAddress(target)); |
2348 return; | 2338 return; |
2349 } | 2339 } |
2350 | 2340 |
2351 heap->DoScavengeObject(first->map(), slot, first); | 2341 heap->DoScavengeObject(first->map(), slot, first); |
2352 object->set_map_word(MapWord::FromForwardingAddress(*slot)); | 2342 object->set_map_word(MapWord::FromForwardingAddress(*slot)); |
2353 return; | 2343 return; |
2354 } | 2344 } |
2355 | 2345 |
2356 int object_size = ConsString::kSize; | 2346 int object_size = ConsString::kSize; |
2357 EvacuateObject<POINTER_OBJECT, kObjectAlignment>(map, slot, object, | 2347 EvacuateObject<POINTER_OBJECT, kWordAligned>(map, slot, object, |
2358 object_size); | 2348 object_size); |
2359 } | 2349 } |
2360 | 2350 |
2361 template <ObjectContents object_contents> | 2351 template <ObjectContents object_contents> |
2362 class ObjectEvacuationStrategy { | 2352 class ObjectEvacuationStrategy { |
2363 public: | 2353 public: |
2364 template <int object_size> | 2354 template <int object_size> |
2365 static inline void VisitSpecialized(Map* map, HeapObject** slot, | 2355 static inline void VisitSpecialized(Map* map, HeapObject** slot, |
2366 HeapObject* object) { | 2356 HeapObject* object) { |
2367 EvacuateObject<object_contents, kObjectAlignment>(map, slot, object, | 2357 EvacuateObject<object_contents, kWordAligned>(map, slot, object, |
2368 object_size); | 2358 object_size); |
2369 } | 2359 } |
2370 | 2360 |
2371 static inline void Visit(Map* map, HeapObject** slot, HeapObject* object) { | 2361 static inline void Visit(Map* map, HeapObject** slot, HeapObject* object) { |
2372 int object_size = map->instance_size(); | 2362 int object_size = map->instance_size(); |
2373 EvacuateObject<object_contents, kObjectAlignment>(map, slot, object, | 2363 EvacuateObject<object_contents, kWordAligned>(map, slot, object, |
2374 object_size); | 2364 object_size); |
2375 } | 2365 } |
2376 }; | 2366 }; |
2377 | 2367 |
2378 static VisitorDispatchTable<ScavengingCallback> table_; | 2368 static VisitorDispatchTable<ScavengingCallback> table_; |
2379 }; | 2369 }; |
2380 | 2370 |
2381 | 2371 |
2382 template <MarksHandling marks_handling, | 2372 template <MarksHandling marks_handling, |
2383 LoggingAndProfiling logging_and_profiling_mode> | 2373 LoggingAndProfiling logging_and_profiling_mode> |
2384 VisitorDispatchTable<ScavengingCallback> | 2374 VisitorDispatchTable<ScavengingCallback> |
(...skipping 4206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6591 *object_type = "CODE_TYPE"; \ | 6581 *object_type = "CODE_TYPE"; \ |
6592 *object_sub_type = "CODE_AGE/" #name; \ | 6582 *object_sub_type = "CODE_AGE/" #name; \ |
6593 return true; | 6583 return true; |
6594 CODE_AGE_LIST_COMPLETE(COMPARE_AND_RETURN_NAME) | 6584 CODE_AGE_LIST_COMPLETE(COMPARE_AND_RETURN_NAME) |
6595 #undef COMPARE_AND_RETURN_NAME | 6585 #undef COMPARE_AND_RETURN_NAME |
6596 } | 6586 } |
6597 return false; | 6587 return false; |
6598 } | 6588 } |
6599 } | 6589 } |
6600 } // namespace v8::internal | 6590 } // namespace v8::internal |
OLD | NEW |