| OLD | NEW | 
|---|
| 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 487 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 498   static const int kBodyOffset = | 498   static const int kBodyOffset = | 
| 499     CODE_POINTER_ALIGN(MAP_POINTER_ALIGN(kHeaderSize + Bitmap::kSize)); | 499     CODE_POINTER_ALIGN(MAP_POINTER_ALIGN(kHeaderSize + Bitmap::kSize)); | 
| 500 | 500 | 
| 501   // The start offset of the object area in a page. Aligned to both maps and | 501   // The start offset of the object area in a page. Aligned to both maps and | 
| 502   // code alignment to be suitable for both.  Also aligned to 32 words because | 502   // code alignment to be suitable for both.  Also aligned to 32 words because | 
| 503   // the marking bitmap is arranged in 32 bit chunks. | 503   // the marking bitmap is arranged in 32 bit chunks. | 
| 504   static const int kObjectStartAlignment = 32 * kPointerSize; | 504   static const int kObjectStartAlignment = 32 * kPointerSize; | 
| 505   static const int kObjectStartOffset = kBodyOffset - 1 + | 505   static const int kObjectStartOffset = kBodyOffset - 1 + | 
| 506       (kObjectStartAlignment - (kBodyOffset - 1) % kObjectStartAlignment); | 506       (kObjectStartAlignment - (kBodyOffset - 1) % kObjectStartAlignment); | 
| 507 | 507 | 
| 508   intptr_t size() const { return size_; } | 508   size_t size() const { return size_; } | 
| 509 | 509 | 
| 510   void set_size(size_t size) { size_ = size; } | 510   void set_size(size_t size) { | 
|  | 511     size_ = size; | 
|  | 512   } | 
| 511 | 513 | 
| 512   Executability executable() { | 514   Executability executable() { | 
| 513     return IsFlagSet(IS_EXECUTABLE) ? EXECUTABLE : NOT_EXECUTABLE; | 515     return IsFlagSet(IS_EXECUTABLE) ? EXECUTABLE : NOT_EXECUTABLE; | 
| 514   } | 516   } | 
| 515 | 517 | 
| 516   bool ContainsOnlyData() { | 518   bool ContainsOnlyData() { | 
| 517     return IsFlagSet(CONTAINS_ONLY_DATA); | 519     return IsFlagSet(CONTAINS_ONLY_DATA); | 
| 518   } | 520   } | 
| 519 | 521 | 
| 520   bool InNewSpace() { | 522   bool InNewSpace() { | 
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 652   // Returns the next page in the chain of pages owned by a space. | 654   // Returns the next page in the chain of pages owned by a space. | 
| 653   inline Page* next_page(); | 655   inline Page* next_page(); | 
| 654   inline Page* prev_page(); | 656   inline Page* prev_page(); | 
| 655   inline void set_next_page(Page* page); | 657   inline void set_next_page(Page* page); | 
| 656   inline void set_prev_page(Page* page); | 658   inline void set_prev_page(Page* page); | 
| 657 | 659 | 
| 658   // Returns the start address of the object area in this page. | 660   // Returns the start address of the object area in this page. | 
| 659   Address ObjectAreaStart() { return address() + kObjectStartOffset; } | 661   Address ObjectAreaStart() { return address() + kObjectStartOffset; } | 
| 660 | 662 | 
| 661   // Returns the end address (exclusive) of the object area in this page. | 663   // Returns the end address (exclusive) of the object area in this page. | 
| 662   Address ObjectAreaEnd() { return address() + size(); } | 664   Address ObjectAreaEnd() { return address() + Page::kPageSize; } | 
| 663 | 665 | 
| 664   // Checks whether an address is page aligned. | 666   // Checks whether an address is page aligned. | 
| 665   static bool IsAlignedToPageSize(Address a) { | 667   static bool IsAlignedToPageSize(Address a) { | 
| 666     return 0 == (OffsetFrom(a) & kPageAlignmentMask); | 668     return 0 == (OffsetFrom(a) & kPageAlignmentMask); | 
| 667   } | 669   } | 
| 668 | 670 | 
| 669   // Returns the offset of a given address to this page. | 671   // Returns the offset of a given address to this page. | 
| 670   INLINE(int Offset(Address a)) { | 672   INLINE(int Offset(Address a)) { | 
| 671     int offset = static_cast<int>(a - address()); | 673     int offset = static_cast<int>(a - address()); | 
| 672     return offset; | 674     return offset; | 
| 673   } | 675   } | 
| 674 | 676 | 
| 675   // Returns the address for a given offset to the this page. | 677   // Returns the address for a given offset to the this page. | 
| 676   Address OffsetToAddress(int offset) { | 678   Address OffsetToAddress(int offset) { | 
| 677     ASSERT_PAGE_OFFSET(offset); | 679     ASSERT_PAGE_OFFSET(offset); | 
| 678     return address() + offset; | 680     return address() + offset; | 
| 679   } | 681   } | 
| 680 | 682 | 
| 681   // Expand the committed area for pages that are small. |  | 
| 682   void CommitMore(intptr_t space_needed); |  | 
| 683 |  | 
| 684   // --------------------------------------------------------------------- | 683   // --------------------------------------------------------------------- | 
| 685 | 684 | 
| 686   // Page size in bytes.  This must be a multiple of the OS page size. | 685   // Page size in bytes.  This must be a multiple of the OS page size. | 
| 687   static const int kPageSize = 1 << kPageSizeBits; | 686   static const int kPageSize = 1 << kPageSizeBits; | 
| 688 | 687 | 
| 689   // For a 1Mbyte page grow 64k at a time. |  | 
| 690   static const int kGrowthUnit = 1 << (kPageSizeBits - 4); |  | 
| 691 |  | 
| 692   // Page size mask. | 688   // Page size mask. | 
| 693   static const intptr_t kPageAlignmentMask = (1 << kPageSizeBits) - 1; | 689   static const intptr_t kPageAlignmentMask = (1 << kPageSizeBits) - 1; | 
| 694 | 690 | 
| 695   // Object area size in bytes. | 691   // Object area size in bytes. | 
| 696   static const int kObjectAreaSize = kPageSize - kObjectStartOffset; | 692   static const int kObjectAreaSize = kPageSize - kObjectStartOffset; | 
| 697 | 693 | 
| 698   // Maximum object size that fits in a page. | 694   // Maximum object size that fits in a page. | 
| 699   static const int kMaxHeapObjectSize = kObjectAreaSize; | 695   static const int kMaxHeapObjectSize = kObjectAreaSize; | 
| 700 | 696 | 
| 701   static const int kFirstUsedCell = | 697   static const int kFirstUsedCell = | 
| (...skipping 15 matching lines...) Expand all  Loading... | 
| 717   bool WasSweptPrecisely() { return IsFlagSet(WAS_SWEPT_PRECISELY); } | 713   bool WasSweptPrecisely() { return IsFlagSet(WAS_SWEPT_PRECISELY); } | 
| 718   bool WasSweptConservatively() { return IsFlagSet(WAS_SWEPT_CONSERVATIVELY); } | 714   bool WasSweptConservatively() { return IsFlagSet(WAS_SWEPT_CONSERVATIVELY); } | 
| 719   bool WasSwept() { return WasSweptPrecisely() || WasSweptConservatively(); } | 715   bool WasSwept() { return WasSweptPrecisely() || WasSweptConservatively(); } | 
| 720 | 716 | 
| 721   void MarkSweptPrecisely() { SetFlag(WAS_SWEPT_PRECISELY); } | 717   void MarkSweptPrecisely() { SetFlag(WAS_SWEPT_PRECISELY); } | 
| 722   void MarkSweptConservatively() { SetFlag(WAS_SWEPT_CONSERVATIVELY); } | 718   void MarkSweptConservatively() { SetFlag(WAS_SWEPT_CONSERVATIVELY); } | 
| 723 | 719 | 
| 724   void ClearSweptPrecisely() { ClearFlag(WAS_SWEPT_PRECISELY); } | 720   void ClearSweptPrecisely() { ClearFlag(WAS_SWEPT_PRECISELY); } | 
| 725   void ClearSweptConservatively() { ClearFlag(WAS_SWEPT_CONSERVATIVELY); } | 721   void ClearSweptConservatively() { ClearFlag(WAS_SWEPT_CONSERVATIVELY); } | 
| 726 | 722 | 
| 727   Address RoundUpToObjectAlignment(Address a); |  | 
| 728 |  | 
| 729 #ifdef DEBUG | 723 #ifdef DEBUG | 
| 730   void Print(); | 724   void Print(); | 
| 731 #endif  // DEBUG | 725 #endif  // DEBUG | 
| 732 | 726 | 
| 733   friend class MemoryAllocator; | 727   friend class MemoryAllocator; | 
| 734 }; | 728 }; | 
| 735 | 729 | 
| 736 | 730 | 
| 737 STATIC_CHECK(sizeof(Page) <= MemoryChunk::kHeaderSize); | 731 STATIC_CHECK(sizeof(Page) <= MemoryChunk::kHeaderSize); | 
| 738 | 732 | 
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 848   Isolate* isolate_; | 842   Isolate* isolate_; | 
| 849 | 843 | 
| 850   // The reserved range of virtual memory that all code objects are put in. | 844   // The reserved range of virtual memory that all code objects are put in. | 
| 851   VirtualMemory* code_range_; | 845   VirtualMemory* code_range_; | 
| 852   // Plain old data class, just a struct plus a constructor. | 846   // Plain old data class, just a struct plus a constructor. | 
| 853   class FreeBlock { | 847   class FreeBlock { | 
| 854    public: | 848    public: | 
| 855     FreeBlock(Address start_arg, size_t size_arg) | 849     FreeBlock(Address start_arg, size_t size_arg) | 
| 856         : start(start_arg), size(size_arg) { | 850         : start(start_arg), size(size_arg) { | 
| 857       ASSERT(IsAddressAligned(start, MemoryChunk::kAlignment)); | 851       ASSERT(IsAddressAligned(start, MemoryChunk::kAlignment)); | 
|  | 852       ASSERT(size >= static_cast<size_t>(Page::kPageSize)); | 
| 858     } | 853     } | 
| 859     FreeBlock(void* start_arg, size_t size_arg) | 854     FreeBlock(void* start_arg, size_t size_arg) | 
| 860         : start(static_cast<Address>(start_arg)), size(size_arg) { | 855         : start(static_cast<Address>(start_arg)), size(size_arg) { | 
| 861       ASSERT(IsAddressAligned(start, MemoryChunk::kAlignment)); | 856       ASSERT(IsAddressAligned(start, MemoryChunk::kAlignment)); | 
|  | 857       ASSERT(size >= static_cast<size_t>(Page::kPageSize)); | 
| 862     } | 858     } | 
| 863 | 859 | 
| 864     Address start; | 860     Address start; | 
| 865     size_t size; | 861     size_t size; | 
| 866   }; | 862   }; | 
| 867 | 863 | 
| 868   // Freed blocks of memory are added to the free list.  When the allocation | 864   // Freed blocks of memory are added to the free list.  When the allocation | 
| 869   // list is exhausted, the free list is sorted and merged to make the new | 865   // list is exhausted, the free list is sorted and merged to make the new | 
| 870   // allocation list. | 866   // allocation list. | 
| 871   List<FreeBlock> free_list_; | 867   List<FreeBlock> free_list_; | 
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 947 class MemoryAllocator { | 943 class MemoryAllocator { | 
| 948  public: | 944  public: | 
| 949   explicit MemoryAllocator(Isolate* isolate); | 945   explicit MemoryAllocator(Isolate* isolate); | 
| 950 | 946 | 
| 951   // Initializes its internal bookkeeping structures. | 947   // Initializes its internal bookkeeping structures. | 
| 952   // Max capacity of the total space and executable memory limit. | 948   // Max capacity of the total space and executable memory limit. | 
| 953   bool SetUp(intptr_t max_capacity, intptr_t capacity_executable); | 949   bool SetUp(intptr_t max_capacity, intptr_t capacity_executable); | 
| 954 | 950 | 
| 955   void TearDown(); | 951   void TearDown(); | 
| 956 | 952 | 
| 957   Page* AllocatePage(intptr_t object_area_size, | 953   Page* AllocatePage(PagedSpace* owner, Executability executable); | 
| 958                      PagedSpace* owner, |  | 
| 959                      Executability executable); |  | 
| 960 | 954 | 
| 961   LargePage* AllocateLargePage(intptr_t object_size, | 955   LargePage* AllocateLargePage(intptr_t object_size, | 
| 962                                       Executability executable, | 956                                       Executability executable, | 
| 963                                       Space* owner); | 957                                       Space* owner); | 
| 964 | 958 | 
| 965   void Free(MemoryChunk* chunk); | 959   void Free(MemoryChunk* chunk); | 
| 966 | 960 | 
| 967   // Returns the maximum available bytes of heaps. | 961   // Returns the maximum available bytes of heaps. | 
| 968   intptr_t Available() { | 962   intptr_t Available() { return capacity_ < size_ ? 0 : capacity_ - size_; } | 
| 969     return capacity_ < memory_allocator_reserved_ ? |  | 
| 970            0 : |  | 
| 971            capacity_ - memory_allocator_reserved_; |  | 
| 972   } |  | 
| 973 | 963 | 
| 974   // Returns allocated spaces in bytes. | 964   // Returns allocated spaces in bytes. | 
| 975   intptr_t Size() { return memory_allocator_reserved_; } | 965   intptr_t Size() { return size_; } | 
| 976 | 966 | 
| 977   // Returns the maximum available executable bytes of heaps. | 967   // Returns the maximum available executable bytes of heaps. | 
| 978   intptr_t AvailableExecutable() { | 968   intptr_t AvailableExecutable() { | 
| 979     if (capacity_executable_ < size_executable_) return 0; | 969     if (capacity_executable_ < size_executable_) return 0; | 
| 980     return capacity_executable_ - size_executable_; | 970     return capacity_executable_ - size_executable_; | 
| 981   } | 971   } | 
| 982 | 972 | 
| 983   // Returns allocated executable spaces in bytes. | 973   // Returns allocated executable spaces in bytes. | 
| 984   intptr_t SizeExecutable() { return size_executable_; } | 974   intptr_t SizeExecutable() { return size_executable_; } | 
| 985 | 975 | 
| 986   // Returns maximum available bytes that the old space can have. | 976   // Returns maximum available bytes that the old space can have. | 
| 987   intptr_t MaxAvailable() { | 977   intptr_t MaxAvailable() { | 
| 988     return (Available() / Page::kPageSize) * Page::kObjectAreaSize; | 978     return (Available() / Page::kPageSize) * Page::kObjectAreaSize; | 
| 989   } | 979   } | 
| 990 | 980 | 
| 991 #ifdef DEBUG | 981 #ifdef DEBUG | 
| 992   // Reports statistic info of the space. | 982   // Reports statistic info of the space. | 
| 993   void ReportStatistics(); | 983   void ReportStatistics(); | 
| 994 #endif | 984 #endif | 
| 995 | 985 | 
| 996   MemoryChunk* AllocateChunk(intptr_t body_size, | 986   MemoryChunk* AllocateChunk(intptr_t body_size, | 
| 997                              intptr_t committed_body_size, |  | 
| 998                              Executability executable, | 987                              Executability executable, | 
| 999                              Space* space); | 988                              Space* space); | 
| 1000 | 989 | 
| 1001   Address ReserveAlignedMemory(size_t requested, | 990   Address ReserveAlignedMemory(size_t requested, | 
| 1002                                size_t alignment, | 991                                size_t alignment, | 
| 1003                                VirtualMemory* controller); | 992                                VirtualMemory* controller); | 
| 1004   Address AllocateAlignedMemory(size_t requested, | 993   Address AllocateAlignedMemory(size_t requested, | 
| 1005                                 size_t committed, |  | 
| 1006                                 size_t alignment, | 994                                 size_t alignment, | 
| 1007                                 Executability executable, | 995                                 Executability executable, | 
| 1008                                 VirtualMemory* controller); | 996                                 VirtualMemory* controller); | 
| 1009 | 997 | 
| 1010   void FreeMemory(VirtualMemory* reservation, Executability executable); | 998   void FreeMemory(VirtualMemory* reservation, Executability executable); | 
| 1011   void FreeMemory(Address addr, size_t size, Executability executable); | 999   void FreeMemory(Address addr, size_t size, Executability executable); | 
| 1012 | 1000 | 
| 1013   // Commit a contiguous block of memory from the initial chunk.  Assumes that | 1001   // Commit a contiguous block of memory from the initial chunk.  Assumes that | 
| 1014   // the address is not NULL, the size is greater than zero, and that the | 1002   // the address is not NULL, the size is greater than zero, and that the | 
| 1015   // block is contained in the initial chunk.  Returns true if it succeeded | 1003   // block is contained in the initial chunk.  Returns true if it succeeded | 
| 1016   // and false otherwise. | 1004   // and false otherwise. | 
| 1017   bool CommitBlock(Address start, size_t size, Executability executable); | 1005   bool CommitBlock(Address start, size_t size, Executability executable); | 
| 1018 | 1006 | 
| 1019   // Uncommit a contiguous block of memory [start..(start+size)[. | 1007   // Uncommit a contiguous block of memory [start..(start+size)[. | 
| 1020   // start is not NULL, the size is greater than zero, and the | 1008   // start is not NULL, the size is greater than zero, and the | 
| 1021   // block is contained in the initial chunk.  Returns true if it succeeded | 1009   // block is contained in the initial chunk.  Returns true if it succeeded | 
| 1022   // and false otherwise. | 1010   // and false otherwise. | 
| 1023   bool UncommitBlock(Address start, size_t size); | 1011   bool UncommitBlock(Address start, size_t size); | 
| 1024 | 1012 | 
| 1025   void AllocationBookkeeping(Space* owner, |  | 
| 1026                              Address base, |  | 
| 1027                              intptr_t reserved_size, |  | 
| 1028                              intptr_t committed_size, |  | 
| 1029                              Executability executable); |  | 
| 1030 |  | 
| 1031   // Zaps a contiguous block of memory [start..(start+size)[ thus | 1013   // Zaps a contiguous block of memory [start..(start+size)[ thus | 
| 1032   // filling it up with a recognizable non-NULL bit pattern. | 1014   // filling it up with a recognizable non-NULL bit pattern. | 
| 1033   void ZapBlock(Address start, size_t size); | 1015   void ZapBlock(Address start, size_t size); | 
| 1034 | 1016 | 
| 1035   void PerformAllocationCallback(ObjectSpace space, | 1017   void PerformAllocationCallback(ObjectSpace space, | 
| 1036                                  AllocationAction action, | 1018                                  AllocationAction action, | 
| 1037                                  size_t size); | 1019                                  size_t size); | 
| 1038 | 1020 | 
| 1039   void AddMemoryAllocationCallback(MemoryAllocationCallback callback, | 1021   void AddMemoryAllocationCallback(MemoryAllocationCallback callback, | 
| 1040                                           ObjectSpace space, | 1022                                           ObjectSpace space, | 
| 1041                                           AllocationAction action); | 1023                                           AllocationAction action); | 
| 1042 | 1024 | 
| 1043   void RemoveMemoryAllocationCallback( | 1025   void RemoveMemoryAllocationCallback( | 
| 1044       MemoryAllocationCallback callback); | 1026       MemoryAllocationCallback callback); | 
| 1045 | 1027 | 
| 1046   bool MemoryAllocationCallbackRegistered( | 1028   bool MemoryAllocationCallbackRegistered( | 
| 1047       MemoryAllocationCallback callback); | 1029       MemoryAllocationCallback callback); | 
| 1048 | 1030 | 
| 1049  private: | 1031  private: | 
| 1050   Isolate* isolate_; | 1032   Isolate* isolate_; | 
| 1051 | 1033 | 
| 1052   // Maximum space size in bytes. | 1034   // Maximum space size in bytes. | 
| 1053   size_t capacity_; | 1035   size_t capacity_; | 
| 1054   // Maximum subset of capacity_ that can be executable | 1036   // Maximum subset of capacity_ that can be executable | 
| 1055   size_t capacity_executable_; | 1037   size_t capacity_executable_; | 
| 1056 | 1038 | 
| 1057   // Allocated space size in bytes. | 1039   // Allocated space size in bytes. | 
| 1058   size_t memory_allocator_reserved_; | 1040   size_t size_; | 
| 1059   // Allocated executable space size in bytes. | 1041   // Allocated executable space size in bytes. | 
| 1060   size_t size_executable_; | 1042   size_t size_executable_; | 
| 1061 | 1043 | 
| 1062   struct MemoryAllocationCallbackRegistration { | 1044   struct MemoryAllocationCallbackRegistration { | 
| 1063     MemoryAllocationCallbackRegistration(MemoryAllocationCallback callback, | 1045     MemoryAllocationCallbackRegistration(MemoryAllocationCallback callback, | 
| 1064                                          ObjectSpace space, | 1046                                          ObjectSpace space, | 
| 1065                                          AllocationAction action) | 1047                                          AllocationAction action) | 
| 1066         : callback(callback), space(space), action(action) { | 1048         : callback(callback), space(space), action(action) { | 
| 1067     } | 1049     } | 
| 1068     MemoryAllocationCallback callback; | 1050     MemoryAllocationCallback callback; | 
| (...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1393 | 1375 | 
| 1394   void CountFreeListItems(Page* p, SizeStats* sizes); | 1376   void CountFreeListItems(Page* p, SizeStats* sizes); | 
| 1395 | 1377 | 
| 1396   intptr_t EvictFreeListItems(Page* p); | 1378   intptr_t EvictFreeListItems(Page* p); | 
| 1397 | 1379 | 
| 1398  private: | 1380  private: | 
| 1399   // The size range of blocks, in bytes. | 1381   // The size range of blocks, in bytes. | 
| 1400   static const int kMinBlockSize = 3 * kPointerSize; | 1382   static const int kMinBlockSize = 3 * kPointerSize; | 
| 1401   static const int kMaxBlockSize = Page::kMaxHeapObjectSize; | 1383   static const int kMaxBlockSize = Page::kMaxHeapObjectSize; | 
| 1402 | 1384 | 
| 1403   FreeListNode* PickNodeFromList(FreeListNode** list, | 1385   FreeListNode* PickNodeFromList(FreeListNode** list, int* node_size); | 
| 1404                                  int* node_size, |  | 
| 1405                                  int minimum_size); |  | 
| 1406 | 1386 | 
| 1407   FreeListNode* FindNodeFor(int size_in_bytes, int* node_size, Address limit); | 1387   FreeListNode* FindNodeFor(int size_in_bytes, int* node_size); | 
| 1408   FreeListNode* FindAbuttingNode(int size_in_bytes, |  | 
| 1409                                  int* node_size, |  | 
| 1410                                  Address limit, |  | 
| 1411                                  FreeListNode** list_head); |  | 
| 1412 | 1388 | 
| 1413   PagedSpace* owner_; | 1389   PagedSpace* owner_; | 
| 1414   Heap* heap_; | 1390   Heap* heap_; | 
| 1415 | 1391 | 
| 1416   // Total available bytes in all blocks on this free list. | 1392   // Total available bytes in all blocks on this free list. | 
| 1417   int available_; | 1393   int available_; | 
| 1418 | 1394 | 
| 1419   static const int kSmallListMin = 0x20 * kPointerSize; | 1395   static const int kSmallListMin = 0x20 * kPointerSize; | 
| 1420   static const int kSmallListMax = 0xff * kPointerSize; | 1396   static const int kSmallListMax = 0xff * kPointerSize; | 
| 1421   static const int kMediumListMax = 0x7ff * kPointerSize; | 1397   static const int kMediumListMax = 0x7ff * kPointerSize; | 
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1501   virtual intptr_t SizeOfObjects() { | 1477   virtual intptr_t SizeOfObjects() { | 
| 1502     ASSERT(!IsSweepingComplete() || (unswept_free_bytes_ == 0)); | 1478     ASSERT(!IsSweepingComplete() || (unswept_free_bytes_ == 0)); | 
| 1503     return Size() - unswept_free_bytes_ - (limit() - top()); | 1479     return Size() - unswept_free_bytes_ - (limit() - top()); | 
| 1504   } | 1480   } | 
| 1505 | 1481 | 
| 1506   // Wasted bytes in this space.  These are just the bytes that were thrown away | 1482   // Wasted bytes in this space.  These are just the bytes that were thrown away | 
| 1507   // due to being too small to use for allocation.  They do not include the | 1483   // due to being too small to use for allocation.  They do not include the | 
| 1508   // free bytes that were not found at all due to lazy sweeping. | 1484   // free bytes that were not found at all due to lazy sweeping. | 
| 1509   virtual intptr_t Waste() { return accounting_stats_.Waste(); } | 1485   virtual intptr_t Waste() { return accounting_stats_.Waste(); } | 
| 1510 | 1486 | 
| 1511   virtual int ObjectAlignment() { return kObjectAlignment; } |  | 
| 1512 |  | 
| 1513   // Returns the allocation pointer in this space. | 1487   // Returns the allocation pointer in this space. | 
| 1514   Address top() { return allocation_info_.top; } | 1488   Address top() { return allocation_info_.top; } | 
| 1515   Address limit() { return allocation_info_.limit; } | 1489   Address limit() { return allocation_info_.limit; } | 
| 1516 | 1490 | 
| 1517   // Allocate the requested number of bytes in the space if possible, return a | 1491   // Allocate the requested number of bytes in the space if possible, return a | 
| 1518   // failure object if not. | 1492   // failure object if not. | 
| 1519   MUST_USE_RESULT inline MaybeObject* AllocateRaw(int size_in_bytes); | 1493   MUST_USE_RESULT inline MaybeObject* AllocateRaw(int size_in_bytes); | 
| 1520 | 1494 | 
| 1521   virtual bool ReserveSpace(int bytes); | 1495   virtual bool ReserveSpace(int bytes); | 
| 1522 | 1496 | 
| 1523   // Give a block of memory to the space's free list.  It might be added to | 1497   // Give a block of memory to the space's free list.  It might be added to | 
| 1524   // the free list or accounted as waste. | 1498   // the free list or accounted as waste. | 
| 1525   // If add_to_freelist is false then just accounting stats are updated and | 1499   // If add_to_freelist is false then just accounting stats are updated and | 
| 1526   // no attempt to add area to free list is made. | 1500   // no attempt to add area to free list is made. | 
| 1527   int AddToFreeLists(Address start, int size_in_bytes) { | 1501   int Free(Address start, int size_in_bytes) { | 
| 1528     int wasted = free_list_.Free(start, size_in_bytes); | 1502     int wasted = free_list_.Free(start, size_in_bytes); | 
| 1529     accounting_stats_.DeallocateBytes(size_in_bytes - wasted); | 1503     accounting_stats_.DeallocateBytes(size_in_bytes - wasted); | 
| 1530     return size_in_bytes - wasted; | 1504     return size_in_bytes - wasted; | 
| 1531   } | 1505   } | 
| 1532 | 1506 | 
| 1533   // Set space allocation info. | 1507   // Set space allocation info. | 
| 1534   void SetTop(Address top, Address limit) { | 1508   void SetTop(Address top, Address limit) { | 
| 1535     ASSERT(top == NULL || top >= Page::FromAddress(top - 1)->ObjectAreaStart()); |  | 
| 1536     ASSERT(top == limit || | 1509     ASSERT(top == limit || | 
| 1537            Page::FromAddress(top) == Page::FromAddress(limit - 1)); | 1510            Page::FromAddress(top) == Page::FromAddress(limit - 1)); | 
| 1538     allocation_info_.top = top; | 1511     allocation_info_.top = top; | 
| 1539     allocation_info_.limit = limit; | 1512     allocation_info_.limit = limit; | 
| 1540   } | 1513   } | 
| 1541 | 1514 | 
| 1542   void Allocate(int bytes) { | 1515   void Allocate(int bytes) { | 
| 1543     accounting_stats_.AllocateBytes(bytes); | 1516     accounting_stats_.AllocateBytes(bytes); | 
| 1544   } | 1517   } | 
| 1545 | 1518 | 
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1592     if (first == &anchor_) first = NULL; | 1565     if (first == &anchor_) first = NULL; | 
| 1593     first_unswept_page_ = first; | 1566     first_unswept_page_ = first; | 
| 1594   } | 1567   } | 
| 1595 | 1568 | 
| 1596   void IncrementUnsweptFreeBytes(int by) { | 1569   void IncrementUnsweptFreeBytes(int by) { | 
| 1597     unswept_free_bytes_ += by; | 1570     unswept_free_bytes_ += by; | 
| 1598   } | 1571   } | 
| 1599 | 1572 | 
| 1600   void IncreaseUnsweptFreeBytes(Page* p) { | 1573   void IncreaseUnsweptFreeBytes(Page* p) { | 
| 1601     ASSERT(ShouldBeSweptLazily(p)); | 1574     ASSERT(ShouldBeSweptLazily(p)); | 
| 1602     unswept_free_bytes_ += | 1575     unswept_free_bytes_ += (Page::kObjectAreaSize - p->LiveBytes()); | 
| 1603         (p->ObjectAreaEnd() - p->ObjectAreaStart()) - p->LiveBytes(); |  | 
| 1604   } | 1576   } | 
| 1605 | 1577 | 
| 1606   void DecreaseUnsweptFreeBytes(Page* p) { | 1578   void DecreaseUnsweptFreeBytes(Page* p) { | 
| 1607     ASSERT(ShouldBeSweptLazily(p)); | 1579     ASSERT(ShouldBeSweptLazily(p)); | 
| 1608     unswept_free_bytes_ -= | 1580     unswept_free_bytes_ -= (Page::kObjectAreaSize - p->LiveBytes()); | 
| 1609         (p->ObjectAreaEnd() - p->ObjectAreaStart() - p->LiveBytes()); |  | 
| 1610   } | 1581   } | 
| 1611 | 1582 | 
| 1612   bool AdvanceSweeper(intptr_t bytes_to_sweep); | 1583   bool AdvanceSweeper(intptr_t bytes_to_sweep); | 
| 1613 | 1584 | 
| 1614   bool IsSweepingComplete() { | 1585   bool IsSweepingComplete() { | 
| 1615     return !first_unswept_page_->is_valid(); | 1586     return !first_unswept_page_->is_valid(); | 
| 1616   } | 1587   } | 
| 1617 | 1588 | 
| 1618   inline bool HasAPage() { return anchor_.next_page() != &anchor_; } |  | 
| 1619   Page* FirstPage() { return anchor_.next_page(); } | 1589   Page* FirstPage() { return anchor_.next_page(); } | 
| 1620   Page* LastPage() { return anchor_.prev_page(); } | 1590   Page* LastPage() { return anchor_.prev_page(); } | 
| 1621 | 1591 | 
| 1622   // Returns zero for pages that have so little fragmentation that it is not | 1592   // Returns zero for pages that have so little fragmentation that it is not | 
| 1623   // worth defragmenting them.  Otherwise a positive integer that gives an | 1593   // worth defragmenting them.  Otherwise a positive integer that gives an | 
| 1624   // estimate of fragmentation on an arbitrary scale. | 1594   // estimate of fragmentation on an arbitrary scale. | 
| 1625   int Fragmentation(Page* p) { | 1595   int Fragmentation(Page* p) { | 
| 1626     FreeList::SizeStats sizes; | 1596     FreeList::SizeStats sizes; | 
| 1627     free_list_.CountFreeListItems(p, &sizes); | 1597     free_list_.CountFreeListItems(p, &sizes); | 
| 1628 | 1598 | 
| 1629     intptr_t object_area_size = p->ObjectAreaEnd() - p->ObjectAreaStart(); |  | 
| 1630 |  | 
| 1631     intptr_t ratio; | 1599     intptr_t ratio; | 
| 1632     intptr_t ratio_threshold; | 1600     intptr_t ratio_threshold; | 
| 1633     if (identity() == CODE_SPACE) { | 1601     if (identity() == CODE_SPACE) { | 
| 1634       ratio = (sizes.medium_size_ * 10 + sizes.large_size_ * 2) * 100 / | 1602       ratio = (sizes.medium_size_ * 10 + sizes.large_size_ * 2) * 100 / | 
| 1635           object_area_size; | 1603           Page::kObjectAreaSize; | 
| 1636       ratio_threshold = 10; | 1604       ratio_threshold = 10; | 
| 1637     } else { | 1605     } else { | 
| 1638       ratio = (sizes.small_size_ * 5 + sizes.medium_size_) * 100 / | 1606       ratio = (sizes.small_size_ * 5 + sizes.medium_size_) * 100 / | 
| 1639           object_area_size; | 1607           Page::kObjectAreaSize; | 
| 1640       ratio_threshold = 15; | 1608       ratio_threshold = 15; | 
| 1641     } | 1609     } | 
| 1642 | 1610 | 
| 1643     if (FLAG_trace_fragmentation) { | 1611     if (FLAG_trace_fragmentation) { | 
| 1644       PrintF("%p [%d]: %d (%.2f%%) %d (%.2f%%) %d (%.2f%%) %d (%.2f%%) %s\n", | 1612       PrintF("%p [%d]: %d (%.2f%%) %d (%.2f%%) %d (%.2f%%) %d (%.2f%%) %s\n", | 
| 1645              reinterpret_cast<void*>(p), | 1613              reinterpret_cast<void*>(p), | 
| 1646              identity(), | 1614              identity(), | 
| 1647              static_cast<int>(sizes.small_size_), | 1615              static_cast<int>(sizes.small_size_), | 
| 1648              static_cast<double>(sizes.small_size_ * 100) / | 1616              static_cast<double>(sizes.small_size_ * 100) / | 
| 1649                  object_area_size, | 1617                  Page::kObjectAreaSize, | 
| 1650              static_cast<int>(sizes.medium_size_), | 1618              static_cast<int>(sizes.medium_size_), | 
| 1651              static_cast<double>(sizes.medium_size_ * 100) / | 1619              static_cast<double>(sizes.medium_size_ * 100) / | 
| 1652                  object_area_size, | 1620                  Page::kObjectAreaSize, | 
| 1653              static_cast<int>(sizes.large_size_), | 1621              static_cast<int>(sizes.large_size_), | 
| 1654              static_cast<double>(sizes.large_size_ * 100) / | 1622              static_cast<double>(sizes.large_size_ * 100) / | 
| 1655                  object_area_size, | 1623                  Page::kObjectAreaSize, | 
| 1656              static_cast<int>(sizes.huge_size_), | 1624              static_cast<int>(sizes.huge_size_), | 
| 1657              static_cast<double>(sizes.huge_size_ * 100) / | 1625              static_cast<double>(sizes.huge_size_ * 100) / | 
| 1658                  object_area_size, | 1626                  Page::kObjectAreaSize, | 
| 1659              (ratio > ratio_threshold) ? "[fragmented]" : ""); | 1627              (ratio > ratio_threshold) ? "[fragmented]" : ""); | 
| 1660     } | 1628     } | 
| 1661 | 1629 | 
| 1662     if (FLAG_always_compact && sizes.Total() != object_area_size) { | 1630     if (FLAG_always_compact && sizes.Total() != Page::kObjectAreaSize) { | 
| 1663       return 1; | 1631       return 1; | 
| 1664     } | 1632     } | 
| 1665     if (ratio <= ratio_threshold) return 0;  // Not fragmented. | 1633     if (ratio <= ratio_threshold) return 0;  // Not fragmented. | 
| 1666 | 1634 | 
| 1667     return static_cast<int>(ratio - ratio_threshold); | 1635     return static_cast<int>(ratio - ratio_threshold); | 
| 1668   } | 1636   } | 
| 1669 | 1637 | 
| 1670   void EvictEvacuationCandidatesFromFreeLists(); | 1638   void EvictEvacuationCandidatesFromFreeLists(); | 
| 1671 | 1639 | 
| 1672   bool CanExpand(); | 1640   bool CanExpand(); | 
| (...skipping 10 matching lines...) Expand all  Loading... | 
| 1683 | 1651 | 
| 1684   // The dummy page that anchors the double linked list of pages. | 1652   // The dummy page that anchors the double linked list of pages. | 
| 1685   Page anchor_; | 1653   Page anchor_; | 
| 1686 | 1654 | 
| 1687   // The space's free list. | 1655   // The space's free list. | 
| 1688   FreeList free_list_; | 1656   FreeList free_list_; | 
| 1689 | 1657 | 
| 1690   // Normal allocation information. | 1658   // Normal allocation information. | 
| 1691   AllocationInfo allocation_info_; | 1659   AllocationInfo allocation_info_; | 
| 1692 | 1660 | 
|  | 1661   // Bytes of each page that cannot be allocated.  Possibly non-zero | 
|  | 1662   // for pages in spaces with only fixed-size objects.  Always zero | 
|  | 1663   // for pages in spaces with variable sized objects (those pages are | 
|  | 1664   // padded with free-list nodes). | 
|  | 1665   int page_extra_; | 
|  | 1666 | 
| 1693   bool was_swept_conservatively_; | 1667   bool was_swept_conservatively_; | 
| 1694 | 1668 | 
| 1695   // The first page to be swept when the lazy sweeper advances. Is set | 1669   // The first page to be swept when the lazy sweeper advances. Is set | 
| 1696   // to NULL when all pages have been swept. | 1670   // to NULL when all pages have been swept. | 
| 1697   Page* first_unswept_page_; | 1671   Page* first_unswept_page_; | 
| 1698 | 1672 | 
| 1699   // The number of free bytes which could be reclaimed by advancing the | 1673   // The number of free bytes which could be reclaimed by advancing the | 
| 1700   // lazy sweeper.  This is only an estimation because lazy sweeping is | 1674   // lazy sweeper.  This is only an estimation because lazy sweeping is | 
| 1701   // done conservatively. | 1675   // done conservatively. | 
| 1702   intptr_t unswept_free_bytes_; | 1676   intptr_t unswept_free_bytes_; | 
| 1703 | 1677 | 
| 1704   // Expands the space by allocating a page. Returns false if it cannot | 1678   // Expands the space by allocating a fixed number of pages. Returns false if | 
| 1705   // allocate a page from OS, or if the hard heap size limit has been hit.  The | 1679   // it cannot allocate requested number of pages from OS, or if the hard heap | 
| 1706   // new page will have at least enough committed space to satisfy the object | 1680   // size limit has been hit. | 
| 1707   // size indicated by the allocation_size argument; | 1681   bool Expand(); | 
| 1708   bool Expand(intptr_t allocation_size); |  | 
| 1709 | 1682 | 
| 1710   // Generic fast case allocation function that tries linear allocation at the | 1683   // Generic fast case allocation function that tries linear allocation at the | 
| 1711   // address denoted by top in allocation_info_. | 1684   // address denoted by top in allocation_info_. | 
| 1712   inline HeapObject* AllocateLinearly(int size_in_bytes); | 1685   inline HeapObject* AllocateLinearly(int size_in_bytes); | 
| 1713 | 1686 | 
| 1714   // Slow path of AllocateRaw.  This function is space-dependent. | 1687   // Slow path of AllocateRaw.  This function is space-dependent. | 
| 1715   MUST_USE_RESULT virtual HeapObject* SlowAllocateRaw(int size_in_bytes); | 1688   MUST_USE_RESULT virtual HeapObject* SlowAllocateRaw(int size_in_bytes); | 
| 1716 | 1689 | 
| 1717   friend class PageIterator; | 1690   friend class PageIterator; | 
| 1718 }; | 1691 }; | 
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1853  public: | 1826  public: | 
| 1854   // Constructor. | 1827   // Constructor. | 
| 1855   SemiSpace(Heap* heap, SemiSpaceId semispace) | 1828   SemiSpace(Heap* heap, SemiSpaceId semispace) | 
| 1856     : Space(heap, NEW_SPACE, NOT_EXECUTABLE), | 1829     : Space(heap, NEW_SPACE, NOT_EXECUTABLE), | 
| 1857       start_(NULL), | 1830       start_(NULL), | 
| 1858       age_mark_(NULL), | 1831       age_mark_(NULL), | 
| 1859       id_(semispace), | 1832       id_(semispace), | 
| 1860       anchor_(this), | 1833       anchor_(this), | 
| 1861       current_page_(NULL) { } | 1834       current_page_(NULL) { } | 
| 1862 | 1835 | 
| 1863   // Sets up the semispace using the given chunk.  After this, call Commit() | 1836   // Sets up the semispace using the given chunk. | 
| 1864   // to make the semispace usable. |  | 
| 1865   void SetUp(Address start, int initial_capacity, int maximum_capacity); | 1837   void SetUp(Address start, int initial_capacity, int maximum_capacity); | 
| 1866 | 1838 | 
| 1867   // Tear down the space.  Heap memory was not allocated by the space, so it | 1839   // Tear down the space.  Heap memory was not allocated by the space, so it | 
| 1868   // is not deallocated here. | 1840   // is not deallocated here. | 
| 1869   void TearDown(); | 1841   void TearDown(); | 
| 1870 | 1842 | 
| 1871   // True if the space has been set up but not torn down. | 1843   // True if the space has been set up but not torn down. | 
| 1872   bool HasBeenSetUp() { return start_ != NULL; } | 1844   bool HasBeenSetUp() { return start_ != NULL; } | 
| 1873 | 1845 | 
| 1874   // Grow the semispace to the new capacity.  The new capacity | 1846   // Grow the semispace to the new capacity.  The new capacity | 
| (...skipping 484 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2359 // Old object space (excluding map objects) | 2331 // Old object space (excluding map objects) | 
| 2360 | 2332 | 
| 2361 class OldSpace : public PagedSpace { | 2333 class OldSpace : public PagedSpace { | 
| 2362  public: | 2334  public: | 
| 2363   // Creates an old space object with a given maximum capacity. | 2335   // Creates an old space object with a given maximum capacity. | 
| 2364   // The constructor does not allocate pages from OS. | 2336   // The constructor does not allocate pages from OS. | 
| 2365   OldSpace(Heap* heap, | 2337   OldSpace(Heap* heap, | 
| 2366            intptr_t max_capacity, | 2338            intptr_t max_capacity, | 
| 2367            AllocationSpace id, | 2339            AllocationSpace id, | 
| 2368            Executability executable) | 2340            Executability executable) | 
| 2369       : PagedSpace(heap, max_capacity, id, executable) { } | 2341       : PagedSpace(heap, max_capacity, id, executable) { | 
|  | 2342     page_extra_ = 0; | 
|  | 2343   } | 
|  | 2344 | 
|  | 2345   // The limit of allocation for a page in this space. | 
|  | 2346   virtual Address PageAllocationLimit(Page* page) { | 
|  | 2347     return page->ObjectAreaEnd(); | 
|  | 2348   } | 
| 2370 | 2349 | 
| 2371  public: | 2350  public: | 
| 2372   TRACK_MEMORY("OldSpace") | 2351   TRACK_MEMORY("OldSpace") | 
| 2373 }; | 2352 }; | 
| 2374 | 2353 | 
| 2375 | 2354 | 
| 2376 // For contiguous spaces, top should be in the space (or at the end) and limit | 2355 // For contiguous spaces, top should be in the space (or at the end) and limit | 
| 2377 // should be the end of the space. | 2356 // should be the end of the space. | 
| 2378 #define ASSERT_SEMISPACE_ALLOCATION_INFO(info, space) \ | 2357 #define ASSERT_SEMISPACE_ALLOCATION_INFO(info, space) \ | 
| 2379   SLOW_ASSERT((space).page_low() <= (info).top             \ | 2358   SLOW_ASSERT((space).page_low() <= (info).top             \ | 
| 2380               && (info).top <= (space).page_high()         \ | 2359               && (info).top <= (space).page_high()         \ | 
| 2381               && (info).limit <= (space).page_high()) | 2360               && (info).limit <= (space).page_high()) | 
| 2382 | 2361 | 
| 2383 | 2362 | 
| 2384 // ----------------------------------------------------------------------------- | 2363 // ----------------------------------------------------------------------------- | 
| 2385 // Old space for objects of a fixed size | 2364 // Old space for objects of a fixed size | 
| 2386 | 2365 | 
| 2387 class FixedSpace : public PagedSpace { | 2366 class FixedSpace : public PagedSpace { | 
| 2388  public: | 2367  public: | 
| 2389   FixedSpace(Heap* heap, | 2368   FixedSpace(Heap* heap, | 
| 2390              intptr_t max_capacity, | 2369              intptr_t max_capacity, | 
| 2391              AllocationSpace id, | 2370              AllocationSpace id, | 
| 2392              int object_size_in_bytes, | 2371              int object_size_in_bytes, | 
| 2393              const char* name) | 2372              const char* name) | 
| 2394       : PagedSpace(heap, max_capacity, id, NOT_EXECUTABLE), | 2373       : PagedSpace(heap, max_capacity, id, NOT_EXECUTABLE), | 
| 2395         object_size_in_bytes_(object_size_in_bytes), | 2374         object_size_in_bytes_(object_size_in_bytes), | 
| 2396         name_(name) { } | 2375         name_(name) { | 
|  | 2376     page_extra_ = Page::kObjectAreaSize % object_size_in_bytes; | 
|  | 2377   } | 
|  | 2378 | 
|  | 2379   // The limit of allocation for a page in this space. | 
|  | 2380   virtual Address PageAllocationLimit(Page* page) { | 
|  | 2381     return page->ObjectAreaEnd() - page_extra_; | 
|  | 2382   } | 
| 2397 | 2383 | 
| 2398   int object_size_in_bytes() { return object_size_in_bytes_; } | 2384   int object_size_in_bytes() { return object_size_in_bytes_; } | 
| 2399 | 2385 | 
| 2400   virtual int ObjectAlignment() { return object_size_in_bytes_; } |  | 
| 2401 |  | 
| 2402   // Prepares for a mark-compact GC. | 2386   // Prepares for a mark-compact GC. | 
| 2403   virtual void PrepareForMarkCompact(); | 2387   virtual void PrepareForMarkCompact(); | 
| 2404 | 2388 | 
| 2405  protected: | 2389  protected: | 
| 2406   void ResetFreeList() { | 2390   void ResetFreeList() { | 
| 2407     free_list_.Reset(); | 2391     free_list_.Reset(); | 
| 2408   } | 2392   } | 
| 2409 | 2393 | 
| 2410  private: | 2394  private: | 
| 2411   // The size of objects in this space. | 2395   // The size of objects in this space. | 
| (...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2672   } | 2656   } | 
| 2673   // Must be small, since an iteration is used for lookup. | 2657   // Must be small, since an iteration is used for lookup. | 
| 2674   static const int kMaxComments = 64; | 2658   static const int kMaxComments = 64; | 
| 2675 }; | 2659 }; | 
| 2676 #endif | 2660 #endif | 
| 2677 | 2661 | 
| 2678 | 2662 | 
| 2679 } }  // namespace v8::internal | 2663 } }  // namespace v8::internal | 
| 2680 | 2664 | 
| 2681 #endif  // V8_SPACES_H_ | 2665 #endif  // V8_SPACES_H_ | 
| OLD | NEW | 
|---|