Index: src/heap/spaces.h |
diff --git a/src/heap/spaces.h b/src/heap/spaces.h |
index 50d3c8d3c4f7a5948eb7e19493dc820e391f7b97..98e89ccad40f118bd988bc8b7119d1970224c99b 100644 |
--- a/src/heap/spaces.h |
+++ b/src/heap/spaces.h |
@@ -9,9 +9,10 @@ |
#include "src/base/atomicops.h" |
#include "src/base/bits.h" |
#include "src/base/platform/mutex.h" |
+#include "src/flags.h" |
#include "src/hashmap.h" |
#include "src/list.h" |
-#include "src/log.h" |
+#include "src/objects.h" |
#include "src/utils.h" |
namespace v8 { |
@@ -656,7 +657,17 @@ class MemoryChunk { |
// Approximate amount of physical memory committed for this chunk. |
size_t CommittedPhysicalMemory() { return high_water_mark_; } |
- static inline void UpdateHighWaterMark(Address mark); |
+ static inline void UpdateHighWaterMark(Address mark) { |
+ if (mark == NULL) return; |
+ // Need to subtract one from the mark because when a chunk is full the |
+ // top points to the next address after the chunk, which effectively belongs |
+ // to another chunk. See the comment to Page::FromAllocationTop. |
+ MemoryChunk* chunk = MemoryChunk::FromAddress(mark - 1); |
+ int new_mark = static_cast<int>(mark - chunk->address()); |
+ if (new_mark > chunk->high_water_mark_) { |
+ chunk->high_water_mark_ = new_mark; |
+ } |
+ } |
protected: |
size_t size_; |
@@ -741,8 +752,14 @@ class Page : public MemoryChunk { |
} |
// Returns the next page in the chain of pages owned by a space. |
- inline Page* next_page(); |
- inline Page* prev_page(); |
+ inline Page* next_page() { |
+ DCHECK(next_chunk()->owner() == owner()); |
+ return static_cast<Page*>(next_chunk()); |
+ } |
+ inline Page* prev_page() { |
+ DCHECK(prev_chunk()->owner() == owner()); |
+ return static_cast<Page*>(prev_chunk()); |
+ } |
inline void set_next_page(Page* page); |
inline void set_prev_page(Page* page); |
@@ -1246,15 +1263,8 @@ class HeapObjectIterator : public ObjectIterator { |
// Advance to the next object, skipping free spaces and other fillers and |
// skipping the special garbage section of which there is one per space. |
// Returns NULL when the iteration has ended. |
- inline HeapObject* Next() { |
- do { |
- HeapObject* next_obj = FromCurrentPage(); |
- if (next_obj != NULL) return next_obj; |
- } while (AdvanceToNextPage()); |
- return NULL; |
- } |
- |
- virtual HeapObject* next_object() { return Next(); } |
+ inline HeapObject* Next(); |
+ virtual inline HeapObject* next_object(); |
private: |
enum PageMode { kOnePageOnly, kAllPagesInSpace }; |
@@ -1645,10 +1655,7 @@ class AllocationResult { |
return object_; |
} |
- AllocationSpace RetrySpace() { |
- DCHECK(IsRetry()); |
- return static_cast<AllocationSpace>(Smi::cast(object_)->value()); |
- } |
+ inline AllocationSpace RetrySpace(); |
private: |
explicit AllocationResult(AllocationSpace space) |
@@ -1684,7 +1691,7 @@ class PagedSpace : public Space { |
// Checks whether an object/address is in this space. |
inline bool Contains(Address a); |
- bool Contains(HeapObject* o) { return Contains(o->address()); } |
+ inline bool Contains(HeapObject* o); |
// Unlike Contains() methods it is safe to call this one even for addresses |
// of unmapped memory. |
bool ContainsSafe(Address addr); |
@@ -2273,25 +2280,10 @@ class SemiSpaceIterator : public ObjectIterator { |
// Create an iterator over the allocated objects in the given to-space. |
explicit SemiSpaceIterator(NewSpace* space); |
- HeapObject* Next() { |
- if (current_ == limit_) return NULL; |
- if (NewSpacePage::IsAtEnd(current_)) { |
- NewSpacePage* page = NewSpacePage::FromLimit(current_); |
- page = page->next_page(); |
- DCHECK(!page->is_anchor()); |
- current_ = page->area_start(); |
- if (current_ == limit_) return NULL; |
- } |
- |
- HeapObject* object = HeapObject::FromAddress(current_); |
- int size = object->Size(); |
- |
- current_ += size; |
- return object; |
- } |
+ inline HeapObject* Next(); |
// Implementation of the ObjectIterator functions. |
- virtual HeapObject* next_object() { return Next(); } |
+ virtual inline HeapObject* next_object(); |
private: |
void Initialize(Address start, Address end); |
@@ -2811,45 +2803,7 @@ class PointerChunkIterator BASE_EMBEDDED { |
inline explicit PointerChunkIterator(Heap* heap); |
// Return NULL when the iterator is done. |
- MemoryChunk* next() { |
- switch (state_) { |
- case kOldSpaceState: { |
- if (old_iterator_.has_next()) { |
- return old_iterator_.next(); |
- } |
- state_ = kMapState; |
- // Fall through. |
- } |
- case kMapState: { |
- if (map_iterator_.has_next()) { |
- return map_iterator_.next(); |
- } |
- state_ = kLargeObjectState; |
- // Fall through. |
- } |
- case kLargeObjectState: { |
- HeapObject* heap_object; |
- do { |
- heap_object = lo_iterator_.Next(); |
- if (heap_object == NULL) { |
- state_ = kFinishedState; |
- return NULL; |
- } |
- // Fixed arrays are the only pointer-containing objects in large |
- // object space. |
- } while (!heap_object->IsFixedArray()); |
- MemoryChunk* answer = MemoryChunk::FromAddress(heap_object->address()); |
- return answer; |
- } |
- case kFinishedState: |
- return NULL; |
- default: |
- break; |
- } |
- UNREACHABLE(); |
- return NULL; |
- } |
- |
+ inline MemoryChunk* next(); |
private: |
enum State { kOldSpaceState, kMapState, kLargeObjectState, kFinishedState }; |