Commit debf58cd authored by hpayer's avatar hpayer Committed by Commit bot

Respect old generation limit in large object space allocations.

Also remove unused max_capcity_ field in old spaces.

BUG=chromium:518028,chromium:504854
LOG=n

Review URL: https://codereview.chromium.org/1284853003

Cr-Commit-Position: refs/heads/master@{#30114}
parent bd873709
...@@ -1069,7 +1069,7 @@ bool Heap::ReserveSpace(Reservation* reservations) { ...@@ -1069,7 +1069,7 @@ bool Heap::ReserveSpace(Reservation* reservations) {
bool perform_gc = false; bool perform_gc = false;
if (space == LO_SPACE) { if (space == LO_SPACE) {
DCHECK_EQ(1, reservation->length()); DCHECK_EQ(1, reservation->length());
perform_gc = !lo_space()->CanAllocateSize(reservation->at(0).size); perform_gc = !CanExpandOldGeneration(reservation->at(0).size);
} else { } else {
for (auto& chunk : *reservation) { for (auto& chunk : *reservation) {
AllocationResult allocation; AllocationResult allocation;
...@@ -5763,8 +5763,7 @@ bool Heap::SetUp() { ...@@ -5763,8 +5763,7 @@ bool Heap::SetUp() {
new_space_top_after_last_gc_ = new_space()->top(); new_space_top_after_last_gc_ = new_space()->top();
// Initialize old space. // Initialize old space.
old_space_ = old_space_ = new OldSpace(this, OLD_SPACE, NOT_EXECUTABLE);
new OldSpace(this, max_old_generation_size_, OLD_SPACE, NOT_EXECUTABLE);
if (old_space_ == NULL) return false; if (old_space_ == NULL) return false;
if (!old_space_->SetUp()) return false; if (!old_space_->SetUp()) return false;
...@@ -5772,20 +5771,19 @@ bool Heap::SetUp() { ...@@ -5772,20 +5771,19 @@ bool Heap::SetUp() {
// Initialize the code space, set its maximum capacity to the old // Initialize the code space, set its maximum capacity to the old
// generation size. It needs executable memory. // generation size. It needs executable memory.
code_space_ = code_space_ = new OldSpace(this, CODE_SPACE, EXECUTABLE);
new OldSpace(this, max_old_generation_size_, CODE_SPACE, EXECUTABLE);
if (code_space_ == NULL) return false; if (code_space_ == NULL) return false;
if (!code_space_->SetUp()) return false; if (!code_space_->SetUp()) return false;
// Initialize map space. // Initialize map space.
map_space_ = new MapSpace(this, max_old_generation_size_, MAP_SPACE); map_space_ = new MapSpace(this, MAP_SPACE);
if (map_space_ == NULL) return false; if (map_space_ == NULL) return false;
if (!map_space_->SetUp()) return false; if (!map_space_->SetUp()) return false;
// The large object code space may contain code or data. We set the memory // The large object code space may contain code or data. We set the memory
// to be non-executable here for safety, but this means we need to enable it // to be non-executable here for safety, but this means we need to enable it
// explicitly when allocating large code objects. // explicitly when allocating large code objects.
lo_space_ = new LargeObjectSpace(this, max_old_generation_size_, LO_SPACE); lo_space_ = new LargeObjectSpace(this, LO_SPACE);
if (lo_space_ == NULL) return false; if (lo_space_ == NULL) return false;
if (!lo_space_->SetUp()) return false; if (!lo_space_->SetUp()) return false;
......
...@@ -931,7 +931,7 @@ STATIC_ASSERT(static_cast<ObjectSpace>(1 << AllocationSpace::MAP_SPACE) == ...@@ -931,7 +931,7 @@ STATIC_ASSERT(static_cast<ObjectSpace>(1 << AllocationSpace::MAP_SPACE) ==
ObjectSpace::kObjectSpaceMapSpace); ObjectSpace::kObjectSpaceMapSpace);
PagedSpace::PagedSpace(Heap* heap, intptr_t max_capacity, AllocationSpace space, PagedSpace::PagedSpace(Heap* heap, AllocationSpace space,
Executability executable) Executability executable)
: Space(heap, space, executable), : Space(heap, space, executable),
free_list_(this), free_list_(this),
...@@ -939,8 +939,6 @@ PagedSpace::PagedSpace(Heap* heap, intptr_t max_capacity, AllocationSpace space, ...@@ -939,8 +939,6 @@ PagedSpace::PagedSpace(Heap* heap, intptr_t max_capacity, AllocationSpace space,
end_of_unswept_pages_(NULL), end_of_unswept_pages_(NULL),
emergency_memory_(NULL) { emergency_memory_(NULL) {
area_size_ = MemoryAllocator::PageAreaSize(space); area_size_ = MemoryAllocator::PageAreaSize(space);
max_capacity_ =
(RoundDown(max_capacity, Page::kPageSize) / Page::kPageSize) * AreaSize();
accounting_stats_.Clear(); accounting_stats_.Clear();
allocation_info_.set_top(NULL); allocation_info_.set_top(NULL);
...@@ -1009,7 +1007,6 @@ Object* PagedSpace::FindObject(Address addr) { ...@@ -1009,7 +1007,6 @@ Object* PagedSpace::FindObject(Address addr) {
bool PagedSpace::CanExpand() { bool PagedSpace::CanExpand() {
DCHECK(max_capacity_ % AreaSize() == 0);
DCHECK(heap()->mark_compact_collector()->is_compacting() || DCHECK(heap()->mark_compact_collector()->is_compacting() ||
Capacity() <= heap()->MaxOldGenerationSize()); Capacity() <= heap()->MaxOldGenerationSize());
DCHECK(heap()->CommittedOldGenerationMemory() <= DCHECK(heap()->CommittedOldGenerationMemory() <=
...@@ -2808,10 +2805,8 @@ HeapObject* LargeObjectIterator::Next() { ...@@ -2808,10 +2805,8 @@ HeapObject* LargeObjectIterator::Next() {
static bool ComparePointers(void* key1, void* key2) { return key1 == key2; } static bool ComparePointers(void* key1, void* key2) { return key1 == key2; }
LargeObjectSpace::LargeObjectSpace(Heap* heap, intptr_t max_capacity, LargeObjectSpace::LargeObjectSpace(Heap* heap, AllocationSpace id)
AllocationSpace id)
: Space(heap, id, NOT_EXECUTABLE), // Managed on a per-allocation basis : Space(heap, id, NOT_EXECUTABLE), // Managed on a per-allocation basis
max_capacity_(max_capacity),
first_page_(NULL), first_page_(NULL),
size_(0), size_(0),
page_count_(0), page_count_(0),
...@@ -2850,12 +2845,10 @@ AllocationResult LargeObjectSpace::AllocateRaw(int object_size, ...@@ -2850,12 +2845,10 @@ AllocationResult LargeObjectSpace::AllocateRaw(int object_size,
// Check if we want to force a GC before growing the old space further. // Check if we want to force a GC before growing the old space further.
// If so, fail the allocation. // If so, fail the allocation.
if (!heap()->always_allocate() && if (!heap()->always_allocate() &&
heap()->OldGenerationAllocationLimitReached()) { !heap()->CanExpandOldGeneration(object_size)) {
return AllocationResult::Retry(identity()); return AllocationResult::Retry(identity());
} }
if (!CanAllocateSize(object_size)) return AllocationResult::Retry(identity());
LargePage* page = heap()->isolate()->memory_allocator()->AllocateLargePage( LargePage* page = heap()->isolate()->memory_allocator()->AllocateLargePage(
object_size, this, executable); object_size, this, executable);
if (page == NULL) return AllocationResult::Retry(identity()); if (page == NULL) return AllocationResult::Retry(identity());
......
...@@ -1663,9 +1663,8 @@ STATIC_ASSERT(sizeof(AllocationResult) == kPointerSize); ...@@ -1663,9 +1663,8 @@ STATIC_ASSERT(sizeof(AllocationResult) == kPointerSize);
class PagedSpace : public Space { class PagedSpace : public Space {
public: public:
// Creates a space with a maximum capacity, and an id. // Creates a space with an id.
PagedSpace(Heap* heap, intptr_t max_capacity, AllocationSpace id, PagedSpace(Heap* heap, AllocationSpace id, Executability executable);
Executability executable);
virtual ~PagedSpace() {} virtual ~PagedSpace() {}
...@@ -1902,9 +1901,6 @@ class PagedSpace : public Space { ...@@ -1902,9 +1901,6 @@ class PagedSpace : public Space {
int area_size_; int area_size_;
// Maximum capacity of this space.
intptr_t max_capacity_;
// Accounting information for this space. // Accounting information for this space.
AllocationStats accounting_stats_; AllocationStats accounting_stats_;
...@@ -2652,11 +2648,10 @@ class NewSpace : public Space { ...@@ -2652,11 +2648,10 @@ class NewSpace : public Space {
class OldSpace : public PagedSpace { class OldSpace : public PagedSpace {
public: public:
// Creates an old space object with a given maximum capacity. // Creates an old space object. The constructor does not allocate pages
// The constructor does not allocate pages from OS. // from OS.
OldSpace(Heap* heap, intptr_t max_capacity, AllocationSpace id, OldSpace(Heap* heap, AllocationSpace id, Executability executable)
Executability executable) : PagedSpace(heap, id, executable) {}
: PagedSpace(heap, max_capacity, id, executable) {}
}; };
...@@ -2673,9 +2668,9 @@ class OldSpace : public PagedSpace { ...@@ -2673,9 +2668,9 @@ class OldSpace : public PagedSpace {
class MapSpace : public PagedSpace { class MapSpace : public PagedSpace {
public: public:
// Creates a map space object with a maximum capacity. // Creates a map space object.
MapSpace(Heap* heap, intptr_t max_capacity, AllocationSpace id) MapSpace(Heap* heap, AllocationSpace id)
: PagedSpace(heap, max_capacity, id, NOT_EXECUTABLE), : PagedSpace(heap, id, NOT_EXECUTABLE),
max_map_space_pages_(kMaxMapPageIndex - 1) {} max_map_space_pages_(kMaxMapPageIndex - 1) {}
// Given an index, returns the page address. // Given an index, returns the page address.
...@@ -2714,7 +2709,7 @@ class MapSpace : public PagedSpace { ...@@ -2714,7 +2709,7 @@ class MapSpace : public PagedSpace {
class LargeObjectSpace : public Space { class LargeObjectSpace : public Space {
public: public:
LargeObjectSpace(Heap* heap, intptr_t max_capacity, AllocationSpace id); LargeObjectSpace(Heap* heap, AllocationSpace id);
virtual ~LargeObjectSpace() {} virtual ~LargeObjectSpace() {}
// Initializes internal data structures. // Initializes internal data structures.
...@@ -2733,8 +2728,6 @@ class LargeObjectSpace : public Space { ...@@ -2733,8 +2728,6 @@ class LargeObjectSpace : public Space {
MUST_USE_RESULT AllocationResult MUST_USE_RESULT AllocationResult
AllocateRaw(int object_size, Executability executable); AllocateRaw(int object_size, Executability executable);
bool CanAllocateSize(int size) { return Size() + size <= max_capacity_; }
// Available bytes for objects in this space. // Available bytes for objects in this space.
inline intptr_t Available() override; inline intptr_t Available() override;
...@@ -2784,7 +2777,6 @@ class LargeObjectSpace : public Space { ...@@ -2784,7 +2777,6 @@ class LargeObjectSpace : public Space {
bool SlowContains(Address addr) { return FindObject(addr)->IsHeapObject(); } bool SlowContains(Address addr) { return FindObject(addr)->IsHeapObject(); }
private: private:
intptr_t max_capacity_;
intptr_t maximum_committed_; intptr_t maximum_committed_;
// The head of the linked list of large object chunks. // The head of the linked list of large object chunks.
LargePage* first_page_; LargePage* first_page_;
......
...@@ -309,7 +309,7 @@ TEST(MemoryAllocator) { ...@@ -309,7 +309,7 @@ TEST(MemoryAllocator) {
heap->MaxExecutableSize())); heap->MaxExecutableSize()));
int total_pages = 0; int total_pages = 0;
OldSpace faked_space(heap, heap->MaxReserved(), OLD_SPACE, NOT_EXECUTABLE); OldSpace faked_space(heap, OLD_SPACE, NOT_EXECUTABLE);
Page* first_page = memory_allocator->AllocatePage( Page* first_page = memory_allocator->AllocatePage(
faked_space.AreaSize(), &faked_space, NOT_EXECUTABLE); faked_space.AreaSize(), &faked_space, NOT_EXECUTABLE);
...@@ -379,8 +379,7 @@ TEST(OldSpace) { ...@@ -379,8 +379,7 @@ TEST(OldSpace) {
heap->MaxExecutableSize())); heap->MaxExecutableSize()));
TestMemoryAllocatorScope test_scope(isolate, memory_allocator); TestMemoryAllocatorScope test_scope(isolate, memory_allocator);
OldSpace* s = new OldSpace(heap, heap->MaxOldGenerationSize(), OLD_SPACE, OldSpace* s = new OldSpace(heap, OLD_SPACE, NOT_EXECUTABLE);
NOT_EXECUTABLE);
CHECK(s != NULL); CHECK(s != NULL);
CHECK(s->SetUp()); CHECK(s->SetUp());
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment