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/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
| 7 #include "src/base/platform/platform.h" |
7 #include "src/full-codegen.h" | 8 #include "src/full-codegen.h" |
8 #include "src/macro-assembler.h" | 9 #include "src/macro-assembler.h" |
9 #include "src/mark-compact.h" | 10 #include "src/mark-compact.h" |
10 #include "src/msan.h" | 11 #include "src/msan.h" |
11 #include "src/platform.h" | |
12 | 12 |
13 namespace v8 { | 13 namespace v8 { |
14 namespace internal { | 14 namespace internal { |
15 | 15 |
16 | 16 |
17 // ---------------------------------------------------------------------------- | 17 // ---------------------------------------------------------------------------- |
18 // HeapObjectIterator | 18 // HeapObjectIterator |
19 | 19 |
20 HeapObjectIterator::HeapObjectIterator(PagedSpace* space) { | 20 HeapObjectIterator::HeapObjectIterator(PagedSpace* space) { |
21 // You can't actually iterate over the anchor page. It is not a real page, | 21 // You can't actually iterate over the anchor page. It is not a real page, |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
119 // in a kMaximalCodeRangeSize range of virtual address space, so that | 119 // in a kMaximalCodeRangeSize range of virtual address space, so that |
120 // they can call each other with near calls. | 120 // they can call each other with near calls. |
121 if (kRequiresCodeRange) { | 121 if (kRequiresCodeRange) { |
122 requested = kMaximalCodeRangeSize; | 122 requested = kMaximalCodeRangeSize; |
123 } else { | 123 } else { |
124 return true; | 124 return true; |
125 } | 125 } |
126 } | 126 } |
127 | 127 |
128 ASSERT(!kRequiresCodeRange || requested <= kMaximalCodeRangeSize); | 128 ASSERT(!kRequiresCodeRange || requested <= kMaximalCodeRangeSize); |
129 code_range_ = new VirtualMemory(requested); | 129 code_range_ = new base::VirtualMemory(requested); |
130 CHECK(code_range_ != NULL); | 130 CHECK(code_range_ != NULL); |
131 if (!code_range_->IsReserved()) { | 131 if (!code_range_->IsReserved()) { |
132 delete code_range_; | 132 delete code_range_; |
133 code_range_ = NULL; | 133 code_range_ = NULL; |
134 return false; | 134 return false; |
135 } | 135 } |
136 | 136 |
137 // We are sure that we have mapped a block of requested addresses. | 137 // We are sure that we have mapped a block of requested addresses. |
138 ASSERT(code_range_->size() == requested); | 138 ASSERT(code_range_->size() == requested); |
139 LOG(isolate_, | 139 LOG(isolate_, |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
294 // TODO(gc) this will be true again when we fix FreeMemory. | 294 // TODO(gc) this will be true again when we fix FreeMemory. |
295 // ASSERT(size_executable_ == 0); | 295 // ASSERT(size_executable_ == 0); |
296 capacity_ = 0; | 296 capacity_ = 0; |
297 capacity_executable_ = 0; | 297 capacity_executable_ = 0; |
298 } | 298 } |
299 | 299 |
300 | 300 |
301 bool MemoryAllocator::CommitMemory(Address base, | 301 bool MemoryAllocator::CommitMemory(Address base, |
302 size_t size, | 302 size_t size, |
303 Executability executable) { | 303 Executability executable) { |
304 if (!VirtualMemory::CommitRegion(base, size, executable == EXECUTABLE)) { | 304 if (!base::VirtualMemory::CommitRegion(base, size, |
| 305 executable == EXECUTABLE)) { |
305 return false; | 306 return false; |
306 } | 307 } |
307 UpdateAllocatedSpaceLimits(base, base + size); | 308 UpdateAllocatedSpaceLimits(base, base + size); |
308 return true; | 309 return true; |
309 } | 310 } |
310 | 311 |
311 | 312 |
312 void MemoryAllocator::FreeMemory(VirtualMemory* reservation, | 313 void MemoryAllocator::FreeMemory(base::VirtualMemory* reservation, |
313 Executability executable) { | 314 Executability executable) { |
314 // TODO(gc) make code_range part of memory allocator? | 315 // TODO(gc) make code_range part of memory allocator? |
315 ASSERT(reservation->IsReserved()); | 316 ASSERT(reservation->IsReserved()); |
316 size_t size = reservation->size(); | 317 size_t size = reservation->size(); |
317 ASSERT(size_ >= size); | 318 ASSERT(size_ >= size); |
318 size_ -= size; | 319 size_ -= size; |
319 | 320 |
320 isolate_->counters()->memory_allocated()->Decrement(static_cast<int>(size)); | 321 isolate_->counters()->memory_allocated()->Decrement(static_cast<int>(size)); |
321 | 322 |
322 if (executable == EXECUTABLE) { | 323 if (executable == EXECUTABLE) { |
(...skipping 25 matching lines...) Expand all Loading... |
348 size_executable_ -= size; | 349 size_executable_ -= size; |
349 } | 350 } |
350 if (isolate_->code_range() != NULL && | 351 if (isolate_->code_range() != NULL && |
351 isolate_->code_range()->contains(static_cast<Address>(base))) { | 352 isolate_->code_range()->contains(static_cast<Address>(base))) { |
352 ASSERT(executable == EXECUTABLE); | 353 ASSERT(executable == EXECUTABLE); |
353 isolate_->code_range()->FreeRawMemory(base, size); | 354 isolate_->code_range()->FreeRawMemory(base, size); |
354 } else { | 355 } else { |
355 ASSERT(executable == NOT_EXECUTABLE || | 356 ASSERT(executable == NOT_EXECUTABLE || |
356 isolate_->code_range() == NULL || | 357 isolate_->code_range() == NULL || |
357 !isolate_->code_range()->valid()); | 358 !isolate_->code_range()->valid()); |
358 bool result = VirtualMemory::ReleaseRegion(base, size); | 359 bool result = base::VirtualMemory::ReleaseRegion(base, size); |
359 USE(result); | 360 USE(result); |
360 ASSERT(result); | 361 ASSERT(result); |
361 } | 362 } |
362 } | 363 } |
363 | 364 |
364 | 365 |
365 Address MemoryAllocator::ReserveAlignedMemory(size_t size, | 366 Address MemoryAllocator::ReserveAlignedMemory(size_t size, |
366 size_t alignment, | 367 size_t alignment, |
367 VirtualMemory* controller) { | 368 base::VirtualMemory* controller) { |
368 VirtualMemory reservation(size, alignment); | 369 base::VirtualMemory reservation(size, alignment); |
369 | 370 |
370 if (!reservation.IsReserved()) return NULL; | 371 if (!reservation.IsReserved()) return NULL; |
371 size_ += reservation.size(); | 372 size_ += reservation.size(); |
372 Address base = RoundUp(static_cast<Address>(reservation.address()), | 373 Address base = RoundUp(static_cast<Address>(reservation.address()), |
373 alignment); | 374 alignment); |
374 controller->TakeControl(&reservation); | 375 controller->TakeControl(&reservation); |
375 return base; | 376 return base; |
376 } | 377 } |
377 | 378 |
378 | 379 |
379 Address MemoryAllocator::AllocateAlignedMemory(size_t reserve_size, | 380 Address MemoryAllocator::AllocateAlignedMemory( |
380 size_t commit_size, | 381 size_t reserve_size, size_t commit_size, size_t alignment, |
381 size_t alignment, | 382 Executability executable, base::VirtualMemory* controller) { |
382 Executability executable, | |
383 VirtualMemory* controller) { | |
384 ASSERT(commit_size <= reserve_size); | 383 ASSERT(commit_size <= reserve_size); |
385 VirtualMemory reservation; | 384 base::VirtualMemory reservation; |
386 Address base = ReserveAlignedMemory(reserve_size, alignment, &reservation); | 385 Address base = ReserveAlignedMemory(reserve_size, alignment, &reservation); |
387 if (base == NULL) return NULL; | 386 if (base == NULL) return NULL; |
388 | 387 |
389 if (executable == EXECUTABLE) { | 388 if (executable == EXECUTABLE) { |
390 if (!CommitExecutableMemory(&reservation, | 389 if (!CommitExecutableMemory(&reservation, |
391 base, | 390 base, |
392 commit_size, | 391 commit_size, |
393 reserve_size)) { | 392 reserve_size)) { |
394 base = NULL; | 393 base = NULL; |
395 } | 394 } |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
504 | 503 |
505 return chunk; | 504 return chunk; |
506 } | 505 } |
507 | 506 |
508 | 507 |
509 // Commit MemoryChunk area to the requested size. | 508 // Commit MemoryChunk area to the requested size. |
510 bool MemoryChunk::CommitArea(size_t requested) { | 509 bool MemoryChunk::CommitArea(size_t requested) { |
511 size_t guard_size = IsFlagSet(IS_EXECUTABLE) ? | 510 size_t guard_size = IsFlagSet(IS_EXECUTABLE) ? |
512 MemoryAllocator::CodePageGuardSize() : 0; | 511 MemoryAllocator::CodePageGuardSize() : 0; |
513 size_t header_size = area_start() - address() - guard_size; | 512 size_t header_size = area_start() - address() - guard_size; |
514 size_t commit_size = RoundUp(header_size + requested, OS::CommitPageSize()); | 513 size_t commit_size = |
| 514 RoundUp(header_size + requested, base::OS::CommitPageSize()); |
515 size_t committed_size = RoundUp(header_size + (area_end() - area_start()), | 515 size_t committed_size = RoundUp(header_size + (area_end() - area_start()), |
516 OS::CommitPageSize()); | 516 base::OS::CommitPageSize()); |
517 | 517 |
518 if (commit_size > committed_size) { | 518 if (commit_size > committed_size) { |
519 // Commit size should be less or equal than the reserved size. | 519 // Commit size should be less or equal than the reserved size. |
520 ASSERT(commit_size <= size() - 2 * guard_size); | 520 ASSERT(commit_size <= size() - 2 * guard_size); |
521 // Append the committed area. | 521 // Append the committed area. |
522 Address start = address() + committed_size + guard_size; | 522 Address start = address() + committed_size + guard_size; |
523 size_t length = commit_size - committed_size; | 523 size_t length = commit_size - committed_size; |
524 if (reservation_.IsReserved()) { | 524 if (reservation_.IsReserved()) { |
525 Executability executable = IsFlagSet(IS_EXECUTABLE) | 525 Executability executable = IsFlagSet(IS_EXECUTABLE) |
526 ? EXECUTABLE : NOT_EXECUTABLE; | 526 ? EXECUTABLE : NOT_EXECUTABLE; |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
580 | 580 |
581 MemoryChunk* MemoryAllocator::AllocateChunk(intptr_t reserve_area_size, | 581 MemoryChunk* MemoryAllocator::AllocateChunk(intptr_t reserve_area_size, |
582 intptr_t commit_area_size, | 582 intptr_t commit_area_size, |
583 Executability executable, | 583 Executability executable, |
584 Space* owner) { | 584 Space* owner) { |
585 ASSERT(commit_area_size <= reserve_area_size); | 585 ASSERT(commit_area_size <= reserve_area_size); |
586 | 586 |
587 size_t chunk_size; | 587 size_t chunk_size; |
588 Heap* heap = isolate_->heap(); | 588 Heap* heap = isolate_->heap(); |
589 Address base = NULL; | 589 Address base = NULL; |
590 VirtualMemory reservation; | 590 base::VirtualMemory reservation; |
591 Address area_start = NULL; | 591 Address area_start = NULL; |
592 Address area_end = NULL; | 592 Address area_end = NULL; |
593 | 593 |
594 // | 594 // |
595 // MemoryChunk layout: | 595 // MemoryChunk layout: |
596 // | 596 // |
597 // Executable | 597 // Executable |
598 // +----------------------------+<- base aligned with MemoryChunk::kAlignment | 598 // +----------------------------+<- base aligned with MemoryChunk::kAlignment |
599 // | Header | | 599 // | Header | |
600 // +----------------------------+<- base + CodePageGuardStartOffset | 600 // +----------------------------+<- base + CodePageGuardStartOffset |
(...skipping 15 matching lines...) Expand all Loading... |
616 // | Area | | 616 // | Area | |
617 // +----------------------------+<- area_end_ (area_start + commit_area_size) | 617 // +----------------------------+<- area_end_ (area_start + commit_area_size) |
618 // | Committed but not used | | 618 // | Committed but not used | |
619 // +----------------------------+<- aligned at OS page boundary | 619 // +----------------------------+<- aligned at OS page boundary |
620 // | Reserved but not committed | | 620 // | Reserved but not committed | |
621 // +----------------------------+<- base + chunk_size | 621 // +----------------------------+<- base + chunk_size |
622 // | 622 // |
623 | 623 |
624 if (executable == EXECUTABLE) { | 624 if (executable == EXECUTABLE) { |
625 chunk_size = RoundUp(CodePageAreaStartOffset() + reserve_area_size, | 625 chunk_size = RoundUp(CodePageAreaStartOffset() + reserve_area_size, |
626 OS::CommitPageSize()) + CodePageGuardSize(); | 626 base::OS::CommitPageSize()) + CodePageGuardSize(); |
627 | 627 |
628 // Check executable memory limit. | 628 // Check executable memory limit. |
629 if (size_executable_ + chunk_size > capacity_executable_) { | 629 if (size_executable_ + chunk_size > capacity_executable_) { |
630 LOG(isolate_, | 630 LOG(isolate_, |
631 StringEvent("MemoryAllocator::AllocateRawMemory", | 631 StringEvent("MemoryAllocator::AllocateRawMemory", |
632 "V8 Executable Allocation capacity exceeded")); | 632 "V8 Executable Allocation capacity exceeded")); |
633 return NULL; | 633 return NULL; |
634 } | 634 } |
635 | 635 |
636 // Size of header (not executable) plus area (executable). | 636 // Size of header (not executable) plus area (executable). |
637 size_t commit_size = RoundUp(CodePageGuardStartOffset() + commit_area_size, | 637 size_t commit_size = RoundUp(CodePageGuardStartOffset() + commit_area_size, |
638 OS::CommitPageSize()); | 638 base::OS::CommitPageSize()); |
639 // Allocate executable memory either from code range or from the | 639 // Allocate executable memory either from code range or from the |
640 // OS. | 640 // OS. |
641 if (isolate_->code_range() != NULL && isolate_->code_range()->valid()) { | 641 if (isolate_->code_range() != NULL && isolate_->code_range()->valid()) { |
642 base = isolate_->code_range()->AllocateRawMemory(chunk_size, | 642 base = isolate_->code_range()->AllocateRawMemory(chunk_size, |
643 commit_size, | 643 commit_size, |
644 &chunk_size); | 644 &chunk_size); |
645 ASSERT(IsAligned(reinterpret_cast<intptr_t>(base), | 645 ASSERT(IsAligned(reinterpret_cast<intptr_t>(base), |
646 MemoryChunk::kAlignment)); | 646 MemoryChunk::kAlignment)); |
647 if (base == NULL) return NULL; | 647 if (base == NULL) return NULL; |
648 size_ += chunk_size; | 648 size_ += chunk_size; |
(...skipping 12 matching lines...) Expand all Loading... |
661 | 661 |
662 if (Heap::ShouldZapGarbage()) { | 662 if (Heap::ShouldZapGarbage()) { |
663 ZapBlock(base, CodePageGuardStartOffset()); | 663 ZapBlock(base, CodePageGuardStartOffset()); |
664 ZapBlock(base + CodePageAreaStartOffset(), commit_area_size); | 664 ZapBlock(base + CodePageAreaStartOffset(), commit_area_size); |
665 } | 665 } |
666 | 666 |
667 area_start = base + CodePageAreaStartOffset(); | 667 area_start = base + CodePageAreaStartOffset(); |
668 area_end = area_start + commit_area_size; | 668 area_end = area_start + commit_area_size; |
669 } else { | 669 } else { |
670 chunk_size = RoundUp(MemoryChunk::kObjectStartOffset + reserve_area_size, | 670 chunk_size = RoundUp(MemoryChunk::kObjectStartOffset + reserve_area_size, |
671 OS::CommitPageSize()); | 671 base::OS::CommitPageSize()); |
672 size_t commit_size = RoundUp(MemoryChunk::kObjectStartOffset + | 672 size_t commit_size = RoundUp(MemoryChunk::kObjectStartOffset + |
673 commit_area_size, OS::CommitPageSize()); | 673 commit_area_size, base::OS::CommitPageSize()); |
674 base = AllocateAlignedMemory(chunk_size, | 674 base = AllocateAlignedMemory(chunk_size, |
675 commit_size, | 675 commit_size, |
676 MemoryChunk::kAlignment, | 676 MemoryChunk::kAlignment, |
677 executable, | 677 executable, |
678 &reservation); | 678 &reservation); |
679 | 679 |
680 if (base == NULL) return NULL; | 680 if (base == NULL) return NULL; |
681 | 681 |
682 if (Heap::ShouldZapGarbage()) { | 682 if (Heap::ShouldZapGarbage()) { |
683 ZapBlock(base, Page::kObjectStartOffset + commit_area_size); | 683 ZapBlock(base, Page::kObjectStartOffset + commit_area_size); |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
750 static_cast<ObjectSpace>(1 << chunk->owner()->identity()); | 750 static_cast<ObjectSpace>(1 << chunk->owner()->identity()); |
751 PerformAllocationCallback(space, kAllocationActionFree, chunk->size()); | 751 PerformAllocationCallback(space, kAllocationActionFree, chunk->size()); |
752 } | 752 } |
753 | 753 |
754 isolate_->heap()->RememberUnmappedPage( | 754 isolate_->heap()->RememberUnmappedPage( |
755 reinterpret_cast<Address>(chunk), chunk->IsEvacuationCandidate()); | 755 reinterpret_cast<Address>(chunk), chunk->IsEvacuationCandidate()); |
756 | 756 |
757 delete chunk->slots_buffer(); | 757 delete chunk->slots_buffer(); |
758 delete chunk->skip_list(); | 758 delete chunk->skip_list(); |
759 | 759 |
760 VirtualMemory* reservation = chunk->reserved_memory(); | 760 base::VirtualMemory* reservation = chunk->reserved_memory(); |
761 if (reservation->IsReserved()) { | 761 if (reservation->IsReserved()) { |
762 FreeMemory(reservation, chunk->executable()); | 762 FreeMemory(reservation, chunk->executable()); |
763 } else { | 763 } else { |
764 FreeMemory(chunk->address(), | 764 FreeMemory(chunk->address(), |
765 chunk->size(), | 765 chunk->size(), |
766 chunk->executable()); | 766 chunk->executable()); |
767 } | 767 } |
768 } | 768 } |
769 | 769 |
770 | 770 |
771 bool MemoryAllocator::CommitBlock(Address start, | 771 bool MemoryAllocator::CommitBlock(Address start, |
772 size_t size, | 772 size_t size, |
773 Executability executable) { | 773 Executability executable) { |
774 if (!CommitMemory(start, size, executable)) return false; | 774 if (!CommitMemory(start, size, executable)) return false; |
775 | 775 |
776 if (Heap::ShouldZapGarbage()) { | 776 if (Heap::ShouldZapGarbage()) { |
777 ZapBlock(start, size); | 777 ZapBlock(start, size); |
778 } | 778 } |
779 | 779 |
780 isolate_->counters()->memory_allocated()->Increment(static_cast<int>(size)); | 780 isolate_->counters()->memory_allocated()->Increment(static_cast<int>(size)); |
781 return true; | 781 return true; |
782 } | 782 } |
783 | 783 |
784 | 784 |
785 bool MemoryAllocator::UncommitBlock(Address start, size_t size) { | 785 bool MemoryAllocator::UncommitBlock(Address start, size_t size) { |
786 if (!VirtualMemory::UncommitRegion(start, size)) return false; | 786 if (!base::VirtualMemory::UncommitRegion(start, size)) return false; |
787 isolate_->counters()->memory_allocated()->Decrement(static_cast<int>(size)); | 787 isolate_->counters()->memory_allocated()->Decrement(static_cast<int>(size)); |
788 return true; | 788 return true; |
789 } | 789 } |
790 | 790 |
791 | 791 |
792 void MemoryAllocator::ZapBlock(Address start, size_t size) { | 792 void MemoryAllocator::ZapBlock(Address start, size_t size) { |
793 for (size_t s = 0; s + kPointerSize <= size; s += kPointerSize) { | 793 for (size_t s = 0; s + kPointerSize <= size; s += kPointerSize) { |
794 Memory::Address_at(start + s) = kZapValue; | 794 Memory::Address_at(start + s) = kZapValue; |
795 } | 795 } |
796 } | 796 } |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
849 ", used: %" V8_PTR_PREFIX "d" | 849 ", used: %" V8_PTR_PREFIX "d" |
850 ", available: %%%d\n\n", | 850 ", available: %%%d\n\n", |
851 capacity_, size_, static_cast<int>(pct*100)); | 851 capacity_, size_, static_cast<int>(pct*100)); |
852 } | 852 } |
853 #endif | 853 #endif |
854 | 854 |
855 | 855 |
856 int MemoryAllocator::CodePageGuardStartOffset() { | 856 int MemoryAllocator::CodePageGuardStartOffset() { |
857 // We are guarding code pages: the first OS page after the header | 857 // We are guarding code pages: the first OS page after the header |
858 // will be protected as non-writable. | 858 // will be protected as non-writable. |
859 return RoundUp(Page::kObjectStartOffset, OS::CommitPageSize()); | 859 return RoundUp(Page::kObjectStartOffset, base::OS::CommitPageSize()); |
860 } | 860 } |
861 | 861 |
862 | 862 |
863 int MemoryAllocator::CodePageGuardSize() { | 863 int MemoryAllocator::CodePageGuardSize() { |
864 return static_cast<int>(OS::CommitPageSize()); | 864 return static_cast<int>(base::OS::CommitPageSize()); |
865 } | 865 } |
866 | 866 |
867 | 867 |
868 int MemoryAllocator::CodePageAreaStartOffset() { | 868 int MemoryAllocator::CodePageAreaStartOffset() { |
869 // We are guarding code pages: the first OS page after the header | 869 // We are guarding code pages: the first OS page after the header |
870 // will be protected as non-writable. | 870 // will be protected as non-writable. |
871 return CodePageGuardStartOffset() + CodePageGuardSize(); | 871 return CodePageGuardStartOffset() + CodePageGuardSize(); |
872 } | 872 } |
873 | 873 |
874 | 874 |
875 int MemoryAllocator::CodePageAreaEndOffset() { | 875 int MemoryAllocator::CodePageAreaEndOffset() { |
876 // We are guarding code pages: the last OS page will be protected as | 876 // We are guarding code pages: the last OS page will be protected as |
877 // non-writable. | 877 // non-writable. |
878 return Page::kPageSize - static_cast<int>(OS::CommitPageSize()); | 878 return Page::kPageSize - static_cast<int>(base::OS::CommitPageSize()); |
879 } | 879 } |
880 | 880 |
881 | 881 |
882 bool MemoryAllocator::CommitExecutableMemory(VirtualMemory* vm, | 882 bool MemoryAllocator::CommitExecutableMemory(base::VirtualMemory* vm, |
883 Address start, | 883 Address start, |
884 size_t commit_size, | 884 size_t commit_size, |
885 size_t reserved_size) { | 885 size_t reserved_size) { |
886 // Commit page header (not executable). | 886 // Commit page header (not executable). |
887 if (!vm->Commit(start, | 887 if (!vm->Commit(start, |
888 CodePageGuardStartOffset(), | 888 CodePageGuardStartOffset(), |
889 false)) { | 889 false)) { |
890 return false; | 890 return false; |
891 } | 891 } |
892 | 892 |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
970 while (iterator.has_next()) { | 970 while (iterator.has_next()) { |
971 heap()->isolate()->memory_allocator()->Free(iterator.next()); | 971 heap()->isolate()->memory_allocator()->Free(iterator.next()); |
972 } | 972 } |
973 anchor_.set_next_page(&anchor_); | 973 anchor_.set_next_page(&anchor_); |
974 anchor_.set_prev_page(&anchor_); | 974 anchor_.set_prev_page(&anchor_); |
975 accounting_stats_.Clear(); | 975 accounting_stats_.Clear(); |
976 } | 976 } |
977 | 977 |
978 | 978 |
979 size_t PagedSpace::CommittedPhysicalMemory() { | 979 size_t PagedSpace::CommittedPhysicalMemory() { |
980 if (!VirtualMemory::HasLazyCommits()) return CommittedMemory(); | 980 if (!base::VirtualMemory::HasLazyCommits()) return CommittedMemory(); |
981 MemoryChunk::UpdateHighWaterMark(allocation_info_.top()); | 981 MemoryChunk::UpdateHighWaterMark(allocation_info_.top()); |
982 size_t size = 0; | 982 size_t size = 0; |
983 PageIterator it(this); | 983 PageIterator it(this); |
984 while (it.has_next()) { | 984 while (it.has_next()) { |
985 size += it.next()->CommittedPhysicalMemory(); | 985 size += it.next()->CommittedPhysicalMemory(); |
986 } | 986 } |
987 return size; | 987 return size; |
988 } | 988 } |
989 | 989 |
990 | 990 |
(...skipping 589 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1580 if (!Commit()) return false; | 1580 if (!Commit()) return false; |
1581 } | 1581 } |
1582 ASSERT((new_capacity & Page::kPageAlignmentMask) == 0); | 1582 ASSERT((new_capacity & Page::kPageAlignmentMask) == 0); |
1583 ASSERT(new_capacity <= maximum_capacity_); | 1583 ASSERT(new_capacity <= maximum_capacity_); |
1584 ASSERT(new_capacity > capacity_); | 1584 ASSERT(new_capacity > capacity_); |
1585 int pages_before = capacity_ / Page::kPageSize; | 1585 int pages_before = capacity_ / Page::kPageSize; |
1586 int pages_after = new_capacity / Page::kPageSize; | 1586 int pages_after = new_capacity / Page::kPageSize; |
1587 | 1587 |
1588 size_t delta = new_capacity - capacity_; | 1588 size_t delta = new_capacity - capacity_; |
1589 | 1589 |
1590 ASSERT(IsAligned(delta, OS::AllocateAlignment())); | 1590 ASSERT(IsAligned(delta, base::OS::AllocateAlignment())); |
1591 if (!heap()->isolate()->memory_allocator()->CommitBlock( | 1591 if (!heap()->isolate()->memory_allocator()->CommitBlock( |
1592 start_ + capacity_, delta, executable())) { | 1592 start_ + capacity_, delta, executable())) { |
1593 return false; | 1593 return false; |
1594 } | 1594 } |
1595 SetCapacity(new_capacity); | 1595 SetCapacity(new_capacity); |
1596 NewSpacePage* last_page = anchor()->prev_page(); | 1596 NewSpacePage* last_page = anchor()->prev_page(); |
1597 ASSERT(last_page != anchor()); | 1597 ASSERT(last_page != anchor()); |
1598 for (int i = pages_before; i < pages_after; i++) { | 1598 for (int i = pages_before; i < pages_after; i++) { |
1599 Address page_address = start_ + i * Page::kPageSize; | 1599 Address page_address = start_ + i * Page::kPageSize; |
1600 NewSpacePage* new_page = NewSpacePage::Initialize(heap(), | 1600 NewSpacePage* new_page = NewSpacePage::Initialize(heap(), |
1601 page_address, | 1601 page_address, |
1602 this); | 1602 this); |
1603 new_page->InsertAfter(last_page); | 1603 new_page->InsertAfter(last_page); |
1604 Bitmap::Clear(new_page); | 1604 Bitmap::Clear(new_page); |
1605 // Duplicate the flags that was set on the old page. | 1605 // Duplicate the flags that was set on the old page. |
1606 new_page->SetFlags(last_page->GetFlags(), | 1606 new_page->SetFlags(last_page->GetFlags(), |
1607 NewSpacePage::kCopyOnFlipFlagsMask); | 1607 NewSpacePage::kCopyOnFlipFlagsMask); |
1608 last_page = new_page; | 1608 last_page = new_page; |
1609 } | 1609 } |
1610 return true; | 1610 return true; |
1611 } | 1611 } |
1612 | 1612 |
1613 | 1613 |
1614 bool SemiSpace::ShrinkTo(int new_capacity) { | 1614 bool SemiSpace::ShrinkTo(int new_capacity) { |
1615 ASSERT((new_capacity & Page::kPageAlignmentMask) == 0); | 1615 ASSERT((new_capacity & Page::kPageAlignmentMask) == 0); |
1616 ASSERT(new_capacity >= initial_capacity_); | 1616 ASSERT(new_capacity >= initial_capacity_); |
1617 ASSERT(new_capacity < capacity_); | 1617 ASSERT(new_capacity < capacity_); |
1618 if (is_committed()) { | 1618 if (is_committed()) { |
1619 size_t delta = capacity_ - new_capacity; | 1619 size_t delta = capacity_ - new_capacity; |
1620 ASSERT(IsAligned(delta, OS::AllocateAlignment())); | 1620 ASSERT(IsAligned(delta, base::OS::AllocateAlignment())); |
1621 | 1621 |
1622 MemoryAllocator* allocator = heap()->isolate()->memory_allocator(); | 1622 MemoryAllocator* allocator = heap()->isolate()->memory_allocator(); |
1623 if (!allocator->UncommitBlock(start_ + new_capacity, delta)) { | 1623 if (!allocator->UncommitBlock(start_ + new_capacity, delta)) { |
1624 return false; | 1624 return false; |
1625 } | 1625 } |
1626 | 1626 |
1627 int pages_after = new_capacity / Page::kPageSize; | 1627 int pages_after = new_capacity / Page::kPageSize; |
1628 NewSpacePage* new_last_page = | 1628 NewSpacePage* new_last_page = |
1629 NewSpacePage::FromAddress(start_ + (pages_after - 1) * Page::kPageSize); | 1629 NewSpacePage::FromAddress(start_ + (pages_after - 1) * Page::kPageSize); |
1630 new_last_page->set_next_page(anchor()); | 1630 new_last_page->set_next_page(anchor()); |
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1976 | 1976 |
1977 void NewSpace::RecordPromotion(HeapObject* obj) { | 1977 void NewSpace::RecordPromotion(HeapObject* obj) { |
1978 InstanceType type = obj->map()->instance_type(); | 1978 InstanceType type = obj->map()->instance_type(); |
1979 ASSERT(0 <= type && type <= LAST_TYPE); | 1979 ASSERT(0 <= type && type <= LAST_TYPE); |
1980 promoted_histogram_[type].increment_number(1); | 1980 promoted_histogram_[type].increment_number(1); |
1981 promoted_histogram_[type].increment_bytes(obj->Size()); | 1981 promoted_histogram_[type].increment_bytes(obj->Size()); |
1982 } | 1982 } |
1983 | 1983 |
1984 | 1984 |
1985 size_t NewSpace::CommittedPhysicalMemory() { | 1985 size_t NewSpace::CommittedPhysicalMemory() { |
1986 if (!VirtualMemory::HasLazyCommits()) return CommittedMemory(); | 1986 if (!base::VirtualMemory::HasLazyCommits()) return CommittedMemory(); |
1987 MemoryChunk::UpdateHighWaterMark(allocation_info_.top()); | 1987 MemoryChunk::UpdateHighWaterMark(allocation_info_.top()); |
1988 size_t size = to_space_.CommittedPhysicalMemory(); | 1988 size_t size = to_space_.CommittedPhysicalMemory(); |
1989 if (from_space_.is_committed()) { | 1989 if (from_space_.is_committed()) { |
1990 size += from_space_.CommittedPhysicalMemory(); | 1990 size += from_space_.CommittedPhysicalMemory(); |
1991 } | 1991 } |
1992 return size; | 1992 return size; |
1993 } | 1993 } |
1994 | 1994 |
1995 | 1995 |
1996 // ----------------------------------------------------------------------------- | 1996 // ----------------------------------------------------------------------------- |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2068 } | 2068 } |
2069 } | 2069 } |
2070 | 2070 |
2071 | 2071 |
2072 intptr_t FreeListCategory::Concatenate(FreeListCategory* category) { | 2072 intptr_t FreeListCategory::Concatenate(FreeListCategory* category) { |
2073 intptr_t free_bytes = 0; | 2073 intptr_t free_bytes = 0; |
2074 if (category->top() != NULL) { | 2074 if (category->top() != NULL) { |
2075 // This is safe (not going to deadlock) since Concatenate operations | 2075 // This is safe (not going to deadlock) since Concatenate operations |
2076 // are never performed on the same free lists at the same time in | 2076 // are never performed on the same free lists at the same time in |
2077 // reverse order. | 2077 // reverse order. |
2078 LockGuard<Mutex> target_lock_guard(mutex()); | 2078 base::LockGuard<base::Mutex> target_lock_guard(mutex()); |
2079 LockGuard<Mutex> source_lock_guard(category->mutex()); | 2079 base::LockGuard<base::Mutex> source_lock_guard(category->mutex()); |
2080 ASSERT(category->end_ != NULL); | 2080 ASSERT(category->end_ != NULL); |
2081 free_bytes = category->available(); | 2081 free_bytes = category->available(); |
2082 if (end_ == NULL) { | 2082 if (end_ == NULL) { |
2083 end_ = category->end(); | 2083 end_ = category->end(); |
2084 } else { | 2084 } else { |
2085 category->end()->set_next(top()); | 2085 category->end()->set_next(top()); |
2086 } | 2086 } |
2087 set_top(category->top()); | 2087 set_top(category->top()); |
2088 base::NoBarrier_Store(&top_, category->top_); | 2088 base::NoBarrier_Store(&top_, category->top_); |
2089 available_ += category->available(); | 2089 available_ += category->available(); |
(...skipping 817 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2907 heap()->fixed_array_map(); | 2907 heap()->fixed_array_map(); |
2908 reinterpret_cast<Object**>(object->address())[1] = Smi::FromInt(0); | 2908 reinterpret_cast<Object**>(object->address())[1] = Smi::FromInt(0); |
2909 } | 2909 } |
2910 | 2910 |
2911 heap()->incremental_marking()->OldSpaceStep(object_size); | 2911 heap()->incremental_marking()->OldSpaceStep(object_size); |
2912 return object; | 2912 return object; |
2913 } | 2913 } |
2914 | 2914 |
2915 | 2915 |
2916 size_t LargeObjectSpace::CommittedPhysicalMemory() { | 2916 size_t LargeObjectSpace::CommittedPhysicalMemory() { |
2917 if (!VirtualMemory::HasLazyCommits()) return CommittedMemory(); | 2917 if (!base::VirtualMemory::HasLazyCommits()) return CommittedMemory(); |
2918 size_t size = 0; | 2918 size_t size = 0; |
2919 LargePage* current = first_page_; | 2919 LargePage* current = first_page_; |
2920 while (current != NULL) { | 2920 while (current != NULL) { |
2921 size += current->CommittedPhysicalMemory(); | 2921 size += current->CommittedPhysicalMemory(); |
2922 current = current->next_page(); | 2922 current = current->next_page(); |
2923 } | 2923 } |
2924 return size; | 2924 return size; |
2925 } | 2925 } |
2926 | 2926 |
2927 | 2927 |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3125 object->ShortPrint(); | 3125 object->ShortPrint(); |
3126 PrintF("\n"); | 3126 PrintF("\n"); |
3127 } | 3127 } |
3128 printf(" --------------------------------------\n"); | 3128 printf(" --------------------------------------\n"); |
3129 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes()); | 3129 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes()); |
3130 } | 3130 } |
3131 | 3131 |
3132 #endif // DEBUG | 3132 #endif // DEBUG |
3133 | 3133 |
3134 } } // namespace v8::internal | 3134 } } // namespace v8::internal |
OLD | NEW |