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

Unified Diff: runtime/vm/pages.cc

Issue 511963007: Pretenure some strings into bump-allocated block (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 4 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
« runtime/vm/freelist.cc ('K') | « runtime/vm/pages.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/pages.cc
===================================================================
--- runtime/vm/pages.cc (revision 39651)
+++ runtime/vm/pages.cc (working copy)
@@ -35,6 +35,7 @@
"Always try to drop code if the function's usage counter is >= 0");
DEFINE_FLAG(bool, concurrent_sweep, false,
"Concurrent sweep for old generation.");
+DEFINE_FLAG(bool, log_growth, false, "Log PageSpace growth policy decisions.");
HeapPage* HeapPage::Initialize(VirtualMemory* memory, PageType type) {
ASSERT(memory->size() > VirtualMemory::PageSize());
@@ -129,6 +130,8 @@
exec_pages_(NULL),
exec_pages_tail_(NULL),
large_pages_(NULL),
+ bump_top_(0),
+ bump_end_(0),
max_capacity_in_words_(max_capacity_in_words),
tasks_lock_(new Monitor()),
tasks_(0),
@@ -281,6 +284,39 @@
}
+uword PageSpace::TryAllocateInNewPage(intptr_t size,
Ivan Posva 2014/08/29 00:07:12 TryAllocateInNewPage is a confusing name as it mak
koda 2014/08/29 00:52:20 Done.
+ HeapPage::PageType type,
+ GrowthPolicy growth_policy,
+ bool is_locked) {
+ ASSERT(size < kAllocatablePageSize);
+ uword result = 0;
+ SpaceUsage after_allocation = usage_;
+ after_allocation.used_in_words += size >> kWordSizeLog2;
+ // Can we grow by one page?
+ after_allocation.capacity_in_words += kPageSizeInWords;
+ if ((growth_policy == kForceGrowth ||
+ !page_space_controller_.NeedsGarbageCollection(after_allocation)) &&
+ CanIncreaseCapacityInWords(kPageSizeInWords)) {
+ HeapPage* page = AllocatePage(type);
+ ASSERT(page != NULL);
+ // Start of the newly allocated page is the allocated object.
+ result = page->object_start();
+ usage_ = after_allocation;
+ // Enqueue the remainder in the free list.
+ uword free_start = result + size;
+ intptr_t free_size = page->object_end() - free_start;
+ if (free_size > 0) {
+ if (is_locked) {
+ freelist_[type].FreeLocked(free_start, free_size);
+ } else {
+ freelist_[type].Free(free_start, free_size);
+ }
+ }
+ }
+ return result;
+}
+
+
uword PageSpace::TryAllocateInternal(intptr_t size,
HeapPage::PageType type,
GrowthPolicy growth_policy,
@@ -289,8 +325,6 @@
ASSERT(size >= kObjectAlignment);
ASSERT(Utils::IsAligned(size, kObjectAlignment));
uword result = 0;
- SpaceUsage after_allocation = usage_;
- after_allocation.used_in_words += size >> kWordSizeLog2;
if (size < kAllocatablePageSize) {
if (is_locked) {
result = freelist_[type].TryAllocateLocked(size, is_protected);
@@ -298,26 +332,7 @@
result = freelist_[type].TryAllocate(size, is_protected);
}
if (result == 0) {
- // Can we grow by one page?
- after_allocation.capacity_in_words += kPageSizeInWords;
- if ((!page_space_controller_.NeedsGarbageCollection(after_allocation) ||
- growth_policy == kForceGrowth) &&
- CanIncreaseCapacityInWords(kPageSizeInWords)) {
- HeapPage* page = AllocatePage(type);
- ASSERT(page != NULL);
- // Start of the newly allocated page is the allocated object.
- result = page->object_start();
- // Enqueue the remainder in the free list.
- uword free_start = result + size;
- intptr_t free_size = page->object_end() - free_start;
- if (free_size > 0) {
- if (is_locked) {
- freelist_[type].FreeLocked(free_start, free_size);
- } else {
- freelist_[type].Free(free_start, free_size);
- }
- }
- }
+ result = TryAllocateInNewPage(size, type, growth_policy, is_locked);
}
} else {
// Large page allocation.
@@ -326,18 +341,20 @@
// On overflow we fail to allocate.
return 0;
}
+ SpaceUsage after_allocation = usage_;
+ after_allocation.used_in_words += size >> kWordSizeLog2;
after_allocation.capacity_in_words += page_size_in_words;
- if ((!page_space_controller_.NeedsGarbageCollection(after_allocation) ||
- growth_policy == kForceGrowth) &&
+ if ((growth_policy == kForceGrowth ||
+ !page_space_controller_.NeedsGarbageCollection(after_allocation)) &&
CanIncreaseCapacityInWords(page_size_in_words)) {
HeapPage* page = AllocateLargePage(size, type);
if (page != NULL) {
result = page->object_start();
+ usage_ = after_allocation;
}
}
}
if (result != 0) {
- usage_ = after_allocation;
if (FLAG_compiler_stats && (type == HeapPage::kExecutable)) {
CompilerStats::code_allocated += size;
}
@@ -628,7 +645,8 @@
int64_t mid1 = OS::GetCurrentTimeMicros();
- // Reset the bump allocation page to unused.
+ // Abandon the remainder of the bump allocation block.
+ bump_top_ = bump_end_;
Ivan Posva 2014/08/29 00:07:12 Why not setting these values to 0?
koda 2014/08/29 00:52:20 Done.
// Reset the freelists and setup sweeping.
freelist_[HeapPage::kData].Reset();
freelist_[HeapPage::kExecutable].Reset();
@@ -735,6 +753,42 @@
}
+uword PageSpace::TryAllocateDataBump(intptr_t size,
+ GrowthPolicy growth_policy) {
+ ASSERT(size >= kObjectAlignment);
+ ASSERT(Utils::IsAligned(size, kObjectAlignment));
+ intptr_t remaining = bump_end_ - bump_top_;
+ if (remaining < size) {
+ if (size >= kAllocatablePageSize) {
Ivan Posva 2014/08/29 00:07:12 Please explain in a comment why this is not done a
koda 2014/08/29 00:52:20 Done.
+ return TryAllocate(size, HeapPage::kData, growth_policy);
+ }
+ FreeListElement* block = freelist_[HeapPage::kData].TryAllocateLarge(size);
+ if (block == NULL) {
+ // Allocating from a new page (if growth policy allows) will have the
+ // side-effect of populating the freelist with a large block.
Ivan Posva 2014/08/29 00:07:12 ...with a large block. Next time we request bump a
koda 2014/08/29 00:52:20 Done.
+ // TODO(koda): Could take freelist lock just once instead of twice.
+ return TryAllocateInNewPage(size,
+ HeapPage::kData,
+ growth_policy,
+ /* is_locked = */ false);
+ }
+ intptr_t block_size = block->Size();
+ bump_top_ = reinterpret_cast<uword>(block);
+ bump_end_ = bump_top_ + block_size;
+ remaining = block_size;
+ }
+ ASSERT(remaining >= size);
+ uword result = bump_top_;
+ bump_top_ += size;
+ usage_.used_in_words += size >> kWordSizeLog2;
+ remaining -= size;
+ if (remaining > 0) {
+ FreeListElement::AsElement(bump_top_, remaining);
+ }
+ return result;
+}
+
+
PageSpaceController::PageSpaceController(Heap* heap,
int heap_growth_ratio,
int heap_growth_max,
@@ -780,7 +834,16 @@
multiplier *= seconds_since_init / kInitialTimeoutSeconds;
}
}
- return capacity_increase_in_pages * multiplier > grow_heap_;
+ bool needs_gc = capacity_increase_in_pages * multiplier > grow_heap_;
+ if (FLAG_log_growth) {
+ OS::PrintErr("%s: %" Pd " * %f %s %" Pd "\n",
+ needs_gc ? "NEEDS GC" : "grow",
+ capacity_increase_in_pages,
+ multiplier,
+ needs_gc ? ">" : "<=",
+ grow_heap_);
+ }
+ return needs_gc;
}
« runtime/vm/freelist.cc ('K') | « runtime/vm/pages.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698