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