| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef V8_HEAP_SPACES_INL_H_ | 5 #ifndef V8_HEAP_SPACES_INL_H_ |
| 6 #define V8_HEAP_SPACES_INL_H_ | 6 #define V8_HEAP_SPACES_INL_H_ |
| 7 | 7 |
| 8 #include "src/heap/incremental-marking.h" | 8 #include "src/heap/incremental-marking.h" |
| 9 #include "src/heap/spaces.h" | 9 #include "src/heap/spaces.h" |
| 10 #include "src/isolate.h" | 10 #include "src/isolate.h" |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 49 next_page_ = next_page_->next_page(); | 49 next_page_ = next_page_->next_page(); |
| 50 return prev_page_; | 50 return prev_page_; |
| 51 } | 51 } |
| 52 | 52 |
| 53 | 53 |
| 54 // ----------------------------------------------------------------------------- | 54 // ----------------------------------------------------------------------------- |
| 55 // SemiSpaceIterator | 55 // SemiSpaceIterator |
| 56 | 56 |
| 57 HeapObject* SemiSpaceIterator::Next() { | 57 HeapObject* SemiSpaceIterator::Next() { |
| 58 while (current_ != limit_) { | 58 while (current_ != limit_) { |
| 59 if (NewSpacePage::IsAtEnd(current_)) { | 59 if (Page::IsAlignedToPageSize(current_)) { |
| 60 NewSpacePage* page = NewSpacePage::FromLimit(current_); | 60 Page* page = Page::FromAllocationAreaAddress(current_); |
| 61 page = page->next_page(); | 61 page = page->next_page(); |
| 62 DCHECK(!page->is_anchor()); | 62 DCHECK(!page->is_anchor()); |
| 63 current_ = page->area_start(); | 63 current_ = page->area_start(); |
| 64 if (current_ == limit_) return nullptr; | 64 if (current_ == limit_) return nullptr; |
| 65 } | 65 } |
| 66 HeapObject* object = HeapObject::FromAddress(current_); | 66 HeapObject* object = HeapObject::FromAddress(current_); |
| 67 current_ += object->Size(); | 67 current_ += object->Size(); |
| 68 if (!object->IsFiller()) { | 68 if (!object->IsFiller()) { |
| 69 return object; | 69 return object; |
| 70 } | 70 } |
| 71 } | 71 } |
| 72 return nullptr; | 72 return nullptr; |
| 73 } | 73 } |
| 74 | 74 |
| 75 | 75 |
| 76 HeapObject* SemiSpaceIterator::next_object() { return Next(); } | 76 HeapObject* SemiSpaceIterator::next_object() { return Next(); } |
| 77 | 77 |
| 78 | 78 |
| 79 // ----------------------------------------------------------------------------- | 79 // ----------------------------------------------------------------------------- |
| 80 // NewSpacePageIterator | 80 // NewSpacePageIterator |
| 81 | 81 |
| 82 NewSpacePageIterator::NewSpacePageIterator(NewSpace* space) | 82 NewSpacePageIterator::NewSpacePageIterator(NewSpace* space) |
| 83 : prev_page_(NewSpacePage::FromAddress(space->ToSpaceStart())->prev_page()), | 83 : prev_page_(Page::FromAddress(space->ToSpaceStart())->prev_page()), |
| 84 next_page_(NewSpacePage::FromAddress(space->ToSpaceStart())), | 84 next_page_(Page::FromAddress(space->ToSpaceStart())), |
| 85 last_page_(NewSpacePage::FromLimit(space->ToSpaceEnd())) {} | 85 last_page_(Page::FromAllocationAreaAddress(space->ToSpaceEnd())) {} |
| 86 | 86 |
| 87 NewSpacePageIterator::NewSpacePageIterator(SemiSpace* space) | 87 NewSpacePageIterator::NewSpacePageIterator(SemiSpace* space) |
| 88 : prev_page_(space->anchor()), | 88 : prev_page_(space->anchor()), |
| 89 next_page_(prev_page_->next_page()), | 89 next_page_(prev_page_->next_page()), |
| 90 last_page_(prev_page_->prev_page()) {} | 90 last_page_(prev_page_->prev_page()) {} |
| 91 | 91 |
| 92 NewSpacePageIterator::NewSpacePageIterator(Address start, Address limit) | 92 NewSpacePageIterator::NewSpacePageIterator(Address start, Address limit) |
| 93 : prev_page_(NewSpacePage::FromAddress(start)->prev_page()), | 93 : prev_page_(Page::FromAddress(start)->prev_page()), |
| 94 next_page_(NewSpacePage::FromAddress(start)), | 94 next_page_(Page::FromAddress(start)), |
| 95 last_page_(NewSpacePage::FromLimit(limit)) { | 95 last_page_(Page::FromAllocationAreaAddress(limit)) { |
| 96 SemiSpace::AssertValidRange(start, limit); | 96 SemiSpace::AssertValidRange(start, limit); |
| 97 } | 97 } |
| 98 | 98 |
| 99 | 99 |
| 100 bool NewSpacePageIterator::has_next() { return prev_page_ != last_page_; } | 100 bool NewSpacePageIterator::has_next() { return prev_page_ != last_page_; } |
| 101 | 101 |
| 102 | 102 Page* NewSpacePageIterator::next() { |
| 103 NewSpacePage* NewSpacePageIterator::next() { | |
| 104 DCHECK(has_next()); | 103 DCHECK(has_next()); |
| 105 prev_page_ = next_page_; | 104 prev_page_ = next_page_; |
| 106 next_page_ = next_page_->next_page(); | 105 next_page_ = next_page_->next_page(); |
| 107 return prev_page_; | 106 return prev_page_; |
| 108 } | 107 } |
| 109 | 108 |
| 110 | 109 |
| 111 // ----------------------------------------------------------------------------- | 110 // ----------------------------------------------------------------------------- |
| 112 // HeapObjectIterator | 111 // HeapObjectIterator |
| 113 | 112 |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 237 } | 236 } |
| 238 | 237 |
| 239 bool NewSpace::FromSpaceContainsSlow(Address a) { | 238 bool NewSpace::FromSpaceContainsSlow(Address a) { |
| 240 return from_space_.ContainsSlow(a); | 239 return from_space_.ContainsSlow(a); |
| 241 } | 240 } |
| 242 | 241 |
| 243 bool NewSpace::ToSpaceContains(Object* o) { return to_space_.Contains(o); } | 242 bool NewSpace::ToSpaceContains(Object* o) { return to_space_.Contains(o); } |
| 244 bool NewSpace::FromSpaceContains(Object* o) { return from_space_.Contains(o); } | 243 bool NewSpace::FromSpaceContains(Object* o) { return from_space_.Contains(o); } |
| 245 | 244 |
| 246 size_t NewSpace::AllocatedSinceLastGC() { | 245 size_t NewSpace::AllocatedSinceLastGC() { |
| 247 const intptr_t age_mark_offset = | 246 const intptr_t age_mark_offset = Page::OffsetInPage(to_space_.age_mark()); |
| 248 NewSpacePage::OffsetInPage(to_space_.age_mark()); | 247 const intptr_t top_offset = Page::OffsetInPage(allocation_info_.top()); |
| 249 const intptr_t top_offset = | |
| 250 NewSpacePage::OffsetInPage(allocation_info_.top()); | |
| 251 const intptr_t age_mark_delta = | 248 const intptr_t age_mark_delta = |
| 252 age_mark_offset >= NewSpacePage::kObjectStartOffset | 249 age_mark_offset >= Page::kObjectStartOffset |
| 253 ? age_mark_offset - NewSpacePage::kObjectStartOffset | 250 ? age_mark_offset - Page::kObjectStartOffset |
| 254 : NewSpacePage::kAllocatableMemory; | 251 : Page::kAllocatableMemory; |
| 255 const intptr_t top_delta = top_offset >= NewSpacePage::kObjectStartOffset | 252 const intptr_t top_delta = top_offset >= Page::kObjectStartOffset |
| 256 ? top_offset - NewSpacePage::kObjectStartOffset | 253 ? top_offset - Page::kObjectStartOffset |
| 257 : NewSpacePage::kAllocatableMemory; | 254 : Page::kAllocatableMemory; |
| 258 DCHECK((allocated_since_last_gc_ > 0) || | 255 DCHECK((allocated_since_last_gc_ > 0) || |
| 259 (NewSpacePage::FromLimit(allocation_info_.top()) == | 256 (Page::FromAllocationAreaAddress(allocation_info_.top()) == |
| 260 NewSpacePage::FromLimit(to_space_.age_mark()))); | 257 Page::FromAllocationAreaAddress(to_space_.age_mark()))); |
| 261 return static_cast<size_t>(allocated_since_last_gc_ + top_delta - | 258 return static_cast<size_t>(allocated_since_last_gc_ + top_delta - |
| 262 age_mark_delta); | 259 age_mark_delta); |
| 263 } | 260 } |
| 264 | 261 |
| 265 // -------------------------------------------------------------------------- | 262 // -------------------------------------------------------------------------- |
| 266 // AllocationResult | 263 // AllocationResult |
| 267 | 264 |
| 268 AllocationSpace AllocationResult::RetrySpace() { | 265 AllocationSpace AllocationResult::RetrySpace() { |
| 269 DCHECK(IsRetry()); | 266 DCHECK(IsRetry()); |
| 270 return static_cast<AllocationSpace>(Smi::cast(object_)->value()); | 267 return static_cast<AllocationSpace>(Smi::cast(object_)->value()); |
| 271 } | 268 } |
| 272 | 269 |
| 273 NewSpacePage* NewSpacePage::Initialize(Heap* heap, MemoryChunk* chunk, | 270 Page* Page::Initialize(Heap* heap, MemoryChunk* chunk, Executability executable, |
| 274 Executability executable, | 271 SemiSpace* owner) { |
| 275 SemiSpace* owner) { | |
| 276 DCHECK_EQ(executable, Executability::NOT_EXECUTABLE); | 272 DCHECK_EQ(executable, Executability::NOT_EXECUTABLE); |
| 277 bool in_to_space = (owner->id() != kFromSpace); | 273 bool in_to_space = (owner->id() != kFromSpace); |
| 278 chunk->SetFlag(in_to_space ? MemoryChunk::IN_TO_SPACE | 274 chunk->SetFlag(in_to_space ? MemoryChunk::IN_TO_SPACE |
| 279 : MemoryChunk::IN_FROM_SPACE); | 275 : MemoryChunk::IN_FROM_SPACE); |
| 280 DCHECK(!chunk->IsFlagSet(in_to_space ? MemoryChunk::IN_FROM_SPACE | 276 DCHECK(!chunk->IsFlagSet(in_to_space ? MemoryChunk::IN_FROM_SPACE |
| 281 : MemoryChunk::IN_TO_SPACE)); | 277 : MemoryChunk::IN_TO_SPACE)); |
| 282 NewSpacePage* page = static_cast<NewSpacePage*>(chunk); | 278 Page* page = static_cast<Page*>(chunk); |
| 283 heap->incremental_marking()->SetNewSpacePageFlags(page); | 279 heap->incremental_marking()->SetNewSpacePageFlags(page); |
| 284 return page; | 280 return page; |
| 285 } | 281 } |
| 286 | 282 |
| 287 // -------------------------------------------------------------------------- | 283 // -------------------------------------------------------------------------- |
| 288 // PagedSpace | 284 // PagedSpace |
| 289 | 285 |
| 290 template <Page::InitializationMode mode> | 286 template <Page::InitializationMode mode> |
| 291 Page* Page::Initialize(Heap* heap, MemoryChunk* chunk, Executability executable, | 287 Page* Page::Initialize(Heap* heap, MemoryChunk* chunk, Executability executable, |
| 292 PagedSpace* owner) { | 288 PagedSpace* owner) { |
| 293 Page* page = reinterpret_cast<Page*>(chunk); | 289 Page* page = reinterpret_cast<Page*>(chunk); |
| 294 page->mutex_ = new base::Mutex(); | 290 page->mutex_ = new base::Mutex(); |
| 295 DCHECK(page->area_size() <= kAllocatableMemory); | 291 DCHECK(page->area_size() <= kAllocatableMemory); |
| 296 DCHECK(chunk->owner() == owner); | 292 DCHECK(chunk->owner() == owner); |
| 297 | 293 |
| 298 owner->IncreaseCapacity(page->area_size()); | 294 owner->IncreaseCapacity(page->area_size()); |
| 299 heap->incremental_marking()->SetOldSpacePageFlags(chunk); | 295 heap->incremental_marking()->SetOldSpacePageFlags(chunk); |
| 300 | 296 |
| 301 // Make sure that categories are initialized before freeing the area. | 297 // Make sure that categories are initialized before freeing the area. |
| 302 page->InitializeFreeListCategories(); | 298 page->InitializeFreeListCategories(); |
| 303 // In the case we do not free the memory, we effectively account for the whole | 299 // In the case we do not free the memory, we effectively account for the whole |
| 304 // page as allocated memory that cannot be used for further allocations. | 300 // page as allocated memory that cannot be used for further allocations. |
| 305 if (mode == kFreeMemory) { | 301 if (mode == kFreeMemory) { |
| 306 owner->Free(page->area_start(), page->area_size()); | 302 owner->Free(page->area_start(), page->area_size()); |
| 307 } | 303 } |
| 308 | 304 |
| 309 return page; | 305 return page; |
| 310 } | 306 } |
| 311 | 307 |
| 312 Page* Page::Convert(NewSpacePage* old_page, PagedSpace* new_owner) { | 308 Page* Page::ConvertNewToOld(Page* old_page, PagedSpace* new_owner) { |
| 309 DCHECK(old_page->InNewSpace()); |
| 313 old_page->set_owner(new_owner); | 310 old_page->set_owner(new_owner); |
| 314 old_page->SetFlags(0, ~0); | 311 old_page->SetFlags(0, ~0); |
| 315 new_owner->AccountCommitted(old_page->size()); | 312 new_owner->AccountCommitted(old_page->size()); |
| 316 Page* new_page = Page::Initialize<kDoNotFreeMemory>( | 313 Page* new_page = Page::Initialize<kDoNotFreeMemory>( |
| 317 old_page->heap(), old_page, NOT_EXECUTABLE, new_owner); | 314 old_page->heap(), old_page, NOT_EXECUTABLE, new_owner); |
| 318 new_page->InsertAfter(new_owner->anchor()->prev_page()); | 315 new_page->InsertAfter(new_owner->anchor()->prev_page()); |
| 319 return new_page; | 316 return new_page; |
| 320 } | 317 } |
| 321 | 318 |
| 322 void Page::InitializeFreeListCategories() { | 319 void Page::InitializeFreeListCategories() { |
| (...skipping 29 matching lines...) Expand all Loading... |
| 352 void MemoryChunk::IncrementLiveBytesFromMutator(HeapObject* object, int by) { | 349 void MemoryChunk::IncrementLiveBytesFromMutator(HeapObject* object, int by) { |
| 353 MemoryChunk* chunk = MemoryChunk::FromAddress(object->address()); | 350 MemoryChunk* chunk = MemoryChunk::FromAddress(object->address()); |
| 354 if (!chunk->InNewSpace() && !static_cast<Page*>(chunk)->SweepingDone()) { | 351 if (!chunk->InNewSpace() && !static_cast<Page*>(chunk)->SweepingDone()) { |
| 355 static_cast<PagedSpace*>(chunk->owner())->Allocate(by); | 352 static_cast<PagedSpace*>(chunk->owner())->Allocate(by); |
| 356 } | 353 } |
| 357 chunk->IncrementLiveBytes(by); | 354 chunk->IncrementLiveBytes(by); |
| 358 } | 355 } |
| 359 | 356 |
| 360 bool PagedSpace::Contains(Address addr) { | 357 bool PagedSpace::Contains(Address addr) { |
| 361 Page* p = Page::FromAddress(addr); | 358 Page* p = Page::FromAddress(addr); |
| 362 if (!p->is_valid()) return false; | 359 if (!Page::IsValid(p)) return false; |
| 363 return p->owner() == this; | 360 return p->owner() == this; |
| 364 } | 361 } |
| 365 | 362 |
| 366 bool PagedSpace::Contains(Object* o) { | 363 bool PagedSpace::Contains(Object* o) { |
| 367 if (!o->IsHeapObject()) return false; | 364 if (!o->IsHeapObject()) return false; |
| 368 Page* p = Page::FromAddress(HeapObject::cast(o)->address()); | 365 Page* p = Page::FromAddress(HeapObject::cast(o)->address()); |
| 369 if (!p->is_valid()) return false; | 366 if (!Page::IsValid(p)) return false; |
| 370 return p->owner() == this; | 367 return p->owner() == this; |
| 371 } | 368 } |
| 372 | 369 |
| 373 void PagedSpace::UnlinkFreeListCategories(Page* page) { | 370 void PagedSpace::UnlinkFreeListCategories(Page* page) { |
| 374 DCHECK_EQ(this, page->owner()); | 371 DCHECK_EQ(this, page->owner()); |
| 375 page->ForAllFreeListCategories([this](FreeListCategory* category) { | 372 page->ForAllFreeListCategories([this](FreeListCategory* category) { |
| 376 DCHECK_EQ(free_list(), category->owner()); | 373 DCHECK_EQ(free_list(), category->owner()); |
| 377 free_list()->RemoveCategory(category); | 374 free_list()->RemoveCategory(category); |
| 378 }); | 375 }); |
| 379 } | 376 } |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 465 } | 462 } |
| 466 case kFinishedState: | 463 case kFinishedState: |
| 467 return nullptr; | 464 return nullptr; |
| 468 default: | 465 default: |
| 469 break; | 466 break; |
| 470 } | 467 } |
| 471 UNREACHABLE(); | 468 UNREACHABLE(); |
| 472 return nullptr; | 469 return nullptr; |
| 473 } | 470 } |
| 474 | 471 |
| 475 void Page::set_next_page(Page* page) { | |
| 476 DCHECK(page->owner() == owner()); | |
| 477 set_next_chunk(page); | |
| 478 } | |
| 479 | |
| 480 void Page::set_prev_page(Page* page) { | |
| 481 DCHECK(page->owner() == owner()); | |
| 482 set_prev_chunk(page); | |
| 483 } | |
| 484 | |
| 485 Page* FreeListCategory::page() { | 472 Page* FreeListCategory::page() { |
| 486 return Page::FromAddress(reinterpret_cast<Address>(this)); | 473 return Page::FromAddress(reinterpret_cast<Address>(this)); |
| 487 } | 474 } |
| 488 | 475 |
| 489 FreeList* FreeListCategory::owner() { | 476 FreeList* FreeListCategory::owner() { |
| 490 return reinterpret_cast<PagedSpace*>( | 477 return reinterpret_cast<PagedSpace*>( |
| 491 Page::FromAddress(reinterpret_cast<Address>(this))->owner()) | 478 Page::FromAddress(reinterpret_cast<Address>(this))->owner()) |
| 492 ->free_list(); | 479 ->free_list(); |
| 493 } | 480 } |
| 494 | 481 |
| (...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 744 other->allocation_info_.Reset(nullptr, nullptr); | 731 other->allocation_info_.Reset(nullptr, nullptr); |
| 745 return true; | 732 return true; |
| 746 } | 733 } |
| 747 return false; | 734 return false; |
| 748 } | 735 } |
| 749 | 736 |
| 750 } // namespace internal | 737 } // namespace internal |
| 751 } // namespace v8 | 738 } // namespace v8 |
| 752 | 739 |
| 753 #endif // V8_HEAP_SPACES_INL_H_ | 740 #endif // V8_HEAP_SPACES_INL_H_ |
| OLD | NEW |