Home | History | Annotate | Download | only in src
      1 // Copyright 2006-2008 the V8 project authors. All rights reserved.
      2 // Redistribution and use in source and binary forms, with or without
      3 // modification, are permitted provided that the following conditions are
      4 // met:
      5 //
      6 //     * Redistributions of source code must retain the above copyright
      7 //       notice, this list of conditions and the following disclaimer.
      8 //     * Redistributions in binary form must reproduce the above
      9 //       copyright notice, this list of conditions and the following
     10 //       disclaimer in the documentation and/or other materials provided
     11 //       with the distribution.
     12 //     * Neither the name of Google Inc. nor the names of its
     13 //       contributors may be used to endorse or promote products derived
     14 //       from this software without specific prior written permission.
     15 //
     16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 
     28 #ifndef V8_SPACES_H_
     29 #define V8_SPACES_H_
     30 
     31 #include "list-inl.h"
     32 #include "log.h"
     33 
     34 namespace v8 {
     35 namespace internal {
     36 
     37 // -----------------------------------------------------------------------------
     38 // Heap structures:
     39 //
     40 // A JS heap consists of a young generation, an old generation, and a large
     41 // object space. The young generation is divided into two semispaces. A
     42 // scavenger implements Cheney's copying algorithm. The old generation is
     43 // separated into a map space and an old object space. The map space contains
     44 // all (and only) map objects, the rest of old objects go into the old space.
     45 // The old generation is collected by a mark-sweep-compact collector.
     46 //
     47 // The semispaces of the young generation are contiguous.  The old and map
     48 // spaces consists of a list of pages. A page has a page header, a remembered
     49 // set area, and an object area. A page size is deliberately chosen as 8K
     50 // bytes. The first word of a page is an opaque page header that has the
     51 // address of the next page and its ownership information. The second word may
     52 // have the allocation top address of this page. The next 248 bytes are
     53 // remembered sets. Heap objects are aligned to the pointer size (4 bytes). A
     54 // remembered set bit corresponds to a pointer in the object area.
     55 //
     56 // There is a separate large object space for objects larger than
     57 // Page::kMaxHeapObjectSize, so that they do not have to move during
     58 // collection.  The large object space is paged and uses the same remembered
     59 // set implementation.  Pages in large object space may be larger than 8K.
     60 //
     61 // NOTE: The mark-compact collector rebuilds the remembered set after a
     62 // collection. It reuses first a few words of the remembered set for
     63 // bookkeeping relocation information.
     64 
     65 
     66 // Some assertion macros used in the debugging mode.
     67 
     68 #define ASSERT_PAGE_ALIGNED(address)                                           \
     69   ASSERT((OffsetFrom(address) & Page::kPageAlignmentMask) == 0)
     70 
     71 #define ASSERT_OBJECT_ALIGNED(address)                                         \
     72   ASSERT((OffsetFrom(address) & kObjectAlignmentMask) == 0)
     73 
     74 #define ASSERT_MAP_ALIGNED(address)                                            \
     75   ASSERT((OffsetFrom(address) & kMapAlignmentMask) == 0)
     76 
     77 #define ASSERT_OBJECT_SIZE(size)                                               \
     78   ASSERT((0 < size) && (size <= Page::kMaxHeapObjectSize))
     79 
     80 #define ASSERT_PAGE_OFFSET(offset)                                             \
     81   ASSERT((Page::kObjectStartOffset <= offset)                                  \
     82       && (offset <= Page::kPageSize))
     83 
     84 #define ASSERT_MAP_PAGE_INDEX(index)                                           \
     85   ASSERT((0 <= index) && (index <= MapSpace::kMaxMapPageIndex))
     86 
     87 
     88 class PagedSpace;
     89 class MemoryAllocator;
     90 class AllocationInfo;
     91 
     92 // -----------------------------------------------------------------------------
     93 // A page normally has 8K bytes. Large object pages may be larger.  A page
     94 // address is always aligned to the 8K page size.  A page is divided into
     95 // three areas: the first two words are used for bookkeeping, the next 248
     96 // bytes are used as remembered set, and the rest of the page is the object
     97 // area.
     98 //
     99 // Pointers are aligned to the pointer size (4), only 1 bit is needed
    100 // for a pointer in the remembered set. Given an address, its remembered set
    101 // bit position (offset from the start of the page) is calculated by dividing
    102 // its page offset by 32. Therefore, the object area in a page starts at the
    103 // 256th byte (8K/32). Bytes 0 to 255 do not need the remembered set, so that
    104 // the first two words (64 bits) in a page can be used for other purposes.
    105 //
    106 // On the 64-bit platform, we add an offset to the start of the remembered set,
    107 // and pointers are aligned to 8-byte pointer size. This means that we need
    108 // only 128 bytes for the RSet, and only get two bytes free in the RSet's RSet.
    109 // For this reason we add an offset to get room for the Page data at the start.
    110 //
    111 // The mark-compact collector transforms a map pointer into a page index and a
    112 // page offset. The excact encoding is described in the comments for
    113 // class MapWord in objects.h.
    114 //
    115 // The only way to get a page pointer is by calling factory methods:
    116 //   Page* p = Page::FromAddress(addr); or
    117 //   Page* p = Page::FromAllocationTop(top);
    118 class Page {
    119  public:
    120   // Returns the page containing a given address. The address ranges
    121   // from [page_addr .. page_addr + kPageSize[
    122   //
    123   // Note that this function only works for addresses in normal paged
    124   // spaces and addresses in the first 8K of large object pages (i.e.,
    125   // the start of large objects but not necessarily derived pointers
    126   // within them).
    127   INLINE(static Page* FromAddress(Address a)) {
    128     return reinterpret_cast<Page*>(OffsetFrom(a) & ~kPageAlignmentMask);
    129   }
    130 
    131   // Returns the page containing an allocation top. Because an allocation
    132   // top address can be the upper bound of the page, we need to subtract
    133   // it with kPointerSize first. The address ranges from
    134   // [page_addr + kObjectStartOffset .. page_addr + kPageSize].
    135   INLINE(static Page* FromAllocationTop(Address top)) {
    136     Page* p = FromAddress(top - kPointerSize);
    137     ASSERT_PAGE_OFFSET(p->Offset(top));
    138     return p;
    139   }
    140 
    141   // Returns the start address of this page.
    142   Address address() { return reinterpret_cast<Address>(this); }
    143 
    144   // Checks whether this is a valid page address.
    145   bool is_valid() { return address() != NULL; }
    146 
    147   // Returns the next page of this page.
    148   inline Page* next_page();
    149 
    150   // Return the end of allocation in this page. Undefined for unused pages.
    151   inline Address AllocationTop();
    152 
    153   // Returns the start address of the object area in this page.
    154   Address ObjectAreaStart() { return address() + kObjectStartOffset; }
    155 
    156   // Returns the end address (exclusive) of the object area in this page.
    157   Address ObjectAreaEnd() { return address() + Page::kPageSize; }
    158 
    159   // Returns the start address of the remembered set area.
    160   Address RSetStart() { return address() + kRSetStartOffset; }
    161 
    162   // Returns the end address of the remembered set area (exclusive).
    163   Address RSetEnd() { return address() + kRSetEndOffset; }
    164 
    165   // Checks whether an address is page aligned.
    166   static bool IsAlignedToPageSize(Address a) {
    167     return 0 == (OffsetFrom(a) & kPageAlignmentMask);
    168   }
    169 
    170   // True if this page is a large object page.
    171   bool IsLargeObjectPage() { return (is_normal_page & 0x1) == 0; }
    172 
    173   // Returns the offset of a given address to this page.
    174   INLINE(int Offset(Address a)) {
    175     int offset = static_cast<int>(a - address());
    176     ASSERT_PAGE_OFFSET(offset);
    177     return offset;
    178   }
    179 
    180   // Returns the address for a given offset to the this page.
    181   Address OffsetToAddress(int offset) {
    182     ASSERT_PAGE_OFFSET(offset);
    183     return address() + offset;
    184   }
    185 
    186   // ---------------------------------------------------------------------
    187   // Remembered set support
    188 
    189   // Clears remembered set in this page.
    190   inline void ClearRSet();
    191 
    192   // Return the address of the remembered set word corresponding to an
    193   // object address/offset pair, and the bit encoded as a single-bit
    194   // mask in the output parameter 'bitmask'.
    195   INLINE(static Address ComputeRSetBitPosition(Address address, int offset,
    196                                                uint32_t* bitmask));
    197 
    198   // Sets the corresponding remembered set bit for a given address.
    199   INLINE(static void SetRSet(Address address, int offset));
    200 
    201   // Clears the corresponding remembered set bit for a given address.
    202   static inline void UnsetRSet(Address address, int offset);
    203 
    204   // Checks whether the remembered set bit for a given address is set.
    205   static inline bool IsRSetSet(Address address, int offset);
    206 
    207 #ifdef DEBUG
    208   // Use a state to mark whether remembered set space can be used for other
    209   // purposes.
    210   enum RSetState { IN_USE,  NOT_IN_USE };
    211   static bool is_rset_in_use() { return rset_state_ == IN_USE; }
    212   static void set_rset_state(RSetState state) { rset_state_ = state; }
    213 #endif
    214 
    215   // Page size in bytes.  This must be a multiple of the OS page size.
    216   static const int kPageSize = 1 << kPageSizeBits;
    217 
    218   // Page size mask.
    219   static const intptr_t kPageAlignmentMask = (1 << kPageSizeBits) - 1;
    220 
    221   // The offset of the remembered set in a page, in addition to the empty bytes
    222   // formed as the remembered bits of the remembered set itself.
    223 #ifdef V8_TARGET_ARCH_X64
    224   static const int kRSetOffset = 4 * kPointerSize;  // Room for four pointers.
    225 #else
    226   static const int kRSetOffset = 0;
    227 #endif
    228   // The end offset of the remembered set in a page
    229   // (heaps are aligned to pointer size).
    230   static const int kRSetEndOffset = kRSetOffset + kPageSize / kBitsPerPointer;
    231 
    232   // The start offset of the object area in a page.
    233   // This needs to be at least (bits per uint32_t) * kBitsPerPointer,
    234   // to align start of rset to a uint32_t address.
    235   static const int kObjectStartOffset = 256;
    236 
    237   // The start offset of the used part of the remembered set in a page.
    238   static const int kRSetStartOffset = kRSetOffset +
    239       kObjectStartOffset / kBitsPerPointer;
    240 
    241   // Object area size in bytes.
    242   static const int kObjectAreaSize = kPageSize - kObjectStartOffset;
    243 
    244   // Maximum object size that fits in a page.
    245   static const int kMaxHeapObjectSize = kObjectAreaSize;
    246 
    247   //---------------------------------------------------------------------------
    248   // Page header description.
    249   //
    250   // If a page is not in the large object space, the first word,
    251   // opaque_header, encodes the next page address (aligned to kPageSize 8K)
    252   // and the chunk number (0 ~ 8K-1).  Only MemoryAllocator should use
    253   // opaque_header. The value range of the opaque_header is [0..kPageSize[,
    254   // or [next_page_start, next_page_end[. It cannot point to a valid address
    255   // in the current page.  If a page is in the large object space, the first
    256   // word *may* (if the page start and large object chunk start are the
    257   // same) contain the address of the next large object chunk.
    258   intptr_t opaque_header;
    259 
    260   // If the page is not in the large object space, the low-order bit of the
    261   // second word is set. If the page is in the large object space, the
    262   // second word *may* (if the page start and large object chunk start are
    263   // the same) contain the large object chunk size.  In either case, the
    264   // low-order bit for large object pages will be cleared.
    265   int is_normal_page;
    266 
    267   // The following fields may overlap with remembered set, they can only
    268   // be used in the mark-compact collector when remembered set is not
    269   // used.
    270 
    271   // The index of the page in its owner space.
    272   int mc_page_index;
    273 
    274   // The allocation pointer after relocating objects to this page.
    275   Address mc_relocation_top;
    276 
    277   // The forwarding address of the first live object in this page.
    278   Address mc_first_forwarded;
    279 
    280 #ifdef DEBUG
    281  private:
    282   static RSetState rset_state_;  // state of the remembered set
    283 #endif
    284 };
    285 
    286 
    287 // ----------------------------------------------------------------------------
    288 // Space is the abstract superclass for all allocation spaces.
    289 class Space : public Malloced {
    290  public:
    291   Space(AllocationSpace id, Executability executable)
    292       : id_(id), executable_(executable) {}
    293 
    294   virtual ~Space() {}
    295 
    296   // Does the space need executable memory?
    297   Executability executable() { return executable_; }
    298 
    299   // Identity used in error reporting.
    300   AllocationSpace identity() { return id_; }
    301 
    302   virtual int Size() = 0;
    303 
    304 #ifdef DEBUG
    305   virtual void Print() = 0;
    306 #endif
    307 
    308   // After calling this we can allocate a certain number of bytes using only
    309   // linear allocation (with a LinearAllocationScope and an AlwaysAllocateScope)
    310   // without using freelists or causing a GC.  This is used by partial
    311   // snapshots.  It returns true of space was reserved or false if a GC is
    312   // needed.  For paged spaces the space requested must include the space wasted
    313   // at the end of each when allocating linearly.
    314   virtual bool ReserveSpace(int bytes) = 0;
    315 
    316  private:
    317   AllocationSpace id_;
    318   Executability executable_;
    319 };
    320 
    321 
    322 // ----------------------------------------------------------------------------
    323 // All heap objects containing executable code (code objects) must be allocated
    324 // from a 2 GB range of memory, so that they can call each other using 32-bit
    325 // displacements.  This happens automatically on 32-bit platforms, where 32-bit
    326 // displacements cover the entire 4GB virtual address space.  On 64-bit
    327 // platforms, we support this using the CodeRange object, which reserves and
    328 // manages a range of virtual memory.
    329 class CodeRange : public AllStatic {
    330  public:
    331   // Reserves a range of virtual memory, but does not commit any of it.
    332   // Can only be called once, at heap initialization time.
    333   // Returns false on failure.
    334   static bool Setup(const size_t requested_size);
    335 
    336   // Frees the range of virtual memory, and frees the data structures used to
    337   // manage it.
    338   static void TearDown();
    339 
    340   static bool exists() { return code_range_ != NULL; }
    341   static bool contains(Address address) {
    342     if (code_range_ == NULL) return false;
    343     Address start = static_cast<Address>(code_range_->address());
    344     return start <= address && address < start + code_range_->size();
    345   }
    346 
    347   // Allocates a chunk of memory from the large-object portion of
    348   // the code range.  On platforms with no separate code range, should
    349   // not be called.
    350   static void* AllocateRawMemory(const size_t requested, size_t* allocated);
    351   static void FreeRawMemory(void* buf, size_t length);
    352 
    353  private:
    354   // The reserved range of virtual memory that all code objects are put in.
    355   static VirtualMemory* code_range_;
    356   // Plain old data class, just a struct plus a constructor.
    357   class FreeBlock {
    358    public:
    359     FreeBlock(Address start_arg, size_t size_arg)
    360         : start(start_arg), size(size_arg) {}
    361     FreeBlock(void* start_arg, size_t size_arg)
    362         : start(static_cast<Address>(start_arg)), size(size_arg) {}
    363 
    364     Address start;
    365     size_t size;
    366   };
    367 
    368   // Freed blocks of memory are added to the free list.  When the allocation
    369   // list is exhausted, the free list is sorted and merged to make the new
    370   // allocation list.
    371   static List<FreeBlock> free_list_;
    372   // Memory is allocated from the free blocks on the allocation list.
    373   // The block at current_allocation_block_index_ is the current block.
    374   static List<FreeBlock> allocation_list_;
    375   static int current_allocation_block_index_;
    376 
    377   // Finds a block on the allocation list that contains at least the
    378   // requested amount of memory.  If none is found, sorts and merges
    379   // the existing free memory blocks, and searches again.
    380   // If none can be found, terminates V8 with FatalProcessOutOfMemory.
    381   static void GetNextAllocationBlock(size_t requested);
    382   // Compares the start addresses of two free blocks.
    383   static int CompareFreeBlockAddress(const FreeBlock* left,
    384                                      const FreeBlock* right);
    385 };
    386 
    387 
    388 // ----------------------------------------------------------------------------
    389 // A space acquires chunks of memory from the operating system. The memory
    390 // allocator manages chunks for the paged heap spaces (old space and map
    391 // space).  A paged chunk consists of pages. Pages in a chunk have contiguous
    392 // addresses and are linked as a list.
    393 //
    394 // The allocator keeps an initial chunk which is used for the new space.  The
    395 // leftover regions of the initial chunk are used for the initial chunks of
    396 // old space and map space if they are big enough to hold at least one page.
    397 // The allocator assumes that there is one old space and one map space, each
    398 // expands the space by allocating kPagesPerChunk pages except the last
    399 // expansion (before running out of space).  The first chunk may contain fewer
    400 // than kPagesPerChunk pages as well.
    401 //
    402 // The memory allocator also allocates chunks for the large object space, but
    403 // they are managed by the space itself.  The new space does not expand.
    404 
    405 class MemoryAllocator : public AllStatic {
    406  public:
    407   // Initializes its internal bookkeeping structures.
    408   // Max capacity of the total space.
    409   static bool Setup(int max_capacity);
    410 
    411   // Deletes valid chunks.
    412   static void TearDown();
    413 
    414   // Reserves an initial address range of virtual memory to be split between
    415   // the two new space semispaces, the old space, and the map space.  The
    416   // memory is not yet committed or assigned to spaces and split into pages.
    417   // The initial chunk is unmapped when the memory allocator is torn down.
    418   // This function should only be called when there is not already a reserved
    419   // initial chunk (initial_chunk_ should be NULL).  It returns the start
    420   // address of the initial chunk if successful, with the side effect of
    421   // setting the initial chunk, or else NULL if unsuccessful and leaves the
    422   // initial chunk NULL.
    423   static void* ReserveInitialChunk(const size_t requested);
    424 
    425   // Commits pages from an as-yet-unmanaged block of virtual memory into a
    426   // paged space.  The block should be part of the initial chunk reserved via
    427   // a call to ReserveInitialChunk.  The number of pages is always returned in
    428   // the output parameter num_pages.  This function assumes that the start
    429   // address is non-null and that it is big enough to hold at least one
    430   // page-aligned page.  The call always succeeds, and num_pages is always
    431   // greater than zero.
    432   static Page* CommitPages(Address start, size_t size, PagedSpace* owner,
    433                            int* num_pages);
    434 
    435   // Commit a contiguous block of memory from the initial chunk.  Assumes that
    436   // the address is not NULL, the size is greater than zero, and that the
    437   // block is contained in the initial chunk.  Returns true if it succeeded
    438   // and false otherwise.
    439   static bool CommitBlock(Address start, size_t size, Executability executable);
    440 
    441   // Uncommit a contiguous block of memory [start..(start+size)[.
    442   // start is not NULL, the size is greater than zero, and the
    443   // block is contained in the initial chunk.  Returns true if it succeeded
    444   // and false otherwise.
    445   static bool UncommitBlock(Address start, size_t size);
    446 
    447   // Zaps a contiguous block of memory [start..(start+size)[ thus
    448   // filling it up with a recognizable non-NULL bit pattern.
    449   static void ZapBlock(Address start, size_t size);
    450 
    451   // Attempts to allocate the requested (non-zero) number of pages from the
    452   // OS.  Fewer pages might be allocated than requested. If it fails to
    453   // allocate memory for the OS or cannot allocate a single page, this
    454   // function returns an invalid page pointer (NULL). The caller must check
    455   // whether the returned page is valid (by calling Page::is_valid()).  It is
    456   // guaranteed that allocated pages have contiguous addresses.  The actual
    457   // number of allocated pages is returned in the output parameter
    458   // allocated_pages.  If the PagedSpace owner is executable and there is
    459   // a code range, the pages are allocated from the code range.
    460   static Page* AllocatePages(int requested_pages, int* allocated_pages,
    461                              PagedSpace* owner);
    462 
    463   // Frees pages from a given page and after. If 'p' is the first page
    464   // of a chunk, pages from 'p' are freed and this function returns an
    465   // invalid page pointer. Otherwise, the function searches a page
    466   // after 'p' that is the first page of a chunk. Pages after the
    467   // found page are freed and the function returns 'p'.
    468   static Page* FreePages(Page* p);
    469 
    470   // Allocates and frees raw memory of certain size.
    471   // These are just thin wrappers around OS::Allocate and OS::Free,
    472   // but keep track of allocated bytes as part of heap.
    473   // If the flag is EXECUTABLE and a code range exists, the requested
    474   // memory is allocated from the code range.  If a code range exists
    475   // and the freed memory is in it, the code range manages the freed memory.
    476   static void* AllocateRawMemory(const size_t requested,
    477                                  size_t* allocated,
    478                                  Executability executable);
    479   static void FreeRawMemory(void* buf, size_t length);
    480 
    481   // Returns the maximum available bytes of heaps.
    482   static int Available() { return capacity_ < size_ ? 0 : capacity_ - size_; }
    483 
    484   // Returns allocated spaces in bytes.
    485   static int Size() { return size_; }
    486 
    487   // Returns maximum available bytes that the old space can have.
    488   static int MaxAvailable() {
    489     return (Available() / Page::kPageSize) * Page::kObjectAreaSize;
    490   }
    491 
    492   // Links two pages.
    493   static inline void SetNextPage(Page* prev, Page* next);
    494 
    495   // Returns the next page of a given page.
    496   static inline Page* GetNextPage(Page* p);
    497 
    498   // Checks whether a page belongs to a space.
    499   static inline bool IsPageInSpace(Page* p, PagedSpace* space);
    500 
    501   // Returns the space that owns the given page.
    502   static inline PagedSpace* PageOwner(Page* page);
    503 
    504   // Finds the first/last page in the same chunk as a given page.
    505   static Page* FindFirstPageInSameChunk(Page* p);
    506   static Page* FindLastPageInSameChunk(Page* p);
    507 
    508 #ifdef ENABLE_HEAP_PROTECTION
    509   // Protect/unprotect a block of memory by marking it read-only/writable.
    510   static inline void Protect(Address start, size_t size);
    511   static inline void Unprotect(Address start, size_t size,
    512                                Executability executable);
    513 
    514   // Protect/unprotect a chunk given a page in the chunk.
    515   static inline void ProtectChunkFromPage(Page* page);
    516   static inline void UnprotectChunkFromPage(Page* page);
    517 #endif
    518 
    519 #ifdef DEBUG
    520   // Reports statistic info of the space.
    521   static void ReportStatistics();
    522 #endif
    523 
    524   // Due to encoding limitation, we can only have 8K chunks.
    525   static const int kMaxNofChunks = 1 << kPageSizeBits;
    526   // If a chunk has at least 16 pages, the maximum heap size is about
    527   // 8K * 8K * 16 = 1G bytes.
    528 #ifdef V8_TARGET_ARCH_X64
    529   static const int kPagesPerChunk = 32;
    530 #else
    531   static const int kPagesPerChunk = 16;
    532 #endif
    533   static const int kChunkSize = kPagesPerChunk * Page::kPageSize;
    534 
    535  private:
    536   // Maximum space size in bytes.
    537   static int capacity_;
    538 
    539   // Allocated space size in bytes.
    540   static int size_;
    541 
    542   // The initial chunk of virtual memory.
    543   static VirtualMemory* initial_chunk_;
    544 
    545   // Allocated chunk info: chunk start address, chunk size, and owning space.
    546   class ChunkInfo BASE_EMBEDDED {
    547    public:
    548     ChunkInfo() : address_(NULL), size_(0), owner_(NULL) {}
    549     void init(Address a, size_t s, PagedSpace* o) {
    550       address_ = a;
    551       size_ = s;
    552       owner_ = o;
    553     }
    554     Address address() { return address_; }
    555     size_t size() { return size_; }
    556     PagedSpace* owner() { return owner_; }
    557 
    558    private:
    559     Address address_;
    560     size_t size_;
    561     PagedSpace* owner_;
    562   };
    563 
    564   // Chunks_, free_chunk_ids_ and top_ act as a stack of free chunk ids.
    565   static List<ChunkInfo> chunks_;
    566   static List<int> free_chunk_ids_;
    567   static int max_nof_chunks_;
    568   static int top_;
    569 
    570   // Push/pop a free chunk id onto/from the stack.
    571   static void Push(int free_chunk_id);
    572   static int Pop();
    573   static bool OutOfChunkIds() { return top_ == 0; }
    574 
    575   // Frees a chunk.
    576   static void DeleteChunk(int chunk_id);
    577 
    578   // Basic check whether a chunk id is in the valid range.
    579   static inline bool IsValidChunkId(int chunk_id);
    580 
    581   // Checks whether a chunk id identifies an allocated chunk.
    582   static inline bool IsValidChunk(int chunk_id);
    583 
    584   // Returns the chunk id that a page belongs to.
    585   static inline int GetChunkId(Page* p);
    586 
    587   // True if the address lies in the initial chunk.
    588   static inline bool InInitialChunk(Address address);
    589 
    590   // Initializes pages in a chunk. Returns the first page address.
    591   // This function and GetChunkId() are provided for the mark-compact
    592   // collector to rebuild page headers in the from space, which is
    593   // used as a marking stack and its page headers are destroyed.
    594   static Page* InitializePagesInChunk(int chunk_id, int pages_in_chunk,
    595                                       PagedSpace* owner);
    596 };
    597 
    598 
    599 // -----------------------------------------------------------------------------
    600 // Interface for heap object iterator to be implemented by all object space
    601 // object iterators.
    602 //
    603 // NOTE: The space specific object iterators also implements the own next()
    604 //       method which is used to avoid using virtual functions
    605 //       iterating a specific space.
    606 
    607 class ObjectIterator : public Malloced {
    608  public:
    609   virtual ~ObjectIterator() { }
    610 
    611   virtual HeapObject* next_object() = 0;
    612 };
    613 
    614 
    615 // -----------------------------------------------------------------------------
    616 // Heap object iterator in new/old/map spaces.
    617 //
    618 // A HeapObjectIterator iterates objects from a given address to the
    619 // top of a space. The given address must be below the current
    620 // allocation pointer (space top). There are some caveats.
    621 //
    622 // (1) If the space top changes upward during iteration (because of
    623 //     allocating new objects), the iterator does not iterate objects
    624 //     above the original space top. The caller must create a new
    625 //     iterator starting from the old top in order to visit these new
    626 //     objects.
    627 //
    628 // (2) If new objects are allocated below the original allocation top
    629 //     (e.g., free-list allocation in paged spaces), the new objects
    630 //     may or may not be iterated depending on their position with
    631 //     respect to the current point of iteration.
    632 //
    633 // (3) The space top should not change downward during iteration,
    634 //     otherwise the iterator will return not-necessarily-valid
    635 //     objects.
    636 
    637 class HeapObjectIterator: public ObjectIterator {
    638  public:
    639   // Creates a new object iterator in a given space. If a start
    640   // address is not given, the iterator starts from the space bottom.
    641   // If the size function is not given, the iterator calls the default
    642   // Object::Size().
    643   explicit HeapObjectIterator(PagedSpace* space);
    644   HeapObjectIterator(PagedSpace* space, HeapObjectCallback size_func);
    645   HeapObjectIterator(PagedSpace* space, Address start);
    646   HeapObjectIterator(PagedSpace* space,
    647                      Address start,
    648                      HeapObjectCallback size_func);
    649 
    650   inline HeapObject* next() {
    651     return (cur_addr_ < cur_limit_) ? FromCurrentPage() : FromNextPage();
    652   }
    653 
    654   // implementation of ObjectIterator.
    655   virtual HeapObject* next_object() { return next(); }
    656 
    657  private:
    658   Address cur_addr_;  // current iteration point
    659   Address end_addr_;  // end iteration point
    660   Address cur_limit_;  // current page limit
    661   HeapObjectCallback size_func_;  // size function
    662   Page* end_page_;  // caches the page of the end address
    663 
    664   HeapObject* FromCurrentPage() {
    665     ASSERT(cur_addr_ < cur_limit_);
    666 
    667     HeapObject* obj = HeapObject::FromAddress(cur_addr_);
    668     int obj_size = (size_func_ == NULL) ? obj->Size() : size_func_(obj);
    669     ASSERT_OBJECT_SIZE(obj_size);
    670 
    671     cur_addr_ += obj_size;
    672     ASSERT(cur_addr_ <= cur_limit_);
    673 
    674     return obj;
    675   }
    676 
    677   // Slow path of next, goes into the next page.
    678   HeapObject* FromNextPage();
    679 
    680   // Initializes fields.
    681   void Initialize(Address start, Address end, HeapObjectCallback size_func);
    682 
    683 #ifdef DEBUG
    684   // Verifies whether fields have valid values.
    685   void Verify();
    686 #endif
    687 };
    688 
    689 
    690 // -----------------------------------------------------------------------------
    691 // A PageIterator iterates the pages in a paged space.
    692 //
    693 // The PageIterator class provides three modes for iterating pages in a space:
    694 //   PAGES_IN_USE iterates pages containing allocated objects.
    695 //   PAGES_USED_BY_MC iterates pages that hold relocated objects during a
    696 //                    mark-compact collection.
    697 //   ALL_PAGES iterates all pages in the space.
    698 //
    699 // There are some caveats.
    700 //
    701 // (1) If the space expands during iteration, new pages will not be
    702 //     returned by the iterator in any mode.
    703 //
    704 // (2) If new objects are allocated during iteration, they will appear
    705 //     in pages returned by the iterator.  Allocation may cause the
    706 //     allocation pointer or MC allocation pointer in the last page to
    707 //     change between constructing the iterator and iterating the last
    708 //     page.
    709 //
    710 // (3) The space should not shrink during iteration, otherwise the
    711 //     iterator will return deallocated pages.
    712 
    713 class PageIterator BASE_EMBEDDED {
    714  public:
    715   enum Mode {
    716     PAGES_IN_USE,
    717     PAGES_USED_BY_MC,
    718     ALL_PAGES
    719   };
    720 
    721   PageIterator(PagedSpace* space, Mode mode);
    722 
    723   inline bool has_next();
    724   inline Page* next();
    725 
    726  private:
    727   PagedSpace* space_;
    728   Page* prev_page_;  // Previous page returned.
    729   Page* stop_page_;  // Page to stop at (last page returned by the iterator).
    730 };
    731 
    732 
    733 // -----------------------------------------------------------------------------
    734 // A space has a list of pages. The next page can be accessed via
    735 // Page::next_page() call. The next page of the last page is an
    736 // invalid page pointer. A space can expand and shrink dynamically.
    737 
    738 // An abstraction of allocation and relocation pointers in a page-structured
    739 // space.
    740 class AllocationInfo {
    741  public:
    742   Address top;  // current allocation top
    743   Address limit;  // current allocation limit
    744 
    745 #ifdef DEBUG
    746   bool VerifyPagedAllocation() {
    747     return (Page::FromAllocationTop(top) == Page::FromAllocationTop(limit))
    748         && (top <= limit);
    749   }
    750 #endif
    751 };
    752 
    753 
    754 // An abstraction of the accounting statistics of a page-structured space.
    755 // The 'capacity' of a space is the number of object-area bytes (ie, not
    756 // including page bookkeeping structures) currently in the space. The 'size'
    757 // of a space is the number of allocated bytes, the 'waste' in the space is
    758 // the number of bytes that are not allocated and not available to
    759 // allocation without reorganizing the space via a GC (eg, small blocks due
    760 // to internal fragmentation, top of page areas in map space), and the bytes
    761 // 'available' is the number of unallocated bytes that are not waste.  The
    762 // capacity is the sum of size, waste, and available.
    763 //
    764 // The stats are only set by functions that ensure they stay balanced. These
    765 // functions increase or decrease one of the non-capacity stats in
    766 // conjunction with capacity, or else they always balance increases and
    767 // decreases to the non-capacity stats.
    768 class AllocationStats BASE_EMBEDDED {
    769  public:
    770   AllocationStats() { Clear(); }
    771 
    772   // Zero out all the allocation statistics (ie, no capacity).
    773   void Clear() {
    774     capacity_ = 0;
    775     available_ = 0;
    776     size_ = 0;
    777     waste_ = 0;
    778   }
    779 
    780   // Reset the allocation statistics (ie, available = capacity with no
    781   // wasted or allocated bytes).
    782   void Reset() {
    783     available_ = capacity_;
    784     size_ = 0;
    785     waste_ = 0;
    786   }
    787 
    788   // Accessors for the allocation statistics.
    789   int Capacity() { return capacity_; }
    790   int Available() { return available_; }
    791   int Size() { return size_; }
    792   int Waste() { return waste_; }
    793 
    794   // Grow the space by adding available bytes.
    795   void ExpandSpace(int size_in_bytes) {
    796     capacity_ += size_in_bytes;
    797     available_ += size_in_bytes;
    798   }
    799 
    800   // Shrink the space by removing available bytes.
    801   void ShrinkSpace(int size_in_bytes) {
    802     capacity_ -= size_in_bytes;
    803     available_ -= size_in_bytes;
    804   }
    805 
    806   // Allocate from available bytes (available -> size).
    807   void AllocateBytes(int size_in_bytes) {
    808     available_ -= size_in_bytes;
    809     size_ += size_in_bytes;
    810   }
    811 
    812   // Free allocated bytes, making them available (size -> available).
    813   void DeallocateBytes(int size_in_bytes) {
    814     size_ -= size_in_bytes;
    815     available_ += size_in_bytes;
    816   }
    817 
    818   // Waste free bytes (available -> waste).
    819   void WasteBytes(int size_in_bytes) {
    820     available_ -= size_in_bytes;
    821     waste_ += size_in_bytes;
    822   }
    823 
    824   // Consider the wasted bytes to be allocated, as they contain filler
    825   // objects (waste -> size).
    826   void FillWastedBytes(int size_in_bytes) {
    827     waste_ -= size_in_bytes;
    828     size_ += size_in_bytes;
    829   }
    830 
    831  private:
    832   int capacity_;
    833   int available_;
    834   int size_;
    835   int waste_;
    836 };
    837 
    838 
    839 class PagedSpace : public Space {
    840  public:
    841   // Creates a space with a maximum capacity, and an id.
    842   PagedSpace(int max_capacity, AllocationSpace id, Executability executable);
    843 
    844   virtual ~PagedSpace() {}
    845 
    846   // Set up the space using the given address range of virtual memory (from
    847   // the memory allocator's initial chunk) if possible.  If the block of
    848   // addresses is not big enough to contain a single page-aligned page, a
    849   // fresh chunk will be allocated.
    850   bool Setup(Address start, size_t size);
    851 
    852   // Returns true if the space has been successfully set up and not
    853   // subsequently torn down.
    854   bool HasBeenSetup();
    855 
    856   // Cleans up the space, frees all pages in this space except those belonging
    857   // to the initial chunk, uncommits addresses in the initial chunk.
    858   void TearDown();
    859 
    860   // Checks whether an object/address is in this space.
    861   inline bool Contains(Address a);
    862   bool Contains(HeapObject* o) { return Contains(o->address()); }
    863 
    864   // Given an address occupied by a live object, return that object if it is
    865   // in this space, or Failure::Exception() if it is not. The implementation
    866   // iterates over objects in the page containing the address, the cost is
    867   // linear in the number of objects in the page. It may be slow.
    868   Object* FindObject(Address addr);
    869 
    870   // Checks whether page is currently in use by this space.
    871   bool IsUsed(Page* page);
    872 
    873   // Clears remembered sets of pages in this space.
    874   void ClearRSet();
    875 
    876   // Prepares for a mark-compact GC.
    877   virtual void PrepareForMarkCompact(bool will_compact) = 0;
    878 
    879   virtual Address PageAllocationTop(Page* page) = 0;
    880 
    881   // Current capacity without growing (Size() + Available() + Waste()).
    882   int Capacity() { return accounting_stats_.Capacity(); }
    883 
    884   // Total amount of memory committed for this space.  For paged
    885   // spaces this equals the capacity.
    886   int CommittedMemory() { return Capacity(); }
    887 
    888   // Available bytes without growing.
    889   int Available() { return accounting_stats_.Available(); }
    890 
    891   // Allocated bytes in this space.
    892   virtual int Size() { return accounting_stats_.Size(); }
    893 
    894   // Wasted bytes due to fragmentation and not recoverable until the
    895   // next GC of this space.
    896   int Waste() { return accounting_stats_.Waste(); }
    897 
    898   // Returns the address of the first object in this space.
    899   Address bottom() { return first_page_->ObjectAreaStart(); }
    900 
    901   // Returns the allocation pointer in this space.
    902   Address top() { return allocation_info_.top; }
    903 
    904   // Allocate the requested number of bytes in the space if possible, return a
    905   // failure object if not.
    906   inline Object* AllocateRaw(int size_in_bytes);
    907 
    908   // Allocate the requested number of bytes for relocation during mark-compact
    909   // collection.
    910   inline Object* MCAllocateRaw(int size_in_bytes);
    911 
    912   virtual bool ReserveSpace(int bytes);
    913 
    914   // Used by ReserveSpace.
    915   virtual void PutRestOfCurrentPageOnFreeList(Page* current_page) = 0;
    916 
    917   // ---------------------------------------------------------------------------
    918   // Mark-compact collection support functions
    919 
    920   // Set the relocation point to the beginning of the space.
    921   void MCResetRelocationInfo();
    922 
    923   // Writes relocation info to the top page.
    924   void MCWriteRelocationInfoToPage() {
    925     TopPageOf(mc_forwarding_info_)->mc_relocation_top = mc_forwarding_info_.top;
    926   }
    927 
    928   // Computes the offset of a given address in this space to the beginning
    929   // of the space.
    930   int MCSpaceOffsetForAddress(Address addr);
    931 
    932   // Updates the allocation pointer to the relocation top after a mark-compact
    933   // collection.
    934   virtual void MCCommitRelocationInfo() = 0;
    935 
    936   // Releases half of unused pages.
    937   void Shrink();
    938 
    939   // Ensures that the capacity is at least 'capacity'. Returns false on failure.
    940   bool EnsureCapacity(int capacity);
    941 
    942 #ifdef ENABLE_HEAP_PROTECTION
    943   // Protect/unprotect the space by marking it read-only/writable.
    944   void Protect();
    945   void Unprotect();
    946 #endif
    947 
    948 #ifdef DEBUG
    949   // Print meta info and objects in this space.
    950   virtual void Print();
    951 
    952   // Verify integrity of this space.
    953   virtual void Verify(ObjectVisitor* visitor);
    954 
    955   // Overridden by subclasses to verify space-specific object
    956   // properties (e.g., only maps or free-list nodes are in map space).
    957   virtual void VerifyObject(HeapObject* obj) {}
    958 
    959   // Report code object related statistics
    960   void CollectCodeStatistics();
    961   static void ReportCodeStatistics();
    962   static void ResetCodeStatistics();
    963 #endif
    964 
    965  protected:
    966   // Maximum capacity of this space.
    967   int max_capacity_;
    968 
    969   // Accounting information for this space.
    970   AllocationStats accounting_stats_;
    971 
    972   // The first page in this space.
    973   Page* first_page_;
    974 
    975   // The last page in this space.  Initially set in Setup, updated in
    976   // Expand and Shrink.
    977   Page* last_page_;
    978 
    979   // Normal allocation information.
    980   AllocationInfo allocation_info_;
    981 
    982   // Relocation information during mark-compact collections.
    983   AllocationInfo mc_forwarding_info_;
    984 
    985   // Bytes of each page that cannot be allocated.  Possibly non-zero
    986   // for pages in spaces with only fixed-size objects.  Always zero
    987   // for pages in spaces with variable sized objects (those pages are
    988   // padded with free-list nodes).
    989   int page_extra_;
    990 
    991   // Sets allocation pointer to a page bottom.
    992   static void SetAllocationInfo(AllocationInfo* alloc_info, Page* p);
    993 
    994   // Returns the top page specified by an allocation info structure.
    995   static Page* TopPageOf(AllocationInfo alloc_info) {
    996     return Page::FromAllocationTop(alloc_info.limit);
    997   }
    998 
    999   int CountPagesToTop() {
   1000     Page* p = Page::FromAllocationTop(allocation_info_.top);
   1001     PageIterator it(this, PageIterator::ALL_PAGES);
   1002     int counter = 1;
   1003     while (it.has_next()) {
   1004       if (it.next() == p) return counter;
   1005       counter++;
   1006     }
   1007     UNREACHABLE();
   1008     return -1;
   1009   }
   1010 
   1011   // Expands the space by allocating a fixed number of pages. Returns false if
   1012   // it cannot allocate requested number of pages from OS. Newly allocated
   1013   // pages are append to the last_page;
   1014   bool Expand(Page* last_page);
   1015 
   1016   // Generic fast case allocation function that tries linear allocation in
   1017   // the top page of 'alloc_info'.  Returns NULL on failure.
   1018   inline HeapObject* AllocateLinearly(AllocationInfo* alloc_info,
   1019                                       int size_in_bytes);
   1020 
   1021   // During normal allocation or deserialization, roll to the next page in
   1022   // the space (there is assumed to be one) and allocate there.  This
   1023   // function is space-dependent.
   1024   virtual HeapObject* AllocateInNextPage(Page* current_page,
   1025                                          int size_in_bytes) = 0;
   1026 
   1027   // Slow path of AllocateRaw.  This function is space-dependent.
   1028   virtual HeapObject* SlowAllocateRaw(int size_in_bytes) = 0;
   1029 
   1030   // Slow path of MCAllocateRaw.
   1031   HeapObject* SlowMCAllocateRaw(int size_in_bytes);
   1032 
   1033 #ifdef DEBUG
   1034   // Returns the number of total pages in this space.
   1035   int CountTotalPages();
   1036 
   1037   void DoPrintRSet(const char* space_name);
   1038 #endif
   1039  private:
   1040   // Returns the page of the allocation pointer.
   1041   Page* AllocationTopPage() { return TopPageOf(allocation_info_); }
   1042 
   1043   // Returns a pointer to the page of the relocation pointer.
   1044   Page* MCRelocationTopPage() { return TopPageOf(mc_forwarding_info_); }
   1045 
   1046   friend class PageIterator;
   1047 };
   1048 
   1049 
   1050 #if defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING)
   1051 class NumberAndSizeInfo BASE_EMBEDDED {
   1052  public:
   1053   NumberAndSizeInfo() : number_(0), bytes_(0) {}
   1054 
   1055   int number() const { return number_; }
   1056   void increment_number(int num) { number_ += num; }
   1057 
   1058   int bytes() const { return bytes_; }
   1059   void increment_bytes(int size) { bytes_ += size; }
   1060 
   1061   void clear() {
   1062     number_ = 0;
   1063     bytes_ = 0;
   1064   }
   1065 
   1066  private:
   1067   int number_;
   1068   int bytes_;
   1069 };
   1070 
   1071 
   1072 // HistogramInfo class for recording a single "bar" of a histogram.  This
   1073 // class is used for collecting statistics to print to stdout (when compiled
   1074 // with DEBUG) or to the log file (when compiled with
   1075 // ENABLE_LOGGING_AND_PROFILING).
   1076 class HistogramInfo: public NumberAndSizeInfo {
   1077  public:
   1078   HistogramInfo() : NumberAndSizeInfo() {}
   1079 
   1080   const char* name() { return name_; }
   1081   void set_name(const char* name) { name_ = name; }
   1082 
   1083  private:
   1084   const char* name_;
   1085 };
   1086 #endif
   1087 
   1088 
   1089 // -----------------------------------------------------------------------------
   1090 // SemiSpace in young generation
   1091 //
   1092 // A semispace is a contiguous chunk of memory. The mark-compact collector
   1093 // uses the memory in the from space as a marking stack when tracing live
   1094 // objects.
   1095 
   1096 class SemiSpace : public Space {
   1097  public:
   1098   // Constructor.
   1099   SemiSpace() :Space(NEW_SPACE, NOT_EXECUTABLE) {
   1100     start_ = NULL;
   1101     age_mark_ = NULL;
   1102   }
   1103 
   1104   // Sets up the semispace using the given chunk.
   1105   bool Setup(Address start, int initial_capacity, int maximum_capacity);
   1106 
   1107   // Tear down the space.  Heap memory was not allocated by the space, so it
   1108   // is not deallocated here.
   1109   void TearDown();
   1110 
   1111   // True if the space has been set up but not torn down.
   1112   bool HasBeenSetup() { return start_ != NULL; }
   1113 
   1114   // Grow the size of the semispace by committing extra virtual memory.
   1115   // Assumes that the caller has checked that the semispace has not reached
   1116   // its maximum capacity (and thus there is space available in the reserved
   1117   // address range to grow).
   1118   bool Grow();
   1119 
   1120   // Grow the semispace to the new capacity.  The new capacity
   1121   // requested must be larger than the current capacity.
   1122   bool GrowTo(int new_capacity);
   1123 
   1124   // Shrinks the semispace to the new capacity.  The new capacity
   1125   // requested must be more than the amount of used memory in the
   1126   // semispace and less than the current capacity.
   1127   bool ShrinkTo(int new_capacity);
   1128 
   1129   // Returns the start address of the space.
   1130   Address low() { return start_; }
   1131   // Returns one past the end address of the space.
   1132   Address high() { return low() + capacity_; }
   1133 
   1134   // Age mark accessors.
   1135   Address age_mark() { return age_mark_; }
   1136   void set_age_mark(Address mark) { age_mark_ = mark; }
   1137 
   1138   // True if the address is in the address range of this semispace (not
   1139   // necessarily below the allocation pointer).
   1140   bool Contains(Address a) {
   1141     return (reinterpret_cast<uintptr_t>(a) & address_mask_)
   1142            == reinterpret_cast<uintptr_t>(start_);
   1143   }
   1144 
   1145   // True if the object is a heap object in the address range of this
   1146   // semispace (not necessarily below the allocation pointer).
   1147   bool Contains(Object* o) {
   1148     return (reinterpret_cast<uintptr_t>(o) & object_mask_) == object_expected_;
   1149   }
   1150 
   1151   // The offset of an address from the beginning of the space.
   1152   int SpaceOffsetForAddress(Address addr) {
   1153     return static_cast<int>(addr - low());
   1154   }
   1155 
   1156   // If we don't have these here then SemiSpace will be abstract.  However
   1157   // they should never be called.
   1158   virtual int Size() {
   1159     UNREACHABLE();
   1160     return 0;
   1161   }
   1162 
   1163   virtual bool ReserveSpace(int bytes) {
   1164     UNREACHABLE();
   1165     return false;
   1166   }
   1167 
   1168   bool is_committed() { return committed_; }
   1169   bool Commit();
   1170   bool Uncommit();
   1171 
   1172 #ifdef DEBUG
   1173   virtual void Print();
   1174   virtual void Verify();
   1175 #endif
   1176 
   1177   // Returns the current capacity of the semi space.
   1178   int Capacity() { return capacity_; }
   1179 
   1180   // Returns the maximum capacity of the semi space.
   1181   int MaximumCapacity() { return maximum_capacity_; }
   1182 
   1183   // Returns the initial capacity of the semi space.
   1184   int InitialCapacity() { return initial_capacity_; }
   1185 
   1186  private:
   1187   // The current and maximum capacity of the space.
   1188   int capacity_;
   1189   int maximum_capacity_;
   1190   int initial_capacity_;
   1191 
   1192   // The start address of the space.
   1193   Address start_;
   1194   // Used to govern object promotion during mark-compact collection.
   1195   Address age_mark_;
   1196 
   1197   // Masks and comparison values to test for containment in this semispace.
   1198   uintptr_t address_mask_;
   1199   uintptr_t object_mask_;
   1200   uintptr_t object_expected_;
   1201 
   1202   bool committed_;
   1203 
   1204  public:
   1205   TRACK_MEMORY("SemiSpace")
   1206 };
   1207 
   1208 
   1209 // A SemiSpaceIterator is an ObjectIterator that iterates over the active
   1210 // semispace of the heap's new space.  It iterates over the objects in the
   1211 // semispace from a given start address (defaulting to the bottom of the
   1212 // semispace) to the top of the semispace.  New objects allocated after the
   1213 // iterator is created are not iterated.
   1214 class SemiSpaceIterator : public ObjectIterator {
   1215  public:
   1216   // Create an iterator over the objects in the given space.  If no start
   1217   // address is given, the iterator starts from the bottom of the space.  If
   1218   // no size function is given, the iterator calls Object::Size().
   1219   explicit SemiSpaceIterator(NewSpace* space);
   1220   SemiSpaceIterator(NewSpace* space, HeapObjectCallback size_func);
   1221   SemiSpaceIterator(NewSpace* space, Address start);
   1222 
   1223   HeapObject* next() {
   1224     if (current_ == limit_) return NULL;
   1225 
   1226     HeapObject* object = HeapObject::FromAddress(current_);
   1227     int size = (size_func_ == NULL) ? object->Size() : size_func_(object);
   1228 
   1229     current_ += size;
   1230     return object;
   1231   }
   1232 
   1233   // Implementation of the ObjectIterator functions.
   1234   virtual HeapObject* next_object() { return next(); }
   1235 
   1236  private:
   1237   void Initialize(NewSpace* space, Address start, Address end,
   1238                   HeapObjectCallback size_func);
   1239 
   1240   // The semispace.
   1241   SemiSpace* space_;
   1242   // The current iteration point.
   1243   Address current_;
   1244   // The end of iteration.
   1245   Address limit_;
   1246   // The callback function.
   1247   HeapObjectCallback size_func_;
   1248 };
   1249 
   1250 
   1251 // -----------------------------------------------------------------------------
   1252 // The young generation space.
   1253 //
   1254 // The new space consists of a contiguous pair of semispaces.  It simply
   1255 // forwards most functions to the appropriate semispace.
   1256 
   1257 class NewSpace : public Space {
   1258  public:
   1259   // Constructor.
   1260   NewSpace() : Space(NEW_SPACE, NOT_EXECUTABLE) {}
   1261 
   1262   // Sets up the new space using the given chunk.
   1263   bool Setup(Address start, int size);
   1264 
   1265   // Tears down the space.  Heap memory was not allocated by the space, so it
   1266   // is not deallocated here.
   1267   void TearDown();
   1268 
   1269   // True if the space has been set up but not torn down.
   1270   bool HasBeenSetup() {
   1271     return to_space_.HasBeenSetup() && from_space_.HasBeenSetup();
   1272   }
   1273 
   1274   // Flip the pair of spaces.
   1275   void Flip();
   1276 
   1277   // Grow the capacity of the semispaces.  Assumes that they are not at
   1278   // their maximum capacity.
   1279   void Grow();
   1280 
   1281   // Shrink the capacity of the semispaces.
   1282   void Shrink();
   1283 
   1284   // True if the address or object lies in the address range of either
   1285   // semispace (not necessarily below the allocation pointer).
   1286   bool Contains(Address a) {
   1287     return (reinterpret_cast<uintptr_t>(a) & address_mask_)
   1288         == reinterpret_cast<uintptr_t>(start_);
   1289   }
   1290   bool Contains(Object* o) {
   1291     return (reinterpret_cast<uintptr_t>(o) & object_mask_) == object_expected_;
   1292   }
   1293 
   1294   // Return the allocated bytes in the active semispace.
   1295   virtual int Size() { return static_cast<int>(top() - bottom()); }
   1296 
   1297   // Return the current capacity of a semispace.
   1298   int Capacity() {
   1299     ASSERT(to_space_.Capacity() == from_space_.Capacity());
   1300     return to_space_.Capacity();
   1301   }
   1302 
   1303   // Return the total amount of memory committed for new space.
   1304   int CommittedMemory() {
   1305     if (from_space_.is_committed()) return 2 * Capacity();
   1306     return Capacity();
   1307   }
   1308 
   1309   // Return the available bytes without growing in the active semispace.
   1310   int Available() { return Capacity() - Size(); }
   1311 
   1312   // Return the maximum capacity of a semispace.
   1313   int MaximumCapacity() {
   1314     ASSERT(to_space_.MaximumCapacity() == from_space_.MaximumCapacity());
   1315     return to_space_.MaximumCapacity();
   1316   }
   1317 
   1318   // Returns the initial capacity of a semispace.
   1319   int InitialCapacity() {
   1320     ASSERT(to_space_.InitialCapacity() == from_space_.InitialCapacity());
   1321     return to_space_.InitialCapacity();
   1322   }
   1323 
   1324   // Return the address of the allocation pointer in the active semispace.
   1325   Address top() { return allocation_info_.top; }
   1326   // Return the address of the first object in the active semispace.
   1327   Address bottom() { return to_space_.low(); }
   1328 
   1329   // Get the age mark of the inactive semispace.
   1330   Address age_mark() { return from_space_.age_mark(); }
   1331   // Set the age mark in the active semispace.
   1332   void set_age_mark(Address mark) { to_space_.set_age_mark(mark); }
   1333 
   1334   // The start address of the space and a bit mask. Anding an address in the
   1335   // new space with the mask will result in the start address.
   1336   Address start() { return start_; }
   1337   uintptr_t mask() { return address_mask_; }
   1338 
   1339   // The allocation top and limit addresses.
   1340   Address* allocation_top_address() { return &allocation_info_.top; }
   1341   Address* allocation_limit_address() { return &allocation_info_.limit; }
   1342 
   1343   Object* AllocateRaw(int size_in_bytes) {
   1344     return AllocateRawInternal(size_in_bytes, &allocation_info_);
   1345   }
   1346 
   1347   // Allocate the requested number of bytes for relocation during mark-compact
   1348   // collection.
   1349   Object* MCAllocateRaw(int size_in_bytes) {
   1350     return AllocateRawInternal(size_in_bytes, &mc_forwarding_info_);
   1351   }
   1352 
   1353   // Reset the allocation pointer to the beginning of the active semispace.
   1354   void ResetAllocationInfo();
   1355   // Reset the reloction pointer to the bottom of the inactive semispace in
   1356   // preparation for mark-compact collection.
   1357   void MCResetRelocationInfo();
   1358   // Update the allocation pointer in the active semispace after a
   1359   // mark-compact collection.
   1360   void MCCommitRelocationInfo();
   1361 
   1362   // Get the extent of the inactive semispace (for use as a marking stack).
   1363   Address FromSpaceLow() { return from_space_.low(); }
   1364   Address FromSpaceHigh() { return from_space_.high(); }
   1365 
   1366   // Get the extent of the active semispace (to sweep newly copied objects
   1367   // during a scavenge collection).
   1368   Address ToSpaceLow() { return to_space_.low(); }
   1369   Address ToSpaceHigh() { return to_space_.high(); }
   1370 
   1371   // Offsets from the beginning of the semispaces.
   1372   int ToSpaceOffsetForAddress(Address a) {
   1373     return to_space_.SpaceOffsetForAddress(a);
   1374   }
   1375   int FromSpaceOffsetForAddress(Address a) {
   1376     return from_space_.SpaceOffsetForAddress(a);
   1377   }
   1378 
   1379   // True if the object is a heap object in the address range of the
   1380   // respective semispace (not necessarily below the allocation pointer of the
   1381   // semispace).
   1382   bool ToSpaceContains(Object* o) { return to_space_.Contains(o); }
   1383   bool FromSpaceContains(Object* o) { return from_space_.Contains(o); }
   1384 
   1385   bool ToSpaceContains(Address a) { return to_space_.Contains(a); }
   1386   bool FromSpaceContains(Address a) { return from_space_.Contains(a); }
   1387 
   1388   virtual bool ReserveSpace(int bytes);
   1389 
   1390 #ifdef ENABLE_HEAP_PROTECTION
   1391   // Protect/unprotect the space by marking it read-only/writable.
   1392   virtual void Protect();
   1393   virtual void Unprotect();
   1394 #endif
   1395 
   1396 #ifdef DEBUG
   1397   // Verify the active semispace.
   1398   virtual void Verify();
   1399   // Print the active semispace.
   1400   virtual void Print() { to_space_.Print(); }
   1401 #endif
   1402 
   1403 #if defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING)
   1404   // Iterates the active semispace to collect statistics.
   1405   void CollectStatistics();
   1406   // Reports previously collected statistics of the active semispace.
   1407   void ReportStatistics();
   1408   // Clears previously collected statistics.
   1409   void ClearHistograms();
   1410 
   1411   // Record the allocation or promotion of a heap object.  Note that we don't
   1412   // record every single allocation, but only those that happen in the
   1413   // to space during a scavenge GC.
   1414   void RecordAllocation(HeapObject* obj);
   1415   void RecordPromotion(HeapObject* obj);
   1416 #endif
   1417 
   1418   // Return whether the operation succeded.
   1419   bool CommitFromSpaceIfNeeded() {
   1420     if (from_space_.is_committed()) return true;
   1421     return from_space_.Commit();
   1422   }
   1423 
   1424   bool UncommitFromSpace() {
   1425     if (!from_space_.is_committed()) return true;
   1426     return from_space_.Uncommit();
   1427   }
   1428 
   1429  private:
   1430   // The semispaces.
   1431   SemiSpace to_space_;
   1432   SemiSpace from_space_;
   1433 
   1434   // Start address and bit mask for containment testing.
   1435   Address start_;
   1436   uintptr_t address_mask_;
   1437   uintptr_t object_mask_;
   1438   uintptr_t object_expected_;
   1439 
   1440   // Allocation pointer and limit for normal allocation and allocation during
   1441   // mark-compact collection.
   1442   AllocationInfo allocation_info_;
   1443   AllocationInfo mc_forwarding_info_;
   1444 
   1445 #if defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING)
   1446   HistogramInfo* allocated_histogram_;
   1447   HistogramInfo* promoted_histogram_;
   1448 #endif
   1449 
   1450   // Implementation of AllocateRaw and MCAllocateRaw.
   1451   inline Object* AllocateRawInternal(int size_in_bytes,
   1452                                      AllocationInfo* alloc_info);
   1453 
   1454   friend class SemiSpaceIterator;
   1455 
   1456  public:
   1457   TRACK_MEMORY("NewSpace")
   1458 };
   1459 
   1460 
   1461 // -----------------------------------------------------------------------------
   1462 // Free lists for old object spaces
   1463 //
   1464 // Free-list nodes are free blocks in the heap.  They look like heap objects
   1465 // (free-list node pointers have the heap object tag, and they have a map like
   1466 // a heap object).  They have a size and a next pointer.  The next pointer is
   1467 // the raw address of the next free list node (or NULL).
   1468 class FreeListNode: public HeapObject {
   1469  public:
   1470   // Obtain a free-list node from a raw address.  This is not a cast because
   1471   // it does not check nor require that the first word at the address is a map
   1472   // pointer.
   1473   static FreeListNode* FromAddress(Address address) {
   1474     return reinterpret_cast<FreeListNode*>(HeapObject::FromAddress(address));
   1475   }
   1476 
   1477   static inline bool IsFreeListNode(HeapObject* object);
   1478 
   1479   // Set the size in bytes, which can be read with HeapObject::Size().  This
   1480   // function also writes a map to the first word of the block so that it
   1481   // looks like a heap object to the garbage collector and heap iteration
   1482   // functions.
   1483   void set_size(int size_in_bytes);
   1484 
   1485   // Accessors for the next field.
   1486   inline Address next();
   1487   inline void set_next(Address next);
   1488 
   1489  private:
   1490   static const int kNextOffset = POINTER_SIZE_ALIGN(ByteArray::kHeaderSize);
   1491 
   1492   DISALLOW_IMPLICIT_CONSTRUCTORS(FreeListNode);
   1493 };
   1494 
   1495 
   1496 // The free list for the old space.
   1497 class OldSpaceFreeList BASE_EMBEDDED {
   1498  public:
   1499   explicit OldSpaceFreeList(AllocationSpace owner);
   1500 
   1501   // Clear the free list.
   1502   void Reset();
   1503 
   1504   // Return the number of bytes available on the free list.
   1505   int available() { return available_; }
   1506 
   1507   // Place a node on the free list.  The block of size 'size_in_bytes'
   1508   // starting at 'start' is placed on the free list.  The return value is the
   1509   // number of bytes that have been lost due to internal fragmentation by
   1510   // freeing the block.  Bookkeeping information will be written to the block,
   1511   // ie, its contents will be destroyed.  The start address should be word
   1512   // aligned, and the size should be a non-zero multiple of the word size.
   1513   int Free(Address start, int size_in_bytes);
   1514 
   1515   // Allocate a block of size 'size_in_bytes' from the free list.  The block
   1516   // is unitialized.  A failure is returned if no block is available.  The
   1517   // number of bytes lost to fragmentation is returned in the output parameter
   1518   // 'wasted_bytes'.  The size should be a non-zero multiple of the word size.
   1519   Object* Allocate(int size_in_bytes, int* wasted_bytes);
   1520 
   1521  private:
   1522   // The size range of blocks, in bytes. (Smaller allocations are allowed, but
   1523   // will always result in waste.)
   1524   static const int kMinBlockSize = 2 * kPointerSize;
   1525   static const int kMaxBlockSize = Page::kMaxHeapObjectSize;
   1526 
   1527   // The identity of the owning space, for building allocation Failure
   1528   // objects.
   1529   AllocationSpace owner_;
   1530 
   1531   // Total available bytes in all blocks on this free list.
   1532   int available_;
   1533 
   1534   // Blocks are put on exact free lists in an array, indexed by size in words.
   1535   // The available sizes are kept in an increasingly ordered list. Entries
   1536   // corresponding to sizes < kMinBlockSize always have an empty free list
   1537   // (but index kHead is used for the head of the size list).
   1538   struct SizeNode {
   1539     // Address of the head FreeListNode of the implied block size or NULL.
   1540     Address head_node_;
   1541     // Size (words) of the next larger available size if head_node_ != NULL.
   1542     int next_size_;
   1543   };
   1544   static const int kFreeListsLength = kMaxBlockSize / kPointerSize + 1;
   1545   SizeNode free_[kFreeListsLength];
   1546 
   1547   // Sentinel elements for the size list. Real elements are in ]kHead..kEnd[.
   1548   static const int kHead = kMinBlockSize / kPointerSize - 1;
   1549   static const int kEnd = kMaxInt;
   1550 
   1551   // We keep a "finger" in the size list to speed up a common pattern:
   1552   // repeated requests for the same or increasing sizes.
   1553   int finger_;
   1554 
   1555   // Starting from *prev, find and return the smallest size >= index (words),
   1556   // or kEnd. Update *prev to be the largest size < index, or kHead.
   1557   int FindSize(int index, int* prev) {
   1558     int cur = free_[*prev].next_size_;
   1559     while (cur < index) {
   1560       *prev = cur;
   1561       cur = free_[cur].next_size_;
   1562     }
   1563     return cur;
   1564   }
   1565 
   1566   // Remove an existing element from the size list.
   1567   void RemoveSize(int index) {
   1568     int prev = kHead;
   1569     int cur = FindSize(index, &prev);
   1570     ASSERT(cur == index);
   1571     free_[prev].next_size_ = free_[cur].next_size_;
   1572     finger_ = prev;
   1573   }
   1574 
   1575   // Insert a new element into the size list.
   1576   void InsertSize(int index) {
   1577     int prev = kHead;
   1578     int cur = FindSize(index, &prev);
   1579     ASSERT(cur != index);
   1580     free_[prev].next_size_ = index;
   1581     free_[index].next_size_ = cur;
   1582   }
   1583 
   1584   // The size list is not updated during a sequence of calls to Free, but is
   1585   // rebuilt before the next allocation.
   1586   void RebuildSizeList();
   1587   bool needs_rebuild_;
   1588 
   1589 #ifdef DEBUG
   1590   // Does this free list contain a free block located at the address of 'node'?
   1591   bool Contains(FreeListNode* node);
   1592 #endif
   1593 
   1594   DISALLOW_COPY_AND_ASSIGN(OldSpaceFreeList);
   1595 };
   1596 
   1597 
   1598 // The free list for the map space.
   1599 class FixedSizeFreeList BASE_EMBEDDED {
   1600  public:
   1601   FixedSizeFreeList(AllocationSpace owner, int object_size);
   1602 
   1603   // Clear the free list.
   1604   void Reset();
   1605 
   1606   // Return the number of bytes available on the free list.
   1607   int available() { return available_; }
   1608 
   1609   // Place a node on the free list.  The block starting at 'start' (assumed to
   1610   // have size object_size_) is placed on the free list.  Bookkeeping
   1611   // information will be written to the block, ie, its contents will be
   1612   // destroyed.  The start address should be word aligned.
   1613   void Free(Address start);
   1614 
   1615   // Allocate a fixed sized block from the free list.  The block is unitialized.
   1616   // A failure is returned if no block is available.
   1617   Object* Allocate();
   1618 
   1619  private:
   1620   // Available bytes on the free list.
   1621   int available_;
   1622 
   1623   // The head of the free list.
   1624   Address head_;
   1625 
   1626   // The identity of the owning space, for building allocation Failure
   1627   // objects.
   1628   AllocationSpace owner_;
   1629 
   1630   // The size of the objects in this space.
   1631   int object_size_;
   1632 
   1633   DISALLOW_COPY_AND_ASSIGN(FixedSizeFreeList);
   1634 };
   1635 
   1636 
   1637 // -----------------------------------------------------------------------------
   1638 // Old object space (excluding map objects)
   1639 
   1640 class OldSpace : public PagedSpace {
   1641  public:
   1642   // Creates an old space object with a given maximum capacity.
   1643   // The constructor does not allocate pages from OS.
   1644   explicit OldSpace(int max_capacity,
   1645                     AllocationSpace id,
   1646                     Executability executable)
   1647       : PagedSpace(max_capacity, id, executable), free_list_(id) {
   1648     page_extra_ = 0;
   1649   }
   1650 
   1651   // The bytes available on the free list (ie, not above the linear allocation
   1652   // pointer).
   1653   int AvailableFree() { return free_list_.available(); }
   1654 
   1655   // The top of allocation in a page in this space. Undefined if page is unused.
   1656   virtual Address PageAllocationTop(Page* page) {
   1657     return page == TopPageOf(allocation_info_) ? top() : page->ObjectAreaEnd();
   1658   }
   1659 
   1660   // Give a block of memory to the space's free list.  It might be added to
   1661   // the free list or accounted as waste.
   1662   void Free(Address start, int size_in_bytes) {
   1663     int wasted_bytes = free_list_.Free(start, size_in_bytes);
   1664     accounting_stats_.DeallocateBytes(size_in_bytes);
   1665     accounting_stats_.WasteBytes(wasted_bytes);
   1666   }
   1667 
   1668   // Prepare for full garbage collection.  Resets the relocation pointer and
   1669   // clears the free list.
   1670   virtual void PrepareForMarkCompact(bool will_compact);
   1671 
   1672   // Updates the allocation pointer to the relocation top after a mark-compact
   1673   // collection.
   1674   virtual void MCCommitRelocationInfo();
   1675 
   1676   virtual void PutRestOfCurrentPageOnFreeList(Page* current_page);
   1677 
   1678 #ifdef DEBUG
   1679   // Reports statistics for the space
   1680   void ReportStatistics();
   1681   // Dump the remembered sets in the space to stdout.
   1682   void PrintRSet();
   1683 #endif
   1684 
   1685  protected:
   1686   // Virtual function in the superclass.  Slow path of AllocateRaw.
   1687   HeapObject* SlowAllocateRaw(int size_in_bytes);
   1688 
   1689   // Virtual function in the superclass.  Allocate linearly at the start of
   1690   // the page after current_page (there is assumed to be one).
   1691   HeapObject* AllocateInNextPage(Page* current_page, int size_in_bytes);
   1692 
   1693  private:
   1694   // The space's free list.
   1695   OldSpaceFreeList free_list_;
   1696 
   1697  public:
   1698   TRACK_MEMORY("OldSpace")
   1699 };
   1700 
   1701 
   1702 // -----------------------------------------------------------------------------
   1703 // Old space for objects of a fixed size
   1704 
   1705 class FixedSpace : public PagedSpace {
   1706  public:
   1707   FixedSpace(int max_capacity,
   1708              AllocationSpace id,
   1709              int object_size_in_bytes,
   1710              const char* name)
   1711       : PagedSpace(max_capacity, id, NOT_EXECUTABLE),
   1712         object_size_in_bytes_(object_size_in_bytes),
   1713         name_(name),
   1714         free_list_(id, object_size_in_bytes) {
   1715     page_extra_ = Page::kObjectAreaSize % object_size_in_bytes;
   1716   }
   1717 
   1718   // The top of allocation in a page in this space. Undefined if page is unused.
   1719   virtual Address PageAllocationTop(Page* page) {
   1720     return page == TopPageOf(allocation_info_) ? top()
   1721         : page->ObjectAreaEnd() - page_extra_;
   1722   }
   1723 
   1724   int object_size_in_bytes() { return object_size_in_bytes_; }
   1725 
   1726   // Give a fixed sized block of memory to the space's free list.
   1727   void Free(Address start) {
   1728     free_list_.Free(start);
   1729     accounting_stats_.DeallocateBytes(object_size_in_bytes_);
   1730   }
   1731 
   1732   // Prepares for a mark-compact GC.
   1733   virtual void PrepareForMarkCompact(bool will_compact);
   1734 
   1735   // Updates the allocation pointer to the relocation top after a mark-compact
   1736   // collection.
   1737   virtual void MCCommitRelocationInfo();
   1738 
   1739   virtual void PutRestOfCurrentPageOnFreeList(Page* current_page);
   1740 
   1741 #ifdef DEBUG
   1742   // Reports statistic info of the space
   1743   void ReportStatistics();
   1744 
   1745   // Dump the remembered sets in the space to stdout.
   1746   void PrintRSet();
   1747 #endif
   1748 
   1749  protected:
   1750   // Virtual function in the superclass.  Slow path of AllocateRaw.
   1751   HeapObject* SlowAllocateRaw(int size_in_bytes);
   1752 
   1753   // Virtual function in the superclass.  Allocate linearly at the start of
   1754   // the page after current_page (there is assumed to be one).
   1755   HeapObject* AllocateInNextPage(Page* current_page, int size_in_bytes);
   1756 
   1757   void ResetFreeList() {
   1758     free_list_.Reset();
   1759   }
   1760 
   1761  private:
   1762   // The size of objects in this space.
   1763   int object_size_in_bytes_;
   1764 
   1765   // The name of this space.
   1766   const char* name_;
   1767 
   1768   // The space's free list.
   1769   FixedSizeFreeList free_list_;
   1770 };
   1771 
   1772 
   1773 // -----------------------------------------------------------------------------
   1774 // Old space for all map objects
   1775 
   1776 class MapSpace : public FixedSpace {
   1777  public:
   1778   // Creates a map space object with a maximum capacity.
   1779   MapSpace(int max_capacity, int max_map_space_pages, AllocationSpace id)
   1780       : FixedSpace(max_capacity, id, Map::kSize, "map"),
   1781         max_map_space_pages_(max_map_space_pages) {
   1782     ASSERT(max_map_space_pages < kMaxMapPageIndex);
   1783   }
   1784 
   1785   // Prepares for a mark-compact GC.
   1786   virtual void PrepareForMarkCompact(bool will_compact);
   1787 
   1788   // Given an index, returns the page address.
   1789   Address PageAddress(int page_index) { return page_addresses_[page_index]; }
   1790 
   1791   static const int kMaxMapPageIndex = 1 << MapWord::kMapPageIndexBits;
   1792 
   1793   // Are map pointers encodable into map word?
   1794   bool MapPointersEncodable() {
   1795     if (!FLAG_use_big_map_space) {
   1796       ASSERT(CountPagesToTop() <= kMaxMapPageIndex);
   1797       return true;
   1798     }
   1799     return CountPagesToTop() <= max_map_space_pages_;
   1800   }
   1801 
   1802   // Should be called after forced sweep to find out if map space needs
   1803   // compaction.
   1804   bool NeedsCompaction(int live_maps) {
   1805     return !MapPointersEncodable() && live_maps <= CompactionThreshold();
   1806   }
   1807 
   1808   Address TopAfterCompaction(int live_maps) {
   1809     ASSERT(NeedsCompaction(live_maps));
   1810 
   1811     int pages_left = live_maps / kMapsPerPage;
   1812     PageIterator it(this, PageIterator::ALL_PAGES);
   1813     while (pages_left-- > 0) {
   1814       ASSERT(it.has_next());
   1815       it.next()->ClearRSet();
   1816     }
   1817     ASSERT(it.has_next());
   1818     Page* top_page = it.next();
   1819     top_page->ClearRSet();
   1820     ASSERT(top_page->is_valid());
   1821 
   1822     int offset = live_maps % kMapsPerPage * Map::kSize;
   1823     Address top = top_page->ObjectAreaStart() + offset;
   1824     ASSERT(top < top_page->ObjectAreaEnd());
   1825     ASSERT(Contains(top));
   1826 
   1827     return top;
   1828   }
   1829 
   1830   void FinishCompaction(Address new_top, int live_maps) {
   1831     Page* top_page = Page::FromAddress(new_top);
   1832     ASSERT(top_page->is_valid());
   1833 
   1834     SetAllocationInfo(&allocation_info_, top_page);
   1835     allocation_info_.top = new_top;
   1836 
   1837     int new_size = live_maps * Map::kSize;
   1838     accounting_stats_.DeallocateBytes(accounting_stats_.Size());
   1839     accounting_stats_.AllocateBytes(new_size);
   1840 
   1841 #ifdef DEBUG
   1842     if (FLAG_enable_slow_asserts) {
   1843       intptr_t actual_size = 0;
   1844       for (Page* p = first_page_; p != top_page; p = p->next_page())
   1845         actual_size += kMapsPerPage * Map::kSize;
   1846       actual_size += (new_top - top_page->ObjectAreaStart());
   1847       ASSERT(accounting_stats_.Size() == actual_size);
   1848     }
   1849 #endif
   1850 
   1851     Shrink();
   1852     ResetFreeList();
   1853   }
   1854 
   1855  protected:
   1856 #ifdef DEBUG
   1857   virtual void VerifyObject(HeapObject* obj);
   1858 #endif
   1859 
   1860  private:
   1861   static const int kMapsPerPage = Page::kObjectAreaSize / Map::kSize;
   1862 
   1863   // Do map space compaction if there is a page gap.
   1864   int CompactionThreshold() {
   1865     return kMapsPerPage * (max_map_space_pages_ - 1);
   1866   }
   1867 
   1868   const int max_map_space_pages_;
   1869 
   1870   // An array of page start address in a map space.
   1871   Address page_addresses_[kMaxMapPageIndex];
   1872 
   1873  public:
   1874   TRACK_MEMORY("MapSpace")
   1875 };
   1876 
   1877 
   1878 // -----------------------------------------------------------------------------
   1879 // Old space for all global object property cell objects
   1880 
   1881 class CellSpace : public FixedSpace {
   1882  public:
   1883   // Creates a property cell space object with a maximum capacity.
   1884   CellSpace(int max_capacity, AllocationSpace id)
   1885       : FixedSpace(max_capacity, id, JSGlobalPropertyCell::kSize, "cell") {}
   1886 
   1887  protected:
   1888 #ifdef DEBUG
   1889   virtual void VerifyObject(HeapObject* obj);
   1890 #endif
   1891 
   1892  public:
   1893   TRACK_MEMORY("CellSpace")
   1894 };
   1895 
   1896 
   1897 // -----------------------------------------------------------------------------
   1898 // Large objects ( > Page::kMaxHeapObjectSize ) are allocated and managed by
   1899 // the large object space. A large object is allocated from OS heap with
   1900 // extra padding bytes (Page::kPageSize + Page::kObjectStartOffset).
   1901 // A large object always starts at Page::kObjectStartOffset to a page.
   1902 // Large objects do not move during garbage collections.
   1903 
   1904 // A LargeObjectChunk holds exactly one large object page with exactly one
   1905 // large object.
   1906 class LargeObjectChunk {
   1907  public:
   1908   // Allocates a new LargeObjectChunk that contains a large object page
   1909   // (Page::kPageSize aligned) that has at least size_in_bytes (for a large
   1910   // object and possibly extra remembered set words) bytes after the object
   1911   // area start of that page. The allocated chunk size is set in the output
   1912   // parameter chunk_size.
   1913   static LargeObjectChunk* New(int size_in_bytes,
   1914                                size_t* chunk_size,
   1915                                Executability executable);
   1916 
   1917   // Interpret a raw address as a large object chunk.
   1918   static LargeObjectChunk* FromAddress(Address address) {
   1919     return reinterpret_cast<LargeObjectChunk*>(address);
   1920   }
   1921 
   1922   // Returns the address of this chunk.
   1923   Address address() { return reinterpret_cast<Address>(this); }
   1924 
   1925   // Accessors for the fields of the chunk.
   1926   LargeObjectChunk* next() { return next_; }
   1927   void set_next(LargeObjectChunk* chunk) { next_ = chunk; }
   1928 
   1929   size_t size() { return size_; }
   1930   void set_size(size_t size_in_bytes) { size_ = size_in_bytes; }
   1931 
   1932   // Returns the object in this chunk.
   1933   inline HeapObject* GetObject();
   1934 
   1935   // Given a requested size (including any extra remembered set words),
   1936   // returns the physical size of a chunk to be allocated.
   1937   static int ChunkSizeFor(int size_in_bytes);
   1938 
   1939   // Given a chunk size, returns the object size it can accommodate (not
   1940   // including any extra remembered set words).  Used by
   1941   // LargeObjectSpace::Available.  Note that this can overestimate the size
   1942   // of object that will fit in a chunk---if the object requires extra
   1943   // remembered set words (eg, for large fixed arrays), the actual object
   1944   // size for the chunk will be smaller than reported by this function.
   1945   static int ObjectSizeFor(int chunk_size) {
   1946     if (chunk_size <= (Page::kPageSize + Page::kObjectStartOffset)) return 0;
   1947     return chunk_size - Page::kPageSize - Page::kObjectStartOffset;
   1948   }
   1949 
   1950  private:
   1951   // A pointer to the next large object chunk in the space or NULL.
   1952   LargeObjectChunk* next_;
   1953 
   1954   // The size of this chunk.
   1955   size_t size_;
   1956 
   1957  public:
   1958   TRACK_MEMORY("LargeObjectChunk")
   1959 };
   1960 
   1961 
   1962 class LargeObjectSpace : public Space {
   1963  public:
   1964   explicit LargeObjectSpace(AllocationSpace id);
   1965   virtual ~LargeObjectSpace() {}
   1966 
   1967   // Initializes internal data structures.
   1968   bool Setup();
   1969 
   1970   // Releases internal resources, frees objects in this space.
   1971   void TearDown();
   1972 
   1973   // Allocates a (non-FixedArray, non-Code) large object.
   1974   Object* AllocateRaw(int size_in_bytes);
   1975   // Allocates a large Code object.
   1976   Object* AllocateRawCode(int size_in_bytes);
   1977   // Allocates a large FixedArray.
   1978   Object* AllocateRawFixedArray(int size_in_bytes);
   1979 
   1980   // Available bytes for objects in this space, not including any extra
   1981   // remembered set words.
   1982   int Available() {
   1983     return LargeObjectChunk::ObjectSizeFor(MemoryAllocator::Available());
   1984   }
   1985 
   1986   virtual int Size() {
   1987     return size_;
   1988   }
   1989 
   1990   int PageCount() {
   1991     return page_count_;
   1992   }
   1993 
   1994   // Finds an object for a given address, returns Failure::Exception()
   1995   // if it is not found. The function iterates through all objects in this
   1996   // space, may be slow.
   1997   Object* FindObject(Address a);
   1998 
   1999   // Clears remembered sets.
   2000   void ClearRSet();
   2001 
   2002   // Iterates objects whose remembered set bits are set.
   2003   void IterateRSet(ObjectSlotCallback func);
   2004 
   2005   // Frees unmarked objects.
   2006   void FreeUnmarkedObjects();
   2007 
   2008   // Checks whether a heap object is in this space; O(1).
   2009   bool Contains(HeapObject* obj);
   2010 
   2011   // Checks whether the space is empty.
   2012   bool IsEmpty() { return first_chunk_ == NULL; }
   2013 
   2014   // See the comments for ReserveSpace in the Space class.  This has to be
   2015   // called after ReserveSpace has been called on the paged spaces, since they
   2016   // may use some memory, leaving less for large objects.
   2017   virtual bool ReserveSpace(int bytes);
   2018 
   2019 #ifdef ENABLE_HEAP_PROTECTION
   2020   // Protect/unprotect the space by marking it read-only/writable.
   2021   void Protect();
   2022   void Unprotect();
   2023 #endif
   2024 
   2025 #ifdef DEBUG
   2026   virtual void Verify();
   2027   virtual void Print();
   2028   void ReportStatistics();
   2029   void CollectCodeStatistics();
   2030   // Dump the remembered sets in the space to stdout.
   2031   void PrintRSet();
   2032 #endif
   2033   // Checks whether an address is in the object area in this space.  It
   2034   // iterates all objects in the space. May be slow.
   2035   bool SlowContains(Address addr) { return !FindObject(addr)->IsFailure(); }
   2036 
   2037  private:
   2038   // The head of the linked list of large object chunks.
   2039   LargeObjectChunk* first_chunk_;
   2040   int size_;  // allocated bytes
   2041   int page_count_;  // number of chunks
   2042 
   2043 
   2044   // Shared implementation of AllocateRaw, AllocateRawCode and
   2045   // AllocateRawFixedArray.
   2046   Object* AllocateRawInternal(int requested_size,
   2047                               int object_size,
   2048                               Executability executable);
   2049 
   2050   // Returns the number of extra bytes (rounded up to the nearest full word)
   2051   // required for extra_object_bytes of extra pointers (in bytes).
   2052   static inline int ExtraRSetBytesFor(int extra_object_bytes);
   2053 
   2054   friend class LargeObjectIterator;
   2055 
   2056  public:
   2057   TRACK_MEMORY("LargeObjectSpace")
   2058 };
   2059 
   2060 
   2061 class LargeObjectIterator: public ObjectIterator {
   2062  public:
   2063   explicit LargeObjectIterator(LargeObjectSpace* space);
   2064   LargeObjectIterator(LargeObjectSpace* space, HeapObjectCallback size_func);
   2065 
   2066   HeapObject* next();
   2067 
   2068   // implementation of ObjectIterator.
   2069   virtual HeapObject* next_object() { return next(); }
   2070 
   2071  private:
   2072   LargeObjectChunk* current_;
   2073   HeapObjectCallback size_func_;
   2074 };
   2075 
   2076 
   2077 } }  // namespace v8::internal
   2078 
   2079 #endif  // V8_SPACES_H_
   2080