From 83f5b8d4cd093df183f3db130651a2db36eb4360 Mon Sep 17 00:00:00 2001 From: Rodrigo Bruno Date: Mon, 2 Jul 2018 10:31:03 +0200 Subject: [PATCH] [heap] Improved spaces verify with fine grained external memory counter checks. Bug: chromium:845409 Change-Id: I422277d565173273e632db07e0e762ee7ae01e87 Reviewed-on: https://chromium-review.googlesource.com/1122116 Reviewed-by: Ulan Degenbaev Commit-Queue: Rodrigo Bruno Cr-Commit-Position: refs/heads/master@{#54129} --- src/heap/spaces.cc | 48 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 40 insertions(+), 8 deletions(-) diff --git a/src/heap/spaces.cc b/src/heap/spaces.cc index ae41a9ed9e..e0dfc38916 100644 --- a/src/heap/spaces.cc +++ b/src/heap/spaces.cc @@ -1899,14 +1899,20 @@ void PagedSpace::Print() {} void PagedSpace::Verify(Isolate* isolate, ObjectVisitor* visitor) { bool allocation_pointer_found_in_space = (allocation_info_.top() == allocation_info_.limit()); - size_t external_backing_store_bytes[kNumTypes]; + size_t external_space_bytes[kNumTypes]; + size_t external_page_bytes[kNumTypes]; for (int i = 0; i < kNumTypes; i++) { - external_backing_store_bytes[static_cast(i)] = 0; + external_space_bytes[static_cast(i)] = 0; } for (Page* page : *this) { CHECK(page->owner() == this); + + for (int i = 0; i < kNumTypes; i++) { + external_page_bytes[static_cast(i)] = 0; + } + if (page == Page::FromAllocationAreaAddress(allocation_info_.top())) { allocation_pointer_found_in_space = true; } @@ -1915,11 +1921,6 @@ void PagedSpace::Verify(Isolate* isolate, ObjectVisitor* visitor) { Address end_of_previous_object = page->area_start(); Address top = page->area_end(); - for (int i = 0; i < kNumTypes; i++) { - ExternalBackingStoreType t = static_cast(i); - external_backing_store_bytes[t] += page->ExternalBackingStoreBytes(t); - } - for (HeapObject* object = it.Next(); object != nullptr; object = it.Next()) { CHECK(end_of_previous_object <= object->address()); @@ -1946,11 +1947,24 @@ void PagedSpace::Verify(Isolate* isolate, ObjectVisitor* visitor) { object->IterateBody(map, size, visitor); CHECK(object->address() + size <= top); end_of_previous_object = object->address() + size; + + if (object->IsJSArrayBuffer()) { + JSArrayBuffer* array_buffer = JSArrayBuffer::cast(object); + if (ArrayBufferTracker::IsTracked(array_buffer)) { + size_t size = NumberToSize(array_buffer->byte_length()); + external_page_bytes[ExternalBackingStoreType::kArrayBuffer] += size; + } + } + } + for (int i = 0; i < kNumTypes; i++) { + ExternalBackingStoreType t = static_cast(i); + CHECK_EQ(external_page_bytes[t], page->ExternalBackingStoreBytes(t)); + external_space_bytes[t] += external_page_bytes[t]; } } for (int i = 0; i < kNumTypes; i++) { ExternalBackingStoreType t = static_cast(i); - CHECK_EQ(external_backing_store_bytes[t], ExternalBackingStoreBytes(t)); + CHECK_EQ(external_space_bytes[t], ExternalBackingStoreBytes(t)); } CHECK(allocation_pointer_found_in_space); #ifdef DEBUG @@ -2386,6 +2400,11 @@ void NewSpace::Verify(Isolate* isolate) { Address current = to_space_.first_page()->area_start(); CHECK_EQ(current, to_space_.space_start()); + size_t external_space_bytes[kNumTypes]; + for (int i = 0; i < kNumTypes; i++) { + external_space_bytes[static_cast(i)] = 0; + } + while (current != top()) { if (!Page::IsAlignedToPageSize(current)) { // The allocation pointer should not be in the middle of an object. @@ -2413,6 +2432,14 @@ void NewSpace::Verify(Isolate* isolate) { int size = object->Size(); object->IterateBody(map, size, &visitor); + if (object->IsJSArrayBuffer()) { + JSArrayBuffer* array_buffer = JSArrayBuffer::cast(object); + if (ArrayBufferTracker::IsTracked(array_buffer)) { + size_t size = NumberToSize(array_buffer->byte_length()); + external_space_bytes[ExternalBackingStoreType::kArrayBuffer] += size; + } + } + current += size; } else { // At end of page, switch to next page. @@ -2421,6 +2448,11 @@ void NewSpace::Verify(Isolate* isolate) { } } + for (int i = 0; i < kNumTypes; i++) { + ExternalBackingStoreType t = static_cast(i); + CHECK_EQ(external_space_bytes[t], ExternalBackingStoreBytes(t)); + } + // Check semi-spaces. CHECK_EQ(from_space_.id(), kFromSpace); CHECK_EQ(to_space_.id(), kToSpace);