| 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 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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; |
| 117 class MemoryAllocator; | 117 class MemoryAllocator; |
| 118 class AllocationInfo; | 118 class AllocationInfo; |
| 119 class Space; | 119 class Space; |
| 120 class FreeList; | 120 class FreeList; |
| 121 | 121 class MemoryChunk; |
| 122 | 122 |
| 123 // TODO(gc): Check that this all gets inlined and register allocated on | 123 // TODO(gc): Check that this all gets inlined and register allocated on |
| 124 // all platforms. | 124 // all platforms. |
| 125 class MarkBit { | 125 class MarkBit { |
| 126 public: | 126 public: |
| 127 typedef uint32_t CellType; | 127 typedef uint32_t CellType; |
| 128 | 128 |
| 129 inline MarkBit(CellType* cell, CellType mask, bool data_only) | 129 inline MarkBit(CellType* cell, CellType mask, bool data_only) |
| 130 : cell_(cell), mask_(mask), data_only_(data_only) { } | 130 : cell_(cell), mask_(mask), data_only_(data_only) { } |
| 131 | 131 |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 215 INLINE(static Bitmap* FromAddress(Address addr)) { | 215 INLINE(static Bitmap* FromAddress(Address addr)) { |
| 216 return reinterpret_cast<Bitmap*>(addr); | 216 return reinterpret_cast<Bitmap*>(addr); |
| 217 } | 217 } |
| 218 | 218 |
| 219 inline MarkBit MarkBitFromIndex(uint32_t index, bool data_only = false) { | 219 inline MarkBit MarkBitFromIndex(uint32_t index, bool data_only = false) { |
| 220 MarkBit::CellType mask = 1 << (index & kBitIndexMask); | 220 MarkBit::CellType mask = 1 << (index & kBitIndexMask); |
| 221 MarkBit::CellType* cell = this->cells() + (index >> kBitsPerCellLog2); | 221 MarkBit::CellType* cell = this->cells() + (index >> kBitsPerCellLog2); |
| 222 return MarkBit(cell, mask, data_only); | 222 return MarkBit(cell, mask, data_only); |
| 223 } | 223 } |
| 224 | 224 |
| 225 INLINE(void ClearRange(uint32_t start, uint32_t size)) { | 225 static inline void Clear(MemoryChunk* chunk); |
| 226 const uint32_t end = start + size; | |
| 227 const uint32_t start_cell = start >> kBitsPerCellLog2; | |
| 228 const uint32_t end_cell = end >> kBitsPerCellLog2; | |
| 229 ASSERT((start & kBitIndexMask) == 0); | |
| 230 ASSERT((end & kBitIndexMask) == 0); | |
| 231 | |
| 232 ASSERT(static_cast<int>(start_cell) < CellsCount()); | |
| 233 ASSERT(static_cast<int>(end_cell) <= CellsCount()); | |
| 234 | |
| 235 for (uint32_t cell = start_cell; cell < end_cell; cell++) { | |
| 236 cells()[cell] = 0; | |
| 237 } | |
| 238 } | |
| 239 | |
| 240 INLINE(void Clear()) { | |
| 241 for (int i = 0; i < CellsCount(); i++) cells()[i] = 0; | |
| 242 } | |
| 243 | 226 |
| 244 static void PrintWord(uint32_t word, uint32_t himask = 0) { | 227 static void PrintWord(uint32_t word, uint32_t himask = 0) { |
| 245 for (uint32_t mask = 1; mask != 0; mask <<= 1) { | 228 for (uint32_t mask = 1; mask != 0; mask <<= 1) { |
| 246 if ((mask & himask) != 0) PrintF("["); | 229 if ((mask & himask) != 0) PrintF("["); |
| 247 PrintF((mask & word) ? "1" : "0"); | 230 PrintF((mask & word) ? "1" : "0"); |
| 248 if ((mask & himask) != 0) PrintF("]"); | 231 if ((mask & himask) != 0) PrintF("]"); |
| 249 } | 232 } |
| 250 } | 233 } |
| 251 | 234 |
| 252 class CellPrinter { | 235 class CellPrinter { |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 418 // Set or clear multiple flags at a time. The flags in the mask | 401 // Set or clear multiple flags at a time. The flags in the mask |
| 419 // are set to the value in "flags", the rest retain the current value | 402 // are set to the value in "flags", the rest retain the current value |
| 420 // in flags_. | 403 // in flags_. |
| 421 void SetFlags(intptr_t flags, intptr_t mask) { | 404 void SetFlags(intptr_t flags, intptr_t mask) { |
| 422 flags_ = (flags_ & ~mask) | (flags & mask); | 405 flags_ = (flags_ & ~mask) | (flags & mask); |
| 423 } | 406 } |
| 424 | 407 |
| 425 // Return all current flags. | 408 // Return all current flags. |
| 426 intptr_t GetFlags() { return flags_; } | 409 intptr_t GetFlags() { return flags_; } |
| 427 | 410 |
| 411 // Manage live byte count (count of bytes known to be live, |
| 412 // because they are marked black). |
| 413 void ResetLiveBytes() { |
| 414 live_byte_count_ = 0; |
| 415 } |
| 416 void IncrementLiveBytes(int by) { |
| 417 live_byte_count_ += by; |
| 418 } |
| 419 int LiveBytes() { return live_byte_count_; } |
| 420 static void IncrementLiveBytes(Address address, int by) { |
| 421 MemoryChunk::FromAddress(address)->IncrementLiveBytes(by); |
| 422 } |
| 423 |
| 428 static const intptr_t kAlignment = (1 << kPageSizeBits); | 424 static const intptr_t kAlignment = (1 << kPageSizeBits); |
| 429 | 425 |
| 430 static const intptr_t kAlignmentMask = kAlignment - 1; | 426 static const intptr_t kAlignmentMask = kAlignment - 1; |
| 431 | 427 |
| 432 static const size_t kHeaderSize = kPointerSize + kPointerSize + kPointerSize + | 428 static const intptr_t kLiveBytesOffset = |
| 433 kPointerSize + kPointerSize + kPointerSize + kPointerSize + kPointerSize; | 429 kPointerSize + kPointerSize + kPointerSize + kPointerSize + |
| 430 kPointerSize + kPointerSize + kIntSize; |
| 431 |
| 432 static const size_t kHeaderSize = kLiveBytesOffset + kIntSize; |
| 434 | 433 |
| 435 static const int kBodyOffset = | 434 static const int kBodyOffset = |
| 436 CODE_POINTER_ALIGN(MAP_POINTER_ALIGN(kHeaderSize + Bitmap::kSize)); | 435 CODE_POINTER_ALIGN(MAP_POINTER_ALIGN(kHeaderSize + Bitmap::kSize)); |
| 437 | 436 |
| 438 // The start offset of the object area in a page. Aligned to both maps and | 437 // The start offset of the object area in a page. Aligned to both maps and |
| 439 // code alignment to be suitable for both. Also aligned to 32 words because | 438 // code alignment to be suitable for both. Also aligned to 32 words because |
| 440 // the marking bitmap is arranged in 32 bit chunks. | 439 // the marking bitmap is arranged in 32 bit chunks. |
| 441 static const int kObjectStartAlignment = 32 * kPointerSize; | 440 static const int kObjectStartAlignment = 32 * kPointerSize; |
| 442 static const int kObjectStartOffset = kBodyOffset - 1 + | 441 static const int kObjectStartOffset = kBodyOffset - 1 + |
| 443 (kObjectStartAlignment - (kBodyOffset - 1) % kObjectStartAlignment); | 442 (kObjectStartAlignment - (kBodyOffset - 1) % kObjectStartAlignment); |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 501 size_t size_; | 500 size_t size_; |
| 502 intptr_t flags_; | 501 intptr_t flags_; |
| 503 // The identity of the owning space. This is tagged as a failure pointer, but | 502 // The identity of the owning space. This is tagged as a failure pointer, but |
| 504 // no failure can be in an object, so this can be distinguished from any entry | 503 // no failure can be in an object, so this can be distinguished from any entry |
| 505 // in a fixed array. | 504 // in a fixed array. |
| 506 Address owner_; | 505 Address owner_; |
| 507 Heap* heap_; | 506 Heap* heap_; |
| 508 // Used by the store buffer to keep track of which pages to mark scan-on- | 507 // Used by the store buffer to keep track of which pages to mark scan-on- |
| 509 // scavenge. | 508 // scavenge. |
| 510 int store_buffer_counter_; | 509 int store_buffer_counter_; |
| 510 // Count of bytes marked black on page. |
| 511 int live_byte_count_; |
| 511 | 512 |
| 512 static MemoryChunk* Initialize(Heap* heap, | 513 static MemoryChunk* Initialize(Heap* heap, |
| 513 Address base, | 514 Address base, |
| 514 size_t size, | 515 size_t size, |
| 515 Executability executable, | 516 Executability executable, |
| 516 Space* owner); | 517 Space* owner); |
| 517 | 518 |
| 518 friend class MemoryAllocator; | 519 friend class MemoryAllocator; |
| 519 }; | 520 }; |
| 520 | 521 |
| (...skipping 906 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1427 bool IsFragmented(Page* p) { | 1428 bool IsFragmented(Page* p) { |
| 1428 intptr_t sizes[4]; | 1429 intptr_t sizes[4]; |
| 1429 free_list_.CountFreeListItems(p, sizes); | 1430 free_list_.CountFreeListItems(p, sizes); |
| 1430 | 1431 |
| 1431 intptr_t ratio = | 1432 intptr_t ratio = |
| 1432 (sizes[0] * 5 + sizes[1]) * 100 / Page::kObjectAreaSize; | 1433 (sizes[0] * 5 + sizes[1]) * 100 / Page::kObjectAreaSize; |
| 1433 | 1434 |
| 1434 if (FLAG_trace_fragmentation) { | 1435 if (FLAG_trace_fragmentation) { |
| 1435 PrintF("%p: %d (%.2f%%) %d (%.2f%%) %d (%.2f%%) %d (%.2f%%) %s\n", | 1436 PrintF("%p: %d (%.2f%%) %d (%.2f%%) %d (%.2f%%) %d (%.2f%%) %s\n", |
| 1436 reinterpret_cast<void*>(p), | 1437 reinterpret_cast<void*>(p), |
| 1437 sizes[0], | 1438 static_cast<int>(sizes[0]), |
| 1438 static_cast<double>(sizes[0] * 100) / Page::kObjectAreaSize, | 1439 static_cast<double>(sizes[0] * 100) / Page::kObjectAreaSize, |
| 1439 sizes[1], | 1440 static_cast<int>(sizes[1]), |
| 1440 static_cast<double>(sizes[1] * 100) / Page::kObjectAreaSize, | 1441 static_cast<double>(sizes[1] * 100) / Page::kObjectAreaSize, |
| 1441 sizes[2], | 1442 static_cast<int>(sizes[2]), |
| 1442 static_cast<double>(sizes[2] * 100) / Page::kObjectAreaSize, | 1443 static_cast<double>(sizes[2] * 100) / Page::kObjectAreaSize, |
| 1443 sizes[3], | 1444 static_cast<int>(sizes[3]), |
| 1444 static_cast<double>(sizes[3] * 100) / Page::kObjectAreaSize, | 1445 static_cast<double>(sizes[3] * 100) / Page::kObjectAreaSize, |
| 1445 (ratio > 15) ? "[fragmented]" : ""); | 1446 (ratio > 15) ? "[fragmented]" : ""); |
| 1446 } | 1447 } |
| 1447 | 1448 |
| 1448 return ratio > 15; | 1449 return ratio > 15; |
| 1449 } | 1450 } |
| 1450 | 1451 |
| 1451 protected: | 1452 protected: |
| 1452 // Maximum capacity of this space. | 1453 // Maximum capacity of this space. |
| 1453 intptr_t max_capacity_; | 1454 intptr_t max_capacity_; |
| (...skipping 1064 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2518 } | 2519 } |
| 2519 // Must be small, since an iteration is used for lookup. | 2520 // Must be small, since an iteration is used for lookup. |
| 2520 static const int kMaxComments = 64; | 2521 static const int kMaxComments = 64; |
| 2521 }; | 2522 }; |
| 2522 #endif | 2523 #endif |
| 2523 | 2524 |
| 2524 | 2525 |
| 2525 } } // namespace v8::internal | 2526 } } // namespace v8::internal |
| 2526 | 2527 |
| 2527 #endif // V8_SPACES_H_ | 2528 #endif // V8_SPACES_H_ |
| OLD | NEW |