Let store buffer start out small for a 1Mbyte saving in boot

memory use (2Mbyte on x64).
Review URL: http://codereview.chromium.org/8776032

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@10143 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
erik.corry@gmail.com 2011-12-02 14:08:12 +00:00
parent c0e7884752
commit 0d7380da55
7 changed files with 57 additions and 18 deletions

View File

@ -1012,7 +1012,7 @@ void StoreBufferRebuilder::Callback(MemoryChunk* page, StoreBufferEvent event) {
// Store Buffer overflowed while scanning promoted objects. These are not // Store Buffer overflowed while scanning promoted objects. These are not
// in any particular page, though they are likely to be clustered by the // in any particular page, though they are likely to be clustered by the
// allocation routines. // allocation routines.
store_buffer_->HandleFullness(); store_buffer_->EnsureSpace(StoreBuffer::kStoreBufferSize);
} else { } else {
// Store Buffer overflowed while scanning a particular old space page for // Store Buffer overflowed while scanning a particular old space page for
// pointers to new space. // pointers to new space.

View File

@ -70,6 +70,11 @@ intptr_t OS::MaxVirtualMemory() {
} }
intptr_t OS::CommitPageSize() {
return 4096;
}
#ifndef __CYGWIN__ #ifndef __CYGWIN__
// Get rid of writable permission on code allocations. // Get rid of writable permission on code allocations.
void OS::ProtectCode(void* address, const size_t size) { void OS::ProtectCode(void* address, const size_t size) {

View File

@ -889,6 +889,11 @@ void OS::Free(void* address, const size_t size) {
} }
intptr_t OS::CommitPageSize() {
return 4096;
}
void OS::ProtectCode(void* address, const size_t size) { void OS::ProtectCode(void* address, const size_t size) {
DWORD old_protect; DWORD old_protect;
VirtualProtect(address, size, PAGE_EXECUTE_READ, &old_protect); VirtualProtect(address, size, PAGE_EXECUTE_READ, &old_protect);

View File

@ -172,6 +172,10 @@ class OS {
bool is_executable); bool is_executable);
static void Free(void* address, const size_t size); static void Free(void* address, const size_t size);
// This is the granularity at which the ProtectCode(...) call can set page
// permissions.
static intptr_t CommitPageSize();
// Mark code segments non-writable. // Mark code segments non-writable.
static void ProtectCode(void* address, const size_t size); static void ProtectCode(void* address, const size_t size);

View File

@ -41,6 +41,7 @@ StoreBuffer::StoreBuffer(Heap* heap)
old_start_(NULL), old_start_(NULL),
old_limit_(NULL), old_limit_(NULL),
old_top_(NULL), old_top_(NULL),
old_reserved_limit_(NULL),
old_buffer_is_sorted_(false), old_buffer_is_sorted_(false),
old_buffer_is_filtered_(false), old_buffer_is_filtered_(false),
during_gc_(false), during_gc_(false),
@ -59,10 +60,25 @@ void StoreBuffer::Setup() {
reinterpret_cast<uintptr_t>(virtual_memory_->address()); reinterpret_cast<uintptr_t>(virtual_memory_->address());
start_ = start_ =
reinterpret_cast<Address*>(RoundUp(start_as_int, kStoreBufferSize * 2)); reinterpret_cast<Address*>(RoundUp(start_as_int, kStoreBufferSize * 2));
limit_ = start_ + (kStoreBufferSize / sizeof(*start_)); limit_ = start_ + (kStoreBufferSize / kPointerSize);
old_top_ = old_start_ = new Address[kOldStoreBufferLength]; old_virtual_memory_ =
old_limit_ = old_start_ + kOldStoreBufferLength; new VirtualMemory(kOldStoreBufferLength * kPointerSize);
old_top_ = old_start_ =
reinterpret_cast<Address*>(old_virtual_memory_->address());
// Don't know the alignment requirements of the OS, but it is certainly not
// less than 0xfff.
ASSERT((reinterpret_cast<uintptr_t>(old_start_) & 0xfff) == 0);
int initial_length = OS::CommitPageSize() / kPointerSize;
ASSERT(initial_length > 0);
ASSERT(initial_length <= kOldStoreBufferLength);
old_limit_ = old_start_ + initial_length;
old_reserved_limit_ = old_start_ + kOldStoreBufferLength;
CHECK(old_virtual_memory_->Commit(
reinterpret_cast<void*>(old_start_),
(old_limit_ - old_start_) * kPointerSize,
false));
ASSERT(reinterpret_cast<Address>(start_) >= virtual_memory_->address()); ASSERT(reinterpret_cast<Address>(start_) >= virtual_memory_->address());
ASSERT(reinterpret_cast<Address>(limit_) >= virtual_memory_->address()); ASSERT(reinterpret_cast<Address>(limit_) >= virtual_memory_->address());
@ -76,9 +92,9 @@ void StoreBuffer::Setup() {
ASSERT((reinterpret_cast<uintptr_t>(limit_ - 1) & kStoreBufferOverflowBit) == ASSERT((reinterpret_cast<uintptr_t>(limit_ - 1) & kStoreBufferOverflowBit) ==
0); 0);
virtual_memory_->Commit(reinterpret_cast<Address>(start_), CHECK(virtual_memory_->Commit(reinterpret_cast<Address>(start_),
kStoreBufferSize, kStoreBufferSize,
false); // Not executable. false)); // Not executable.
heap_->public_set_store_buffer_top(start_); heap_->public_set_store_buffer_top(start_);
hash_map_1_ = new uintptr_t[kHashMapLength]; hash_map_1_ = new uintptr_t[kHashMapLength];
@ -90,10 +106,10 @@ void StoreBuffer::Setup() {
void StoreBuffer::TearDown() { void StoreBuffer::TearDown() {
delete virtual_memory_; delete virtual_memory_;
delete old_virtual_memory_;
delete[] hash_map_1_; delete[] hash_map_1_;
delete[] hash_map_2_; delete[] hash_map_2_;
delete[] old_start_; old_start_ = old_top_ = old_limit_ = old_reserved_limit_ = NULL;
old_start_ = old_top_ = old_limit_ = NULL;
start_ = limit_ = NULL; start_ = limit_ = NULL;
heap_->public_set_store_buffer_top(start_); heap_->public_set_store_buffer_top(start_);
} }
@ -150,7 +166,18 @@ void StoreBuffer::Uniq() {
} }
void StoreBuffer::HandleFullness() { void StoreBuffer::EnsureSpace(intptr_t space_needed) {
while (old_limit_ - old_top_ < space_needed &&
old_limit_ < old_reserved_limit_) {
size_t grow = old_limit_ - old_start_; // Double size.
CHECK(old_virtual_memory_->Commit(reinterpret_cast<void*>(old_limit_),
grow * kPointerSize,
false));
old_limit_ += grow;
}
if (old_limit_ - old_top_ >= space_needed) return;
if (old_buffer_is_filtered_) return; if (old_buffer_is_filtered_) return;
ASSERT(may_move_store_buffer_entries_); ASSERT(may_move_store_buffer_entries_);
Compact(); Compact();
@ -645,9 +672,7 @@ void StoreBuffer::Compact() {
// the worst case (compaction doesn't eliminate any pointers). // the worst case (compaction doesn't eliminate any pointers).
ASSERT(top <= limit_); ASSERT(top <= limit_);
heap_->public_set_store_buffer_top(start_); heap_->public_set_store_buffer_top(start_);
if (top - start_ > old_limit_ - old_top_) { EnsureSpace(top - start_);
HandleFullness();
}
ASSERT(may_move_store_buffer_entries_); ASSERT(may_move_store_buffer_entries_);
// Goes through the addresses in the store buffer attempting to remove // Goes through the addresses in the store buffer attempting to remove
// duplicates. In the interest of speed this is a lossy operation. Some // duplicates. In the interest of speed this is a lossy operation. Some
@ -688,9 +713,7 @@ void StoreBuffer::Compact() {
void StoreBuffer::CheckForFullBuffer() { void StoreBuffer::CheckForFullBuffer() {
if (old_limit_ - old_top_ < kStoreBufferSize * 2) { EnsureSpace(kStoreBufferSize * 2);
HandleFullness();
}
} }
} } // namespace v8::internal } } // namespace v8::internal

View File

@ -109,7 +109,7 @@ class StoreBuffer {
// been promoted. Rebuilds the store buffer completely if it overflowed. // been promoted. Rebuilds the store buffer completely if it overflowed.
void SortUniq(); void SortUniq();
void HandleFullness(); void EnsureSpace(intptr_t space_needed);
void Verify(); void Verify();
bool PrepareForIteration(); bool PrepareForIteration();
@ -134,6 +134,8 @@ class StoreBuffer {
Address* old_start_; Address* old_start_;
Address* old_limit_; Address* old_limit_;
Address* old_top_; Address* old_top_;
Address* old_reserved_limit_;
VirtualMemory* old_virtual_memory_;
bool old_buffer_is_sorted_; bool old_buffer_is_sorted_;
bool old_buffer_is_filtered_; bool old_buffer_is_filtered_;

View File

@ -528,7 +528,7 @@ TEST(BootUpMemoryUse) {
if (initial_memory >= 0) { if (initial_memory >= 0) {
InitializeVM(); InitializeVM();
intptr_t booted_memory = MemoryInUse(); intptr_t booted_memory = MemoryInUse();
CHECK_LE(booted_memory - initial_memory, 20 * 1024 * 1024); CHECK_LE(booted_memory - initial_memory, 18 * 1024 * 1024);
} }
} }