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

Unified Diff: runtime/vm/scavenger.cc

Issue 320463003: Make unused semispace available to other isolates. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 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 | « runtime/vm/scavenger.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/scavenger.cc
===================================================================
--- runtime/vm/scavenger.cc (revision 37032)
+++ runtime/vm/scavenger.cc (working copy)
@@ -14,6 +14,7 @@
#include "vm/object.h"
#include "vm/stack_frame.h"
#include "vm/store_buffer.h"
+#include "vm/thread.h"
#include "vm/verifier.h"
#include "vm/visitor.h"
#include "vm/weak_table.h"
@@ -285,7 +286,8 @@
// StoreBuffers.
class VerifyStoreBufferPointerVisitor : public ObjectPointerVisitor {
public:
- VerifyStoreBufferPointerVisitor(Isolate* isolate, MemoryRegion* to)
+ VerifyStoreBufferPointerVisitor(Isolate* isolate,
+ const SemiSpace* to)
: ObjectPointerVisitor(isolate), to_(to) {}
void VisitPointers(RawObject** first, RawObject** last) {
@@ -298,12 +300,87 @@
}
private:
- MemoryRegion* to_;
+ const SemiSpace* to_;
DISALLOW_COPY_AND_ASSIGN(VerifyStoreBufferPointerVisitor);
};
+SemiSpace::SemiSpace(VirtualMemory* reserved)
+ : reserved_(reserved), region_(NULL, 0) {
+ if (reserved != NULL) {
+ region_ = MemoryRegion(reserved_->address(), reserved_->size());
+ }
+}
+
+
+SemiSpace::~SemiSpace() {
+ if (reserved_ != NULL) {
+#if defined(DEBUG)
+ memset(reserved_->address(), 0xf3, size());
+#endif // defined(DEBUG)
+ delete reserved_;
+ }
+}
+
+
+Mutex* SemiSpace::mutex_ = NULL;
+SemiSpace* SemiSpace::cache_ = NULL;
+
+
+void SemiSpace::InitOnce() {
+ ASSERT(mutex_ == NULL);
+ mutex_ = new Mutex();
+ ASSERT(mutex_ != NULL);
+}
+
+
+SemiSpace* SemiSpace::New(intptr_t size) {
+ {
+ MutexLocker locker(mutex_);
+ if (cache_ != NULL && cache_->size() == size) {
+ SemiSpace* result = cache_;
+ cache_ = NULL;
+ return result;
+ }
+ }
+ if (size == 0) {
+ return new SemiSpace(NULL);
+ } else {
+ VirtualMemory* reserved = VirtualMemory::Reserve(size);
+ if ((reserved == NULL) || !reserved->Commit(VirtualMemory::kReadWrite)) {
+ // TODO(koda): If cache_ is not empty, we could try to delete it.
+ delete reserved;
+ return NULL;
+ }
+#if defined(DEBUG)
+ memset(reserved->address(), 0xf3, size);
+#endif // defined(DEBUG)
+ return new SemiSpace(reserved);
+ }
+}
+
+
+void SemiSpace::Delete() {
+ SemiSpace* old_cache = NULL;
+ {
+ MutexLocker locker(mutex_);
+ old_cache = cache_;
+ cache_ = this;
+ }
+ delete old_cache;
+}
+
+
+void SemiSpace::WriteProtect(bool read_only) {
+ if (reserved_ != NULL) {
+ bool success = reserved_->Protect(
+ read_only ? VirtualMemory::kReadOnly : VirtualMemory::kReadWrite);
+ ASSERT(success);
+ }
+}
+
+
Scavenger::Scavenger(Heap* heap,
intptr_t max_capacity_in_words,
uword object_alignment)
@@ -317,50 +394,26 @@
// going to use for forwarding pointers.
ASSERT(Object::tags_offset() == 0);
- if (max_capacity_in_words == 0) {
- space_ = NULL;
- to_ = new MemoryRegion(NULL, 0);
- from_ = new MemoryRegion(NULL, 0);
- } else {
- // Allocate the virtual memory for this scavenge heap.
- space_ = VirtualMemory::Reserve(max_capacity_in_words << kWordSizeLog2);
- if (space_ == NULL) {
- FATAL("Out of memory.\n");
- }
-
- // Allocate the entire space at the beginning.
- space_->Commit(false);
-
- // Setup the semi spaces.
- uword semi_space_size = space_->size() / 2;
- ASSERT((semi_space_size & (VirtualMemory::PageSize() - 1)) == 0);
- to_ = new MemoryRegion(space_->address(), semi_space_size);
- uword middle = space_->start() + semi_space_size;
- from_ = new MemoryRegion(reinterpret_cast<void*>(middle), semi_space_size);
+ const intptr_t semi_space_size = (max_capacity_in_words / 2) * kWordSize;
+ to_ = SemiSpace::New(semi_space_size);
+ if (to_ == NULL) {
+ FATAL("Out of memory.\n");
}
+ from_ = NULL;
- // Make sure that the two semi-spaces are aligned properly.
- ASSERT(Utils::IsAligned(to_->start(), kObjectAlignment));
- ASSERT(Utils::IsAligned(from_->start(), kObjectAlignment));
-
// Setup local fields.
top_ = FirstObjectStart();
resolved_top_ = top_;
end_ = to_->end();
survivor_end_ = FirstObjectStart();
-
-#if defined(DEBUG)
- memset(to_->pointer(), 0xf3, to_->size());
- memset(from_->pointer(), 0xf3, from_->size());
-#endif // defined(DEBUG)
}
Scavenger::~Scavenger() {
- delete to_;
- delete from_;
- delete space_;
+ ASSERT(!scavenging_);
+ ASSERT(from_ == NULL);
+ to_->Delete();
}
@@ -370,9 +423,13 @@
}
// Flip the two semi-spaces so that to_ is always the space for allocating
// objects.
- MemoryRegion* temp = from_;
from_ = to_;
- to_ = temp;
+ to_ = SemiSpace::New(from_->size());
+ if (to_ == NULL) {
+ // TODO(koda): We could try to recover (collect old space, wait for another
+ // isolate to finish scavenge, etc.).
+ FATAL("Out of memory.\n");
+ }
top_ = FirstObjectStart();
resolved_top_ = top_;
end_ = to_->end();
@@ -399,9 +456,9 @@
#if defined(DEBUG)
VerifyStoreBufferPointerVisitor verify_store_buffer_visitor(isolate, to_);
heap_->IterateOldPointers(&verify_store_buffer_visitor);
-
- memset(from_->pointer(), 0xf3, from_->size());
#endif // defined(DEBUG)
+ from_->Delete();
+ from_ = NULL;
if (invoke_api_callbacks && (isolate->gc_epilogue_callback() != NULL)) {
(isolate->gc_epilogue_callback())();
}
@@ -739,10 +796,9 @@
void Scavenger::WriteProtect(bool read_only) {
- if (space_ != NULL) {
- space_->Protect(
- read_only ? VirtualMemory::kReadOnly : VirtualMemory::kReadWrite);
- }
+ ASSERT(!scavenging_);
+ ASSERT(from_ == NULL);
+ to_->WriteProtect(read_only);
}
« no previous file with comments | « runtime/vm/scavenger.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698