| Index: src/heap/heap.cc
|
| diff --git a/src/heap/heap.cc b/src/heap/heap.cc
|
| index 010b3726dfc01d949c0e47b9c0edd0f8dce4d3f0..e0dd8b63b2dd0ea3f073aff50f896110d7fcae9c 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(true);
|
| }
|
|
|
| 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;
|
| }
|
|
|