Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(379)

Unified Diff: src/heap/spaces.cc

Issue 2032393002: [heap] Uncommit unused large object page memory. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/heap/spaces.cc
diff --git a/src/heap/spaces.cc b/src/heap/spaces.cc
index 332d59114b2c601b2a27ae1ac21eb8557d3ac00c..fef1bb8e64d50dbc1ef7c9b0077b429cd2577299 100644
--- a/src/heap/spaces.cc
+++ b/src/heap/spaces.cc
@@ -419,6 +419,18 @@ void MemoryAllocator::FreeMemory(base::VirtualMemory* reservation,
reservation->Release();
}
+void MemoryAllocator::PartialFreeMemory(base::VirtualMemory* reservation,
+ Executability executable,
ulan 2016/06/06 13:44:22 Maybe completely disallow the function for executa
Hannes Payer (out of office) 2016/06/06 14:42:44 I added checks to the lower level functions.
+ Address free_start, size_t size) {
+ // TODO(gc) make code_range part of memory allocator?
+ // Code which is part of the code-range does not have its own VirtualMemory.
+ DCHECK(code_range() == NULL ||
+ !code_range()->contains(static_cast<Address>(reservation->address())));
+ DCHECK(executable == NOT_EXECUTABLE || !code_range()->valid() ||
+ reservation->size() <= Page::kPageSize);
+
+ reservation->ReleasePartial(free_start, size);
+}
void MemoryAllocator::FreeMemory(Address base, size_t size,
Executability executable) {
@@ -584,6 +596,11 @@ bool MemoryChunk::CommitArea(size_t requested) {
return true;
}
+size_t MemoryChunk::CommittedPhysicalMemory() {
+ if (!base::VirtualMemory::HasLazyCommits() || owner()->identity() == LO_SPACE)
+ return size();
+ return high_water_mark_.Value();
+}
void MemoryChunk::InsertAfter(MemoryChunk* other) {
MemoryChunk* other_next = other->next_chunk();
@@ -751,6 +768,37 @@ void Page::ResetFreeListStatistics() {
available_in_free_list_ = 0;
}
+void MemoryAllocator::PartialFreeMemory(MemoryChunk* chunk,
+ Address start_free) {
+ intptr_t size;
+ base::VirtualMemory* reservation = chunk->reserved_memory();
+ if (reservation->IsReserved()) {
+ size = static_cast<intptr_t>(reservation->size());
+ } else {
+ size = static_cast<intptr_t>(chunk->size());
+ }
+
+ size_t to_free_size = size - (start_free - chunk->address());
+
+ DCHECK(size_.Value() >= static_cast<intptr_t>(to_free_size));
+ size_.Increment(-static_cast<intptr_t>(to_free_size));
+ isolate_->counters()->memory_allocated()->Decrement(
+ static_cast<int>(to_free_size));
+ chunk->set_size(size - to_free_size);
+
+ if (chunk->executable() == EXECUTABLE) {
+ DCHECK(size_executable_.Value() >= static_cast<intptr_t>(to_free_size));
+ size_executable_.Increment(-static_cast<intptr_t>(to_free_size));
+ }
+
+ if (reservation->IsReserved()) {
+ PartialFreeMemory(reservation, chunk->executable(), start_free,
+ to_free_size);
+ } else {
+ FreeMemory(start_free, to_free_size, chunk->executable());
+ }
+}
+
void MemoryAllocator::PreFreeMemory(MemoryChunk* chunk) {
DCHECK(!chunk->IsFlagSet(MemoryChunk::PRE_FREED));
LOG(isolate_, DeleteEvent("MemoryChunk", chunk));
@@ -2884,6 +2932,19 @@ void PagedSpace::ResetCodeAndMetadataStatistics(Isolate* isolate) {
void MapSpace::VerifyObject(HeapObject* object) { CHECK(object->IsMap()); }
#endif
+Address LargePage::GetAddressToShrink() {
+ HeapObject* object = GetObject();
+ CodeRange* code_range = heap()->memory_allocator()->code_range();
+ if (code_range != NULL && code_range->contains(object->address())) {
+ return 0;
+ }
+ size_t used_size = RoundUp((object->address() - address()) + object->Size(),
+ base::OS::CommitPageSize());
+ if (used_size < CommittedPhysicalMemory()) {
+ return address() + used_size;
+ }
+ return 0;
+}
// -----------------------------------------------------------------------------
// LargeObjectIterator
@@ -3034,7 +3095,6 @@ void LargeObjectSpace::ClearMarkingStateOfLiveObjects() {
}
}
-
void LargeObjectSpace::FreeUnmarkedObjects() {
LargePage* previous = NULL;
LargePage* current = first_page_;
@@ -3043,6 +3103,11 @@ void LargeObjectSpace::FreeUnmarkedObjects() {
MarkBit mark_bit = Marking::MarkBitFrom(object);
DCHECK(!Marking::IsGrey(mark_bit));
if (Marking::IsBlack(mark_bit)) {
+ Address free_start;
+ if ((free_start = current->GetAddressToShrink()) != 0) {
+ // TODO(hpayer): Perform partial free concurrently.
+ heap()->memory_allocator()->PartialFreeMemory(current, free_start);
+ }
previous = current;
current = current->next_page();
} else {

Powered by Google App Engine
This is Rietveld 408576698