OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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/scavenger.h" | 5 #include "src/heap/scavenger.h" |
6 | 6 |
7 #include "src/contexts.h" | 7 #include "src/contexts.h" |
8 #include "src/heap/heap.h" | 8 #include "src/heap/heap.h" |
9 #include "src/heap/objects-visiting-inl.h" | 9 #include "src/heap/objects-visiting-inl.h" |
10 #include "src/heap/scavenger-inl.h" | 10 #include "src/heap/scavenger-inl.h" |
11 #include "src/isolate.h" | 11 #include "src/isolate.h" |
12 #include "src/log.h" | 12 #include "src/log.h" |
13 #include "src/profiler/cpu-profiler.h" | 13 #include "src/profiler/cpu-profiler.h" |
14 | 14 |
15 namespace v8 { | 15 namespace v8 { |
16 namespace internal { | 16 namespace internal { |
17 | 17 |
18 enum LoggingAndProfiling { | 18 enum LoggingAndProfiling { |
19 LOGGING_AND_PROFILING_ENABLED, | 19 LOGGING_AND_PROFILING_ENABLED, |
20 LOGGING_AND_PROFILING_DISABLED | 20 LOGGING_AND_PROFILING_DISABLED |
21 }; | 21 }; |
22 | 22 |
23 | 23 |
24 enum MarksHandling { TRANSFER_MARKS, IGNORE_MARKS }; | 24 enum MarksHandling { TRANSFER_MARKS, IGNORE_MARKS }; |
25 | 25 |
26 | 26 template <MarksHandling marks_handling, PromotionMode promotion_mode, |
27 template <MarksHandling marks_handling, | |
28 LoggingAndProfiling logging_and_profiling_mode> | 27 LoggingAndProfiling logging_and_profiling_mode> |
29 class ScavengingVisitor : public StaticVisitorBase { | 28 class ScavengingVisitor : public StaticVisitorBase { |
30 public: | 29 public: |
31 static void Initialize() { | 30 static void Initialize() { |
32 table_.Register(kVisitSeqOneByteString, &EvacuateSeqOneByteString); | 31 table_.Register(kVisitSeqOneByteString, &EvacuateSeqOneByteString); |
33 table_.Register(kVisitSeqTwoByteString, &EvacuateSeqTwoByteString); | 32 table_.Register(kVisitSeqTwoByteString, &EvacuateSeqTwoByteString); |
34 table_.Register(kVisitShortcutCandidate, &EvacuateShortcutCandidate); | 33 table_.Register(kVisitShortcutCandidate, &EvacuateShortcutCandidate); |
35 table_.Register(kVisitByteArray, &EvacuateByteArray); | 34 table_.Register(kVisitByteArray, &EvacuateByteArray); |
36 table_.Register(kVisitFixedArray, &EvacuateFixedArray); | 35 table_.Register(kVisitFixedArray, &EvacuateFixedArray); |
37 table_.Register(kVisitFixedDoubleArray, &EvacuateFixedDoubleArray); | 36 table_.Register(kVisitFixedDoubleArray, &EvacuateFixedDoubleArray); |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
195 Marking::IsBlack(Marking::MarkBitFrom(object))); | 194 Marking::IsBlack(Marking::MarkBitFrom(object))); |
196 } | 195 } |
197 heap->IncrementPromotedObjectsSize(object_size); | 196 heap->IncrementPromotedObjectsSize(object_size); |
198 return true; | 197 return true; |
199 } | 198 } |
200 return false; | 199 return false; |
201 } | 200 } |
202 | 201 |
203 template <ObjectContents object_contents, AllocationAlignment alignment> | 202 template <ObjectContents object_contents, AllocationAlignment alignment> |
204 static inline void EvacuateObject(Map* map, HeapObject** slot, | 203 static inline void EvacuateObject(Map* map, HeapObject** slot, |
205 HeapObject* object, int object_size, | 204 HeapObject* object, int object_size) { |
206 PromotionMode promotion_mode) { | |
207 SLOW_DCHECK(object_size <= Page::kAllocatableMemory); | 205 SLOW_DCHECK(object_size <= Page::kAllocatableMemory); |
208 SLOW_DCHECK(object->Size() == object_size); | 206 SLOW_DCHECK(object->Size() == object_size); |
209 Heap* heap = map->GetHeap(); | 207 Heap* heap = map->GetHeap(); |
210 | 208 |
211 if (promotion_mode != FORCE_PROMOTION && | 209 if (!heap->ShouldBePromoted<promotion_mode>(object->address(), |
212 !heap->ShouldBePromoted(object->address(), object_size)) { | 210 object_size)) { |
213 // A semi-space copy may fail due to fragmentation. In that case, we | 211 // A semi-space copy may fail due to fragmentation. In that case, we |
214 // try to promote the object. | 212 // try to promote the object. |
215 if (SemiSpaceCopyObject<alignment>(map, slot, object, object_size)) { | 213 if (SemiSpaceCopyObject<alignment>(map, slot, object, object_size)) { |
216 return; | 214 return; |
217 } | 215 } |
218 } | 216 } |
219 | 217 |
220 if (PromoteObject<object_contents, alignment>(map, slot, object, | 218 if (PromoteObject<object_contents, alignment>(map, slot, object, |
221 object_size)) { | 219 object_size)) { |
222 return; | 220 return; |
223 } | 221 } |
224 if (promotion_mode == FORCE_PROMOTION) { | 222 if (promotion_mode == PROMOTE_MARKED) { |
225 FatalProcessOutOfMemory("Scavenger: forced promotion\n"); | 223 FatalProcessOutOfMemory("Scavenger: promoting marked\n"); |
226 } | 224 } |
227 // If promotion failed, we try to copy the object to the other semi-space | 225 // If promotion failed, we try to copy the object to the other semi-space |
228 if (SemiSpaceCopyObject<alignment>(map, slot, object, object_size)) return; | 226 if (SemiSpaceCopyObject<alignment>(map, slot, object, object_size)) return; |
229 | 227 |
230 FatalProcessOutOfMemory("Scavenger: semi-space copy\n"); | 228 FatalProcessOutOfMemory("Scavenger: semi-space copy\n"); |
231 } | 229 } |
232 | 230 |
233 static inline void EvacuateJSFunction(Map* map, HeapObject** slot, | 231 static inline void EvacuateJSFunction(Map* map, HeapObject** slot, |
234 HeapObject* object, | 232 HeapObject* object) { |
235 PromotionMode promotion_mode) { | 233 ObjectEvacuationStrategy<POINTER_OBJECT>::Visit(map, slot, object); |
236 ObjectEvacuationStrategy<POINTER_OBJECT>::Visit(map, slot, object, | |
237 promotion_mode); | |
238 | 234 |
239 if (marks_handling == IGNORE_MARKS) return; | 235 if (marks_handling == IGNORE_MARKS) return; |
240 | 236 |
241 MapWord map_word = object->map_word(); | 237 MapWord map_word = object->map_word(); |
242 DCHECK(map_word.IsForwardingAddress()); | 238 DCHECK(map_word.IsForwardingAddress()); |
243 HeapObject* target = map_word.ToForwardingAddress(); | 239 HeapObject* target = map_word.ToForwardingAddress(); |
244 | 240 |
245 MarkBit mark_bit = Marking::MarkBitFrom(target); | 241 MarkBit mark_bit = Marking::MarkBitFrom(target); |
246 if (Marking::IsBlack(mark_bit)) { | 242 if (Marking::IsBlack(mark_bit)) { |
247 // This object is black and it might not be rescanned by marker. | 243 // This object is black and it might not be rescanned by marker. |
248 // We should explicitly record code entry slot for compaction because | 244 // We should explicitly record code entry slot for compaction because |
249 // promotion queue processing (IteratePromotedObjectPointers) will | 245 // promotion queue processing (IteratePromotedObjectPointers) will |
250 // miss it as it is not HeapObject-tagged. | 246 // miss it as it is not HeapObject-tagged. |
251 Address code_entry_slot = | 247 Address code_entry_slot = |
252 target->address() + JSFunction::kCodeEntryOffset; | 248 target->address() + JSFunction::kCodeEntryOffset; |
253 Code* code = Code::cast(Code::GetObjectFromEntryAddress(code_entry_slot)); | 249 Code* code = Code::cast(Code::GetObjectFromEntryAddress(code_entry_slot)); |
254 map->GetHeap()->mark_compact_collector()->RecordCodeEntrySlot( | 250 map->GetHeap()->mark_compact_collector()->RecordCodeEntrySlot( |
255 target, code_entry_slot, code); | 251 target, code_entry_slot, code); |
256 } | 252 } |
257 } | 253 } |
258 | 254 |
259 static inline void EvacuateFixedArray(Map* map, HeapObject** slot, | 255 static inline void EvacuateFixedArray(Map* map, HeapObject** slot, |
260 HeapObject* object, | 256 HeapObject* object) { |
261 PromotionMode promotion_mode) { | |
262 int length = reinterpret_cast<FixedArray*>(object)->synchronized_length(); | 257 int length = reinterpret_cast<FixedArray*>(object)->synchronized_length(); |
263 int object_size = FixedArray::SizeFor(length); | 258 int object_size = FixedArray::SizeFor(length); |
264 EvacuateObject<POINTER_OBJECT, kWordAligned>(map, slot, object, object_size, | 259 EvacuateObject<POINTER_OBJECT, kWordAligned>(map, slot, object, |
265 promotion_mode); | 260 object_size); |
266 } | 261 } |
267 | 262 |
268 static inline void EvacuateFixedDoubleArray(Map* map, HeapObject** slot, | 263 static inline void EvacuateFixedDoubleArray(Map* map, HeapObject** slot, |
269 HeapObject* object, | 264 HeapObject* object) { |
270 PromotionMode promotion_mode) { | |
271 int length = reinterpret_cast<FixedDoubleArray*>(object)->length(); | 265 int length = reinterpret_cast<FixedDoubleArray*>(object)->length(); |
272 int object_size = FixedDoubleArray::SizeFor(length); | 266 int object_size = FixedDoubleArray::SizeFor(length); |
273 EvacuateObject<DATA_OBJECT, kDoubleAligned>(map, slot, object, object_size, | 267 EvacuateObject<DATA_OBJECT, kDoubleAligned>(map, slot, object, object_size); |
274 promotion_mode); | |
275 } | 268 } |
276 | 269 |
277 static inline void EvacuateFixedTypedArray(Map* map, HeapObject** slot, | 270 static inline void EvacuateFixedTypedArray(Map* map, HeapObject** slot, |
278 HeapObject* object, | 271 HeapObject* object) { |
279 PromotionMode promotion_mode) { | |
280 int object_size = reinterpret_cast<FixedTypedArrayBase*>(object)->size(); | 272 int object_size = reinterpret_cast<FixedTypedArrayBase*>(object)->size(); |
281 EvacuateObject<POINTER_OBJECT, kWordAligned>(map, slot, object, object_size, | 273 EvacuateObject<POINTER_OBJECT, kWordAligned>(map, slot, object, |
282 promotion_mode); | 274 object_size); |
283 } | 275 } |
284 | 276 |
285 static inline void EvacuateFixedFloat64Array(Map* map, HeapObject** slot, | 277 static inline void EvacuateFixedFloat64Array(Map* map, HeapObject** slot, |
286 HeapObject* object, | 278 HeapObject* object) { |
287 PromotionMode promotion_mode) { | |
288 int object_size = reinterpret_cast<FixedFloat64Array*>(object)->size(); | 279 int object_size = reinterpret_cast<FixedFloat64Array*>(object)->size(); |
289 EvacuateObject<POINTER_OBJECT, kDoubleAligned>(map, slot, object, | 280 EvacuateObject<POINTER_OBJECT, kDoubleAligned>(map, slot, object, |
290 object_size, promotion_mode); | 281 object_size); |
291 } | 282 } |
292 | 283 |
293 static inline void EvacuateJSArrayBuffer(Map* map, HeapObject** slot, | 284 static inline void EvacuateJSArrayBuffer(Map* map, HeapObject** slot, |
294 HeapObject* object, | 285 HeapObject* object) { |
295 PromotionMode promotion_mode) { | 286 ObjectEvacuationStrategy<POINTER_OBJECT>::Visit(map, slot, object); |
296 ObjectEvacuationStrategy<POINTER_OBJECT>::Visit(map, slot, object, | |
297 promotion_mode); | |
298 | 287 |
299 Heap* heap = map->GetHeap(); | 288 Heap* heap = map->GetHeap(); |
300 MapWord map_word = object->map_word(); | 289 MapWord map_word = object->map_word(); |
301 DCHECK(map_word.IsForwardingAddress()); | 290 DCHECK(map_word.IsForwardingAddress()); |
302 HeapObject* target = map_word.ToForwardingAddress(); | 291 HeapObject* target = map_word.ToForwardingAddress(); |
303 if (!heap->InNewSpace(target)) { | 292 if (!heap->InNewSpace(target)) { |
304 heap->array_buffer_tracker()->Promote(JSArrayBuffer::cast(target)); | 293 heap->array_buffer_tracker()->Promote(JSArrayBuffer::cast(target)); |
305 } | 294 } |
306 } | 295 } |
307 | 296 |
308 static inline void EvacuateByteArray(Map* map, HeapObject** slot, | 297 static inline void EvacuateByteArray(Map* map, HeapObject** slot, |
309 HeapObject* object, | 298 HeapObject* object) { |
310 PromotionMode promotion_mode) { | |
311 int object_size = reinterpret_cast<ByteArray*>(object)->ByteArraySize(); | 299 int object_size = reinterpret_cast<ByteArray*>(object)->ByteArraySize(); |
312 EvacuateObject<DATA_OBJECT, kWordAligned>(map, slot, object, object_size, | 300 EvacuateObject<DATA_OBJECT, kWordAligned>(map, slot, object, object_size); |
313 promotion_mode); | |
314 } | 301 } |
315 | 302 |
316 static inline void EvacuateSeqOneByteString(Map* map, HeapObject** slot, | 303 static inline void EvacuateSeqOneByteString(Map* map, HeapObject** slot, |
317 HeapObject* object, | 304 HeapObject* object) { |
318 PromotionMode promotion_mode) { | |
319 int object_size = SeqOneByteString::cast(object) | 305 int object_size = SeqOneByteString::cast(object) |
320 ->SeqOneByteStringSize(map->instance_type()); | 306 ->SeqOneByteStringSize(map->instance_type()); |
321 EvacuateObject<DATA_OBJECT, kWordAligned>(map, slot, object, object_size, | 307 EvacuateObject<DATA_OBJECT, kWordAligned>(map, slot, object, object_size); |
322 promotion_mode); | |
323 } | 308 } |
324 | 309 |
325 static inline void EvacuateSeqTwoByteString(Map* map, HeapObject** slot, | 310 static inline void EvacuateSeqTwoByteString(Map* map, HeapObject** slot, |
326 HeapObject* object, | 311 HeapObject* object) { |
327 PromotionMode promotion_mode) { | |
328 int object_size = SeqTwoByteString::cast(object) | 312 int object_size = SeqTwoByteString::cast(object) |
329 ->SeqTwoByteStringSize(map->instance_type()); | 313 ->SeqTwoByteStringSize(map->instance_type()); |
330 EvacuateObject<DATA_OBJECT, kWordAligned>(map, slot, object, object_size, | 314 EvacuateObject<DATA_OBJECT, kWordAligned>(map, slot, object, object_size); |
331 promotion_mode); | |
332 } | 315 } |
333 | 316 |
334 static inline void EvacuateShortcutCandidate(Map* map, HeapObject** slot, | 317 static inline void EvacuateShortcutCandidate(Map* map, HeapObject** slot, |
335 HeapObject* object, | 318 HeapObject* object) { |
336 PromotionMode promotion_mode) { | |
337 DCHECK(IsShortcutCandidate(map->instance_type())); | 319 DCHECK(IsShortcutCandidate(map->instance_type())); |
338 | 320 |
339 Heap* heap = map->GetHeap(); | 321 Heap* heap = map->GetHeap(); |
340 | 322 |
341 if (marks_handling == IGNORE_MARKS && | 323 if (marks_handling == IGNORE_MARKS && |
342 ConsString::cast(object)->unchecked_second() == heap->empty_string()) { | 324 ConsString::cast(object)->unchecked_second() == heap->empty_string()) { |
343 HeapObject* first = | 325 HeapObject* first = |
344 HeapObject::cast(ConsString::cast(object)->unchecked_first()); | 326 HeapObject::cast(ConsString::cast(object)->unchecked_first()); |
345 | 327 |
346 *slot = first; | 328 *slot = first; |
347 | 329 |
348 if (!heap->InNewSpace(first)) { | 330 if (!heap->InNewSpace(first)) { |
349 object->set_map_word(MapWord::FromForwardingAddress(first)); | 331 object->set_map_word(MapWord::FromForwardingAddress(first)); |
350 return; | 332 return; |
351 } | 333 } |
352 | 334 |
353 MapWord first_word = first->map_word(); | 335 MapWord first_word = first->map_word(); |
354 if (first_word.IsForwardingAddress()) { | 336 if (first_word.IsForwardingAddress()) { |
355 HeapObject* target = first_word.ToForwardingAddress(); | 337 HeapObject* target = first_word.ToForwardingAddress(); |
356 | 338 |
357 *slot = target; | 339 *slot = target; |
358 object->set_map_word(MapWord::FromForwardingAddress(target)); | 340 object->set_map_word(MapWord::FromForwardingAddress(target)); |
359 return; | 341 return; |
360 } | 342 } |
361 | 343 |
362 Scavenger::ScavengeObjectSlow(slot, first, promotion_mode); | 344 Scavenger::ScavengeObjectSlow(slot, first); |
363 object->set_map_word(MapWord::FromForwardingAddress(*slot)); | 345 object->set_map_word(MapWord::FromForwardingAddress(*slot)); |
364 return; | 346 return; |
365 } | 347 } |
366 | 348 |
367 int object_size = ConsString::kSize; | 349 int object_size = ConsString::kSize; |
368 EvacuateObject<POINTER_OBJECT, kWordAligned>(map, slot, object, object_size, | 350 EvacuateObject<POINTER_OBJECT, kWordAligned>(map, slot, object, |
369 promotion_mode); | 351 object_size); |
370 } | 352 } |
371 | 353 |
372 template <ObjectContents object_contents> | 354 template <ObjectContents object_contents> |
373 class ObjectEvacuationStrategy { | 355 class ObjectEvacuationStrategy { |
374 public: | 356 public: |
375 template <int object_size> | 357 template <int object_size> |
376 static inline void VisitSpecialized(Map* map, HeapObject** slot, | 358 static inline void VisitSpecialized(Map* map, HeapObject** slot, |
377 HeapObject* object, | 359 HeapObject* object) { |
378 PromotionMode promotion_mode) { | 360 EvacuateObject<object_contents, kWordAligned>(map, slot, object, |
379 EvacuateObject<object_contents, kWordAligned>( | 361 object_size); |
380 map, slot, object, object_size, promotion_mode); | |
381 } | 362 } |
382 | 363 |
383 static inline void Visit(Map* map, HeapObject** slot, HeapObject* object, | 364 static inline void Visit(Map* map, HeapObject** slot, HeapObject* object) { |
384 PromotionMode promotion_mode) { | |
385 int object_size = map->instance_size(); | 365 int object_size = map->instance_size(); |
386 EvacuateObject<object_contents, kWordAligned>( | 366 EvacuateObject<object_contents, kWordAligned>(map, slot, object, |
387 map, slot, object, object_size, promotion_mode); | 367 object_size); |
388 } | 368 } |
389 }; | 369 }; |
390 | 370 |
391 static VisitorDispatchTable<ScavengingCallback> table_; | 371 static VisitorDispatchTable<ScavengingCallback> table_; |
392 }; | 372 }; |
393 | 373 |
394 | 374 template <MarksHandling marks_handling, PromotionMode promotion_mode, |
395 template <MarksHandling marks_handling, | |
396 LoggingAndProfiling logging_and_profiling_mode> | 375 LoggingAndProfiling logging_and_profiling_mode> |
397 VisitorDispatchTable<ScavengingCallback> | 376 VisitorDispatchTable<ScavengingCallback> ScavengingVisitor< |
398 ScavengingVisitor<marks_handling, logging_and_profiling_mode>::table_; | 377 marks_handling, promotion_mode, logging_and_profiling_mode>::table_; |
399 | |
400 | 378 |
401 // static | 379 // static |
402 void Scavenger::Initialize() { | 380 void Scavenger::Initialize() { |
403 ScavengingVisitor<TRANSFER_MARKS, | 381 ScavengingVisitor<TRANSFER_MARKS, PROMOTE_MARKED, |
404 LOGGING_AND_PROFILING_DISABLED>::Initialize(); | 382 LOGGING_AND_PROFILING_DISABLED>::Initialize(); |
405 ScavengingVisitor<IGNORE_MARKS, LOGGING_AND_PROFILING_DISABLED>::Initialize(); | 383 ScavengingVisitor<IGNORE_MARKS, DEFAULT_PROMOTION, |
406 ScavengingVisitor<TRANSFER_MARKS, | 384 LOGGING_AND_PROFILING_DISABLED>::Initialize(); |
| 385 ScavengingVisitor<TRANSFER_MARKS, PROMOTE_MARKED, |
407 LOGGING_AND_PROFILING_ENABLED>::Initialize(); | 386 LOGGING_AND_PROFILING_ENABLED>::Initialize(); |
408 ScavengingVisitor<IGNORE_MARKS, LOGGING_AND_PROFILING_ENABLED>::Initialize(); | 387 ScavengingVisitor<IGNORE_MARKS, DEFAULT_PROMOTION, |
| 388 LOGGING_AND_PROFILING_ENABLED>::Initialize(); |
409 } | 389 } |
410 | 390 |
411 | 391 |
412 // static | 392 // static |
413 void Scavenger::ScavengeObjectSlow(HeapObject** p, HeapObject* object, | 393 void Scavenger::ScavengeObjectSlow(HeapObject** p, HeapObject* object) { |
414 PromotionMode promotion_mode) { | |
415 SLOW_DCHECK(object->GetIsolate()->heap()->InFromSpace(object)); | 394 SLOW_DCHECK(object->GetIsolate()->heap()->InFromSpace(object)); |
416 MapWord first_word = object->map_word(); | 395 MapWord first_word = object->map_word(); |
417 SLOW_DCHECK(!first_word.IsForwardingAddress()); | 396 SLOW_DCHECK(!first_word.IsForwardingAddress()); |
418 Map* map = first_word.ToMap(); | 397 Map* map = first_word.ToMap(); |
419 Scavenger* scavenger = map->GetHeap()->scavenge_collector_; | 398 Scavenger* scavenger = map->GetHeap()->scavenge_collector_; |
420 scavenger->scavenging_visitors_table_.GetVisitor(map)(map, p, object, | 399 scavenger->scavenging_visitors_table_.GetVisitor(map)(map, p, object); |
421 promotion_mode); | |
422 } | 400 } |
423 | 401 |
424 | 402 |
425 void Scavenger::SelectScavengingVisitorsTable() { | 403 void Scavenger::SelectScavengingVisitorsTable() { |
426 bool logging_and_profiling = | 404 bool logging_and_profiling = |
427 FLAG_verify_predictable || isolate()->logger()->is_logging() || | 405 FLAG_verify_predictable || isolate()->logger()->is_logging() || |
428 isolate()->cpu_profiler()->is_profiling() || | 406 isolate()->cpu_profiler()->is_profiling() || |
429 (isolate()->heap_profiler() != NULL && | 407 (isolate()->heap_profiler() != NULL && |
430 isolate()->heap_profiler()->is_tracking_object_moves()); | 408 isolate()->heap_profiler()->is_tracking_object_moves()); |
431 | 409 |
432 if (!heap()->incremental_marking()->IsMarking()) { | 410 if (!heap()->incremental_marking()->IsMarking()) { |
433 if (!logging_and_profiling) { | 411 if (!logging_and_profiling) { |
434 scavenging_visitors_table_.CopyFrom( | 412 scavenging_visitors_table_.CopyFrom( |
435 ScavengingVisitor<IGNORE_MARKS, | 413 ScavengingVisitor<IGNORE_MARKS, DEFAULT_PROMOTION, |
436 LOGGING_AND_PROFILING_DISABLED>::GetTable()); | 414 LOGGING_AND_PROFILING_DISABLED>::GetTable()); |
437 } else { | 415 } else { |
438 scavenging_visitors_table_.CopyFrom( | 416 scavenging_visitors_table_.CopyFrom( |
439 ScavengingVisitor<IGNORE_MARKS, | 417 ScavengingVisitor<IGNORE_MARKS, DEFAULT_PROMOTION, |
440 LOGGING_AND_PROFILING_ENABLED>::GetTable()); | 418 LOGGING_AND_PROFILING_ENABLED>::GetTable()); |
441 } | 419 } |
442 } else { | 420 } else { |
443 if (!logging_and_profiling) { | 421 if (!logging_and_profiling) { |
444 scavenging_visitors_table_.CopyFrom( | 422 scavenging_visitors_table_.CopyFrom( |
445 ScavengingVisitor<TRANSFER_MARKS, | 423 ScavengingVisitor<TRANSFER_MARKS, PROMOTE_MARKED, |
446 LOGGING_AND_PROFILING_DISABLED>::GetTable()); | 424 LOGGING_AND_PROFILING_DISABLED>::GetTable()); |
447 } else { | 425 } else { |
448 scavenging_visitors_table_.CopyFrom( | 426 scavenging_visitors_table_.CopyFrom( |
449 ScavengingVisitor<TRANSFER_MARKS, | 427 ScavengingVisitor<TRANSFER_MARKS, PROMOTE_MARKED, |
450 LOGGING_AND_PROFILING_ENABLED>::GetTable()); | 428 LOGGING_AND_PROFILING_ENABLED>::GetTable()); |
451 } | 429 } |
452 | 430 |
453 if (heap()->incremental_marking()->IsCompacting()) { | 431 if (heap()->incremental_marking()->IsCompacting()) { |
454 // When compacting forbid short-circuiting of cons-strings. | 432 // When compacting forbid short-circuiting of cons-strings. |
455 // Scavenging code relies on the fact that new space object | 433 // Scavenging code relies on the fact that new space object |
456 // can't be evacuated into evacuation candidate but | 434 // can't be evacuated into evacuation candidate but |
457 // short-circuiting violates this assumption. | 435 // short-circuiting violates this assumption. |
458 scavenging_visitors_table_.Register( | 436 scavenging_visitors_table_.Register( |
459 StaticVisitorBase::kVisitShortcutCandidate, | 437 StaticVisitorBase::kVisitShortcutCandidate, |
(...skipping 18 matching lines...) Expand all Loading... |
478 | 456 |
479 void ScavengeVisitor::ScavengePointer(Object** p) { | 457 void ScavengeVisitor::ScavengePointer(Object** p) { |
480 Object* object = *p; | 458 Object* object = *p; |
481 if (!heap_->InNewSpace(object)) return; | 459 if (!heap_->InNewSpace(object)) return; |
482 Scavenger::ScavengeObject(reinterpret_cast<HeapObject**>(p), | 460 Scavenger::ScavengeObject(reinterpret_cast<HeapObject**>(p), |
483 reinterpret_cast<HeapObject*>(object)); | 461 reinterpret_cast<HeapObject*>(object)); |
484 } | 462 } |
485 | 463 |
486 } // namespace internal | 464 } // namespace internal |
487 } // namespace v8 | 465 } // namespace v8 |
OLD | NEW |