| Index: src/spaces.h
|
| ===================================================================
|
| --- src/spaces.h (revision 10542)
|
| +++ src/spaces.h (working copy)
|
| @@ -505,9 +505,11 @@
|
| static const int kObjectStartOffset = kBodyOffset - 1 +
|
| (kObjectStartAlignment - (kBodyOffset - 1) % kObjectStartAlignment);
|
|
|
| - intptr_t size() const { return size_; }
|
| + size_t size() const { return size_; }
|
|
|
| - void set_size(size_t size) { size_ = size; }
|
| + void set_size(size_t size) {
|
| + size_ = size;
|
| + }
|
|
|
| Executability executable() {
|
| return IsFlagSet(IS_EXECUTABLE) ? EXECUTABLE : NOT_EXECUTABLE;
|
| @@ -659,7 +661,7 @@
|
| Address ObjectAreaStart() { return address() + kObjectStartOffset; }
|
|
|
| // Returns the end address (exclusive) of the object area in this page.
|
| - Address ObjectAreaEnd() { return address() + size(); }
|
| + Address ObjectAreaEnd() { return address() + Page::kPageSize; }
|
|
|
| // Checks whether an address is page aligned.
|
| static bool IsAlignedToPageSize(Address a) {
|
| @@ -678,17 +680,11 @@
|
| return address() + offset;
|
| }
|
|
|
| - // Expand the committed area for pages that are small.
|
| - void CommitMore(intptr_t space_needed);
|
| -
|
| // ---------------------------------------------------------------------
|
|
|
| // Page size in bytes. This must be a multiple of the OS page size.
|
| static const int kPageSize = 1 << kPageSizeBits;
|
|
|
| - // For a 1Mbyte page grow 64k at a time.
|
| - static const int kGrowthUnit = 1 << (kPageSizeBits - 4);
|
| -
|
| // Page size mask.
|
| static const intptr_t kPageAlignmentMask = (1 << kPageSizeBits) - 1;
|
|
|
| @@ -853,10 +849,12 @@
|
| FreeBlock(Address start_arg, size_t size_arg)
|
| : start(start_arg), size(size_arg) {
|
| ASSERT(IsAddressAligned(start, MemoryChunk::kAlignment));
|
| + ASSERT(size >= static_cast<size_t>(Page::kPageSize));
|
| }
|
| FreeBlock(void* start_arg, size_t size_arg)
|
| : start(static_cast<Address>(start_arg)), size(size_arg) {
|
| ASSERT(IsAddressAligned(start, MemoryChunk::kAlignment));
|
| + ASSERT(size >= static_cast<size_t>(Page::kPageSize));
|
| }
|
|
|
| Address start;
|
| @@ -952,9 +950,7 @@
|
|
|
| void TearDown();
|
|
|
| - Page* AllocatePage(intptr_t object_area_size,
|
| - PagedSpace* owner,
|
| - Executability executable);
|
| + Page* AllocatePage(PagedSpace* owner, Executability executable);
|
|
|
| LargePage* AllocateLargePage(intptr_t object_size,
|
| Executability executable,
|
| @@ -963,14 +959,10 @@
|
| void Free(MemoryChunk* chunk);
|
|
|
| // Returns the maximum available bytes of heaps.
|
| - intptr_t Available() {
|
| - return capacity_ < memory_allocator_reserved_ ?
|
| - 0 :
|
| - capacity_ - memory_allocator_reserved_;
|
| - }
|
| + intptr_t Available() { return capacity_ < size_ ? 0 : capacity_ - size_; }
|
|
|
| // Returns allocated spaces in bytes.
|
| - intptr_t Size() { return memory_allocator_reserved_; }
|
| + intptr_t Size() { return size_; }
|
|
|
| // Returns the maximum available executable bytes of heaps.
|
| intptr_t AvailableExecutable() {
|
| @@ -992,7 +984,6 @@
|
| #endif
|
|
|
| MemoryChunk* AllocateChunk(intptr_t body_size,
|
| - intptr_t committed_body_size,
|
| Executability executable,
|
| Space* space);
|
|
|
| @@ -1000,7 +991,6 @@
|
| size_t alignment,
|
| VirtualMemory* controller);
|
| Address AllocateAlignedMemory(size_t requested,
|
| - size_t committed,
|
| size_t alignment,
|
| Executability executable,
|
| VirtualMemory* controller);
|
| @@ -1020,12 +1010,6 @@
|
| // and false otherwise.
|
| bool UncommitBlock(Address start, size_t size);
|
|
|
| - void AllocationBookkeeping(Space* owner,
|
| - Address base,
|
| - intptr_t reserved_size,
|
| - intptr_t committed_size,
|
| - Executability executable);
|
| -
|
| // Zaps a contiguous block of memory [start..(start+size)[ thus
|
| // filling it up with a recognizable non-NULL bit pattern.
|
| void ZapBlock(Address start, size_t size);
|
| @@ -1053,7 +1037,7 @@
|
| size_t capacity_executable_;
|
|
|
| // Allocated space size in bytes.
|
| - size_t memory_allocator_reserved_;
|
| + size_t size_;
|
| // Allocated executable space size in bytes.
|
| size_t size_executable_;
|
|
|
| @@ -1398,15 +1382,9 @@
|
| static const int kMinBlockSize = 3 * kPointerSize;
|
| static const int kMaxBlockSize = Page::kMaxHeapObjectSize;
|
|
|
| - FreeListNode* PickNodeFromList(FreeListNode** list,
|
| - int* node_size,
|
| - int minimum_size);
|
| + FreeListNode* PickNodeFromList(FreeListNode** list, int* node_size);
|
|
|
| - FreeListNode* FindNodeFor(int size_in_bytes, int* node_size, Address limit);
|
| - FreeListNode* FindAbuttingNode(int size_in_bytes,
|
| - int* node_size,
|
| - Address limit,
|
| - FreeListNode** list_head);
|
| + FreeListNode* FindNodeFor(int size_in_bytes, int* node_size);
|
|
|
| PagedSpace* owner_;
|
| Heap* heap_;
|
| @@ -1506,8 +1484,6 @@
|
| // free bytes that were not found at all due to lazy sweeping.
|
| virtual intptr_t Waste() { return accounting_stats_.Waste(); }
|
|
|
| - virtual int ObjectAlignment() { return kObjectAlignment; }
|
| -
|
| // Returns the allocation pointer in this space.
|
| Address top() { return allocation_info_.top; }
|
| Address limit() { return allocation_info_.limit; }
|
| @@ -1522,7 +1498,7 @@
|
| // the free list or accounted as waste.
|
| // If add_to_freelist is false then just accounting stats are updated and
|
| // no attempt to add area to free list is made.
|
| - int AddToFreeLists(Address start, int size_in_bytes) {
|
| + int Free(Address start, int size_in_bytes) {
|
| int wasted = free_list_.Free(start, size_in_bytes);
|
| accounting_stats_.DeallocateBytes(size_in_bytes - wasted);
|
| return size_in_bytes - wasted;
|
| @@ -1530,7 +1506,6 @@
|
|
|
| // Set space allocation info.
|
| void SetTop(Address top, Address limit) {
|
| - ASSERT(top == NULL || top >= Page::FromAddress(top - 1)->ObjectAreaStart());
|
| ASSERT(top == limit ||
|
| Page::FromAddress(top) == Page::FromAddress(limit - 1));
|
| allocation_info_.top = top;
|
| @@ -1597,14 +1572,12 @@
|
|
|
| void IncreaseUnsweptFreeBytes(Page* p) {
|
| ASSERT(ShouldBeSweptLazily(p));
|
| - unswept_free_bytes_ +=
|
| - (p->ObjectAreaEnd() - p->ObjectAreaStart()) - p->LiveBytes();
|
| + unswept_free_bytes_ += (Page::kObjectAreaSize - p->LiveBytes());
|
| }
|
|
|
| void DecreaseUnsweptFreeBytes(Page* p) {
|
| ASSERT(ShouldBeSweptLazily(p));
|
| - unswept_free_bytes_ -=
|
| - (p->ObjectAreaEnd() - p->ObjectAreaStart() - p->LiveBytes());
|
| + unswept_free_bytes_ -= (Page::kObjectAreaSize - p->LiveBytes());
|
| }
|
|
|
| bool AdvanceSweeper(intptr_t bytes_to_sweep);
|
| @@ -1613,7 +1586,6 @@
|
| return !first_unswept_page_->is_valid();
|
| }
|
|
|
| - inline bool HasAPage() { return anchor_.next_page() != &anchor_; }
|
| Page* FirstPage() { return anchor_.next_page(); }
|
| Page* LastPage() { return anchor_.prev_page(); }
|
|
|
| @@ -1624,17 +1596,15 @@
|
| FreeList::SizeStats sizes;
|
| free_list_.CountFreeListItems(p, &sizes);
|
|
|
| - intptr_t object_area_size = p->ObjectAreaEnd() - p->ObjectAreaStart();
|
| -
|
| intptr_t ratio;
|
| intptr_t ratio_threshold;
|
| if (identity() == CODE_SPACE) {
|
| ratio = (sizes.medium_size_ * 10 + sizes.large_size_ * 2) * 100 /
|
| - object_area_size;
|
| + Page::kObjectAreaSize;
|
| ratio_threshold = 10;
|
| } else {
|
| ratio = (sizes.small_size_ * 5 + sizes.medium_size_) * 100 /
|
| - object_area_size;
|
| + Page::kObjectAreaSize;
|
| ratio_threshold = 15;
|
| }
|
|
|
| @@ -1644,20 +1614,20 @@
|
| identity(),
|
| static_cast<int>(sizes.small_size_),
|
| static_cast<double>(sizes.small_size_ * 100) /
|
| - object_area_size,
|
| + Page::kObjectAreaSize,
|
| static_cast<int>(sizes.medium_size_),
|
| static_cast<double>(sizes.medium_size_ * 100) /
|
| - object_area_size,
|
| + Page::kObjectAreaSize,
|
| static_cast<int>(sizes.large_size_),
|
| static_cast<double>(sizes.large_size_ * 100) /
|
| - object_area_size,
|
| + Page::kObjectAreaSize,
|
| static_cast<int>(sizes.huge_size_),
|
| static_cast<double>(sizes.huge_size_ * 100) /
|
| - object_area_size,
|
| + Page::kObjectAreaSize,
|
| (ratio > ratio_threshold) ? "[fragmented]" : "");
|
| }
|
|
|
| - if (FLAG_always_compact && sizes.Total() != object_area_size) {
|
| + if (FLAG_always_compact && sizes.Total() != Page::kObjectAreaSize) {
|
| return 1;
|
| }
|
| if (ratio <= ratio_threshold) return 0; // Not fragmented.
|
| @@ -1688,6 +1658,12 @@
|
| // 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
|
| @@ -1699,11 +1675,10 @@
|
| // done conservatively.
|
| intptr_t unswept_free_bytes_;
|
|
|
| - // Expands the space by allocating a page. Returns false if it cannot
|
| - // allocate a page from OS, or if the hard heap size limit has been hit. The
|
| - // new page will have at least enough committed space to satisfy the object
|
| - // size indicated by the allocation_size argument;
|
| - bool Expand(intptr_t allocation_size);
|
| + // Expands the space by allocating a fixed number of pages. Returns false if
|
| + // it cannot allocate requested number of pages from OS, or if the hard heap
|
| + // size limit has been hit.
|
| + bool Expand();
|
|
|
| // Generic fast case allocation function that tries linear allocation at the
|
| // address denoted by top in allocation_info_.
|
| @@ -1858,8 +1833,7 @@
|
| anchor_(this),
|
| current_page_(NULL) { }
|
|
|
| - // Sets up the semispace using the given chunk. After this, call Commit()
|
| - // to make the semispace usable.
|
| + // Sets up the semispace using the given chunk.
|
| void SetUp(Address start, int initial_capacity, int maximum_capacity);
|
|
|
| // Tear down the space. Heap memory was not allocated by the space, so it
|
| @@ -2364,8 +2338,15 @@
|
| intptr_t max_capacity,
|
| AllocationSpace id,
|
| Executability executable)
|
| - : PagedSpace(heap, max_capacity, id, 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->ObjectAreaEnd();
|
| + }
|
| +
|
| public:
|
| TRACK_MEMORY("OldSpace")
|
| };
|
| @@ -2391,12 +2372,17 @@
|
| const char* name)
|
| : PagedSpace(heap, max_capacity, id, NOT_EXECUTABLE),
|
| object_size_in_bytes_(object_size_in_bytes),
|
| - name_(name) { }
|
| + name_(name) {
|
| + page_extra_ = Page::kObjectAreaSize % object_size_in_bytes;
|
| + }
|
|
|
| + // The limit of allocation for a page in this space.
|
| + virtual Address PageAllocationLimit(Page* page) {
|
| + return page->ObjectAreaEnd() - page_extra_;
|
| + }
|
| +
|
| int object_size_in_bytes() { return object_size_in_bytes_; }
|
|
|
| - virtual int ObjectAlignment() { return object_size_in_bytes_; }
|
| -
|
| // Prepares for a mark-compact GC.
|
| virtual void PrepareForMarkCompact();
|
|
|
|
|