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 |