OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 abort_incremental_marking_(false), | 65 abort_incremental_marking_(false), |
66 marking_parity_(ODD_MARKING_PARITY), | 66 marking_parity_(ODD_MARKING_PARITY), |
67 compacting_(false), | 67 compacting_(false), |
68 was_marked_incrementally_(false), | 68 was_marked_incrementally_(false), |
69 sweeping_pending_(false), | 69 sweeping_pending_(false), |
70 sequential_sweeping_(false), | 70 sequential_sweeping_(false), |
71 tracer_(NULL), | 71 tracer_(NULL), |
72 migration_slots_buffer_(NULL), | 72 migration_slots_buffer_(NULL), |
73 heap_(NULL), | 73 heap_(NULL), |
74 code_flusher_(NULL), | 74 code_flusher_(NULL), |
75 encountered_weak_maps_(NULL) { } | 75 encountered_weak_maps_(Smi::FromInt(0)), |
| 76 encountered_array_buffers_(Smi::FromInt(0)) { } |
76 | 77 |
77 | 78 |
78 #ifdef VERIFY_HEAP | 79 #ifdef VERIFY_HEAP |
79 class VerifyMarkingVisitor: public ObjectVisitor { | 80 class VerifyMarkingVisitor: public ObjectVisitor { |
80 public: | 81 public: |
81 void VisitPointers(Object** start, Object** end) { | 82 void VisitPointers(Object** start, Object** end) { |
82 for (Object** current = start; current < end; current++) { | 83 for (Object** current = start; current < end; current++) { |
83 if ((*current)->IsHeapObject()) { | 84 if ((*current)->IsHeapObject()) { |
84 HeapObject* object = HeapObject::cast(*current); | 85 HeapObject* object = HeapObject::cast(*current); |
85 CHECK(HEAP->mark_compact_collector()->IsMarked(object)); | 86 CHECK(HEAP->mark_compact_collector()->IsMarked(object)); |
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
386 | 387 |
387 return compacting_; | 388 return compacting_; |
388 } | 389 } |
389 | 390 |
390 | 391 |
391 void MarkCompactCollector::CollectGarbage() { | 392 void MarkCompactCollector::CollectGarbage() { |
392 // Make sure that Prepare() has been called. The individual steps below will | 393 // Make sure that Prepare() has been called. The individual steps below will |
393 // update the state as they proceed. | 394 // update the state as they proceed. |
394 ASSERT(state_ == PREPARE_GC); | 395 ASSERT(state_ == PREPARE_GC); |
395 ASSERT(encountered_weak_maps_ == Smi::FromInt(0)); | 396 ASSERT(encountered_weak_maps_ == Smi::FromInt(0)); |
| 397 ASSERT(encountered_array_buffers_ == Smi::FromInt(0)); |
396 | 398 |
397 MarkLiveObjects(); | 399 MarkLiveObjects(); |
398 ASSERT(heap_->incremental_marking()->IsStopped()); | 400 ASSERT(heap_->incremental_marking()->IsStopped()); |
399 | 401 |
400 if (FLAG_collect_maps) ClearNonLiveReferences(); | 402 if (FLAG_collect_maps) ClearNonLiveReferences(); |
401 | 403 |
402 ClearWeakMaps(); | 404 ClearWeakMaps(); |
403 | 405 |
404 #ifdef VERIFY_HEAP | 406 #ifdef VERIFY_HEAP |
405 if (FLAG_verify_heap) { | 407 if (FLAG_verify_heap) { |
(...skipping 1872 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2278 string_table->IterateElements(&v); | 2280 string_table->IterateElements(&v); |
2279 string_table->ElementsRemoved(v.PointersRemoved()); | 2281 string_table->ElementsRemoved(v.PointersRemoved()); |
2280 heap()->external_string_table_.Iterate(&v); | 2282 heap()->external_string_table_.Iterate(&v); |
2281 heap()->external_string_table_.CleanUp(); | 2283 heap()->external_string_table_.CleanUp(); |
2282 heap()->error_object_list_.RemoveUnmarked(heap()); | 2284 heap()->error_object_list_.RemoveUnmarked(heap()); |
2283 | 2285 |
2284 // Process the weak references. | 2286 // Process the weak references. |
2285 MarkCompactWeakObjectRetainer mark_compact_object_retainer; | 2287 MarkCompactWeakObjectRetainer mark_compact_object_retainer; |
2286 heap()->ProcessWeakReferences(&mark_compact_object_retainer); | 2288 heap()->ProcessWeakReferences(&mark_compact_object_retainer); |
2287 | 2289 |
| 2290 // Update references from array buffers to typed arrays. |
| 2291 ProcessArrayBuffers(); |
| 2292 |
2288 // Remove object groups after marking phase. | 2293 // Remove object groups after marking phase. |
2289 heap()->isolate()->global_handles()->RemoveObjectGroups(); | 2294 heap()->isolate()->global_handles()->RemoveObjectGroups(); |
2290 heap()->isolate()->global_handles()->RemoveImplicitRefGroups(); | 2295 heap()->isolate()->global_handles()->RemoveImplicitRefGroups(); |
2291 | 2296 |
2292 // Flush code from collected candidates. | 2297 // Flush code from collected candidates. |
2293 if (is_code_flushing_enabled()) { | 2298 if (is_code_flushing_enabled()) { |
2294 code_flusher_->ProcessCandidates(); | 2299 code_flusher_->ProcessCandidates(); |
2295 // If incremental marker does not support code flushing, we need to | 2300 // If incremental marker does not support code flushing, we need to |
2296 // disable it before incremental marking steps for next cycle. | 2301 // disable it before incremental marking steps for next cycle. |
2297 if (FLAG_flush_code && !FLAG_flush_code_incrementally) { | 2302 if (FLAG_flush_code && !FLAG_flush_code_incrementally) { |
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2564 table->RemoveEntry(i); | 2569 table->RemoveEntry(i); |
2565 } | 2570 } |
2566 } | 2571 } |
2567 weak_map_obj = weak_map->next(); | 2572 weak_map_obj = weak_map->next(); |
2568 weak_map->set_next(Smi::FromInt(0)); | 2573 weak_map->set_next(Smi::FromInt(0)); |
2569 } | 2574 } |
2570 set_encountered_weak_maps(Smi::FromInt(0)); | 2575 set_encountered_weak_maps(Smi::FromInt(0)); |
2571 } | 2576 } |
2572 | 2577 |
2573 | 2578 |
| 2579 void MarkCompactCollector::ProcessArrayBuffers() { |
| 2580 Object* array_buffer_obj = encountered_array_buffers(); |
| 2581 set_encountered_array_buffers(Smi::FromInt(0)); |
| 2582 while (array_buffer_obj != Smi::FromInt(0)) { |
| 2583 ASSERT(IsMarked(HeapObject::cast(array_buffer_obj))); |
| 2584 JSArrayBuffer* array_buffer = |
| 2585 reinterpret_cast<JSArrayBuffer*>(array_buffer_obj); |
| 2586 Object** slot = HeapObject::RawField(array_buffer, JSArrayBuffer::kFirstArra
yOffset); |
| 2587 while (*slot != Smi::FromInt(0)) { |
| 2588 Object* next_obj = *slot; |
| 2589 while (next_obj != Smi::FromInt(0) && !IsMarked(next_obj)) { |
| 2590 next_obj = JSTypedArray::cast(next_obj)->next(); |
| 2591 } |
| 2592 if (next_obj == Smi::FromInt(0)) { |
| 2593 *slot = Smi::FromInt(0); |
| 2594 break; |
| 2595 } |
| 2596 JSTypedArray* next_typed_array = JSTypedArray::cast(next_obj); |
| 2597 *slot = next_obj; |
| 2598 RecordSlot(slot, slot, next_typed_array); |
| 2599 slot = HeapObject::RawField(next_typed_array, JSTypedArray::kNextOffset); |
| 2600 } |
| 2601 |
| 2602 array_buffer_obj = array_buffer->next(); |
| 2603 array_buffer->set_next(Smi::FromInt(0)); |
| 2604 } |
| 2605 } |
| 2606 |
| 2607 |
| 2608 void MarkCompactCollector::ClearArrayBuffersOnAbort() { |
| 2609 Object* array_buffer_obj = encountered_array_buffers(); |
| 2610 set_encountered_array_buffers(Smi::FromInt(0)); |
| 2611 while (array_buffer_obj != Smi::FromInt(0)) { |
| 2612 JSArrayBuffer* array_buffer = JSArrayBuffer::cast(array_buffer_obj); |
| 2613 array_buffer_obj = array_buffer->next(); |
| 2614 array_buffer->set_next(Smi::FromInt(0)); |
| 2615 } |
| 2616 } |
2574 // We scavange new space simultaneously with sweeping. This is done in two | 2617 // We scavange new space simultaneously with sweeping. This is done in two |
2575 // passes. | 2618 // passes. |
2576 // | 2619 // |
2577 // The first pass migrates all alive objects from one semispace to another or | 2620 // The first pass migrates all alive objects from one semispace to another or |
2578 // promotes them to old space. Forwarding address is written directly into | 2621 // promotes them to old space. Forwarding address is written directly into |
2579 // first word of object without any encoding. If object is dead we write | 2622 // first word of object without any encoding. If object is dead we write |
2580 // NULL as a forwarding address. | 2623 // NULL as a forwarding address. |
2581 // | 2624 // |
2582 // The second pass updates pointers to new space in all spaces. It is possible | 2625 // The second pass updates pointers to new space in all spaces. It is possible |
2583 // to encounter pointers to dead new space objects during traversal of pointers | 2626 // to encounter pointers to dead new space objects during traversal of pointers |
(...skipping 1659 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4243 while (buffer != NULL) { | 4286 while (buffer != NULL) { |
4244 SlotsBuffer* next_buffer = buffer->next(); | 4287 SlotsBuffer* next_buffer = buffer->next(); |
4245 DeallocateBuffer(buffer); | 4288 DeallocateBuffer(buffer); |
4246 buffer = next_buffer; | 4289 buffer = next_buffer; |
4247 } | 4290 } |
4248 *buffer_address = NULL; | 4291 *buffer_address = NULL; |
4249 } | 4292 } |
4250 | 4293 |
4251 | 4294 |
4252 } } // namespace v8::internal | 4295 } } // namespace v8::internal |
OLD | NEW |