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

Unified Diff: src/heap/mark-compact.cc

Issue 1133153003: Never uncommit the whole marking deque in case we can't get it back (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Merge Created 5 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
« no previous file with comments | « src/heap/mark-compact.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/heap/mark-compact.cc
diff --git a/src/heap/mark-compact.cc b/src/heap/mark-compact.cc
index cd268032bfa15db422cf4b44f137a516061e05da..133fb24c40ee0ddbaa6c6661abec96c2680d4e76 100644
--- a/src/heap/mark-compact.cc
+++ b/src/heap/mark-compact.cc
@@ -52,7 +52,7 @@ MarkCompactCollector::MarkCompactCollector(Heap* heap)
migration_slots_buffer_(NULL),
heap_(heap),
marking_deque_memory_(NULL),
- marking_deque_memory_committed_(false),
+ marking_deque_memory_committed_(0),
code_flusher_(NULL),
have_code_to_deoptimize_(false) {
}
@@ -226,7 +226,8 @@ static void VerifyEvacuation(Heap* heap) {
void MarkCompactCollector::SetUp() {
free_list_old_space_.Reset(new FreeList(heap_->old_space()));
- EnsureMarkingDequeIsCommittedAndInitialize(256 * KB);
+ EnsureMarkingDequeIsReserved();
+ EnsureMarkingDequeIsCommitted(kMinMarkingDequeSize);
}
@@ -336,6 +337,7 @@ void MarkCompactCollector::CollectGarbage() {
DCHECK(state_ == PREPARE_GC);
MarkLiveObjects();
+
DCHECK(heap_->incremental_marking()->IsStopped());
// ClearNonLiveReferences can deoptimize code in dependent code arrays.
@@ -2149,41 +2151,46 @@ void MarkCompactCollector::RetainMaps() {
}
-void MarkCompactCollector::EnsureMarkingDequeIsCommittedAndInitialize(
- size_t max_size) {
+void MarkCompactCollector::EnsureMarkingDequeIsReserved() {
+ DCHECK(!marking_deque_.in_use());
+ if (marking_deque_memory_ == NULL) {
+ marking_deque_memory_ = new base::VirtualMemory(kMaxMarkingDequeSize);
+ marking_deque_memory_committed_ = 0;
+ }
+ if (marking_deque_memory_ == NULL) {
+ V8::FatalProcessOutOfMemory("EnsureMarkingDequeIsReserved");
+ }
+}
+
+
+void MarkCompactCollector::EnsureMarkingDequeIsCommitted(size_t max_size) {
// If the marking deque is too small, we try to allocate a bigger one.
// If that fails, make do with a smaller one.
- for (size_t size = max_size; size >= 256 * KB; size >>= 1) {
+ CHECK(!marking_deque_.in_use());
+ for (size_t size = max_size; size >= kMinMarkingDequeSize; size >>= 1) {
base::VirtualMemory* memory = marking_deque_memory_;
- bool is_committed = marking_deque_memory_committed_;
+ size_t currently_committed = marking_deque_memory_committed_;
- if (memory == NULL || memory->size() < size) {
- // If we don't have memory or we only have small memory, then
- // try to reserve a new one.
- memory = new base::VirtualMemory(size);
- is_committed = false;
- }
- if (is_committed) return;
- if (memory->IsReserved() &&
- memory->Commit(reinterpret_cast<Address>(memory->address()),
- memory->size(),
- false)) { // Not executable.
- if (marking_deque_memory_ != NULL && marking_deque_memory_ != memory) {
- delete marking_deque_memory_;
+ if (currently_committed == size) return;
+
+ if (currently_committed > size) {
+ bool success = marking_deque_memory_->Uncommit(
+ reinterpret_cast<Address>(marking_deque_memory_->address()) + size,
+ currently_committed - size);
+ if (success) {
+ marking_deque_memory_committed_ = size;
+ return;
}
- marking_deque_memory_ = memory;
- marking_deque_memory_committed_ = true;
- InitializeMarkingDeque();
+ UNREACHABLE();
+ }
+
+ bool success = memory->Commit(
+ reinterpret_cast<Address>(memory->address()) + currently_committed,
+ size - currently_committed,
+ false); // Not executable.
+ if (success) {
+ marking_deque_memory_committed_ = size;
return;
- } else {
- // Commit failed, so we are under memory pressure. If this was the
- // previously reserved area we tried to commit, then remove references
- // to it before deleting it and unreserving it.
- if (marking_deque_memory_ == memory) {
- marking_deque_memory_ = NULL;
- marking_deque_memory_committed_ = false;
- }
- delete memory; // Will also unreserve the virtual allocation.
}
}
V8::FatalProcessOutOfMemory("EnsureMarkingDequeIsCommitted");
@@ -2191,23 +2198,37 @@ void MarkCompactCollector::EnsureMarkingDequeIsCommittedAndInitialize(
void MarkCompactCollector::InitializeMarkingDeque() {
- if (marking_deque_memory_committed_) {
- Address addr = static_cast<Address>(marking_deque_memory_->address());
- size_t size = marking_deque_memory_->size();
- if (FLAG_force_marking_deque_overflows) size = 64 * kPointerSize;
- marking_deque_.Initialize(addr, addr + size);
- }
+ DCHECK(!marking_deque_.in_use());
+ DCHECK(marking_deque_memory_committed_ > 0);
+ Address addr = static_cast<Address>(marking_deque_memory_->address());
+ size_t size = marking_deque_memory_committed_;
+ if (FLAG_force_marking_deque_overflows) size = 64 * kPointerSize;
+ marking_deque_.Initialize(addr, addr + size);
}
-void MarkCompactCollector::UncommitMarkingDeque() {
- if (marking_deque_memory_committed_) {
- bool success = marking_deque_memory_->Uncommit(
- reinterpret_cast<Address>(marking_deque_memory_->address()),
- marking_deque_memory_->size());
- CHECK(success);
- marking_deque_memory_committed_ = false;
+void MarkingDeque::Initialize(Address low, Address high) {
+ DCHECK(!in_use_);
+ HeapObject** obj_low = reinterpret_cast<HeapObject**>(low);
+ HeapObject** obj_high = reinterpret_cast<HeapObject**>(high);
+ array_ = obj_low;
+ mask_ = base::bits::RoundDownToPowerOfTwo32(
+ static_cast<uint32_t>(obj_high - obj_low)) -
+ 1;
+ top_ = bottom_ = 0;
+ overflowed_ = false;
+ in_use_ = true;
+}
+
+
+void MarkingDeque::Uninitialize(bool aborting) {
+ if (!aborting) {
+ DCHECK(IsEmpty());
+ DCHECK(!overflowed_);
}
+ DCHECK(in_use_);
+ top_ = bottom_ = 0xdecbad;
+ in_use_ = false;
}
@@ -2228,7 +2249,9 @@ void MarkCompactCollector::MarkLiveObjects() {
} else {
// Abort any pending incremental activities e.g. incremental sweeping.
incremental_marking->Abort();
- InitializeMarkingDeque();
+ if (marking_deque_.in_use()) {
+ marking_deque_.Uninitialize(true);
+ }
}
#ifdef DEBUG
@@ -2236,7 +2259,8 @@ void MarkCompactCollector::MarkLiveObjects() {
state_ = MARK_LIVE_OBJECTS;
#endif
- EnsureMarkingDequeIsCommittedAndInitialize();
+ EnsureMarkingDequeIsCommittedAndInitialize(
+ MarkCompactCollector::kMaxMarkingDequeSize);
PrepareForCodeFlushing();
« no previous file with comments | « src/heap/mark-compact.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698