Chromium Code Reviews| Index: src/spaces-inl.h |
| =================================================================== |
| --- src/spaces-inl.h (revision 7216) |
| +++ src/spaces-inl.h (working copy) |
| @@ -1,4 +1,4 @@ |
| -// Copyright 2006-2010 the V8 project authors. All rights reserved. |
| +// Copyright 2011 the V8 project authors. All rights reserved. |
| // Redistribution and use in source and binary forms, with or without |
| // modification, are permitted provided that the following conditions are |
| // met: |
| @@ -38,107 +38,47 @@ |
| // ----------------------------------------------------------------------------- |
| // PageIterator |
| + |
| +PageIterator::PageIterator(PagedSpace* space) |
| + : space_(space), |
| + prev_page_(&space->anchor_), |
| + next_page_(prev_page_->next_page()) { } |
| + |
| + |
| bool PageIterator::has_next() { |
| - return prev_page_ != stop_page_; |
| + return next_page_ != &space_->anchor_; |
| } |
| Page* PageIterator::next() { |
| ASSERT(has_next()); |
| - prev_page_ = (prev_page_ == NULL) |
| - ? space_->first_page_ |
| - : prev_page_->next_page(); |
| + prev_page_ = next_page_; |
| + next_page_ = next_page_->next_page(); |
| return prev_page_; |
| } |
| // ----------------------------------------------------------------------------- |
| -// Page |
| - |
| - |
| -Address Page::AllocationTop() { |
| - return static_cast<PagedSpace*>(owner())->PageAllocationTop(this); |
| -} |
| - |
| - |
| -Address Page::AllocationWatermark() { |
| - if (this == static_cast<PagedSpace*>(owner())->AllocationTopPage()) { |
| - return static_cast<PagedSpace*>(owner())->top(); |
| +// HeapObjectIterator |
| +HeapObject* HeapObjectIterator::FromCurrentPage() { |
| + while (cur_addr_ != cur_end_) { |
| + if (cur_addr_ == space_->top() && cur_addr_ != space_->limit()) { |
| + cur_addr_ = space_->limit(); |
| + continue; |
| + } |
| + HeapObject* obj = HeapObject::FromAddress(cur_addr_); |
| + int obj_size = (size_func_ == NULL) ? obj->Size() : size_func_(obj); |
| + cur_addr_ += obj_size; |
| + ASSERT(cur_addr_ <= cur_end_); |
| + if (!obj->IsFiller()) { |
| + ASSERT_OBJECT_SIZE(obj_size); |
| + return obj; |
| + } |
| } |
| - return address() + AllocationWatermarkOffset(); |
| + return NULL; |
| } |
| -uint32_t Page::AllocationWatermarkOffset() { |
| - return static_cast<uint32_t>((flags_ & kAllocationWatermarkOffsetMask) >> |
| - kAllocationWatermarkOffsetShift); |
| -} |
| - |
| - |
| -void Page::SetAllocationWatermark(Address allocation_watermark) { |
| - if ((Heap::gc_state() == Heap::SCAVENGE) && IsWatermarkValid()) { |
| - // When iterating intergenerational references during scavenge |
| - // we might decide to promote an encountered young object. |
| - // We will allocate a space for such an object and put it |
| - // into the promotion queue to process it later. |
| - // If space for object was allocated somewhere beyond allocation |
| - // watermark this might cause garbage pointers to appear under allocation |
| - // watermark. To avoid visiting them during pointer-to-newspace iteration |
| - // which might be still in progress we store a valid allocation watermark |
| - // value and mark this page as having an invalid watermark. |
| - SetCachedAllocationWatermark(AllocationWatermark()); |
| - InvalidateWatermark(true); |
| - } |
| - |
| - flags_ = (flags_ & kFlagsMask) | |
| - Offset(allocation_watermark) << kAllocationWatermarkOffsetShift; |
| - ASSERT(AllocationWatermarkOffset() |
| - == static_cast<uint32_t>(Offset(allocation_watermark))); |
| -} |
| - |
| - |
| -void Page::SetCachedAllocationWatermark(Address allocation_watermark) { |
| - allocation_watermark_ = allocation_watermark; |
| -} |
| - |
| - |
| -Address Page::CachedAllocationWatermark() { |
| - return allocation_watermark_; |
| -} |
| - |
| - |
| -void Page::FlipMeaningOfInvalidatedWatermarkFlag() { |
| - watermark_invalidated_mark_ ^= 1 << WATERMARK_INVALIDATED; |
| -} |
| - |
| - |
| -bool Page::IsWatermarkValid() { |
| - return (flags_ & (1 << WATERMARK_INVALIDATED)) != watermark_invalidated_mark_; |
| -} |
| - |
| - |
| -void Page::InvalidateWatermark(bool value) { |
| - if (value) { |
| - flags_ = (flags_ & ~(1 << WATERMARK_INVALIDATED)) | |
| - watermark_invalidated_mark_; |
| - } else { |
| - flags_ = (flags_ & ~(1 << WATERMARK_INVALIDATED)) | |
| - (watermark_invalidated_mark_ ^ (1 << WATERMARK_INVALIDATED)); |
| - } |
| - |
| - ASSERT(IsWatermarkValid() == !value); |
| -} |
| - |
| - |
| -void Page::ClearGCFields() { |
| - InvalidateWatermark(true); |
| - SetAllocationWatermark(ObjectAreaStart()); |
| - if (Heap::gc_state() == Heap::SCAVENGE) { |
| - SetCachedAllocationWatermark(ObjectAreaStart()); |
| - } |
| -} |
| - |
| - |
| // ----------------------------------------------------------------------------- |
| // MemoryAllocator |
| @@ -181,6 +121,45 @@ |
| } |
| +Page* Page::Initialize(MemoryChunk* chunk, |
| + Executability executable, |
| + PagedSpace* owner) { |
| + Page* page = reinterpret_cast<Page*>(chunk); |
| + MemoryChunk::Initialize(reinterpret_cast<Address>(chunk), |
| + kPageSize, |
| + executable, |
| + owner); |
| + owner->IncreaseCapacity(Page::kObjectAreaSize); |
| + owner->Free(page->ObjectAreaStart(), |
| + page->ObjectAreaEnd() - page->ObjectAreaStart()); |
| + return page; |
| +} |
| + |
| + |
| +Page* Page::next_page() { |
| + ASSERT(next_chunk()->owner() == owner()); |
| + return static_cast<Page*>(next_chunk()); |
| +} |
| + |
| + |
| +Page* Page::prev_page() { |
| + ASSERT(prev_chunk()->owner() == owner()); |
| + return static_cast<Page*>(prev_chunk()); |
| +} |
| + |
| + |
| +void Page::set_next_page(Page* page) { |
| + ASSERT(page->owner() == owner()); |
| + set_next_chunk(page); |
| +} |
| + |
| + |
| +void Page::set_prev_page(Page* page) { |
| + ASSERT(page->owner() == owner()); |
| + set_prev_chunk(page); |
| +} |
| + |
| + |
| // Try linear allocation in the page of alloc_info's allocation top. Does |
| // not contain slow case logic (eg, move to the next page or try free list |
| // allocation) so it can be used by all the allocation functions and for all |
| @@ -193,7 +172,7 @@ |
| alloc_info->top = new_top; |
| ASSERT(alloc_info->VerifyPagedAllocation()); |
| - accounting_stats_.AllocateBytes(size_in_bytes); |
| + ASSERT(current_top != NULL); |
| return HeapObject::FromAddress(current_top); |
| } |
| @@ -202,16 +181,18 @@ |
| MaybeObject* PagedSpace::AllocateRaw(int size_in_bytes) { |
| ASSERT(HasBeenSetup()); |
| ASSERT_OBJECT_SIZE(size_in_bytes); |
| + MaybeObject* object = AllocateLinearly(&allocation_info_, size_in_bytes); |
| + if (object != NULL) { |
| + return object; |
| + } |
| - HeapObject* object = AllocateLinearly(&allocation_info_, size_in_bytes); |
| + object = free_list_.Allocate(size_in_bytes); |
| if (object != NULL) { |
| - IncrementalMarking::Step(size_in_bytes); |
|
Vyacheslav Egorov (Chromium)
2011/03/17 16:11:00
It seems that we are doing step less frequently. W
Erik Corry
2011/03/17 17:24:26
The idea is that we set the linear allocation limi
|
| return object; |
| } |
| object = SlowAllocateRaw(size_in_bytes); |
| if (object != NULL) { |
| - IncrementalMarking::Step(size_in_bytes); |
| return object; |
| } |
| @@ -256,7 +237,7 @@ |
| bool FreeListNode::IsFreeListNode(HeapObject* object) { |
| - return object->map() == Heap::raw_unchecked_byte_array_map() |
| + return object->map() == Heap::raw_unchecked_free_space_map() |
| || object->map() == Heap::raw_unchecked_one_pointer_filler_map() |
| || object->map() == Heap::raw_unchecked_two_pointer_filler_map(); |
| } |