| Index: src/spaces.h
 | 
| ===================================================================
 | 
| --- src/spaces.h	(revision 3016)
 | 
| +++ src/spaces.h	(working copy)
 | 
| @@ -315,6 +315,72 @@
 | 
|  
 | 
|  
 | 
|  // ----------------------------------------------------------------------------
 | 
| +// All heap objects containing executable code (code objects) must be allocated
 | 
| +// from a 2 GB range of memory, so that they can call each other using 32-bit
 | 
| +// displacements.  This happens automatically on 32-bit platforms, where 32-bit
 | 
| +// displacements cover the entire 4GB virtual address space.  On 64-bit
 | 
| +// platforms, we support this using the CodeRange object, which reserves and
 | 
| +// manages a range of virtual memory.
 | 
| +class CodeRange : public AllStatic {
 | 
| + public:
 | 
| +  // Reserves a range of virtual memory, but does not commit any of it.
 | 
| +  // Can only be called once, at heap initialization time.
 | 
| +  // Returns false on failure.
 | 
| +  static bool Setup(const size_t requested_size);
 | 
| +
 | 
| +  // Frees the range of virtual memory, and frees the data structures used to
 | 
| +  // manage it.
 | 
| +  static void TearDown();
 | 
| +
 | 
| +  static bool exists() { return code_range_ != NULL; }
 | 
| +  static bool contains(Address address) {
 | 
| +    if (code_range_ == NULL) return false;
 | 
| +    Address start = static_cast<Address>(code_range_->address());
 | 
| +    return start <= address && address < start + code_range_->size();
 | 
| +  }
 | 
| +
 | 
| +  // Allocates a chunk of memory from the large-object portion of
 | 
| +  // the code range.  On platforms with no separate code range, should
 | 
| +  // not be called.
 | 
| +  static void* AllocateRawMemory(const size_t requested, size_t* allocated);
 | 
| +  static void FreeRawMemory(void* buf, size_t length);
 | 
| +
 | 
| + private:
 | 
| +  // The reserved range of virtual memory that all code objects are put in.
 | 
| +  static VirtualMemory* code_range_;
 | 
| +  // Plain old data class, just a struct plus a constructor.
 | 
| +  class FreeBlock {
 | 
| +   public:
 | 
| +    FreeBlock(Address start_arg, size_t size_arg)
 | 
| +        : start(start_arg), size(size_arg) {}
 | 
| +    FreeBlock(void* start_arg, size_t size_arg)
 | 
| +        : start(static_cast<Address>(start_arg)), size(size_arg) {}
 | 
| +
 | 
| +    Address start;
 | 
| +    size_t size;
 | 
| +  };
 | 
| +
 | 
| +  // Freed blocks of memory are added to the free list.  When the allocation
 | 
| +  // list is exhausted, the free list is sorted and merged to make the new
 | 
| +  // allocation list.
 | 
| +  static List<FreeBlock> free_list_;
 | 
| +  // Memory is allocated from the free blocks on the allocation list.
 | 
| +  // The block at current_allocation_block_index_ is the current block.
 | 
| +  static List<FreeBlock> allocation_list_;
 | 
| +  static int current_allocation_block_index_;
 | 
| +
 | 
| +  // Finds a block on the allocation list that contains at least the
 | 
| +  // requested amount of memory.  If none is found, sorts and merges
 | 
| +  // the existing free memory blocks, and searches again.
 | 
| +  // If none can be found, terminates V8 with FatalProcessOutOfMemory.
 | 
| +  static void GetNextAllocationBlock(size_t requested);
 | 
| +  // Compares the start addresses of two free blocks.
 | 
| +  static int CompareFreeBlockAddress(const FreeBlock* left,
 | 
| +                                     const FreeBlock* right);
 | 
| +};
 | 
| +
 | 
| +
 | 
| +// ----------------------------------------------------------------------------
 | 
|  // A space acquires chunks of memory from the operating system. The memory
 | 
|  // allocator manages chunks for the paged heap spaces (old space and map
 | 
|  // space).  A paged chunk consists of pages. Pages in a chunk have contiguous
 | 
| @@ -380,8 +446,9 @@
 | 
|    // function returns an invalid page pointer (NULL). The caller must check
 | 
|    // whether the returned page is valid (by calling Page::is_valid()).  It is
 | 
|    // guaranteed that allocated pages have contiguous addresses.  The actual
 | 
| -  // number of allocated page is returned in the output parameter
 | 
| -  // allocated_pages.
 | 
| +  // number of allocated pages is returned in the output parameter
 | 
| +  // allocated_pages.  If the PagedSpace owner is executable and there is
 | 
| +  // a code range, the pages are allocated from the code range.
 | 
|    static Page* AllocatePages(int requested_pages, int* allocated_pages,
 | 
|                               PagedSpace* owner);
 | 
|  
 | 
| @@ -395,6 +462,9 @@
 | 
|    // Allocates and frees raw memory of certain size.
 | 
|    // These are just thin wrappers around OS::Allocate and OS::Free,
 | 
|    // but keep track of allocated bytes as part of heap.
 | 
| +  // If the flag is EXECUTABLE and a code range exists, the requested
 | 
| +  // memory is allocated from the code range.  If a code range exists
 | 
| +  // and the freed memory is in it, the code range manages the freed memory.
 | 
|    static void* AllocateRawMemory(const size_t requested,
 | 
|                                   size_t* allocated,
 | 
|                                   Executability executable);
 | 
| 
 |