| OLD | NEW | 
|     1 // Copyright 2011 the V8 project authors. All rights reserved. |     1 // Copyright 2011 the V8 project authors. All rights reserved. | 
|     2 // Use of this source code is governed by a BSD-style license that can be |     2 // Use of this source code is governed by a BSD-style license that can be | 
|     3 // found in the LICENSE file. |     3 // found in the LICENSE file. | 
|     4  |     4  | 
|     5 #ifndef V8_HEAP_SPACES_H_ |     5 #ifndef V8_HEAP_SPACES_H_ | 
|     6 #define V8_HEAP_SPACES_H_ |     6 #define V8_HEAP_SPACES_H_ | 
|     7  |     7  | 
|     8 #include <list> |     8 #include <list> | 
|     9  |     9  | 
|    10 #include "src/allocation.h" |    10 #include "src/allocation.h" | 
|    11 #include "src/base/atomic-utils.h" |    11 #include "src/base/atomic-utils.h" | 
|    12 #include "src/base/atomicops.h" |    12 #include "src/base/atomicops.h" | 
|    13 #include "src/base/bits.h" |    13 #include "src/base/bits.h" | 
|    14 #include "src/base/hashmap.h" |    14 #include "src/base/hashmap.h" | 
|    15 #include "src/base/platform/mutex.h" |    15 #include "src/base/platform/mutex.h" | 
|    16 #include "src/flags.h" |    16 #include "src/flags.h" | 
 |    17 #include "src/heap/marking.h" | 
|    17 #include "src/list.h" |    18 #include "src/list.h" | 
|    18 #include "src/objects.h" |    19 #include "src/objects.h" | 
|    19 #include "src/utils.h" |    20 #include "src/utils.h" | 
|    20  |    21  | 
|    21 namespace v8 { |    22 namespace v8 { | 
|    22 namespace internal { |    23 namespace internal { | 
|    23  |    24  | 
|    24 class AllocationInfo; |    25 class AllocationInfo; | 
|    25 class AllocationObserver; |    26 class AllocationObserver; | 
|    26 class CompactionSpace; |    27 class CompactionSpace; | 
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   103  |   104  | 
|   104 #define DCHECK_OBJECT_SIZE(size) \ |   105 #define DCHECK_OBJECT_SIZE(size) \ | 
|   105   DCHECK((0 < size) && (size <= Page::kMaxRegularHeapObjectSize)) |   106   DCHECK((0 < size) && (size <= Page::kMaxRegularHeapObjectSize)) | 
|   106  |   107  | 
|   107 #define DCHECK_CODEOBJECT_SIZE(size, code_space) \ |   108 #define DCHECK_CODEOBJECT_SIZE(size, code_space) \ | 
|   108   DCHECK((0 < size) && (size <= code_space->AreaSize())) |   109   DCHECK((0 < size) && (size <= code_space->AreaSize())) | 
|   109  |   110  | 
|   110 #define DCHECK_PAGE_OFFSET(offset) \ |   111 #define DCHECK_PAGE_OFFSET(offset) \ | 
|   111   DCHECK((Page::kObjectStartOffset <= offset) && (offset <= Page::kPageSize)) |   112   DCHECK((Page::kObjectStartOffset <= offset) && (offset <= Page::kPageSize)) | 
|   112  |   113  | 
|   113 class MarkBit { |  | 
|   114  public: |  | 
|   115   typedef uint32_t CellType; |  | 
|   116  |  | 
|   117   inline MarkBit(CellType* cell, CellType mask) : cell_(cell), mask_(mask) {} |  | 
|   118  |  | 
|   119 #ifdef DEBUG |  | 
|   120   bool operator==(const MarkBit& other) { |  | 
|   121     return cell_ == other.cell_ && mask_ == other.mask_; |  | 
|   122   } |  | 
|   123 #endif |  | 
|   124  |  | 
|   125  private: |  | 
|   126   inline CellType* cell() { return cell_; } |  | 
|   127   inline CellType mask() { return mask_; } |  | 
|   128  |  | 
|   129   inline MarkBit Next() { |  | 
|   130     CellType new_mask = mask_ << 1; |  | 
|   131     if (new_mask == 0) { |  | 
|   132       return MarkBit(cell_ + 1, 1); |  | 
|   133     } else { |  | 
|   134       return MarkBit(cell_, new_mask); |  | 
|   135     } |  | 
|   136   } |  | 
|   137  |  | 
|   138   inline void Set() { *cell_ |= mask_; } |  | 
|   139   inline bool Get() { return (*cell_ & mask_) != 0; } |  | 
|   140   inline void Clear() { *cell_ &= ~mask_; } |  | 
|   141  |  | 
|   142   CellType* cell_; |  | 
|   143   CellType mask_; |  | 
|   144  |  | 
|   145   friend class Marking; |  | 
|   146 }; |  | 
|   147  |  | 
|   148  |  | 
|   149 // Bitmap is a sequence of cells each containing fixed number of bits. |  | 
|   150 class Bitmap { |  | 
|   151  public: |  | 
|   152   static const uint32_t kBitsPerCell = 32; |  | 
|   153   static const uint32_t kBitsPerCellLog2 = 5; |  | 
|   154   static const uint32_t kBitIndexMask = kBitsPerCell - 1; |  | 
|   155   static const uint32_t kBytesPerCell = kBitsPerCell / kBitsPerByte; |  | 
|   156   static const uint32_t kBytesPerCellLog2 = kBitsPerCellLog2 - kBitsPerByteLog2; |  | 
|   157  |  | 
|   158   static const size_t kLength = (1 << kPageSizeBits) >> (kPointerSizeLog2); |  | 
|   159  |  | 
|   160   static const size_t kSize = |  | 
|   161       (1 << kPageSizeBits) >> (kPointerSizeLog2 + kBitsPerByteLog2); |  | 
|   162  |  | 
|   163  |  | 
|   164   static int CellsForLength(int length) { |  | 
|   165     return (length + kBitsPerCell - 1) >> kBitsPerCellLog2; |  | 
|   166   } |  | 
|   167  |  | 
|   168   int CellsCount() { return CellsForLength(kLength); } |  | 
|   169  |  | 
|   170   static int SizeFor(int cells_count) { |  | 
|   171     return sizeof(MarkBit::CellType) * cells_count; |  | 
|   172   } |  | 
|   173  |  | 
|   174   INLINE(static uint32_t IndexToCell(uint32_t index)) { |  | 
|   175     return index >> kBitsPerCellLog2; |  | 
|   176   } |  | 
|   177  |  | 
|   178   V8_INLINE static uint32_t IndexInCell(uint32_t index) { |  | 
|   179     return index & kBitIndexMask; |  | 
|   180   } |  | 
|   181  |  | 
|   182   INLINE(static uint32_t CellToIndex(uint32_t index)) { |  | 
|   183     return index << kBitsPerCellLog2; |  | 
|   184   } |  | 
|   185  |  | 
|   186   INLINE(static uint32_t CellAlignIndex(uint32_t index)) { |  | 
|   187     return (index + kBitIndexMask) & ~kBitIndexMask; |  | 
|   188   } |  | 
|   189  |  | 
|   190   INLINE(MarkBit::CellType* cells()) { |  | 
|   191     return reinterpret_cast<MarkBit::CellType*>(this); |  | 
|   192   } |  | 
|   193  |  | 
|   194   INLINE(Address address()) { return reinterpret_cast<Address>(this); } |  | 
|   195  |  | 
|   196   INLINE(static Bitmap* FromAddress(Address addr)) { |  | 
|   197     return reinterpret_cast<Bitmap*>(addr); |  | 
|   198   } |  | 
|   199  |  | 
|   200   inline MarkBit MarkBitFromIndex(uint32_t index) { |  | 
|   201     MarkBit::CellType mask = 1u << IndexInCell(index); |  | 
|   202     MarkBit::CellType* cell = this->cells() + (index >> kBitsPerCellLog2); |  | 
|   203     return MarkBit(cell, mask); |  | 
|   204   } |  | 
|   205  |  | 
|   206   static inline void Clear(MemoryChunk* chunk); |  | 
|   207  |  | 
|   208   static inline void SetAllBits(MemoryChunk* chunk); |  | 
|   209  |  | 
|   210   static void PrintWord(uint32_t word, uint32_t himask = 0) { |  | 
|   211     for (uint32_t mask = 1; mask != 0; mask <<= 1) { |  | 
|   212       if ((mask & himask) != 0) PrintF("["); |  | 
|   213       PrintF((mask & word) ? "1" : "0"); |  | 
|   214       if ((mask & himask) != 0) PrintF("]"); |  | 
|   215     } |  | 
|   216   } |  | 
|   217  |  | 
|   218   class CellPrinter { |  | 
|   219    public: |  | 
|   220     CellPrinter() : seq_start(0), seq_type(0), seq_length(0) {} |  | 
|   221  |  | 
|   222     void Print(uint32_t pos, uint32_t cell) { |  | 
|   223       if (cell == seq_type) { |  | 
|   224         seq_length++; |  | 
|   225         return; |  | 
|   226       } |  | 
|   227  |  | 
|   228       Flush(); |  | 
|   229  |  | 
|   230       if (IsSeq(cell)) { |  | 
|   231         seq_start = pos; |  | 
|   232         seq_length = 0; |  | 
|   233         seq_type = cell; |  | 
|   234         return; |  | 
|   235       } |  | 
|   236  |  | 
|   237       PrintF("%d: ", pos); |  | 
|   238       PrintWord(cell); |  | 
|   239       PrintF("\n"); |  | 
|   240     } |  | 
|   241  |  | 
|   242     void Flush() { |  | 
|   243       if (seq_length > 0) { |  | 
|   244         PrintF("%d: %dx%d\n", seq_start, seq_type == 0 ? 0 : 1, |  | 
|   245                seq_length * kBitsPerCell); |  | 
|   246         seq_length = 0; |  | 
|   247       } |  | 
|   248     } |  | 
|   249  |  | 
|   250     static bool IsSeq(uint32_t cell) { return cell == 0 || cell == 0xFFFFFFFF; } |  | 
|   251  |  | 
|   252    private: |  | 
|   253     uint32_t seq_start; |  | 
|   254     uint32_t seq_type; |  | 
|   255     uint32_t seq_length; |  | 
|   256   }; |  | 
|   257  |  | 
|   258   void Print() { |  | 
|   259     CellPrinter printer; |  | 
|   260     for (int i = 0; i < CellsCount(); i++) { |  | 
|   261       printer.Print(i, cells()[i]); |  | 
|   262     } |  | 
|   263     printer.Flush(); |  | 
|   264     PrintF("\n"); |  | 
|   265   } |  | 
|   266  |  | 
|   267   bool IsClean() { |  | 
|   268     for (int i = 0; i < CellsCount(); i++) { |  | 
|   269       if (cells()[i] != 0) { |  | 
|   270         return false; |  | 
|   271       } |  | 
|   272     } |  | 
|   273     return true; |  | 
|   274   } |  | 
|   275  |  | 
|   276   // Clears all bits starting from {cell_base_index} up to and excluding |  | 
|   277   // {index}. Note that {cell_base_index} is required to be cell aligned. |  | 
|   278   void ClearRange(uint32_t cell_base_index, uint32_t index) { |  | 
|   279     DCHECK_EQ(IndexInCell(cell_base_index), 0u); |  | 
|   280     DCHECK_GE(index, cell_base_index); |  | 
|   281     uint32_t start_cell_index = IndexToCell(cell_base_index); |  | 
|   282     uint32_t end_cell_index = IndexToCell(index); |  | 
|   283     DCHECK_GE(end_cell_index, start_cell_index); |  | 
|   284     // Clear all cells till the cell containing the last index. |  | 
|   285     for (uint32_t i = start_cell_index; i < end_cell_index; i++) { |  | 
|   286       cells()[i] = 0; |  | 
|   287     } |  | 
|   288     // Clear all bits in the last cell till the last bit before index. |  | 
|   289     uint32_t clear_mask = ~((1u << IndexInCell(index)) - 1); |  | 
|   290     cells()[end_cell_index] &= clear_mask; |  | 
|   291   } |  | 
|   292 }; |  | 
|   293  |  | 
|   294 enum FreeListCategoryType { |   114 enum FreeListCategoryType { | 
|   295   kTiniest, |   115   kTiniest, | 
|   296   kTiny, |   116   kTiny, | 
|   297   kSmall, |   117   kSmall, | 
|   298   kMedium, |   118   kMedium, | 
|   299   kLarge, |   119   kLarge, | 
|   300   kHuge, |   120   kHuge, | 
|   301  |   121  | 
|   302   kFirstCategory = kTiniest, |   122   kFirstCategory = kTiniest, | 
|   303   kLastCategory = kHuge, |   123   kLastCategory = kHuge, | 
| (...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   690   } |   510   } | 
|   691  |   511  | 
|   692   inline uint32_t AddressToMarkbitIndex(Address addr) { |   512   inline uint32_t AddressToMarkbitIndex(Address addr) { | 
|   693     return static_cast<uint32_t>(addr - this->address()) >> kPointerSizeLog2; |   513     return static_cast<uint32_t>(addr - this->address()) >> kPointerSizeLog2; | 
|   694   } |   514   } | 
|   695  |   515  | 
|   696   inline Address MarkbitIndexToAddress(uint32_t index) { |   516   inline Address MarkbitIndexToAddress(uint32_t index) { | 
|   697     return this->address() + (index << kPointerSizeLog2); |   517     return this->address() + (index << kPointerSizeLog2); | 
|   698   } |   518   } | 
|   699  |   519  | 
 |   520   void ClearLiveness(); | 
 |   521  | 
|   700   void PrintMarkbits() { markbits()->Print(); } |   522   void PrintMarkbits() { markbits()->Print(); } | 
|   701  |   523  | 
|   702   void SetFlag(int flag) { flags_ |= static_cast<uintptr_t>(1) << flag; } |   524   void SetFlag(int flag) { flags_ |= static_cast<uintptr_t>(1) << flag; } | 
|   703  |   525  | 
|   704   void ClearFlag(int flag) { flags_ &= ~(static_cast<uintptr_t>(1) << flag); } |   526   void ClearFlag(int flag) { flags_ &= ~(static_cast<uintptr_t>(1) << flag); } | 
|   705  |   527  | 
|   706   bool IsFlagSet(int flag) { |   528   bool IsFlagSet(int flag) { | 
|   707     return (flags_ & (static_cast<uintptr_t>(1) << flag)) != 0; |   529     return (flags_ & (static_cast<uintptr_t>(1) << flag)) != 0; | 
|   708   } |   530   } | 
|   709  |   531  | 
| (...skipping 2459 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  3169     count = 0; |  2991     count = 0; | 
|  3170   } |  2992   } | 
|  3171   // Must be small, since an iteration is used for lookup. |  2993   // Must be small, since an iteration is used for lookup. | 
|  3172   static const int kMaxComments = 64; |  2994   static const int kMaxComments = 64; | 
|  3173 }; |  2995 }; | 
|  3174 #endif |  2996 #endif | 
|  3175 }  // namespace internal |  2997 }  // namespace internal | 
|  3176 }  // namespace v8 |  2998 }  // namespace v8 | 
|  3177  |  2999  | 
|  3178 #endif  // V8_HEAP_SPACES_H_ |  3000 #endif  // V8_HEAP_SPACES_H_ | 
| OLD | NEW |