Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: src/spaces.h

Issue 9537011: Merge r10809 into 3.7 branch (Closed) Base URL: http://v8.googlecode.com/svn/branches/3.7/
Patch Set: Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/serialize.cc ('k') | src/spaces.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
96 #define ASSERT_PAGE_ALIGNED(address) \ 96 #define ASSERT_PAGE_ALIGNED(address) \
97 ASSERT((OffsetFrom(address) & Page::kPageAlignmentMask) == 0) 97 ASSERT((OffsetFrom(address) & Page::kPageAlignmentMask) == 0)
98 98
99 #define ASSERT_OBJECT_ALIGNED(address) \ 99 #define ASSERT_OBJECT_ALIGNED(address) \
100 ASSERT((OffsetFrom(address) & kObjectAlignmentMask) == 0) 100 ASSERT((OffsetFrom(address) & kObjectAlignmentMask) == 0)
101 101
102 #define ASSERT_MAP_ALIGNED(address) \ 102 #define ASSERT_MAP_ALIGNED(address) \
103 ASSERT((OffsetFrom(address) & kMapAlignmentMask) == 0) 103 ASSERT((OffsetFrom(address) & kMapAlignmentMask) == 0)
104 104
105 #define ASSERT_OBJECT_SIZE(size) \ 105 #define ASSERT_OBJECT_SIZE(size) \
106 ASSERT((0 < size) && (size <= Page::kMaxHeapObjectSize)) 106 ASSERT((0 < size) && (size <= Page::kMaxNonCodeHeapObjectSize))
107 107
108 #define ASSERT_PAGE_OFFSET(offset) \ 108 #define ASSERT_PAGE_OFFSET(offset) \
109 ASSERT((Page::kObjectStartOffset <= offset) \ 109 ASSERT((Page::kObjectStartOffset <= offset) \
110 && (offset <= Page::kPageSize)) 110 && (offset <= Page::kPageSize))
111 111
112 #define ASSERT_MAP_PAGE_INDEX(index) \ 112 #define ASSERT_MAP_PAGE_INDEX(index) \
113 ASSERT((0 <= index) && (index <= MapSpace::kMaxMapPageIndex)) 113 ASSERT((0 <= index) && (index <= MapSpace::kMaxMapPageIndex))
114 114
115 115
116 class PagedSpace; 116 class PagedSpace;
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after
354 ClearFlag(SCAN_ON_SCAVENGE); 354 ClearFlag(SCAN_ON_SCAVENGE);
355 } 355 }
356 } 356 }
357 inline void set_scan_on_scavenge(bool scan); 357 inline void set_scan_on_scavenge(bool scan);
358 358
359 int store_buffer_counter() { return store_buffer_counter_; } 359 int store_buffer_counter() { return store_buffer_counter_; }
360 void set_store_buffer_counter(int counter) { 360 void set_store_buffer_counter(int counter) {
361 store_buffer_counter_ = counter; 361 store_buffer_counter_ = counter;
362 } 362 }
363 363
364 Address body() { return address() + kObjectStartOffset; }
365
366 Address body_limit() { return address() + size(); }
367
368 int body_size() { return static_cast<int>(size() - kObjectStartOffset); }
369
370 bool Contains(Address addr) { 364 bool Contains(Address addr) {
371 return addr >= body() && addr < address() + size(); 365 return addr >= area_start() && addr < area_end();
372 } 366 }
373 367
374 // Checks whether addr can be a limit of addresses in this page. 368 // Checks whether addr can be a limit of addresses in this page.
375 // It's a limit if it's in the page, or if it's just after the 369 // It's a limit if it's in the page, or if it's just after the
376 // last byte of the page. 370 // last byte of the page.
377 bool ContainsLimit(Address addr) { 371 bool ContainsLimit(Address addr) {
378 return addr >= body() && addr <= address() + size(); 372 return addr >= area_start() && addr <= area_end();
379 } 373 }
380 374
381 enum MemoryChunkFlags { 375 enum MemoryChunkFlags {
382 IS_EXECUTABLE, 376 IS_EXECUTABLE,
383 ABOUT_TO_BE_FREED, 377 ABOUT_TO_BE_FREED,
384 POINTERS_TO_HERE_ARE_INTERESTING, 378 POINTERS_TO_HERE_ARE_INTERESTING,
385 POINTERS_FROM_HERE_ARE_INTERESTING, 379 POINTERS_FROM_HERE_ARE_INTERESTING,
386 SCAN_ON_SCAVENGE, 380 SCAN_ON_SCAVENGE,
387 IN_FROM_SPACE, // Mutually exclusive with IN_TO_SPACE. 381 IN_FROM_SPACE, // Mutually exclusive with IN_TO_SPACE.
388 IN_TO_SPACE, // All pages in new space has one of these two set. 382 IN_TO_SPACE, // All pages in new space has one of these two set.
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
477 } 471 }
478 472
479 static const intptr_t kAlignment = 473 static const intptr_t kAlignment =
480 (static_cast<uintptr_t>(1) << kPageSizeBits); 474 (static_cast<uintptr_t>(1) << kPageSizeBits);
481 475
482 static const intptr_t kAlignmentMask = kAlignment - 1; 476 static const intptr_t kAlignmentMask = kAlignment - 1;
483 477
484 static const intptr_t kSizeOffset = kPointerSize + kPointerSize; 478 static const intptr_t kSizeOffset = kPointerSize + kPointerSize;
485 479
486 static const intptr_t kLiveBytesOffset = 480 static const intptr_t kLiveBytesOffset =
487 kSizeOffset + kPointerSize + kPointerSize + kPointerSize + 481 kSizeOffset + kPointerSize + kPointerSize + kPointerSize +
488 kPointerSize + kPointerSize + kPointerSize + kIntSize; 482 kPointerSize + kPointerSize +
483 kPointerSize + kPointerSize + kPointerSize + kIntSize;
489 484
490 static const size_t kSlotsBufferOffset = kLiveBytesOffset + kIntSize; 485 static const size_t kSlotsBufferOffset = kLiveBytesOffset + kIntSize;
491 486
492 static const size_t kHeaderSize = 487 static const size_t kHeaderSize =
493 kSlotsBufferOffset + kPointerSize + kPointerSize; 488 kSlotsBufferOffset + kPointerSize + kPointerSize;
494 489
495 static const int kBodyOffset = 490 static const int kBodyOffset =
496 CODE_POINTER_ALIGN(MAP_POINTER_ALIGN(kHeaderSize + Bitmap::kSize)); 491 CODE_POINTER_ALIGN(MAP_POINTER_ALIGN(kHeaderSize + Bitmap::kSize));
497 492
498 // The start offset of the object area in a page. Aligned to both maps and 493 // The start offset of the object area in a page. Aligned to both maps and
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
584 void MarkEvacuationCandidate() { 579 void MarkEvacuationCandidate() {
585 ASSERT(slots_buffer_ == NULL); 580 ASSERT(slots_buffer_ == NULL);
586 SetFlag(EVACUATION_CANDIDATE); 581 SetFlag(EVACUATION_CANDIDATE);
587 } 582 }
588 583
589 void ClearEvacuationCandidate() { 584 void ClearEvacuationCandidate() {
590 ASSERT(slots_buffer_ == NULL); 585 ASSERT(slots_buffer_ == NULL);
591 ClearFlag(EVACUATION_CANDIDATE); 586 ClearFlag(EVACUATION_CANDIDATE);
592 } 587 }
593 588
589 Address area_start() { return area_start_; }
590 Address area_end() { return area_end_; }
591 int area_size() {
592 return static_cast<int>(area_end() - area_start());
593 }
594 594
595 protected: 595 protected:
596 MemoryChunk* next_chunk_; 596 MemoryChunk* next_chunk_;
597 MemoryChunk* prev_chunk_; 597 MemoryChunk* prev_chunk_;
598 size_t size_; 598 size_t size_;
599 intptr_t flags_; 599 intptr_t flags_;
600
601 // Start and end of allocatable memory on this chunk.
602 Address area_start_;
603 Address area_end_;
604
600 // If the chunk needs to remember its memory reservation, it is stored here. 605 // If the chunk needs to remember its memory reservation, it is stored here.
601 VirtualMemory reservation_; 606 VirtualMemory reservation_;
602 // The identity of the owning space. This is tagged as a failure pointer, but 607 // The identity of the owning space. This is tagged as a failure pointer, but
603 // no failure can be in an object, so this can be distinguished from any entry 608 // no failure can be in an object, so this can be distinguished from any entry
604 // in a fixed array. 609 // in a fixed array.
605 Address owner_; 610 Address owner_;
606 Heap* heap_; 611 Heap* heap_;
607 // Used by the store buffer to keep track of which pages to mark scan-on- 612 // Used by the store buffer to keep track of which pages to mark scan-on-
608 // scavenge. 613 // scavenge.
609 int store_buffer_counter_; 614 int store_buffer_counter_;
610 // Count of bytes marked black on page. 615 // Count of bytes marked black on page.
611 int live_byte_count_; 616 int live_byte_count_;
612 SlotsBuffer* slots_buffer_; 617 SlotsBuffer* slots_buffer_;
613 SkipList* skip_list_; 618 SkipList* skip_list_;
614 619
615 static MemoryChunk* Initialize(Heap* heap, 620 static MemoryChunk* Initialize(Heap* heap,
616 Address base, 621 Address base,
617 size_t size, 622 size_t size,
623 Address area_start,
624 Address area_end,
618 Executability executable, 625 Executability executable,
619 Space* owner); 626 Space* owner);
620 627
621 friend class MemoryAllocator; 628 friend class MemoryAllocator;
622 }; 629 };
623 630
624 STATIC_CHECK(sizeof(MemoryChunk) <= MemoryChunk::kHeaderSize); 631 STATIC_CHECK(sizeof(MemoryChunk) <= MemoryChunk::kHeaderSize);
625 632
626 // ----------------------------------------------------------------------------- 633 // -----------------------------------------------------------------------------
627 // A page is a memory chunk of a size 1MB. Large object pages may be larger. 634 // A page is a memory chunk of a size 1MB. Large object pages may be larger.
(...skipping 19 matching lines...) Expand all
647 Page* p = FromAddress(top - kPointerSize); 654 Page* p = FromAddress(top - kPointerSize);
648 return p; 655 return p;
649 } 656 }
650 657
651 // Returns the next page in the chain of pages owned by a space. 658 // Returns the next page in the chain of pages owned by a space.
652 inline Page* next_page(); 659 inline Page* next_page();
653 inline Page* prev_page(); 660 inline Page* prev_page();
654 inline void set_next_page(Page* page); 661 inline void set_next_page(Page* page);
655 inline void set_prev_page(Page* page); 662 inline void set_prev_page(Page* page);
656 663
657 // Returns the start address of the object area in this page.
658 Address ObjectAreaStart() { return address() + kObjectStartOffset; }
659
660 // Returns the end address (exclusive) of the object area in this page.
661 Address ObjectAreaEnd() { return address() + Page::kPageSize; }
662
663 // Checks whether an address is page aligned. 664 // Checks whether an address is page aligned.
664 static bool IsAlignedToPageSize(Address a) { 665 static bool IsAlignedToPageSize(Address a) {
665 return 0 == (OffsetFrom(a) & kPageAlignmentMask); 666 return 0 == (OffsetFrom(a) & kPageAlignmentMask);
666 } 667 }
667 668
668 // Returns the offset of a given address to this page. 669 // Returns the offset of a given address to this page.
669 INLINE(int Offset(Address a)) { 670 INLINE(int Offset(Address a)) {
670 int offset = static_cast<int>(a - address()); 671 int offset = static_cast<int>(a - address());
671 return offset; 672 return offset;
672 } 673 }
673 674
674 // Returns the address for a given offset to the this page. 675 // Returns the address for a given offset to the this page.
675 Address OffsetToAddress(int offset) { 676 Address OffsetToAddress(int offset) {
676 ASSERT_PAGE_OFFSET(offset); 677 ASSERT_PAGE_OFFSET(offset);
677 return address() + offset; 678 return address() + offset;
678 } 679 }
679 680
680 // --------------------------------------------------------------------- 681 // ---------------------------------------------------------------------
681 682
682 // Page size in bytes. This must be a multiple of the OS page size. 683 // Page size in bytes. This must be a multiple of the OS page size.
683 static const int kPageSize = 1 << kPageSizeBits; 684 static const int kPageSize = 1 << kPageSizeBits;
684 685
686 // Object area size in bytes.
687 static const int kNonCodeObjectAreaSize = kPageSize - kObjectStartOffset;
688
689 // Maximum object size that fits in a page.
690 static const int kMaxNonCodeHeapObjectSize = kNonCodeObjectAreaSize;
691
685 // Page size mask. 692 // Page size mask.
686 static const intptr_t kPageAlignmentMask = (1 << kPageSizeBits) - 1; 693 static const intptr_t kPageAlignmentMask = (1 << kPageSizeBits) - 1;
687 694
688 // Object area size in bytes.
689 static const int kObjectAreaSize = kPageSize - kObjectStartOffset;
690
691 // Maximum object size that fits in a page.
692 static const int kMaxHeapObjectSize = kObjectAreaSize;
693
694 static const int kFirstUsedCell =
695 (kObjectStartOffset/kPointerSize) >> Bitmap::kBitsPerCellLog2;
696
697 static const int kLastUsedCell =
698 ((kPageSize - kPointerSize)/kPointerSize) >>
699 Bitmap::kBitsPerCellLog2;
700
701 inline void ClearGCFields(); 695 inline void ClearGCFields();
702 696
703 static inline Page* Initialize(Heap* heap, 697 static inline Page* Initialize(Heap* heap,
704 MemoryChunk* chunk, 698 MemoryChunk* chunk,
705 Executability executable, 699 Executability executable,
706 PagedSpace* owner); 700 PagedSpace* owner);
707 701
708 void InitializeAsAnchor(PagedSpace* owner); 702 void InitializeAsAnchor(PagedSpace* owner);
709 703
710 bool WasSweptPrecisely() { return IsFlagSet(WAS_SWEPT_PRECISELY); } 704 bool WasSweptPrecisely() { return IsFlagSet(WAS_SWEPT_PRECISELY); }
(...skipping 13 matching lines...) Expand all
724 friend class MemoryAllocator; 718 friend class MemoryAllocator;
725 }; 719 };
726 720
727 721
728 STATIC_CHECK(sizeof(Page) <= MemoryChunk::kHeaderSize); 722 STATIC_CHECK(sizeof(Page) <= MemoryChunk::kHeaderSize);
729 723
730 724
731 class LargePage : public MemoryChunk { 725 class LargePage : public MemoryChunk {
732 public: 726 public:
733 HeapObject* GetObject() { 727 HeapObject* GetObject() {
734 return HeapObject::FromAddress(body()); 728 return HeapObject::FromAddress(area_start());
735 } 729 }
736 730
737 inline LargePage* next_page() const { 731 inline LargePage* next_page() const {
738 return static_cast<LargePage*>(next_chunk()); 732 return static_cast<LargePage*>(next_chunk());
739 } 733 }
740 734
741 inline void set_next_page(LargePage* page) { 735 inline void set_next_page(LargePage* page) {
742 set_next_chunk(page); 736 set_next_chunk(page);
743 } 737 }
744 private: 738 private:
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after
965 intptr_t AvailableExecutable() { 959 intptr_t AvailableExecutable() {
966 if (capacity_executable_ < size_executable_) return 0; 960 if (capacity_executable_ < size_executable_) return 0;
967 return capacity_executable_ - size_executable_; 961 return capacity_executable_ - size_executable_;
968 } 962 }
969 963
970 // Returns allocated executable spaces in bytes. 964 // Returns allocated executable spaces in bytes.
971 intptr_t SizeExecutable() { return size_executable_; } 965 intptr_t SizeExecutable() { return size_executable_; }
972 966
973 // Returns maximum available bytes that the old space can have. 967 // Returns maximum available bytes that the old space can have.
974 intptr_t MaxAvailable() { 968 intptr_t MaxAvailable() {
975 return (Available() / Page::kPageSize) * Page::kObjectAreaSize; 969 return (Available() / Page::kPageSize) * Page::kMaxNonCodeHeapObjectSize;
976 } 970 }
977 971
978 #ifdef DEBUG 972 #ifdef DEBUG
979 // Reports statistic info of the space. 973 // Reports statistic info of the space.
980 void ReportStatistics(); 974 void ReportStatistics();
981 #endif 975 #endif
982 976
983 MemoryChunk* AllocateChunk(intptr_t body_size, 977 MemoryChunk* AllocateChunk(intptr_t body_size,
984 Executability executable, 978 Executability executable,
985 Space* space); 979 Space* space);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1018 void AddMemoryAllocationCallback(MemoryAllocationCallback callback, 1012 void AddMemoryAllocationCallback(MemoryAllocationCallback callback,
1019 ObjectSpace space, 1013 ObjectSpace space,
1020 AllocationAction action); 1014 AllocationAction action);
1021 1015
1022 void RemoveMemoryAllocationCallback( 1016 void RemoveMemoryAllocationCallback(
1023 MemoryAllocationCallback callback); 1017 MemoryAllocationCallback callback);
1024 1018
1025 bool MemoryAllocationCallbackRegistered( 1019 bool MemoryAllocationCallbackRegistered(
1026 MemoryAllocationCallback callback); 1020 MemoryAllocationCallback callback);
1027 1021
1022 static int CodePageGuardStartOffset();
1023
1024 static int CodePageGuardSize();
1025
1026 static int CodePageAreaStartOffset();
1027
1028 static int CodePageAreaEndOffset();
1029
1030 static int CodePageAreaSize() {
1031 return CodePageAreaEndOffset() - CodePageAreaStartOffset();
1032 }
1033
1034 static bool CommitCodePage(VirtualMemory* vm, Address start, size_t size);
1035
1028 private: 1036 private:
1029 Isolate* isolate_; 1037 Isolate* isolate_;
1030 1038
1031 // Maximum space size in bytes. 1039 // Maximum space size in bytes.
1032 size_t capacity_; 1040 size_t capacity_;
1033 // Maximum subset of capacity_ that can be executable 1041 // Maximum subset of capacity_ that can be executable
1034 size_t capacity_executable_; 1042 size_t capacity_executable_;
1035 1043
1036 // Allocated space size in bytes. 1044 // Allocated space size in bytes.
1037 size_t size_; 1045 size_t size_;
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after
1370 intptr_t huge_size_; 1378 intptr_t huge_size_;
1371 }; 1379 };
1372 1380
1373 void CountFreeListItems(Page* p, SizeStats* sizes); 1381 void CountFreeListItems(Page* p, SizeStats* sizes);
1374 1382
1375 intptr_t EvictFreeListItems(Page* p); 1383 intptr_t EvictFreeListItems(Page* p);
1376 1384
1377 private: 1385 private:
1378 // The size range of blocks, in bytes. 1386 // The size range of blocks, in bytes.
1379 static const int kMinBlockSize = 3 * kPointerSize; 1387 static const int kMinBlockSize = 3 * kPointerSize;
1380 static const int kMaxBlockSize = Page::kMaxHeapObjectSize; 1388 static const int kMaxBlockSize = Page::kMaxNonCodeHeapObjectSize;
1381 1389
1382 FreeListNode* PickNodeFromList(FreeListNode** list, int* node_size); 1390 FreeListNode* PickNodeFromList(FreeListNode** list, int* node_size);
1383 1391
1384 FreeListNode* FindNodeFor(int size_in_bytes, int* node_size); 1392 FreeListNode* FindNodeFor(int size_in_bytes, int* node_size);
1385 1393
1386 PagedSpace* owner_; 1394 PagedSpace* owner_;
1387 Heap* heap_; 1395 Heap* heap_;
1388 1396
1389 // Total available bytes in all blocks on this free list. 1397 // Total available bytes in all blocks on this free list.
1390 int available_; 1398 int available_;
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
1574 // worth defragmenting them. Otherwise a positive integer that gives an 1582 // worth defragmenting them. Otherwise a positive integer that gives an
1575 // estimate of fragmentation on an arbitrary scale. 1583 // estimate of fragmentation on an arbitrary scale.
1576 int Fragmentation(Page* p) { 1584 int Fragmentation(Page* p) {
1577 FreeList::SizeStats sizes; 1585 FreeList::SizeStats sizes;
1578 free_list_.CountFreeListItems(p, &sizes); 1586 free_list_.CountFreeListItems(p, &sizes);
1579 1587
1580 intptr_t ratio; 1588 intptr_t ratio;
1581 intptr_t ratio_threshold; 1589 intptr_t ratio_threshold;
1582 if (identity() == CODE_SPACE) { 1590 if (identity() == CODE_SPACE) {
1583 ratio = (sizes.medium_size_ * 10 + sizes.large_size_ * 2) * 100 / 1591 ratio = (sizes.medium_size_ * 10 + sizes.large_size_ * 2) * 100 /
1584 Page::kObjectAreaSize; 1592 AreaSize();
1585 ratio_threshold = 10; 1593 ratio_threshold = 10;
1586 } else { 1594 } else {
1587 ratio = (sizes.small_size_ * 5 + sizes.medium_size_) * 100 / 1595 ratio = (sizes.small_size_ * 5 + sizes.medium_size_) * 100 /
1588 Page::kObjectAreaSize; 1596 AreaSize();
1589 ratio_threshold = 15; 1597 ratio_threshold = 15;
1590 } 1598 }
1591 1599
1592 if (FLAG_trace_fragmentation) { 1600 if (FLAG_trace_fragmentation) {
1593 PrintF("%p [%d]: %d (%.2f%%) %d (%.2f%%) %d (%.2f%%) %d (%.2f%%) %s\n", 1601 PrintF("%p [%d]: %d (%.2f%%) %d (%.2f%%) %d (%.2f%%) %d (%.2f%%) %s\n",
1594 reinterpret_cast<void*>(p), 1602 reinterpret_cast<void*>(p),
1595 identity(), 1603 identity(),
1596 static_cast<int>(sizes.small_size_), 1604 static_cast<int>(sizes.small_size_),
1597 static_cast<double>(sizes.small_size_ * 100) / 1605 static_cast<double>(sizes.small_size_ * 100) /
1598 Page::kObjectAreaSize, 1606 AreaSize(),
1599 static_cast<int>(sizes.medium_size_), 1607 static_cast<int>(sizes.medium_size_),
1600 static_cast<double>(sizes.medium_size_ * 100) / 1608 static_cast<double>(sizes.medium_size_ * 100) /
1601 Page::kObjectAreaSize, 1609 AreaSize(),
1602 static_cast<int>(sizes.large_size_), 1610 static_cast<int>(sizes.large_size_),
1603 static_cast<double>(sizes.large_size_ * 100) / 1611 static_cast<double>(sizes.large_size_ * 100) /
1604 Page::kObjectAreaSize, 1612 AreaSize(),
1605 static_cast<int>(sizes.huge_size_), 1613 static_cast<int>(sizes.huge_size_),
1606 static_cast<double>(sizes.huge_size_ * 100) / 1614 static_cast<double>(sizes.huge_size_ * 100) /
1607 Page::kObjectAreaSize, 1615 AreaSize(),
1608 (ratio > ratio_threshold) ? "[fragmented]" : ""); 1616 (ratio > ratio_threshold) ? "[fragmented]" : "");
1609 } 1617 }
1610 1618
1611 if (FLAG_always_compact && sizes.Total() != Page::kObjectAreaSize) { 1619 if (FLAG_always_compact && sizes.Total() != AreaSize()) {
1612 return 1; 1620 return 1;
1613 } 1621 }
1614 if (ratio <= ratio_threshold) return 0; // Not fragmented. 1622 if (ratio <= ratio_threshold) return 0; // Not fragmented.
1615 1623
1616 return static_cast<int>(ratio - ratio_threshold); 1624 return static_cast<int>(ratio - ratio_threshold);
1617 } 1625 }
1618 1626
1619 void EvictEvacuationCandidatesFromFreeLists(); 1627 void EvictEvacuationCandidatesFromFreeLists();
1620 1628
1621 bool CanExpand(); 1629 bool CanExpand();
1622 1630
1623 // Returns the number of total pages in this space. 1631 // Returns the number of total pages in this space.
1624 int CountTotalPages(); 1632 int CountTotalPages();
1625 1633
1634 // Return size of allocatable area on a page in this space.
1635 inline int AreaSize() {
1636 return area_size_;
1637 }
1638
1626 protected: 1639 protected:
1640 int area_size_;
1641
1627 // Maximum capacity of this space. 1642 // Maximum capacity of this space.
1628 intptr_t max_capacity_; 1643 intptr_t max_capacity_;
1629 1644
1630 // Accounting information for this space. 1645 // Accounting information for this space.
1631 AllocationStats accounting_stats_; 1646 AllocationStats accounting_stats_;
1632 1647
1633 // The dummy page that anchors the double linked list of pages. 1648 // The dummy page that anchors the double linked list of pages.
1634 Page anchor_; 1649 Page anchor_;
1635 1650
1636 // The space's free list. 1651 // The space's free list.
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
1710 1725
1711 class NewSpacePage : public MemoryChunk { 1726 class NewSpacePage : public MemoryChunk {
1712 public: 1727 public:
1713 // GC related flags copied from from-space to to-space when 1728 // GC related flags copied from from-space to to-space when
1714 // flipping semispaces. 1729 // flipping semispaces.
1715 static const intptr_t kCopyOnFlipFlagsMask = 1730 static const intptr_t kCopyOnFlipFlagsMask =
1716 (1 << MemoryChunk::POINTERS_TO_HERE_ARE_INTERESTING) | 1731 (1 << MemoryChunk::POINTERS_TO_HERE_ARE_INTERESTING) |
1717 (1 << MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING) | 1732 (1 << MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING) |
1718 (1 << MemoryChunk::SCAN_ON_SCAVENGE); 1733 (1 << MemoryChunk::SCAN_ON_SCAVENGE);
1719 1734
1735 static const int kAreaSize = Page::kNonCodeObjectAreaSize;
1736
1720 inline NewSpacePage* next_page() const { 1737 inline NewSpacePage* next_page() const {
1721 return static_cast<NewSpacePage*>(next_chunk()); 1738 return static_cast<NewSpacePage*>(next_chunk());
1722 } 1739 }
1723 1740
1724 inline void set_next_page(NewSpacePage* page) { 1741 inline void set_next_page(NewSpacePage* page) {
1725 set_next_chunk(page); 1742 set_next_chunk(page);
1726 } 1743 }
1727 1744
1728 inline NewSpacePage* prev_page() const { 1745 inline NewSpacePage* prev_page() const {
1729 return static_cast<NewSpacePage*>(prev_chunk()); 1746 return static_cast<NewSpacePage*>(prev_chunk());
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
1822 bool GrowTo(int new_capacity); 1839 bool GrowTo(int new_capacity);
1823 1840
1824 // Shrinks the semispace to the new capacity. The new capacity 1841 // Shrinks the semispace to the new capacity. The new capacity
1825 // requested must be more than the amount of used memory in the 1842 // requested must be more than the amount of used memory in the
1826 // semispace and less than the current capacity. 1843 // semispace and less than the current capacity.
1827 bool ShrinkTo(int new_capacity); 1844 bool ShrinkTo(int new_capacity);
1828 1845
1829 // Returns the start address of the first page of the space. 1846 // Returns the start address of the first page of the space.
1830 Address space_start() { 1847 Address space_start() {
1831 ASSERT(anchor_.next_page() != &anchor_); 1848 ASSERT(anchor_.next_page() != &anchor_);
1832 return anchor_.next_page()->body(); 1849 return anchor_.next_page()->area_start();
1833 } 1850 }
1834 1851
1835 // Returns the start address of the current page of the space. 1852 // Returns the start address of the current page of the space.
1836 Address page_low() { 1853 Address page_low() {
1837 return current_page_->body(); 1854 return current_page_->area_start();
1838 } 1855 }
1839 1856
1840 // Returns one past the end address of the space. 1857 // Returns one past the end address of the space.
1841 Address space_end() { 1858 Address space_end() {
1842 return anchor_.prev_page()->body_limit(); 1859 return anchor_.prev_page()->area_end();
1843 } 1860 }
1844 1861
1845 // Returns one past the end address of the current page of the space. 1862 // Returns one past the end address of the current page of the space.
1846 Address page_high() { 1863 Address page_high() {
1847 return current_page_->body_limit(); 1864 return current_page_->area_end();
1848 } 1865 }
1849 1866
1850 bool AdvancePage() { 1867 bool AdvancePage() {
1851 NewSpacePage* next_page = current_page_->next_page(); 1868 NewSpacePage* next_page = current_page_->next_page();
1852 if (next_page == anchor()) return false; 1869 if (next_page == anchor()) return false;
1853 current_page_ = next_page; 1870 current_page_ = next_page;
1854 return true; 1871 return true;
1855 } 1872 }
1856 1873
1857 // Resets the space to using the first page. 1874 // Resets the space to using the first page.
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
1973 SemiSpaceIterator(NewSpace* space, Address start); 1990 SemiSpaceIterator(NewSpace* space, Address start);
1974 // Iterate from one address to another in the same semi-space. 1991 // Iterate from one address to another in the same semi-space.
1975 SemiSpaceIterator(Address from, Address to); 1992 SemiSpaceIterator(Address from, Address to);
1976 1993
1977 HeapObject* Next() { 1994 HeapObject* Next() {
1978 if (current_ == limit_) return NULL; 1995 if (current_ == limit_) return NULL;
1979 if (NewSpacePage::IsAtEnd(current_)) { 1996 if (NewSpacePage::IsAtEnd(current_)) {
1980 NewSpacePage* page = NewSpacePage::FromLimit(current_); 1997 NewSpacePage* page = NewSpacePage::FromLimit(current_);
1981 page = page->next_page(); 1998 page = page->next_page();
1982 ASSERT(!page->is_anchor()); 1999 ASSERT(!page->is_anchor());
1983 current_ = page->body(); 2000 current_ = page->area_start();
1984 if (current_ == limit_) return NULL; 2001 if (current_ == limit_) return NULL;
1985 } 2002 }
1986 2003
1987 HeapObject* object = HeapObject::FromAddress(current_); 2004 HeapObject* object = HeapObject::FromAddress(current_);
1988 int size = (size_func_ == NULL) ? object->Size() : size_func_(object); 2005 int size = (size_func_ == NULL) ? object->Size() : size_func_(object);
1989 2006
1990 current_ += size; 2007 current_ += size;
1991 return object; 2008 return object;
1992 } 2009 }
1993 2010
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
2081 == reinterpret_cast<uintptr_t>(start_); 2098 == reinterpret_cast<uintptr_t>(start_);
2082 } 2099 }
2083 2100
2084 bool Contains(Object* o) { 2101 bool Contains(Object* o) {
2085 Address a = reinterpret_cast<Address>(o); 2102 Address a = reinterpret_cast<Address>(o);
2086 return (reinterpret_cast<uintptr_t>(a) & object_mask_) == object_expected_; 2103 return (reinterpret_cast<uintptr_t>(a) & object_mask_) == object_expected_;
2087 } 2104 }
2088 2105
2089 // Return the allocated bytes in the active semispace. 2106 // Return the allocated bytes in the active semispace.
2090 virtual intptr_t Size() { 2107 virtual intptr_t Size() {
2091 return pages_used_ * Page::kObjectAreaSize + 2108 return pages_used_ * NewSpacePage::kAreaSize +
2092 static_cast<int>(top() - to_space_.page_low()); 2109 static_cast<int>(top() - to_space_.page_low());
2093 } 2110 }
2094 2111
2095 // The same, but returning an int. We have to have the one that returns 2112 // The same, but returning an int. We have to have the one that returns
2096 // intptr_t because it is inherited, but if we know we are dealing with the 2113 // intptr_t because it is inherited, but if we know we are dealing with the
2097 // new space, which can't get as big as the other spaces then this is useful: 2114 // new space, which can't get as big as the other spaces then this is useful:
2098 int SizeAsInt() { return static_cast<int>(Size()); } 2115 int SizeAsInt() { return static_cast<int>(Size()); }
2099 2116
2100 // Return the current capacity of a semispace. 2117 // Return the current capacity of a semispace.
2101 intptr_t EffectiveCapacity() { 2118 intptr_t EffectiveCapacity() {
2102 SLOW_ASSERT(to_space_.Capacity() == from_space_.Capacity()); 2119 SLOW_ASSERT(to_space_.Capacity() == from_space_.Capacity());
2103 return (to_space_.Capacity() / Page::kPageSize) * Page::kObjectAreaSize; 2120 return (to_space_.Capacity() / Page::kPageSize) * NewSpacePage::kAreaSize;
2104 } 2121 }
2105 2122
2106 // Return the current capacity of a semispace. 2123 // Return the current capacity of a semispace.
2107 intptr_t Capacity() { 2124 intptr_t Capacity() {
2108 ASSERT(to_space_.Capacity() == from_space_.Capacity()); 2125 ASSERT(to_space_.Capacity() == from_space_.Capacity());
2109 return to_space_.Capacity(); 2126 return to_space_.Capacity();
2110 } 2127 }
2111 2128
2112 // Return the total amount of memory committed for new space. 2129 // Return the total amount of memory committed for new space.
2113 intptr_t CommittedMemory() { 2130 intptr_t CommittedMemory() {
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
2310 OldSpace(Heap* heap, 2327 OldSpace(Heap* heap,
2311 intptr_t max_capacity, 2328 intptr_t max_capacity,
2312 AllocationSpace id, 2329 AllocationSpace id,
2313 Executability executable) 2330 Executability executable)
2314 : PagedSpace(heap, max_capacity, id, executable) { 2331 : PagedSpace(heap, max_capacity, id, executable) {
2315 page_extra_ = 0; 2332 page_extra_ = 0;
2316 } 2333 }
2317 2334
2318 // The limit of allocation for a page in this space. 2335 // The limit of allocation for a page in this space.
2319 virtual Address PageAllocationLimit(Page* page) { 2336 virtual Address PageAllocationLimit(Page* page) {
2320 return page->ObjectAreaEnd(); 2337 return page->area_end();
2321 } 2338 }
2322 2339
2323 public: 2340 public:
2324 TRACK_MEMORY("OldSpace") 2341 TRACK_MEMORY("OldSpace")
2325 }; 2342 };
2326 2343
2327 2344
2328 // For contiguous spaces, top should be in the space (or at the end) and limit 2345 // For contiguous spaces, top should be in the space (or at the end) and limit
2329 // should be the end of the space. 2346 // should be the end of the space.
2330 #define ASSERT_SEMISPACE_ALLOCATION_INFO(info, space) \ 2347 #define ASSERT_SEMISPACE_ALLOCATION_INFO(info, space) \
2331 SLOW_ASSERT((space).page_low() <= (info).top \ 2348 SLOW_ASSERT((space).page_low() <= (info).top \
2332 && (info).top <= (space).page_high() \ 2349 && (info).top <= (space).page_high() \
2333 && (info).limit <= (space).page_high()) 2350 && (info).limit <= (space).page_high())
2334 2351
2335 2352
2336 // ----------------------------------------------------------------------------- 2353 // -----------------------------------------------------------------------------
2337 // Old space for objects of a fixed size 2354 // Old space for objects of a fixed size
2338 2355
2339 class FixedSpace : public PagedSpace { 2356 class FixedSpace : public PagedSpace {
2340 public: 2357 public:
2341 FixedSpace(Heap* heap, 2358 FixedSpace(Heap* heap,
2342 intptr_t max_capacity, 2359 intptr_t max_capacity,
2343 AllocationSpace id, 2360 AllocationSpace id,
2344 int object_size_in_bytes, 2361 int object_size_in_bytes,
2345 const char* name) 2362 const char* name)
2346 : PagedSpace(heap, max_capacity, id, NOT_EXECUTABLE), 2363 : PagedSpace(heap, max_capacity, id, NOT_EXECUTABLE),
2347 object_size_in_bytes_(object_size_in_bytes), 2364 object_size_in_bytes_(object_size_in_bytes),
2348 name_(name) { 2365 name_(name) {
2349 page_extra_ = Page::kObjectAreaSize % object_size_in_bytes; 2366 page_extra_ = Page::kNonCodeObjectAreaSize % object_size_in_bytes;
2350 } 2367 }
2351 2368
2352 // The limit of allocation for a page in this space. 2369 // The limit of allocation for a page in this space.
2353 virtual Address PageAllocationLimit(Page* page) { 2370 virtual Address PageAllocationLimit(Page* page) {
2354 return page->ObjectAreaEnd() - page_extra_; 2371 return page->area_end() - page_extra_;
2355 } 2372 }
2356 2373
2357 int object_size_in_bytes() { return object_size_in_bytes_; } 2374 int object_size_in_bytes() { return object_size_in_bytes_; }
2358 2375
2359 // Prepares for a mark-compact GC. 2376 // Prepares for a mark-compact GC.
2360 virtual void PrepareForMarkCompact(); 2377 virtual void PrepareForMarkCompact();
2361 2378
2362 protected: 2379 protected:
2363 void ResetFreeList() { 2380 void ResetFreeList() {
2364 free_list_.Reset(); 2381 free_list_.Reset();
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
2398 return (size / Map::kSize) * Map::kSize; 2415 return (size / Map::kSize) * Map::kSize;
2399 } 2416 }
2400 } 2417 }
2401 2418
2402 protected: 2419 protected:
2403 #ifdef DEBUG 2420 #ifdef DEBUG
2404 virtual void VerifyObject(HeapObject* obj); 2421 virtual void VerifyObject(HeapObject* obj);
2405 #endif 2422 #endif
2406 2423
2407 private: 2424 private:
2408 static const int kMapsPerPage = Page::kObjectAreaSize / Map::kSize; 2425 static const int kMapsPerPage = Page::kNonCodeObjectAreaSize / Map::kSize;
2409 2426
2410 // Do map space compaction if there is a page gap. 2427 // Do map space compaction if there is a page gap.
2411 int CompactionThreshold() { 2428 int CompactionThreshold() {
2412 return kMapsPerPage * (max_map_space_pages_ - 1); 2429 return kMapsPerPage * (max_map_space_pages_ - 1);
2413 } 2430 }
2414 2431
2415 const int max_map_space_pages_; 2432 const int max_map_space_pages_;
2416 2433
2417 public: 2434 public:
2418 TRACK_MEMORY("MapSpace") 2435 TRACK_MEMORY("MapSpace")
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
2629 } 2646 }
2630 // Must be small, since an iteration is used for lookup. 2647 // Must be small, since an iteration is used for lookup.
2631 static const int kMaxComments = 64; 2648 static const int kMaxComments = 64;
2632 }; 2649 };
2633 #endif 2650 #endif
2634 2651
2635 2652
2636 } } // namespace v8::internal 2653 } } // namespace v8::internal
2637 2654
2638 #endif // V8_SPACES_H_ 2655 #endif // V8_SPACES_H_
OLDNEW
« no previous file with comments | « src/serialize.cc ('k') | src/spaces.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698