Chromium Code Reviews| Index: src/heap/heap.cc |
| diff --git a/src/heap/heap.cc b/src/heap/heap.cc |
| index 010b3726dfc01d949c0e47b9c0edd0f8dce4d3f0..d1607ec117ad17a8a32a0cad63f132853c026f88 100644 |
| --- a/src/heap/heap.cc |
| +++ b/src/heap/heap.cc |
| @@ -143,7 +143,9 @@ Heap::Heap() |
| chunks_queued_for_free_(NULL), |
| gc_callbacks_depth_(0), |
| deserialization_complete_(false), |
| - concurrent_sweeping_enabled_(false) { |
| + concurrent_sweeping_enabled_(false), |
| + migration_failure_(false), |
| + previous_migration_failure_(false) { |
| // Allow build-time customization of the max semispace size. Building |
| // V8 with snapshots and a non-default max semispace size is much |
| // easier if you can define it as part of the build environment. |
| @@ -737,6 +739,13 @@ void Heap::GarbageCollectionEpilogue() { |
| // Remember the last top pointer so that we can later find out |
| // whether we allocated in new space since the last GC. |
| new_space_top_after_last_gc_ = new_space()->top(); |
| + |
| + if (migration_failure_) { |
| + set_previous_migration_failure(true); |
| + } else { |
| + set_previous_migration_failure(false); |
| + } |
| + set_migration_failure(false); |
| } |
| @@ -1738,29 +1747,63 @@ void Heap::UpdateReferencesInExternalStringTable( |
| void Heap::ProcessAllWeakReferences(WeakObjectRetainer* retainer) { |
| - ProcessArrayBuffers(retainer); |
| + ProcessArrayBuffers(retainer, false); |
| + ProcessNewArrayBufferViews(retainer); |
| ProcessNativeContexts(retainer); |
| ProcessAllocationSites(retainer); |
| } |
| void Heap::ProcessYoungWeakReferences(WeakObjectRetainer* retainer) { |
| - ProcessArrayBuffers(retainer); |
| + ProcessArrayBuffers(retainer, true); |
| + ProcessNewArrayBufferViews(retainer); |
| ProcessNativeContexts(retainer); |
| } |
| void Heap::ProcessNativeContexts(WeakObjectRetainer* retainer) { |
| - Object* head = VisitWeakList<Context>(this, native_contexts_list(), retainer); |
| + Object* head = |
| + VisitWeakList<Context>(this, native_contexts_list(), retainer, false); |
| // Update the head of the list of contexts. |
| set_native_contexts_list(head); |
| } |
| -void Heap::ProcessArrayBuffers(WeakObjectRetainer* retainer) { |
| - Object* array_buffer_obj = |
| - VisitWeakList<JSArrayBuffer>(this, array_buffers_list(), retainer); |
| +void Heap::ProcessArrayBuffers(WeakObjectRetainer* retainer, |
| + bool stop_after_young) { |
| + Object* array_buffer_obj = VisitWeakList<JSArrayBuffer>( |
| + this, array_buffers_list(), retainer, stop_after_young); |
| set_array_buffers_list(array_buffer_obj); |
| + |
| +#ifdef DEBUG |
| + // Verify invariant that young array buffers come before old array buffers |
| + // in array buffers list if there was no promotion failure. |
| + Object* undefined = undefined_value(); |
| + Object* next = array_buffers_list(); |
| + bool old_objects_recorded = false; |
| + if (migration_failure()) return; |
| + while (next != undefined) { |
| + if (!old_objects_recorded) { |
| + old_objects_recorded = !InNewSpace(next); |
| + } |
| + DCHECK((InNewSpace(next) && !old_objects_recorded) || !InNewSpace(next)); |
| + next = JSArrayBuffer::cast(next)->weak_next(); |
| + } |
| +#endif |
| +} |
| + |
| + |
| +void Heap::ProcessNewArrayBufferViews(WeakObjectRetainer* retainer) { |
| + // Retain the list of new space views. |
| + Object* typed_array_obj = VisitWeakList<JSArrayBufferView>( |
| + this, new_array_buffer_views_list_, retainer, false); |
| + set_new_array_buffer_views_list(typed_array_obj); |
| + |
| + // Some objects in the list may be in old space now. Find them |
| + // and move them to the corresponding array buffer. |
| + Object* view = VisitNewArrayBufferViewsWeakList( |
| + this, new_array_buffer_views_list_, retainer); |
| + set_new_array_buffer_views_list(view); |
| } |
| @@ -1776,8 +1819,8 @@ void Heap::TearDownArrayBuffers() { |
| void Heap::ProcessAllocationSites(WeakObjectRetainer* retainer) { |
| - Object* allocation_site_obj = |
| - VisitWeakList<AllocationSite>(this, allocation_sites_list(), retainer); |
| + Object* allocation_site_obj = VisitWeakList<AllocationSite>( |
| + this, allocation_sites_list(), retainer, false); |
| set_allocation_sites_list(allocation_site_obj); |
| } |
| @@ -2189,6 +2232,7 @@ class ScavengingVisitor : public StaticVisitorBase { |
| if (SemiSpaceCopyObject<alignment>(map, slot, object, object_size)) { |
| return; |
| } |
| + heap->set_migration_failure(false); |
|
ulan
2015/03/10 14:56:14
Where is migration_failure set to true?
Hannes Payer (out of office)
2015/03/10 15:12:24
here. that was a manual merge conflict error.
|
| } |
| if (PromoteObject<object_contents, alignment>(map, slot, object, |
| @@ -5542,6 +5586,7 @@ bool Heap::CreateHeapObjects() { |
| set_native_contexts_list(undefined_value()); |
| set_array_buffers_list(undefined_value()); |
| + set_new_array_buffer_views_list(undefined_value()); |
| set_allocation_sites_list(undefined_value()); |
| return true; |
| } |