| 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);
|
|
|