| Index: src/spaces.h
|
| diff --git a/src/spaces.h b/src/spaces.h
|
| index 6144c95d14d689876dc2008c5c506ecfd37faa51..83793e300e4270c4c9cbdb74d7c2248961fa8241 100644
|
| --- a/src/spaces.h
|
| +++ b/src/spaces.h
|
| @@ -1317,18 +1317,53 @@ class PageIterator BASE_EMBEDDED {
|
| // space.
|
| class AllocationInfo {
|
| public:
|
| - AllocationInfo() : top(NULL), limit(NULL) {
|
| + AllocationInfo() : top_(NULL), limit_(NULL) {
|
| }
|
|
|
| - Address top; // Current allocation top.
|
| - Address limit; // Current allocation limit.
|
| + INLINE(void set_top(Address top)) {
|
| + SLOW_ASSERT(top == NULL ||
|
| + (reinterpret_cast<intptr_t>(top) & HeapObjectTagMask()) == 0);
|
| + top_ = top;
|
| + }
|
| +
|
| + INLINE(Address top()) const {
|
| + SLOW_ASSERT(top_ == NULL ||
|
| + (reinterpret_cast<intptr_t>(top_) & HeapObjectTagMask()) == 0);
|
| + return top_;
|
| + }
|
| +
|
| + Address* top_address() {
|
| + return &top_;
|
| + }
|
| +
|
| + INLINE(void set_limit(Address limit)) {
|
| + SLOW_ASSERT(limit == NULL ||
|
| + (reinterpret_cast<intptr_t>(limit) & HeapObjectTagMask()) == 0);
|
| + limit_ = limit;
|
| + }
|
| +
|
| + INLINE(Address limit()) const {
|
| + SLOW_ASSERT(limit_ == NULL ||
|
| + (reinterpret_cast<intptr_t>(limit_) & HeapObjectTagMask()) == 0);
|
| + return limit_;
|
| + }
|
| +
|
| + Address* limit_address() {
|
| + return &limit_;
|
| + }
|
|
|
| #ifdef DEBUG
|
| bool VerifyPagedAllocation() {
|
| - return (Page::FromAllocationTop(top) == Page::FromAllocationTop(limit))
|
| - && (top <= limit);
|
| + return (Page::FromAllocationTop(top_) == Page::FromAllocationTop(limit_))
|
| + && (top_ <= limit_);
|
| }
|
| #endif
|
| +
|
| + private:
|
| + // Current allocation top.
|
| + Address top_;
|
| + // Current allocation limit.
|
| + Address limit_;
|
| };
|
|
|
|
|
| @@ -1353,6 +1388,7 @@ class AllocationStats BASE_EMBEDDED {
|
| // Zero out all the allocation statistics (i.e., no capacity).
|
| void Clear() {
|
| capacity_ = 0;
|
| + max_capacity_ = 0;
|
| size_ = 0;
|
| waste_ = 0;
|
| }
|
| @@ -1371,6 +1407,7 @@ class AllocationStats BASE_EMBEDDED {
|
|
|
| // Accessors for the allocation statistics.
|
| intptr_t Capacity() { return capacity_; }
|
| + intptr_t MaxCapacity() { return max_capacity_; }
|
| intptr_t Size() { return size_; }
|
| intptr_t Waste() { return waste_; }
|
|
|
| @@ -1380,6 +1417,9 @@ class AllocationStats BASE_EMBEDDED {
|
| void ExpandSpace(int size_in_bytes) {
|
| capacity_ += size_in_bytes;
|
| size_ += size_in_bytes;
|
| + if (capacity_ > max_capacity_) {
|
| + max_capacity_ = capacity_;
|
| + }
|
| ASSERT(size_ >= 0);
|
| }
|
|
|
| @@ -1413,6 +1453,7 @@ class AllocationStats BASE_EMBEDDED {
|
|
|
| private:
|
| intptr_t capacity_;
|
| + intptr_t max_capacity_;
|
| intptr_t size_;
|
| intptr_t waste_;
|
| };
|
| @@ -1642,10 +1683,10 @@ class PagedSpace : public Space {
|
|
|
| // During boot the free_space_map is created, and afterwards we may need
|
| // to write it into the free list nodes that were already created.
|
| - virtual void RepairFreeListsAfterBoot();
|
| + void RepairFreeListsAfterBoot();
|
|
|
| // Prepares for a mark-compact GC.
|
| - virtual void PrepareForMarkCompact();
|
| + void PrepareForMarkCompact();
|
|
|
| // Current capacity without growing (Size() + Available()).
|
| intptr_t Capacity() { return accounting_stats_.Capacity(); }
|
| @@ -1654,6 +1695,9 @@ class PagedSpace : public Space {
|
| // spaces this equals the capacity.
|
| intptr_t CommittedMemory() { return Capacity(); }
|
|
|
| + // The maximum amount of memory ever committed for this space.
|
| + intptr_t MaximumCommittedMemory() { return accounting_stats_.MaxCapacity(); }
|
| +
|
| // Approximate amount of physical memory committed for this space.
|
| size_t CommittedPhysicalMemory();
|
|
|
| @@ -1707,25 +1751,22 @@ class PagedSpace : public Space {
|
| virtual intptr_t Waste() { return accounting_stats_.Waste(); }
|
|
|
| // Returns the allocation pointer in this space.
|
| - Address top() { return allocation_info_.top; }
|
| - Address limit() { return allocation_info_.limit; }
|
| + Address top() { return allocation_info_.top(); }
|
| + Address limit() { return allocation_info_.limit(); }
|
|
|
| - // The allocation top and limit addresses.
|
| - Address* allocation_top_address() { return &allocation_info_.top; }
|
| - Address* allocation_limit_address() { return &allocation_info_.limit; }
|
| + // The allocation top address.
|
| + Address* allocation_top_address() {
|
| + return allocation_info_.top_address();
|
| + }
|
|
|
| - enum AllocationType {
|
| - NEW_OBJECT,
|
| - MOVE_OBJECT
|
| - };
|
| + // The allocation limit address.
|
| + Address* allocation_limit_address() {
|
| + return allocation_info_.limit_address();
|
| + }
|
|
|
| // Allocate the requested number of bytes in the space if possible, return a
|
| // failure object if not.
|
| - MUST_USE_RESULT inline MaybeObject* AllocateRaw(
|
| - int size_in_bytes,
|
| - AllocationType event = NEW_OBJECT);
|
| -
|
| - virtual bool ReserveSpace(int bytes);
|
| + MUST_USE_RESULT inline MaybeObject* AllocateRaw(int size_in_bytes);
|
|
|
| // Give a block of memory to the space's free list. It might be added to
|
| // the free list or accounted as waste.
|
| @@ -1745,18 +1786,16 @@ class PagedSpace : public Space {
|
| void SetTop(Address top, Address limit) {
|
| ASSERT(top == limit ||
|
| Page::FromAddress(top) == Page::FromAddress(limit - 1));
|
| - MemoryChunk::UpdateHighWaterMark(allocation_info_.top);
|
| - allocation_info_.top = top;
|
| - allocation_info_.limit = limit;
|
| + MemoryChunk::UpdateHighWaterMark(allocation_info_.top());
|
| + allocation_info_.set_top(top);
|
| + allocation_info_.set_limit(limit);
|
| }
|
|
|
| void Allocate(int bytes) {
|
| accounting_stats_.AllocateBytes(bytes);
|
| }
|
|
|
| - void IncreaseCapacity(int size) {
|
| - accounting_stats_.ExpandSpace(size);
|
| - }
|
| + void IncreaseCapacity(int size);
|
|
|
| // Releases an unused page and shrinks the space.
|
| void ReleasePage(Page* page, bool unlink);
|
| @@ -1873,12 +1912,6 @@ class PagedSpace : public Space {
|
| // Normal allocation information.
|
| AllocationInfo allocation_info_;
|
|
|
| - // Bytes of each page that cannot be allocated. Possibly non-zero
|
| - // for pages in spaces with only fixed-size objects. Always zero
|
| - // for pages in spaces with variable sized objects (those pages are
|
| - // padded with free-list nodes).
|
| - int page_extra_;
|
| -
|
| bool was_swept_conservatively_;
|
|
|
| // The first page to be swept when the lazy sweeper advances. Is set
|
| @@ -2126,11 +2159,6 @@ class SemiSpace : public Space {
|
| return 0;
|
| }
|
|
|
| - virtual bool ReserveSpace(int bytes) {
|
| - UNREACHABLE();
|
| - return false;
|
| - }
|
| -
|
| bool is_committed() { return committed_; }
|
| bool Commit();
|
| bool Uncommit();
|
| @@ -2166,6 +2194,9 @@ class SemiSpace : public Space {
|
|
|
| static void Swap(SemiSpace* from, SemiSpace* to);
|
|
|
| + // Returns the maximum amount of memory ever committed by the semi space.
|
| + size_t MaximumCommittedMemory() { return maximum_committed_; }
|
| +
|
| // Approximate amount of physical memory committed for this space.
|
| size_t CommittedPhysicalMemory();
|
|
|
| @@ -2174,6 +2205,9 @@ class SemiSpace : public Space {
|
| // Copies the flags into the masked positions on all pages in the space.
|
| void FlipPages(intptr_t flags, intptr_t flag_mask);
|
|
|
| + // Updates Capacity and MaximumCommitted based on new capacity.
|
| + void SetCapacity(int new_capacity);
|
| +
|
| NewSpacePage* anchor() { return &anchor_; }
|
|
|
| // The current and maximum capacity of the space.
|
| @@ -2181,6 +2215,8 @@ class SemiSpace : public Space {
|
| int maximum_capacity_;
|
| int initial_capacity_;
|
|
|
| + intptr_t maximum_committed_;
|
| +
|
| // The start address of the space.
|
| Address start_;
|
| // Used to govern object promotion during mark-compact collection.
|
| @@ -2366,6 +2402,12 @@ class NewSpace : public Space {
|
| return Capacity();
|
| }
|
|
|
| + // Return the total amount of memory committed for new space.
|
| + intptr_t MaximumCommittedMemory() {
|
| + return to_space_.MaximumCommittedMemory() +
|
| + from_space_.MaximumCommittedMemory();
|
| + }
|
| +
|
| // Approximate amount of physical memory committed for this space.
|
| size_t CommittedPhysicalMemory();
|
|
|
| @@ -2388,9 +2430,15 @@ class NewSpace : public Space {
|
|
|
| // Return the address of the allocation pointer in the active semispace.
|
| Address top() {
|
| - ASSERT(to_space_.current_page()->ContainsLimit(allocation_info_.top));
|
| - return allocation_info_.top;
|
| + ASSERT(to_space_.current_page()->ContainsLimit(allocation_info_.top()));
|
| + return allocation_info_.top();
|
| }
|
| +
|
| + void set_top(Address top) {
|
| + ASSERT(to_space_.current_page()->ContainsLimit(top));
|
| + allocation_info_.set_top(top);
|
| + }
|
| +
|
| // Return the address of the first object in the active semispace.
|
| Address bottom() { return to_space_.space_start(); }
|
|
|
| @@ -2415,9 +2463,15 @@ class NewSpace : public Space {
|
| return reinterpret_cast<Address>(index << kPointerSizeLog2);
|
| }
|
|
|
| - // The allocation top and limit addresses.
|
| - Address* allocation_top_address() { return &allocation_info_.top; }
|
| - Address* allocation_limit_address() { return &allocation_info_.limit; }
|
| + // The allocation top and limit address.
|
| + Address* allocation_top_address() {
|
| + return allocation_info_.top_address();
|
| + }
|
| +
|
| + // The allocation limit address.
|
| + Address* allocation_limit_address() {
|
| + return allocation_info_.limit_address();
|
| + }
|
|
|
| MUST_USE_RESULT INLINE(MaybeObject* AllocateRaw(int size_in_bytes));
|
|
|
| @@ -2427,13 +2481,14 @@ class NewSpace : public Space {
|
| void LowerInlineAllocationLimit(intptr_t step) {
|
| inline_allocation_limit_step_ = step;
|
| if (step == 0) {
|
| - allocation_info_.limit = to_space_.page_high();
|
| + allocation_info_.set_limit(to_space_.page_high());
|
| } else {
|
| - allocation_info_.limit = Min(
|
| - allocation_info_.top + inline_allocation_limit_step_,
|
| - allocation_info_.limit);
|
| + Address new_limit = Min(
|
| + allocation_info_.top() + inline_allocation_limit_step_,
|
| + allocation_info_.limit());
|
| + allocation_info_.set_limit(new_limit);
|
| }
|
| - top_on_previous_step_ = allocation_info_.top;
|
| + top_on_previous_step_ = allocation_info_.top();
|
| }
|
|
|
| // Get the extent of the inactive semispace (for use as a marking stack,
|
| @@ -2467,8 +2522,6 @@ class NewSpace : public Space {
|
| // if successful.
|
| bool AddFreshPage();
|
|
|
| - virtual bool ReserveSpace(int bytes);
|
| -
|
| #ifdef VERIFY_HEAP
|
| // Verify the active semispace.
|
| virtual void Verify();
|
| @@ -2564,12 +2617,6 @@ class OldSpace : public PagedSpace {
|
| AllocationSpace id,
|
| Executability executable)
|
| : PagedSpace(heap, max_capacity, id, executable) {
|
| - page_extra_ = 0;
|
| - }
|
| -
|
| - // The limit of allocation for a page in this space.
|
| - virtual Address PageAllocationLimit(Page* page) {
|
| - return page->area_end();
|
| }
|
|
|
| public:
|
| @@ -2580,49 +2627,19 @@ class OldSpace : public PagedSpace {
|
| // For contiguous spaces, top should be in the space (or at the end) and limit
|
| // should be the end of the space.
|
| #define ASSERT_SEMISPACE_ALLOCATION_INFO(info, space) \
|
| - SLOW_ASSERT((space).page_low() <= (info).top \
|
| - && (info).top <= (space).page_high() \
|
| - && (info).limit <= (space).page_high())
|
| -
|
| -
|
| -// -----------------------------------------------------------------------------
|
| -// Old space for objects of a fixed size
|
| -
|
| -class FixedSpace : public PagedSpace {
|
| - public:
|
| - FixedSpace(Heap* heap,
|
| - intptr_t max_capacity,
|
| - AllocationSpace id,
|
| - int object_size_in_bytes)
|
| - : PagedSpace(heap, max_capacity, id, NOT_EXECUTABLE),
|
| - object_size_in_bytes_(object_size_in_bytes) {
|
| - page_extra_ = Page::kNonCodeObjectAreaSize % object_size_in_bytes;
|
| - }
|
| -
|
| - // The limit of allocation for a page in this space.
|
| - virtual Address PageAllocationLimit(Page* page) {
|
| - return page->area_end() - page_extra_;
|
| - }
|
| -
|
| - int object_size_in_bytes() { return object_size_in_bytes_; }
|
| -
|
| - // Prepares for a mark-compact GC.
|
| - virtual void PrepareForMarkCompact();
|
| -
|
| - private:
|
| - // The size of objects in this space.
|
| - int object_size_in_bytes_;
|
| -};
|
| + SLOW_ASSERT((space).page_low() <= (info).top() \
|
| + && (info).top() <= (space).page_high() \
|
| + && (info).limit() <= (space).page_high())
|
|
|
|
|
| // -----------------------------------------------------------------------------
|
| // Old space for all map objects
|
|
|
| -class MapSpace : public FixedSpace {
|
| +class MapSpace : public PagedSpace {
|
| public:
|
| // Creates a map space object with a maximum capacity.
|
| MapSpace(Heap* heap, intptr_t max_capacity, AllocationSpace id)
|
| - : FixedSpace(heap, max_capacity, id, Map::kSize),
|
| + : PagedSpace(heap, max_capacity, id, NOT_EXECUTABLE),
|
| max_map_space_pages_(kMaxMapPageIndex - 1) {
|
| }
|
|
|
| @@ -2659,12 +2676,12 @@ class MapSpace : public FixedSpace {
|
| // -----------------------------------------------------------------------------
|
| // Old space for simple property cell objects
|
|
|
| -class CellSpace : public FixedSpace {
|
| +class CellSpace : public PagedSpace {
|
| public:
|
| // Creates a property cell space object with a maximum capacity.
|
| CellSpace(Heap* heap, intptr_t max_capacity, AllocationSpace id)
|
| - : FixedSpace(heap, max_capacity, id, Cell::kSize)
|
| - {}
|
| + : PagedSpace(heap, max_capacity, id, NOT_EXECUTABLE) {
|
| + }
|
|
|
| virtual int RoundSizeDownToObjectAlignment(int size) {
|
| if (IsPowerOf2(Cell::kSize)) {
|
| @@ -2685,13 +2702,13 @@ class CellSpace : public FixedSpace {
|
| // -----------------------------------------------------------------------------
|
| // Old space for all global object property cell objects
|
|
|
| -class PropertyCellSpace : public FixedSpace {
|
| +class PropertyCellSpace : public PagedSpace {
|
| public:
|
| // Creates a property cell space object with a maximum capacity.
|
| PropertyCellSpace(Heap* heap, intptr_t max_capacity,
|
| AllocationSpace id)
|
| - : FixedSpace(heap, max_capacity, id, PropertyCell::kSize)
|
| - {}
|
| + : PagedSpace(heap, max_capacity, id, NOT_EXECUTABLE) {
|
| + }
|
|
|
| virtual int RoundSizeDownToObjectAlignment(int size) {
|
| if (IsPowerOf2(PropertyCell::kSize)) {
|
| @@ -2748,6 +2765,10 @@ class LargeObjectSpace : public Space {
|
| return objects_size_;
|
| }
|
|
|
| + intptr_t MaximumCommittedMemory() {
|
| + return maximum_committed_;
|
| + }
|
| +
|
| intptr_t CommittedMemory() {
|
| return Size();
|
| }
|
| @@ -2777,11 +2798,6 @@ class LargeObjectSpace : public Space {
|
| // Checks whether the space is empty.
|
| bool IsEmpty() { return first_page_ == NULL; }
|
|
|
| - // See the comments for ReserveSpace in the Space class. This has to be
|
| - // called after ReserveSpace has been called on the paged spaces, since they
|
| - // may use some memory, leaving less for large objects.
|
| - virtual bool ReserveSpace(int bytes);
|
| -
|
| LargePage* first_page() { return first_page_; }
|
|
|
| #ifdef VERIFY_HEAP
|
| @@ -2799,6 +2815,7 @@ class LargeObjectSpace : public Space {
|
|
|
| private:
|
| intptr_t max_capacity_;
|
| + intptr_t maximum_committed_;
|
| // The head of the linked list of large object chunks.
|
| LargePage* first_page_;
|
| intptr_t size_; // allocated bytes
|
|
|