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 #include "src/heap/spaces.h" | 5 #include "src/heap/spaces.h" |
6 | 6 |
7 #include "src/base/bits.h" | 7 #include "src/base/bits.h" |
8 #include "src/base/platform/platform.h" | 8 #include "src/base/platform/platform.h" |
9 #include "src/full-codegen/full-codegen.h" | 9 #include "src/full-codegen/full-codegen.h" |
10 #include "src/heap/slot-set.h" | 10 #include "src/heap/slot-set.h" |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
215 CHECK_LE(commit_size, | 215 CHECK_LE(commit_size, |
216 requested_size - 2 * MemoryAllocator::CodePageGuardSize()); | 216 requested_size - 2 * MemoryAllocator::CodePageGuardSize()); |
217 FreeBlock current; | 217 FreeBlock current; |
218 if (!ReserveBlock(requested_size, ¤t)) { | 218 if (!ReserveBlock(requested_size, ¤t)) { |
219 *allocated = 0; | 219 *allocated = 0; |
220 return NULL; | 220 return NULL; |
221 } | 221 } |
222 *allocated = current.size; | 222 *allocated = current.size; |
223 DCHECK(*allocated <= current.size); | 223 DCHECK(*allocated <= current.size); |
224 DCHECK(IsAddressAligned(current.start, MemoryChunk::kAlignment)); | 224 DCHECK(IsAddressAligned(current.start, MemoryChunk::kAlignment)); |
225 if (!isolate_->memory_allocator()->CommitExecutableMemory( | 225 if (!isolate_->heap()->memory_allocator()->CommitExecutableMemory( |
226 code_range_, current.start, commit_size, *allocated)) { | 226 code_range_, current.start, commit_size, *allocated)) { |
227 *allocated = 0; | 227 *allocated = 0; |
228 ReleaseBlock(¤t); | 228 ReleaseBlock(¤t); |
229 return NULL; | 229 return NULL; |
230 } | 230 } |
231 return current.start; | 231 return current.start; |
232 } | 232 } |
233 | 233 |
234 | 234 |
235 bool CodeRange::CommitRawMemory(Address start, size_t length) { | 235 bool CodeRange::CommitRawMemory(Address start, size_t length) { |
236 return isolate_->memory_allocator()->CommitMemory(start, length, EXECUTABLE); | 236 return isolate_->heap()->memory_allocator()->CommitMemory(start, length, |
| 237 EXECUTABLE); |
237 } | 238 } |
238 | 239 |
239 | 240 |
240 bool CodeRange::UncommitRawMemory(Address start, size_t length) { | 241 bool CodeRange::UncommitRawMemory(Address start, size_t length) { |
241 return code_range_->Uncommit(start, length); | 242 return code_range_->Uncommit(start, length); |
242 } | 243 } |
243 | 244 |
244 | 245 |
245 void CodeRange::FreeRawMemory(Address address, size_t length) { | 246 void CodeRange::FreeRawMemory(Address address, size_t length) { |
246 DCHECK(IsAddressAligned(address, MemoryChunk::kAlignment)); | 247 DCHECK(IsAddressAligned(address, MemoryChunk::kAlignment)); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
287 free_list_.Add(*block); | 288 free_list_.Add(*block); |
288 } | 289 } |
289 | 290 |
290 | 291 |
291 // ----------------------------------------------------------------------------- | 292 // ----------------------------------------------------------------------------- |
292 // MemoryAllocator | 293 // MemoryAllocator |
293 // | 294 // |
294 | 295 |
295 MemoryAllocator::MemoryAllocator(Isolate* isolate) | 296 MemoryAllocator::MemoryAllocator(Isolate* isolate) |
296 : isolate_(isolate), | 297 : isolate_(isolate), |
| 298 code_range_(nullptr), |
297 capacity_(0), | 299 capacity_(0), |
298 capacity_executable_(0), | 300 capacity_executable_(0), |
299 size_(0), | 301 size_(0), |
300 size_executable_(0), | 302 size_executable_(0), |
301 lowest_ever_allocated_(reinterpret_cast<void*>(-1)), | 303 lowest_ever_allocated_(reinterpret_cast<void*>(-1)), |
302 highest_ever_allocated_(reinterpret_cast<void*>(0)) {} | 304 highest_ever_allocated_(reinterpret_cast<void*>(0)) {} |
303 | 305 |
304 | 306 bool MemoryAllocator::SetUp(intptr_t capacity, intptr_t capacity_executable, |
305 bool MemoryAllocator::SetUp(intptr_t capacity, intptr_t capacity_executable) { | 307 intptr_t code_range_size) { |
306 capacity_ = RoundUp(capacity, Page::kPageSize); | 308 capacity_ = RoundUp(capacity, Page::kPageSize); |
307 capacity_executable_ = RoundUp(capacity_executable, Page::kPageSize); | 309 capacity_executable_ = RoundUp(capacity_executable, Page::kPageSize); |
308 DCHECK_GE(capacity_, capacity_executable_); | 310 DCHECK_GE(capacity_, capacity_executable_); |
309 | 311 |
310 size_ = 0; | 312 size_ = 0; |
311 size_executable_ = 0; | 313 size_executable_ = 0; |
312 | 314 |
| 315 code_range_ = new CodeRange(isolate_); |
| 316 if (!code_range_->SetUp(static_cast<size_t>(code_range_size))) return false; |
| 317 |
313 return true; | 318 return true; |
314 } | 319 } |
315 | 320 |
316 | 321 |
317 void MemoryAllocator::TearDown() { | 322 void MemoryAllocator::TearDown() { |
318 for (MemoryChunk* chunk : chunk_pool_) { | 323 for (MemoryChunk* chunk : chunk_pool_) { |
319 FreeMemory(reinterpret_cast<Address>(chunk), MemoryChunk::kPageSize, | 324 FreeMemory(reinterpret_cast<Address>(chunk), MemoryChunk::kPageSize, |
320 NOT_EXECUTABLE); | 325 NOT_EXECUTABLE); |
321 } | 326 } |
322 // Check that spaces were torn down before MemoryAllocator. | 327 // Check that spaces were torn down before MemoryAllocator. |
323 DCHECK_EQ(size_.Value(), 0); | 328 DCHECK_EQ(size_.Value(), 0); |
324 // TODO(gc) this will be true again when we fix FreeMemory. | 329 // TODO(gc) this will be true again when we fix FreeMemory. |
325 // DCHECK(size_executable_ == 0); | 330 // DCHECK(size_executable_ == 0); |
326 capacity_ = 0; | 331 capacity_ = 0; |
327 capacity_executable_ = 0; | 332 capacity_executable_ = 0; |
| 333 |
| 334 delete code_range_; |
| 335 code_range_ = nullptr; |
328 } | 336 } |
329 | 337 |
330 bool MemoryAllocator::CommitMemory(Address base, size_t size, | 338 bool MemoryAllocator::CommitMemory(Address base, size_t size, |
331 Executability executable) { | 339 Executability executable) { |
332 if (!base::VirtualMemory::CommitRegion(base, size, | 340 if (!base::VirtualMemory::CommitRegion(base, size, |
333 executable == EXECUTABLE)) { | 341 executable == EXECUTABLE)) { |
334 return false; | 342 return false; |
335 } | 343 } |
336 UpdateAllocatedSpaceLimits(base, base + size); | 344 UpdateAllocatedSpaceLimits(base, base + size); |
337 return true; | 345 return true; |
338 } | 346 } |
339 | 347 |
340 | 348 |
341 void MemoryAllocator::FreeMemory(base::VirtualMemory* reservation, | 349 void MemoryAllocator::FreeMemory(base::VirtualMemory* reservation, |
342 Executability executable) { | 350 Executability executable) { |
343 // TODO(gc) make code_range part of memory allocator? | 351 // TODO(gc) make code_range part of memory allocator? |
344 // Code which is part of the code-range does not have its own VirtualMemory. | 352 // Code which is part of the code-range does not have its own VirtualMemory. |
345 DCHECK(isolate_->code_range() == NULL || | 353 DCHECK(code_range() == NULL || |
346 !isolate_->code_range()->contains( | 354 !code_range()->contains(static_cast<Address>(reservation->address()))); |
347 static_cast<Address>(reservation->address()))); | 355 DCHECK(executable == NOT_EXECUTABLE || code_range() == NULL || |
348 DCHECK(executable == NOT_EXECUTABLE || isolate_->code_range() == NULL || | 356 !code_range()->valid() || reservation->size() <= Page::kPageSize); |
349 !isolate_->code_range()->valid() || | |
350 reservation->size() <= Page::kPageSize); | |
351 | 357 |
352 reservation->Release(); | 358 reservation->Release(); |
353 } | 359 } |
354 | 360 |
355 | 361 |
356 void MemoryAllocator::FreeMemory(Address base, size_t size, | 362 void MemoryAllocator::FreeMemory(Address base, size_t size, |
357 Executability executable) { | 363 Executability executable) { |
358 // TODO(gc) make code_range part of memory allocator? | 364 // TODO(gc) make code_range part of memory allocator? |
359 if (isolate_->code_range() != NULL && | 365 if (code_range() != NULL && |
360 isolate_->code_range()->contains(static_cast<Address>(base))) { | 366 code_range()->contains(static_cast<Address>(base))) { |
361 DCHECK(executable == EXECUTABLE); | 367 DCHECK(executable == EXECUTABLE); |
362 isolate_->code_range()->FreeRawMemory(base, size); | 368 code_range()->FreeRawMemory(base, size); |
363 } else { | 369 } else { |
364 DCHECK(executable == NOT_EXECUTABLE || isolate_->code_range() == NULL || | 370 DCHECK(executable == NOT_EXECUTABLE || code_range() == NULL || |
365 !isolate_->code_range()->valid()); | 371 !code_range()->valid()); |
366 bool result = base::VirtualMemory::ReleaseRegion(base, size); | 372 bool result = base::VirtualMemory::ReleaseRegion(base, size); |
367 USE(result); | 373 USE(result); |
368 DCHECK(result); | 374 DCHECK(result); |
369 } | 375 } |
370 } | 376 } |
371 | 377 |
372 | |
373 Address MemoryAllocator::ReserveAlignedMemory(size_t size, size_t alignment, | 378 Address MemoryAllocator::ReserveAlignedMemory(size_t size, size_t alignment, |
374 base::VirtualMemory* controller) { | 379 base::VirtualMemory* controller) { |
375 base::VirtualMemory reservation(size, alignment); | 380 base::VirtualMemory reservation(size, alignment); |
376 | 381 |
377 if (!reservation.IsReserved()) return NULL; | 382 if (!reservation.IsReserved()) return NULL; |
378 size_.Increment(static_cast<intptr_t>(reservation.size())); | 383 size_.Increment(static_cast<intptr_t>(reservation.size())); |
379 Address base = | 384 Address base = |
380 RoundUp(static_cast<Address>(reservation.address()), alignment); | 385 RoundUp(static_cast<Address>(reservation.address()), alignment); |
381 controller->TakeControl(&reservation); | 386 controller->TakeControl(&reservation); |
382 return base; | 387 return base; |
383 } | 388 } |
384 | 389 |
385 | |
386 Address MemoryAllocator::AllocateAlignedMemory( | 390 Address MemoryAllocator::AllocateAlignedMemory( |
387 size_t reserve_size, size_t commit_size, size_t alignment, | 391 size_t reserve_size, size_t commit_size, size_t alignment, |
388 Executability executable, base::VirtualMemory* controller) { | 392 Executability executable, base::VirtualMemory* controller) { |
389 DCHECK(commit_size <= reserve_size); | 393 DCHECK(commit_size <= reserve_size); |
390 base::VirtualMemory reservation; | 394 base::VirtualMemory reservation; |
391 Address base = ReserveAlignedMemory(reserve_size, alignment, &reservation); | 395 Address base = ReserveAlignedMemory(reserve_size, alignment, &reservation); |
392 if (base == NULL) return NULL; | 396 if (base == NULL) return NULL; |
393 | 397 |
394 if (executable == EXECUTABLE) { | 398 if (executable == EXECUTABLE) { |
395 if (!CommitExecutableMemory(&reservation, base, commit_size, | 399 if (!CommitExecutableMemory(&reservation, base, commit_size, |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
489 | 493 |
490 if (commit_size > committed_size) { | 494 if (commit_size > committed_size) { |
491 // Commit size should be less or equal than the reserved size. | 495 // Commit size should be less or equal than the reserved size. |
492 DCHECK(commit_size <= size() - 2 * guard_size); | 496 DCHECK(commit_size <= size() - 2 * guard_size); |
493 // Append the committed area. | 497 // Append the committed area. |
494 Address start = address() + committed_size + guard_size; | 498 Address start = address() + committed_size + guard_size; |
495 size_t length = commit_size - committed_size; | 499 size_t length = commit_size - committed_size; |
496 if (reservation_.IsReserved()) { | 500 if (reservation_.IsReserved()) { |
497 Executability executable = | 501 Executability executable = |
498 IsFlagSet(IS_EXECUTABLE) ? EXECUTABLE : NOT_EXECUTABLE; | 502 IsFlagSet(IS_EXECUTABLE) ? EXECUTABLE : NOT_EXECUTABLE; |
499 if (!heap()->isolate()->memory_allocator()->CommitMemory(start, length, | 503 if (!heap()->memory_allocator()->CommitMemory(start, length, |
500 executable)) { | 504 executable)) { |
501 return false; | 505 return false; |
502 } | 506 } |
503 } else { | 507 } else { |
504 CodeRange* code_range = heap_->isolate()->code_range(); | 508 CodeRange* code_range = heap_->memory_allocator()->code_range(); |
505 DCHECK(code_range != NULL && code_range->valid() && | 509 DCHECK(code_range != NULL && code_range->valid() && |
506 IsFlagSet(IS_EXECUTABLE)); | 510 IsFlagSet(IS_EXECUTABLE)); |
507 if (!code_range->CommitRawMemory(start, length)) return false; | 511 if (!code_range->CommitRawMemory(start, length)) return false; |
508 } | 512 } |
509 | 513 |
510 if (Heap::ShouldZapGarbage()) { | 514 if (Heap::ShouldZapGarbage()) { |
511 heap_->isolate()->memory_allocator()->ZapBlock(start, length); | 515 heap_->memory_allocator()->ZapBlock(start, length); |
512 } | 516 } |
513 } else if (commit_size < committed_size) { | 517 } else if (commit_size < committed_size) { |
514 DCHECK(commit_size > 0); | 518 DCHECK(commit_size > 0); |
515 // Shrink the committed area. | 519 // Shrink the committed area. |
516 size_t length = committed_size - commit_size; | 520 size_t length = committed_size - commit_size; |
517 Address start = address() + committed_size + guard_size - length; | 521 Address start = address() + committed_size + guard_size - length; |
518 if (reservation_.IsReserved()) { | 522 if (reservation_.IsReserved()) { |
519 if (!reservation_.Uncommit(start, length)) return false; | 523 if (!reservation_.Uncommit(start, length)) return false; |
520 } else { | 524 } else { |
521 CodeRange* code_range = heap_->isolate()->code_range(); | 525 CodeRange* code_range = heap_->memory_allocator()->code_range(); |
522 DCHECK(code_range != NULL && code_range->valid() && | 526 DCHECK(code_range != NULL && code_range->valid() && |
523 IsFlagSet(IS_EXECUTABLE)); | 527 IsFlagSet(IS_EXECUTABLE)); |
524 if (!code_range->UncommitRawMemory(start, length)) return false; | 528 if (!code_range->UncommitRawMemory(start, length)) return false; |
525 } | 529 } |
526 } | 530 } |
527 | 531 |
528 area_end_ = area_start_ + requested; | 532 area_end_ = area_start_ + requested; |
529 return true; | 533 return true; |
530 } | 534 } |
531 | 535 |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
607 } | 611 } |
608 | 612 |
609 // Size of header (not executable) plus area (executable). | 613 // Size of header (not executable) plus area (executable). |
610 size_t commit_size = RoundUp(CodePageGuardStartOffset() + commit_area_size, | 614 size_t commit_size = RoundUp(CodePageGuardStartOffset() + commit_area_size, |
611 base::OS::CommitPageSize()); | 615 base::OS::CommitPageSize()); |
612 // Allocate executable memory either from code range or from the | 616 // Allocate executable memory either from code range or from the |
613 // OS. | 617 // OS. |
614 #ifdef V8_TARGET_ARCH_MIPS64 | 618 #ifdef V8_TARGET_ARCH_MIPS64 |
615 // Use code range only for large object space on mips64 to keep address | 619 // Use code range only for large object space on mips64 to keep address |
616 // range within 256-MB memory region. | 620 // range within 256-MB memory region. |
617 if (isolate_->code_range() != NULL && isolate_->code_range()->valid() && | 621 if (code_range() != NULL && code_range()->valid() && |
618 reserve_area_size > CodePageAreaSize()) { | 622 reserve_area_size > CodePageAreaSize()) { |
619 #else | 623 #else |
620 if (isolate_->code_range() != NULL && isolate_->code_range()->valid()) { | 624 if (code_range() != NULL && code_range()->valid()) { |
621 #endif | 625 #endif |
622 base = isolate_->code_range()->AllocateRawMemory(chunk_size, commit_size, | 626 base = |
623 &chunk_size); | 627 code_range()->AllocateRawMemory(chunk_size, commit_size, &chunk_size); |
624 DCHECK( | 628 DCHECK( |
625 IsAligned(reinterpret_cast<intptr_t>(base), MemoryChunk::kAlignment)); | 629 IsAligned(reinterpret_cast<intptr_t>(base), MemoryChunk::kAlignment)); |
626 if (base == NULL) return NULL; | 630 if (base == NULL) return NULL; |
627 size_.Increment(static_cast<intptr_t>(chunk_size)); | 631 size_.Increment(static_cast<intptr_t>(chunk_size)); |
628 // Update executable memory size. | 632 // Update executable memory size. |
629 size_executable_.Increment(static_cast<intptr_t>(chunk_size)); | 633 size_executable_.Increment(static_cast<intptr_t>(chunk_size)); |
630 } else { | 634 } else { |
631 base = AllocateAlignedMemory(chunk_size, commit_size, | 635 base = AllocateAlignedMemory(chunk_size, commit_size, |
632 MemoryChunk::kAlignment, executable, | 636 MemoryChunk::kAlignment, executable, |
633 &reservation); | 637 &reservation); |
(...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1029 | 1033 |
1030 bool PagedSpace::SetUp() { return true; } | 1034 bool PagedSpace::SetUp() { return true; } |
1031 | 1035 |
1032 | 1036 |
1033 bool PagedSpace::HasBeenSetUp() { return true; } | 1037 bool PagedSpace::HasBeenSetUp() { return true; } |
1034 | 1038 |
1035 | 1039 |
1036 void PagedSpace::TearDown() { | 1040 void PagedSpace::TearDown() { |
1037 PageIterator iterator(this); | 1041 PageIterator iterator(this); |
1038 while (iterator.has_next()) { | 1042 while (iterator.has_next()) { |
1039 heap()->isolate()->memory_allocator()->Free(iterator.next()); | 1043 heap()->memory_allocator()->Free(iterator.next()); |
1040 } | 1044 } |
1041 anchor_.set_next_page(&anchor_); | 1045 anchor_.set_next_page(&anchor_); |
1042 anchor_.set_prev_page(&anchor_); | 1046 anchor_.set_prev_page(&anchor_); |
1043 accounting_stats_.Clear(); | 1047 accounting_stats_.Clear(); |
1044 } | 1048 } |
1045 | 1049 |
1046 void PagedSpace::RefillFreeList() { | 1050 void PagedSpace::RefillFreeList() { |
1047 // Any PagedSpace might invoke RefillFreeList. We filter all but our old | 1051 // Any PagedSpace might invoke RefillFreeList. We filter all but our old |
1048 // generation spaces out. | 1052 // generation spaces out. |
1049 if (identity() != OLD_SPACE && identity() != CODE_SPACE && | 1053 if (identity() != OLD_SPACE && identity() != CODE_SPACE && |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1165 | 1169 |
1166 | 1170 |
1167 bool PagedSpace::Expand() { | 1171 bool PagedSpace::Expand() { |
1168 intptr_t size = AreaSize(); | 1172 intptr_t size = AreaSize(); |
1169 if (snapshotable() && !HasPages()) { | 1173 if (snapshotable() && !HasPages()) { |
1170 size = Snapshot::SizeOfFirstPage(heap()->isolate(), identity()); | 1174 size = Snapshot::SizeOfFirstPage(heap()->isolate(), identity()); |
1171 } | 1175 } |
1172 | 1176 |
1173 if (!CanExpand(size)) return false; | 1177 if (!CanExpand(size)) return false; |
1174 | 1178 |
1175 Page* p = heap()->isolate()->memory_allocator()->AllocatePage<Page>( | 1179 Page* p = |
1176 size, this, executable()); | 1180 heap()->memory_allocator()->AllocatePage<Page>(size, this, executable()); |
1177 if (p == NULL) return false; | 1181 if (p == NULL) return false; |
1178 | 1182 |
1179 AccountCommitted(static_cast<intptr_t>(p->size())); | 1183 AccountCommitted(static_cast<intptr_t>(p->size())); |
1180 | 1184 |
1181 // Pages created during bootstrapping may contain immortal immovable objects. | 1185 // Pages created during bootstrapping may contain immortal immovable objects. |
1182 if (!heap()->deserialization_complete()) p->MarkNeverEvacuate(); | 1186 if (!heap()->deserialization_complete()) p->MarkNeverEvacuate(); |
1183 | 1187 |
1184 // When incremental marking was activated, old generation pages are allocated | 1188 // When incremental marking was activated, old generation pages are allocated |
1185 // black. | 1189 // black. |
1186 if (heap()->incremental_marking()->black_allocation()) { | 1190 if (heap()->incremental_marking()->black_allocation()) { |
(...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1675 } | 1679 } |
1676 | 1680 |
1677 | 1681 |
1678 bool SemiSpace::Commit() { | 1682 bool SemiSpace::Commit() { |
1679 DCHECK(!is_committed()); | 1683 DCHECK(!is_committed()); |
1680 NewSpacePage* current = anchor(); | 1684 NewSpacePage* current = anchor(); |
1681 const int num_pages = current_capacity_ / Page::kPageSize; | 1685 const int num_pages = current_capacity_ / Page::kPageSize; |
1682 for (int i = 0; i < num_pages; i++) { | 1686 for (int i = 0; i < num_pages; i++) { |
1683 NewSpacePage* new_page = | 1687 NewSpacePage* new_page = |
1684 heap() | 1688 heap() |
1685 ->isolate() | |
1686 ->memory_allocator() | 1689 ->memory_allocator() |
1687 ->AllocatePage<NewSpacePage, MemoryAllocator::kPooled>( | 1690 ->AllocatePage<NewSpacePage, MemoryAllocator::kPooled>( |
1688 NewSpacePage::kAllocatableMemory, this, executable()); | 1691 NewSpacePage::kAllocatableMemory, this, executable()); |
1689 new_page->InsertAfter(current); | 1692 new_page->InsertAfter(current); |
1690 current = new_page; | 1693 current = new_page; |
1691 } | 1694 } |
1692 Reset(); | 1695 Reset(); |
1693 AccountCommitted(current_capacity_); | 1696 AccountCommitted(current_capacity_); |
1694 if (age_mark_ == nullptr) { | 1697 if (age_mark_ == nullptr) { |
1695 age_mark_ = first_page()->area_start(); | 1698 age_mark_ = first_page()->area_start(); |
1696 } | 1699 } |
1697 committed_ = true; | 1700 committed_ = true; |
1698 return true; | 1701 return true; |
1699 } | 1702 } |
1700 | 1703 |
1701 | 1704 |
1702 bool SemiSpace::Uncommit() { | 1705 bool SemiSpace::Uncommit() { |
1703 DCHECK(is_committed()); | 1706 DCHECK(is_committed()); |
1704 NewSpacePageIterator it(this); | 1707 NewSpacePageIterator it(this); |
1705 while (it.has_next()) { | 1708 while (it.has_next()) { |
1706 heap()->isolate()->memory_allocator()->Free<MemoryAllocator::kPooled>( | 1709 heap()->memory_allocator()->Free<MemoryAllocator::kPooled>(it.next()); |
1707 it.next()); | |
1708 } | 1710 } |
1709 anchor()->set_next_page(anchor()); | 1711 anchor()->set_next_page(anchor()); |
1710 anchor()->set_prev_page(anchor()); | 1712 anchor()->set_prev_page(anchor()); |
1711 AccountUncommitted(current_capacity_); | 1713 AccountUncommitted(current_capacity_); |
1712 committed_ = false; | 1714 committed_ = false; |
1713 return true; | 1715 return true; |
1714 } | 1716 } |
1715 | 1717 |
1716 | 1718 |
1717 size_t SemiSpace::CommittedPhysicalMemory() { | 1719 size_t SemiSpace::CommittedPhysicalMemory() { |
(...skipping 15 matching lines...) Expand all Loading... |
1733 DCHECK_LE(new_capacity, maximum_capacity_); | 1735 DCHECK_LE(new_capacity, maximum_capacity_); |
1734 DCHECK_GT(new_capacity, current_capacity_); | 1736 DCHECK_GT(new_capacity, current_capacity_); |
1735 const int delta = new_capacity - current_capacity_; | 1737 const int delta = new_capacity - current_capacity_; |
1736 DCHECK(IsAligned(delta, base::OS::AllocateAlignment())); | 1738 DCHECK(IsAligned(delta, base::OS::AllocateAlignment())); |
1737 int delta_pages = delta / NewSpacePage::kPageSize; | 1739 int delta_pages = delta / NewSpacePage::kPageSize; |
1738 NewSpacePage* last_page = anchor()->prev_page(); | 1740 NewSpacePage* last_page = anchor()->prev_page(); |
1739 DCHECK_NE(last_page, anchor()); | 1741 DCHECK_NE(last_page, anchor()); |
1740 while (delta_pages > 0) { | 1742 while (delta_pages > 0) { |
1741 NewSpacePage* new_page = | 1743 NewSpacePage* new_page = |
1742 heap() | 1744 heap() |
1743 ->isolate() | |
1744 ->memory_allocator() | 1745 ->memory_allocator() |
1745 ->AllocatePage<NewSpacePage, MemoryAllocator::kPooled>( | 1746 ->AllocatePage<NewSpacePage, MemoryAllocator::kPooled>( |
1746 NewSpacePage::kAllocatableMemory, this, executable()); | 1747 NewSpacePage::kAllocatableMemory, this, executable()); |
1747 new_page->InsertAfter(last_page); | 1748 new_page->InsertAfter(last_page); |
1748 Bitmap::Clear(new_page); | 1749 Bitmap::Clear(new_page); |
1749 // Duplicate the flags that was set on the old page. | 1750 // Duplicate the flags that was set on the old page. |
1750 new_page->SetFlags(last_page->GetFlags(), | 1751 new_page->SetFlags(last_page->GetFlags(), |
1751 NewSpacePage::kCopyOnFlipFlagsMask); | 1752 NewSpacePage::kCopyOnFlipFlagsMask); |
1752 last_page = new_page; | 1753 last_page = new_page; |
1753 delta_pages--; | 1754 delta_pages--; |
(...skipping 12 matching lines...) Expand all Loading... |
1766 const int delta = current_capacity_ - new_capacity; | 1767 const int delta = current_capacity_ - new_capacity; |
1767 DCHECK(IsAligned(delta, base::OS::AllocateAlignment())); | 1768 DCHECK(IsAligned(delta, base::OS::AllocateAlignment())); |
1768 int delta_pages = delta / NewSpacePage::kPageSize; | 1769 int delta_pages = delta / NewSpacePage::kPageSize; |
1769 NewSpacePage* new_last_page; | 1770 NewSpacePage* new_last_page; |
1770 NewSpacePage* last_page; | 1771 NewSpacePage* last_page; |
1771 while (delta_pages > 0) { | 1772 while (delta_pages > 0) { |
1772 last_page = anchor()->prev_page(); | 1773 last_page = anchor()->prev_page(); |
1773 new_last_page = last_page->prev_page(); | 1774 new_last_page = last_page->prev_page(); |
1774 new_last_page->set_next_page(anchor()); | 1775 new_last_page->set_next_page(anchor()); |
1775 anchor()->set_prev_page(new_last_page); | 1776 anchor()->set_prev_page(new_last_page); |
1776 heap()->isolate()->memory_allocator()->Free<MemoryAllocator::kPooled>( | 1777 heap()->memory_allocator()->Free<MemoryAllocator::kPooled>(last_page); |
1777 last_page); | |
1778 delta_pages--; | 1778 delta_pages--; |
1779 } | 1779 } |
1780 AccountUncommitted(static_cast<intptr_t>(delta)); | 1780 AccountUncommitted(static_cast<intptr_t>(delta)); |
1781 } | 1781 } |
1782 current_capacity_ = new_capacity; | 1782 current_capacity_ = new_capacity; |
1783 return true; | 1783 return true; |
1784 } | 1784 } |
1785 | 1785 |
1786 void SemiSpace::FixPagesFlags(intptr_t flags, intptr_t mask) { | 1786 void SemiSpace::FixPagesFlags(intptr_t flags, intptr_t mask) { |
1787 anchor_.set_owner(this); | 1787 anchor_.set_owner(this); |
(...skipping 1065 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2853 } | 2853 } |
2854 | 2854 |
2855 | 2855 |
2856 void LargeObjectSpace::TearDown() { | 2856 void LargeObjectSpace::TearDown() { |
2857 while (first_page_ != NULL) { | 2857 while (first_page_ != NULL) { |
2858 LargePage* page = first_page_; | 2858 LargePage* page = first_page_; |
2859 first_page_ = first_page_->next_page(); | 2859 first_page_ = first_page_->next_page(); |
2860 LOG(heap()->isolate(), DeleteEvent("LargeObjectChunk", page->address())); | 2860 LOG(heap()->isolate(), DeleteEvent("LargeObjectChunk", page->address())); |
2861 | 2861 |
2862 ObjectSpace space = static_cast<ObjectSpace>(1 << identity()); | 2862 ObjectSpace space = static_cast<ObjectSpace>(1 << identity()); |
2863 heap()->isolate()->memory_allocator()->PerformAllocationCallback( | 2863 heap()->memory_allocator()->PerformAllocationCallback( |
2864 space, kAllocationActionFree, page->size()); | 2864 space, kAllocationActionFree, page->size()); |
2865 heap()->isolate()->memory_allocator()->Free(page); | 2865 heap()->memory_allocator()->Free(page); |
2866 } | 2866 } |
2867 SetUp(); | 2867 SetUp(); |
2868 } | 2868 } |
2869 | 2869 |
2870 | 2870 |
2871 AllocationResult LargeObjectSpace::AllocateRaw(int object_size, | 2871 AllocationResult LargeObjectSpace::AllocateRaw(int object_size, |
2872 Executability executable) { | 2872 Executability executable) { |
2873 // Check if we want to force a GC before growing the old space further. | 2873 // Check if we want to force a GC before growing the old space further. |
2874 // If so, fail the allocation. | 2874 // If so, fail the allocation. |
2875 if (!heap()->CanExpandOldGeneration(object_size)) { | 2875 if (!heap()->CanExpandOldGeneration(object_size)) { |
2876 return AllocationResult::Retry(identity()); | 2876 return AllocationResult::Retry(identity()); |
2877 } | 2877 } |
2878 | 2878 |
2879 LargePage* page = | 2879 LargePage* page = heap()->memory_allocator()->AllocatePage<LargePage>( |
2880 heap()->isolate()->memory_allocator()->AllocatePage<LargePage>( | 2880 object_size, this, executable); |
2881 object_size, this, executable); | |
2882 if (page == NULL) return AllocationResult::Retry(identity()); | 2881 if (page == NULL) return AllocationResult::Retry(identity()); |
2883 DCHECK(page->area_size() >= object_size); | 2882 DCHECK(page->area_size() >= object_size); |
2884 | 2883 |
2885 size_ += static_cast<int>(page->size()); | 2884 size_ += static_cast<int>(page->size()); |
2886 AccountCommitted(static_cast<intptr_t>(page->size())); | 2885 AccountCommitted(static_cast<intptr_t>(page->size())); |
2887 objects_size_ += object_size; | 2886 objects_size_ += object_size; |
2888 page_count_++; | 2887 page_count_++; |
2889 page->set_next_page(first_page_); | 2888 page->set_next_page(first_page_); |
2890 first_page_ = page; | 2889 first_page_ = page; |
2891 | 2890 |
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3135 object->ShortPrint(); | 3134 object->ShortPrint(); |
3136 PrintF("\n"); | 3135 PrintF("\n"); |
3137 } | 3136 } |
3138 printf(" --------------------------------------\n"); | 3137 printf(" --------------------------------------\n"); |
3139 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes()); | 3138 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes()); |
3140 } | 3139 } |
3141 | 3140 |
3142 #endif // DEBUG | 3141 #endif // DEBUG |
3143 } // namespace internal | 3142 } // namespace internal |
3144 } // namespace v8 | 3143 } // namespace v8 |
OLD | NEW |