Index: src/spaces.h |
=================================================================== |
--- src/spaces.h (revision 7267) |
+++ src/spaces.h (working copy) |
@@ -34,6 +34,8 @@ |
namespace v8 { |
namespace internal { |
+class Isolate; |
+ |
// ----------------------------------------------------------------------------- |
// Heap structures: |
// |
@@ -241,7 +243,7 @@ |
static const intptr_t kPageAlignmentMask = (1 << kPageSizeBits) - 1; |
static const int kPageHeaderSize = kPointerSize + kPointerSize + kIntSize + |
- kIntSize + kPointerSize; |
+ kIntSize + kPointerSize + kPointerSize; |
// The start offset of the object area in a page. Aligned to both maps and |
// code alignment to be suitable for both. |
@@ -286,7 +288,7 @@ |
// This invariant guarantees that after flipping flag meaning at the |
// beginning of scavenge all pages in use will be marked as having valid |
// watermark. |
- static inline void FlipMeaningOfInvalidatedWatermarkFlag(); |
+ static inline void FlipMeaningOfInvalidatedWatermarkFlag(Heap* heap); |
// Returns true if the page allocation watermark was not altered during |
// scavenge. |
@@ -312,11 +314,6 @@ |
STATIC_CHECK(kBitsPerInt - kAllocationWatermarkOffsetShift >= |
kAllocationWatermarkOffsetBits); |
- // This field contains the meaning of the WATERMARK_INVALIDATED flag. |
- // Instead of clearing this flag from all pages we just flip |
- // its meaning at the beginning of a scavenge. |
- static intptr_t watermark_invalidated_mark_; |
- |
//--------------------------------------------------------------------------- |
// Page header description. |
// |
@@ -353,6 +350,8 @@ |
// During scavenge collection this field is used to store allocation watermark |
// if it is altered during scavenge. |
Address mc_first_forwarded; |
+ |
+ Heap* heap_; |
}; |
@@ -360,11 +359,13 @@ |
// Space is the abstract superclass for all allocation spaces. |
class Space : public Malloced { |
public: |
- Space(AllocationSpace id, Executability executable) |
- : id_(id), executable_(executable) {} |
+ Space(Heap* heap, AllocationSpace id, Executability executable) |
+ : heap_(heap), id_(id), executable_(executable) {} |
virtual ~Space() {} |
+ Heap* heap() const { return heap_; } |
+ |
// Does the space need executable memory? |
Executability executable() { return executable_; } |
@@ -397,6 +398,7 @@ |
virtual bool ReserveSpace(int bytes) = 0; |
private: |
+ Heap* heap_; |
AllocationSpace id_; |
Executability executable_; |
}; |
@@ -409,19 +411,19 @@ |
// 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 { |
+class CodeRange { |
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); |
+ 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(); |
+ void TearDown(); |
- static bool exists() { return code_range_ != NULL; } |
- static bool contains(Address address) { |
+ bool exists() { return code_range_ != NULL; } |
+ 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(); |
@@ -430,13 +432,15 @@ |
// 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. |
- MUST_USE_RESULT static void* AllocateRawMemory(const size_t requested, |
- size_t* allocated); |
- static void FreeRawMemory(void* buf, size_t length); |
+ MUST_USE_RESULT void* AllocateRawMemory(const size_t requested, |
+ size_t* allocated); |
+ void FreeRawMemory(void* buf, size_t length); |
private: |
+ CodeRange(); |
+ |
// The reserved range of virtual memory that all code objects are put in. |
- static VirtualMemory* code_range_; |
+ VirtualMemory* code_range_; |
// Plain old data class, just a struct plus a constructor. |
class FreeBlock { |
public: |
@@ -452,20 +456,26 @@ |
// 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_; |
+ 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_; |
+ List<FreeBlock> allocation_list_; |
+ 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); |
+ void GetNextAllocationBlock(size_t requested); |
// Compares the start addresses of two free blocks. |
static int CompareFreeBlockAddress(const FreeBlock* left, |
const FreeBlock* right); |
+ |
+ friend class Isolate; |
+ |
+ Isolate* isolate_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(CodeRange); |
}; |
@@ -493,14 +503,14 @@ |
// |
-class MemoryAllocator : public AllStatic { |
+class MemoryAllocator { |
public: |
// Initializes its internal bookkeeping structures. |
// Max capacity of the total space and executable memory limit. |
- static bool Setup(intptr_t max_capacity, intptr_t capacity_executable); |
+ bool Setup(intptr_t max_capacity, intptr_t capacity_executable); |
// Deletes valid chunks. |
- static void TearDown(); |
+ void TearDown(); |
// Reserves an initial address range of virtual memory to be split between |
// the two new space semispaces, the old space, and the map space. The |
@@ -511,7 +521,7 @@ |
// address of the initial chunk if successful, with the side effect of |
// setting the initial chunk, or else NULL if unsuccessful and leaves the |
// initial chunk NULL. |
- static void* ReserveInitialChunk(const size_t requested); |
+ void* ReserveInitialChunk(const size_t requested); |
// Commits pages from an as-yet-unmanaged block of virtual memory into a |
// paged space. The block should be part of the initial chunk reserved via |
@@ -520,24 +530,24 @@ |
// address is non-null and that it is big enough to hold at least one |
// page-aligned page. The call always succeeds, and num_pages is always |
// greater than zero. |
- static Page* CommitPages(Address start, size_t size, PagedSpace* owner, |
- int* num_pages); |
+ Page* CommitPages(Address start, size_t size, PagedSpace* owner, |
+ int* num_pages); |
// Commit a contiguous block of memory from the initial chunk. Assumes that |
// the address is not NULL, the size is greater than zero, and that the |
// block is contained in the initial chunk. Returns true if it succeeded |
// and false otherwise. |
- static bool CommitBlock(Address start, size_t size, Executability executable); |
+ bool CommitBlock(Address start, size_t size, Executability executable); |
// Uncommit a contiguous block of memory [start..(start+size)[. |
// start is not NULL, the size is greater than zero, and the |
// block is contained in the initial chunk. Returns true if it succeeded |
// and false otherwise. |
- static bool UncommitBlock(Address start, size_t size); |
+ bool UncommitBlock(Address start, size_t size); |
// Zaps a contiguous block of memory [start..(start+size)[ thus |
// filling it up with a recognizable non-NULL bit pattern. |
- static void ZapBlock(Address start, size_t size); |
+ void ZapBlock(Address start, size_t size); |
// Attempts to allocate the requested (non-zero) number of pages from the |
// OS. Fewer pages might be allocated than requested. If it fails to |
@@ -548,8 +558,8 @@ |
// 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); |
+ Page* AllocatePages(int requested_pages, int* allocated_pages, |
+ PagedSpace* owner); |
// Frees pages from a given page and after. Requires pages to be |
// linked in chunk-order (see comment for class). |
@@ -558,10 +568,10 @@ |
// Otherwise, the function searches a page after 'p' that is |
// the first page of a chunk. Pages after the found page |
// are freed and the function returns 'p'. |
- static Page* FreePages(Page* p); |
+ Page* FreePages(Page* p); |
// Frees all pages owned by given space. |
- static void FreeAllPages(PagedSpace* space); |
+ void FreeAllPages(PagedSpace* space); |
// Allocates and frees raw memory of certain size. |
// These are just thin wrappers around OS::Allocate and OS::Free, |
@@ -569,96 +579,83 @@ |
// 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. |
- MUST_USE_RESULT static void* AllocateRawMemory(const size_t requested, |
- size_t* allocated, |
- Executability executable); |
- static void FreeRawMemory(void* buf, |
- size_t length, |
- Executability executable); |
- static void PerformAllocationCallback(ObjectSpace space, |
- AllocationAction action, |
- size_t size); |
+ MUST_USE_RESULT void* AllocateRawMemory(const size_t requested, |
+ size_t* allocated, |
+ Executability executable); |
+ void FreeRawMemory(void* buf, |
+ size_t length, |
+ Executability executable); |
+ void PerformAllocationCallback(ObjectSpace space, |
+ AllocationAction action, |
+ size_t size); |
- static void AddMemoryAllocationCallback(MemoryAllocationCallback callback, |
- ObjectSpace space, |
- AllocationAction action); |
- static void RemoveMemoryAllocationCallback( |
- MemoryAllocationCallback callback); |
- static bool MemoryAllocationCallbackRegistered( |
- MemoryAllocationCallback callback); |
+ void AddMemoryAllocationCallback(MemoryAllocationCallback callback, |
+ ObjectSpace space, |
+ AllocationAction action); |
+ void RemoveMemoryAllocationCallback(MemoryAllocationCallback callback); |
+ bool MemoryAllocationCallbackRegistered(MemoryAllocationCallback callback); |
// Returns the maximum available bytes of heaps. |
- static intptr_t Available() { |
- return capacity_ < size_ ? 0 : capacity_ - size_; |
- } |
+ intptr_t Available() { return capacity_ < size_ ? 0 : capacity_ - size_; } |
// Returns allocated spaces in bytes. |
- static intptr_t Size() { return size_; } |
+ intptr_t Size() { return size_; } |
// Returns the maximum available executable bytes of heaps. |
- static intptr_t AvailableExecutable() { |
+ intptr_t AvailableExecutable() { |
if (capacity_executable_ < size_executable_) return 0; |
return capacity_executable_ - size_executable_; |
} |
// Returns allocated executable spaces in bytes. |
- static intptr_t SizeExecutable() { return size_executable_; } |
+ intptr_t SizeExecutable() { return size_executable_; } |
// Returns maximum available bytes that the old space can have. |
- static intptr_t MaxAvailable() { |
+ intptr_t MaxAvailable() { |
return (Available() / Page::kPageSize) * Page::kObjectAreaSize; |
} |
- // Sanity check on a pointer. |
- static bool SafeIsInAPageChunk(Address addr); |
- |
// Links two pages. |
- static inline void SetNextPage(Page* prev, Page* next); |
+ inline void SetNextPage(Page* prev, Page* next); |
// Returns the next page of a given page. |
- static inline Page* GetNextPage(Page* p); |
+ inline Page* GetNextPage(Page* p); |
// Checks whether a page belongs to a space. |
- static inline bool IsPageInSpace(Page* p, PagedSpace* space); |
+ inline bool IsPageInSpace(Page* p, PagedSpace* space); |
// Returns the space that owns the given page. |
- static inline PagedSpace* PageOwner(Page* page); |
+ inline PagedSpace* PageOwner(Page* page); |
// Finds the first/last page in the same chunk as a given page. |
- static Page* FindFirstPageInSameChunk(Page* p); |
- static Page* FindLastPageInSameChunk(Page* p); |
+ Page* FindFirstPageInSameChunk(Page* p); |
+ Page* FindLastPageInSameChunk(Page* p); |
// Relinks list of pages owned by space to make it chunk-ordered. |
// Returns new first and last pages of space. |
// Also returns last page in relinked list which has WasInUsedBeforeMC |
// flag set. |
- static void RelinkPageListInChunkOrder(PagedSpace* space, |
- Page** first_page, |
- Page** last_page, |
- Page** last_page_in_use); |
+ void RelinkPageListInChunkOrder(PagedSpace* space, |
+ Page** first_page, |
+ Page** last_page, |
+ Page** last_page_in_use); |
#ifdef ENABLE_HEAP_PROTECTION |
// Protect/unprotect a block of memory by marking it read-only/writable. |
- static inline void Protect(Address start, size_t size); |
- static inline void Unprotect(Address start, size_t size, |
- Executability executable); |
+ inline void Protect(Address start, size_t size); |
+ inline void Unprotect(Address start, size_t size, |
+ Executability executable); |
// Protect/unprotect a chunk given a page in the chunk. |
- static inline void ProtectChunkFromPage(Page* page); |
- static inline void UnprotectChunkFromPage(Page* page); |
+ inline void ProtectChunkFromPage(Page* page); |
+ inline void UnprotectChunkFromPage(Page* page); |
#endif |
#ifdef DEBUG |
// Reports statistic info of the space. |
- static void ReportStatistics(); |
+ void ReportStatistics(); |
#endif |
- static void AddToAllocatedChunks(Address addr, intptr_t size); |
- static void RemoveFromAllocatedChunks(Address addr, intptr_t size); |
- // Note: This only checks the regular chunks, not the odd-sized initial |
- // chunk. |
- static bool InAllocatedChunks(Address addr); |
- |
// Due to encoding limitation, we can only have 8K chunks. |
static const int kMaxNofChunks = 1 << kPageSizeBits; |
// If a chunk has at least 16 pages, the maximum heap size is about |
@@ -678,29 +675,21 @@ |
#endif |
private: |
+ MemoryAllocator(); |
+ |
static const int kChunkSize = kPagesPerChunk * Page::kPageSize; |
static const int kChunkSizeLog2 = kPagesPerChunkLog2 + kPageSizeBits; |
- static const int kChunkTableTopLevelEntries = |
- 1 << (sizeof(intptr_t) * kBitsPerByte - kChunkSizeLog2 - |
- (kChunkTableLevels - 1) * kChunkTableBitsPerLevel); |
- // The chunks are not chunk-size aligned so for a given chunk-sized area of |
- // memory there can be two chunks that cover it. |
- static const int kChunkTableFineGrainedWordsPerEntry = 2; |
- static const uintptr_t kUnusedChunkTableEntry = 0; |
- |
// Maximum space size in bytes. |
- static intptr_t capacity_; |
+ intptr_t capacity_; |
// Maximum subset of capacity_ that can be executable |
- static intptr_t capacity_executable_; |
+ intptr_t capacity_executable_; |
- // Top level table to track whether memory is part of a chunk or not. |
- static uintptr_t chunk_table_[kChunkTableTopLevelEntries]; |
+ // Allocated space size in bytes. |
+ intptr_t size_; |
- // Allocated space size in bytes. |
- static intptr_t size_; |
// Allocated executable space size in bytes. |
- static intptr_t size_executable_; |
+ intptr_t size_executable_; |
struct MemoryAllocationCallbackRegistration { |
MemoryAllocationCallbackRegistration(MemoryAllocationCallback callback, |
@@ -713,11 +702,11 @@ |
AllocationAction action; |
}; |
// A List of callback that are triggered when memory is allocated or free'd |
- static List<MemoryAllocationCallbackRegistration> |
+ List<MemoryAllocationCallbackRegistration> |
memory_allocation_callbacks_; |
// The initial chunk of virtual memory. |
- static VirtualMemory* initial_chunk_; |
+ VirtualMemory* initial_chunk_; |
// Allocated chunk info: chunk start address, chunk size, and owning space. |
class ChunkInfo BASE_EMBEDDED { |
@@ -725,7 +714,8 @@ |
ChunkInfo() : address_(NULL), |
size_(0), |
owner_(NULL), |
- executable_(NOT_EXECUTABLE) {} |
+ executable_(NOT_EXECUTABLE), |
+ owner_identity_(FIRST_SPACE) {} |
inline void init(Address a, size_t s, PagedSpace* o); |
Address address() { return address_; } |
size_t size() { return size_; } |
@@ -733,74 +723,60 @@ |
// We save executability of the owner to allow using it |
// when collecting stats after the owner has been destroyed. |
Executability executable() const { return executable_; } |
+ AllocationSpace owner_identity() const { return owner_identity_; } |
private: |
Address address_; |
size_t size_; |
PagedSpace* owner_; |
Executability executable_; |
+ AllocationSpace owner_identity_; |
}; |
// Chunks_, free_chunk_ids_ and top_ act as a stack of free chunk ids. |
- static List<ChunkInfo> chunks_; |
- static List<int> free_chunk_ids_; |
- static int max_nof_chunks_; |
- static int top_; |
+ List<ChunkInfo> chunks_; |
+ List<int> free_chunk_ids_; |
+ int max_nof_chunks_; |
+ int top_; |
// Push/pop a free chunk id onto/from the stack. |
- static void Push(int free_chunk_id); |
- static int Pop(); |
- static bool OutOfChunkIds() { return top_ == 0; } |
+ void Push(int free_chunk_id); |
+ int Pop(); |
+ bool OutOfChunkIds() { return top_ == 0; } |
// Frees a chunk. |
- static void DeleteChunk(int chunk_id); |
+ void DeleteChunk(int chunk_id); |
- // Helpers to maintain and query the chunk tables. |
- static void AddChunkUsingAddress( |
- uintptr_t chunk_start, // Where the chunk starts. |
- uintptr_t chunk_index_base); // Used to place the chunk in the tables. |
- static void RemoveChunkFoundUsingAddress( |
- uintptr_t chunk_start, // Where the chunk starts. |
- uintptr_t chunk_index_base); // Used to locate the entry in the tables. |
- // Controls whether the lookup creates intermediate levels of tables as |
- // needed. |
- enum CreateTables { kDontCreateTables, kCreateTablesAsNeeded }; |
- static uintptr_t* AllocatedChunksFinder(uintptr_t* table, |
- uintptr_t address, |
- int bit_position, |
- CreateTables create_as_needed); |
- static void FreeChunkTables(uintptr_t* array, int length, int level); |
- static int FineGrainedIndexForAddress(uintptr_t address) { |
- int index = ((address >> kChunkSizeLog2) & |
- ((1 << kChunkTableBitsPerLevel) - 1)); |
- return index * kChunkTableFineGrainedWordsPerEntry; |
- } |
- |
- |
// Basic check whether a chunk id is in the valid range. |
- static inline bool IsValidChunkId(int chunk_id); |
+ inline bool IsValidChunkId(int chunk_id); |
// Checks whether a chunk id identifies an allocated chunk. |
- static inline bool IsValidChunk(int chunk_id); |
+ inline bool IsValidChunk(int chunk_id); |
// Returns the chunk id that a page belongs to. |
- static inline int GetChunkId(Page* p); |
+ inline int GetChunkId(Page* p); |
// True if the address lies in the initial chunk. |
- static inline bool InInitialChunk(Address address); |
+ inline bool InInitialChunk(Address address); |
// Initializes pages in a chunk. Returns the first page address. |
// This function and GetChunkId() are provided for the mark-compact |
// collector to rebuild page headers in the from space, which is |
// used as a marking stack and its page headers are destroyed. |
- static Page* InitializePagesInChunk(int chunk_id, int pages_in_chunk, |
- PagedSpace* owner); |
+ Page* InitializePagesInChunk(int chunk_id, int pages_in_chunk, |
+ PagedSpace* owner); |
- static Page* RelinkPagesInChunk(int chunk_id, |
- Address chunk_start, |
- size_t chunk_size, |
- Page* prev, |
- Page** last_page_in_use); |
+ Page* RelinkPagesInChunk(int chunk_id, |
+ Address chunk_start, |
+ size_t chunk_size, |
+ Page* prev, |
+ Page** last_page_in_use); |
+ |
+ friend class Isolate; |
+ |
+ Isolate* isolate_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(MemoryAllocator); |
}; |
@@ -1048,7 +1024,8 @@ |
class PagedSpace : public Space { |
public: |
// Creates a space with a maximum capacity, and an id. |
- PagedSpace(intptr_t max_capacity, |
+ PagedSpace(Heap* heap, |
+ intptr_t max_capacity, |
AllocationSpace id, |
Executability executable); |
@@ -1341,7 +1318,7 @@ |
class SemiSpace : public Space { |
public: |
// Constructor. |
- SemiSpace() :Space(NEW_SPACE, NOT_EXECUTABLE) { |
+ explicit SemiSpace(Heap* heap) : Space(heap, NEW_SPACE, NOT_EXECUTABLE) { |
start_ = NULL; |
age_mark_ = NULL; |
} |
@@ -1508,7 +1485,10 @@ |
class NewSpace : public Space { |
public: |
// Constructor. |
- NewSpace() : Space(NEW_SPACE, NOT_EXECUTABLE) {} |
+ explicit NewSpace(Heap* heap) |
+ : Space(heap, NEW_SPACE, NOT_EXECUTABLE), |
+ to_space_(heap), |
+ from_space_(heap) {} |
// Sets up the new space using the given chunk. |
bool Setup(Address start, int size); |
@@ -1909,10 +1889,11 @@ |
public: |
// Creates an old space object with a given maximum capacity. |
// The constructor does not allocate pages from OS. |
- explicit OldSpace(intptr_t max_capacity, |
- AllocationSpace id, |
- Executability executable) |
- : PagedSpace(max_capacity, id, executable), free_list_(id) { |
+ OldSpace(Heap* heap, |
+ intptr_t max_capacity, |
+ AllocationSpace id, |
+ Executability executable) |
+ : PagedSpace(heap, max_capacity, id, executable), free_list_(id) { |
page_extra_ = 0; |
} |
@@ -1981,11 +1962,12 @@ |
class FixedSpace : public PagedSpace { |
public: |
- FixedSpace(intptr_t max_capacity, |
+ FixedSpace(Heap* heap, |
+ intptr_t max_capacity, |
AllocationSpace id, |
int object_size_in_bytes, |
const char* name) |
- : PagedSpace(max_capacity, id, NOT_EXECUTABLE), |
+ : PagedSpace(heap, max_capacity, id, NOT_EXECUTABLE), |
object_size_in_bytes_(object_size_in_bytes), |
name_(name), |
free_list_(id, object_size_in_bytes) { |
@@ -2059,8 +2041,11 @@ |
class MapSpace : public FixedSpace { |
public: |
// Creates a map space object with a maximum capacity. |
- MapSpace(intptr_t max_capacity, int max_map_space_pages, AllocationSpace id) |
- : FixedSpace(max_capacity, id, Map::kSize, "map"), |
+ MapSpace(Heap* heap, |
+ intptr_t max_capacity, |
+ int max_map_space_pages, |
+ AllocationSpace id) |
+ : FixedSpace(heap, max_capacity, id, Map::kSize, "map"), |
max_map_space_pages_(max_map_space_pages) { |
ASSERT(max_map_space_pages < kMaxMapPageIndex); |
} |
@@ -2170,8 +2155,9 @@ |
class CellSpace : public FixedSpace { |
public: |
// Creates a property cell space object with a maximum capacity. |
- CellSpace(intptr_t max_capacity, AllocationSpace id) |
- : FixedSpace(max_capacity, id, JSGlobalPropertyCell::kSize, "cell") {} |
+ CellSpace(Heap* heap, intptr_t max_capacity, AllocationSpace id) |
+ : FixedSpace(heap, max_capacity, id, JSGlobalPropertyCell::kSize, "cell") |
+ {} |
protected: |
#ifdef DEBUG |
@@ -2246,7 +2232,7 @@ |
class LargeObjectSpace : public Space { |
public: |
- explicit LargeObjectSpace(AllocationSpace id); |
+ LargeObjectSpace(Heap* heap, AllocationSpace id); |
virtual ~LargeObjectSpace() {} |
// Initializes internal data structures. |
@@ -2263,9 +2249,7 @@ |
MUST_USE_RESULT MaybeObject* AllocateRawFixedArray(int size_in_bytes); |
// Available bytes for objects in this space. |
- intptr_t Available() { |
- return LargeObjectChunk::ObjectSizeFor(MemoryAllocator::Available()); |
- } |
+ inline intptr_t Available(); |
virtual intptr_t Size() { |
return size_; |
@@ -2357,6 +2341,22 @@ |
}; |
+#ifdef DEBUG |
+struct CommentStatistic { |
+ const char* comment; |
+ int size; |
+ int count; |
+ void Clear() { |
+ comment = NULL; |
+ size = 0; |
+ count = 0; |
+ } |
+ // Must be small, since an iteration is used for lookup. |
+ static const int kMaxComments = 64; |
+}; |
+#endif |
+ |
+ |
} } // namespace v8::internal |
#endif // V8_SPACES_H_ |