| 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 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 284 | 284 |
| 285 bool IsClean() { | 285 bool IsClean() { |
| 286 for (int i = 0; i < CellsCount(); i++) { | 286 for (int i = 0; i < CellsCount(); i++) { |
| 287 if (cells()[i] != 0) return false; | 287 if (cells()[i] != 0) return false; |
| 288 } | 288 } |
| 289 return true; | 289 return true; |
| 290 } | 290 } |
| 291 }; | 291 }; |
| 292 | 292 |
| 293 | 293 |
| 294 class SlotsBuffer; |
| 295 |
| 294 // MemoryChunk represents a memory region owned by a specific space. | 296 // MemoryChunk represents a memory region owned by a specific space. |
| 295 // It is divided into the header and the body. Chunk start is always | 297 // It is divided into the header and the body. Chunk start is always |
| 296 // 1MB aligned. Start of the body is aligned so it can accomodate | 298 // 1MB aligned. Start of the body is aligned so it can accomodate |
| 297 // any heap object. | 299 // any heap object. |
| 298 class MemoryChunk { | 300 class MemoryChunk { |
| 299 public: | 301 public: |
| 300 // Only works if the pointer is in the first kPageSize of the MemoryChunk. | 302 // Only works if the pointer is in the first kPageSize of the MemoryChunk. |
| 301 static MemoryChunk* FromAddress(Address a) { | 303 static MemoryChunk* FromAddress(Address a) { |
| 302 return reinterpret_cast<MemoryChunk*>(OffsetFrom(a) & ~kAlignmentMask); | 304 return reinterpret_cast<MemoryChunk*>(OffsetFrom(a) & ~kAlignmentMask); |
| 303 } | 305 } |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 368 WAS_SWEPT_CONSERVATIVELY, | 370 WAS_SWEPT_CONSERVATIVELY, |
| 369 ABOUT_TO_BE_FREED, | 371 ABOUT_TO_BE_FREED, |
| 370 POINTERS_TO_HERE_ARE_INTERESTING, | 372 POINTERS_TO_HERE_ARE_INTERESTING, |
| 371 POINTERS_FROM_HERE_ARE_INTERESTING, | 373 POINTERS_FROM_HERE_ARE_INTERESTING, |
| 372 SCAN_ON_SCAVENGE, | 374 SCAN_ON_SCAVENGE, |
| 373 IN_FROM_SPACE, // Mutually exclusive with IN_TO_SPACE. | 375 IN_FROM_SPACE, // Mutually exclusive with IN_TO_SPACE. |
| 374 IN_TO_SPACE, // All pages in new space has one of these two set. | 376 IN_TO_SPACE, // All pages in new space has one of these two set. |
| 375 NEW_SPACE_BELOW_AGE_MARK, | 377 NEW_SPACE_BELOW_AGE_MARK, |
| 376 CONTAINS_ONLY_DATA, | 378 CONTAINS_ONLY_DATA, |
| 377 EVACUATION_CANDIDATE, | 379 EVACUATION_CANDIDATE, |
| 378 EVACUATED, | 380 RESCAN_ON_EVACUATION, |
| 381 WAS_SWEPT, |
| 379 NUM_MEMORY_CHUNK_FLAGS | 382 NUM_MEMORY_CHUNK_FLAGS |
| 380 }; | 383 }; |
| 381 | 384 |
| 382 | 385 |
| 383 static const int kPointersToHereAreInterestingMask = | 386 static const int kPointersToHereAreInterestingMask = |
| 384 1 << POINTERS_TO_HERE_ARE_INTERESTING; | 387 1 << POINTERS_TO_HERE_ARE_INTERESTING; |
| 385 | 388 |
| 386 static const int kPointersFromHereAreInterestingMask = | 389 static const int kPointersFromHereAreInterestingMask = |
| 387 1 << POINTERS_FROM_HERE_ARE_INTERESTING; | 390 1 << POINTERS_FROM_HERE_ARE_INTERESTING; |
| 388 | 391 |
| 389 static const int kEvacuationCandidateMask = | 392 static const int kEvacuationCandidateMask = |
| 390 1 << EVACUATION_CANDIDATE; | 393 1 << EVACUATION_CANDIDATE; |
| 391 | 394 |
| 392 static const int kEvacuationCandidateOrNewSpaceMask = | 395 static const int kSkipEvacuationSlotsRecordingMask = |
| 393 (1 << EVACUATION_CANDIDATE) | (1 << IN_FROM_SPACE) | (1 << IN_TO_SPACE); | 396 (1 << EVACUATION_CANDIDATE) | |
| 397 (1 << RESCAN_ON_EVACUATION) | |
| 398 (1 << IN_FROM_SPACE) | |
| 399 (1 << IN_TO_SPACE); |
| 394 | 400 |
| 395 | 401 |
| 396 void SetFlag(int flag) { | 402 void SetFlag(int flag) { |
| 397 flags_ |= static_cast<uintptr_t>(1) << flag; | 403 flags_ |= static_cast<uintptr_t>(1) << flag; |
| 398 } | 404 } |
| 399 | 405 |
| 400 void ClearFlag(int flag) { | 406 void ClearFlag(int flag) { |
| 401 flags_ &= ~(static_cast<uintptr_t>(1) << flag); | 407 flags_ &= ~(static_cast<uintptr_t>(1) << flag); |
| 402 } | 408 } |
| 403 | 409 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 438 | 444 |
| 439 static const intptr_t kAlignment = | 445 static const intptr_t kAlignment = |
| 440 (static_cast<uintptr_t>(1) << kPageSizeBits); | 446 (static_cast<uintptr_t>(1) << kPageSizeBits); |
| 441 | 447 |
| 442 static const intptr_t kAlignmentMask = kAlignment - 1; | 448 static const intptr_t kAlignmentMask = kAlignment - 1; |
| 443 | 449 |
| 444 static const intptr_t kLiveBytesOffset = | 450 static const intptr_t kLiveBytesOffset = |
| 445 kPointerSize + kPointerSize + kPointerSize + kPointerSize + | 451 kPointerSize + kPointerSize + kPointerSize + kPointerSize + |
| 446 kPointerSize + kPointerSize + kIntSize; | 452 kPointerSize + kPointerSize + kIntSize; |
| 447 | 453 |
| 448 static const size_t kHeaderSize = kLiveBytesOffset + kIntSize; | 454 static const size_t kSlotsBufferOffset = kLiveBytesOffset + kIntSize; |
| 455 |
| 456 static const size_t kHeaderSize = kSlotsBufferOffset + kPointerSize; |
| 449 | 457 |
| 450 static const int kBodyOffset = | 458 static const int kBodyOffset = |
| 451 CODE_POINTER_ALIGN(MAP_POINTER_ALIGN(kHeaderSize + Bitmap::kSize)); | 459 CODE_POINTER_ALIGN(MAP_POINTER_ALIGN(kHeaderSize + Bitmap::kSize)); |
| 452 | 460 |
| 453 // The start offset of the object area in a page. Aligned to both maps and | 461 // The start offset of the object area in a page. Aligned to both maps and |
| 454 // code alignment to be suitable for both. Also aligned to 32 words because | 462 // code alignment to be suitable for both. Also aligned to 32 words because |
| 455 // the marking bitmap is arranged in 32 bit chunks. | 463 // the marking bitmap is arranged in 32 bit chunks. |
| 456 static const int kObjectStartAlignment = 32 * kPointerSize; | 464 static const int kObjectStartAlignment = 32 * kPointerSize; |
| 457 static const int kObjectStartOffset = kBodyOffset - 1 + | 465 static const int kObjectStartOffset = kBodyOffset - 1 + |
| 458 (kObjectStartAlignment - (kBodyOffset - 1) % kObjectStartAlignment); | 466 (kObjectStartAlignment - (kBodyOffset - 1) % kObjectStartAlignment); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 503 return this->address() + (index << kPointerSizeLog2); | 511 return this->address() + (index << kPointerSizeLog2); |
| 504 } | 512 } |
| 505 | 513 |
| 506 void InsertAfter(MemoryChunk* other); | 514 void InsertAfter(MemoryChunk* other); |
| 507 void Unlink(); | 515 void Unlink(); |
| 508 | 516 |
| 509 inline Heap* heap() { return heap_; } | 517 inline Heap* heap() { return heap_; } |
| 510 | 518 |
| 511 static const int kFlagsOffset = kPointerSize * 3; | 519 static const int kFlagsOffset = kPointerSize * 3; |
| 512 | 520 |
| 521 bool IsEvacuationCandidate() { return IsFlagSet(EVACUATION_CANDIDATE); } |
| 522 |
| 523 bool ShouldSkipEvacuationSlotRecording() { |
| 524 return (flags_ & kSkipEvacuationSlotsRecordingMask) != 0; |
| 525 } |
| 526 |
| 527 inline SlotsBuffer* slots_buffer() { |
| 528 return slots_buffer_; |
| 529 } |
| 530 |
| 531 inline SlotsBuffer** slots_buffer_address() { |
| 532 return &slots_buffer_; |
| 533 } |
| 534 |
| 535 void MarkEvacuationCandidate() { |
| 536 ASSERT(slots_buffer_ == NULL); |
| 537 SetFlag(EVACUATION_CANDIDATE); |
| 538 } |
| 539 |
| 540 void ClearEvacuationCandidate() { |
| 541 ASSERT(slots_buffer_ == NULL); |
| 542 ClearFlag(EVACUATION_CANDIDATE); |
| 543 } |
| 544 |
| 545 |
| 513 protected: | 546 protected: |
| 514 MemoryChunk* next_chunk_; | 547 MemoryChunk* next_chunk_; |
| 515 MemoryChunk* prev_chunk_; | 548 MemoryChunk* prev_chunk_; |
| 516 size_t size_; | 549 size_t size_; |
| 517 intptr_t flags_; | 550 intptr_t flags_; |
| 518 // The identity of the owning space. This is tagged as a failure pointer, but | 551 // The identity of the owning space. This is tagged as a failure pointer, but |
| 519 // no failure can be in an object, so this can be distinguished from any entry | 552 // no failure can be in an object, so this can be distinguished from any entry |
| 520 // in a fixed array. | 553 // in a fixed array. |
| 521 Address owner_; | 554 Address owner_; |
| 522 Heap* heap_; | 555 Heap* heap_; |
| 523 // Used by the store buffer to keep track of which pages to mark scan-on- | 556 // Used by the store buffer to keep track of which pages to mark scan-on- |
| 524 // scavenge. | 557 // scavenge. |
| 525 int store_buffer_counter_; | 558 int store_buffer_counter_; |
| 526 // Count of bytes marked black on page. | 559 // Count of bytes marked black on page. |
| 527 int live_byte_count_; | 560 int live_byte_count_; |
| 561 SlotsBuffer* slots_buffer_; |
| 528 | 562 |
| 529 static MemoryChunk* Initialize(Heap* heap, | 563 static MemoryChunk* Initialize(Heap* heap, |
| 530 Address base, | 564 Address base, |
| 531 size_t size, | 565 size_t size, |
| 532 Executability executable, | 566 Executability executable, |
| 533 Space* owner); | 567 Space* owner); |
| 534 | 568 |
| 535 friend class MemoryAllocator; | 569 friend class MemoryAllocator; |
| 536 }; | 570 }; |
| 537 | 571 |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 616 | 650 |
| 617 inline void ClearGCFields(); | 651 inline void ClearGCFields(); |
| 618 | 652 |
| 619 static inline Page* Initialize(Heap* heap, | 653 static inline Page* Initialize(Heap* heap, |
| 620 MemoryChunk* chunk, | 654 MemoryChunk* chunk, |
| 621 Executability executable, | 655 Executability executable, |
| 622 PagedSpace* owner); | 656 PagedSpace* owner); |
| 623 | 657 |
| 624 void InitializeAsAnchor(PagedSpace* owner); | 658 void InitializeAsAnchor(PagedSpace* owner); |
| 625 | 659 |
| 626 bool IsEvacuationCandidate() { return IsFlagSet(EVACUATION_CANDIDATE); } | 660 bool WasSwept() { return IsFlagSet(WAS_SWEPT); } |
| 627 | 661 |
| 628 bool IsEvacuationCandidateOrNewSpace() { | 662 void MarkSwept() { SetFlag(WAS_SWEPT); } |
| 629 return (flags_ & kEvacuationCandidateOrNewSpaceMask) != 0; | |
| 630 } | |
| 631 | 663 |
| 632 void MarkEvacuationCandidate() { SetFlag(EVACUATION_CANDIDATE); } | 664 void ClearSwept() { ClearFlag(WAS_SWEPT); } |
| 633 | |
| 634 void ClearEvacuationCandidate() { ClearFlag(EVACUATION_CANDIDATE); } | |
| 635 | |
| 636 bool WasEvacuated() { return IsFlagSet(EVACUATED); } | |
| 637 | |
| 638 void MarkEvacuated() { SetFlag(EVACUATED); } | |
| 639 | |
| 640 void ClearEvacuated() { ClearFlag(EVACUATED); } | |
| 641 | 665 |
| 642 friend class MemoryAllocator; | 666 friend class MemoryAllocator; |
| 643 }; | 667 }; |
| 644 | 668 |
| 645 | 669 |
| 646 STATIC_CHECK(sizeof(Page) <= MemoryChunk::kHeaderSize); | 670 STATIC_CHECK(sizeof(Page) <= MemoryChunk::kHeaderSize); |
| 647 | 671 |
| 648 | 672 |
| 649 class LargePage : public MemoryChunk { | 673 class LargePage : public MemoryChunk { |
| 650 public: | 674 public: |
| (...skipping 1267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1918 // | 1942 // |
| 1919 // The new space consists of a contiguous pair of semispaces. It simply | 1943 // The new space consists of a contiguous pair of semispaces. It simply |
| 1920 // forwards most functions to the appropriate semispace. | 1944 // forwards most functions to the appropriate semispace. |
| 1921 | 1945 |
| 1922 class NewSpace : public Space { | 1946 class NewSpace : public Space { |
| 1923 public: | 1947 public: |
| 1924 // Constructor. | 1948 // Constructor. |
| 1925 explicit NewSpace(Heap* heap) | 1949 explicit NewSpace(Heap* heap) |
| 1926 : Space(heap, NEW_SPACE, NOT_EXECUTABLE), | 1950 : Space(heap, NEW_SPACE, NOT_EXECUTABLE), |
| 1927 to_space_(heap, kToSpace), | 1951 to_space_(heap, kToSpace), |
| 1928 from_space_(heap, kFromSpace) {} | 1952 from_space_(heap, kFromSpace), |
| 1953 inline_allocation_limit_step_(0) {} |
| 1929 | 1954 |
| 1930 // Sets up the new space using the given chunk. | 1955 // Sets up the new space using the given chunk. |
| 1931 bool Setup(int max_semispace_size); | 1956 bool Setup(int max_semispace_size); |
| 1932 | 1957 |
| 1933 // Tears down the space. Heap memory was not allocated by the space, so it | 1958 // Tears down the space. Heap memory was not allocated by the space, so it |
| 1934 // is not deallocated here. | 1959 // is not deallocated here. |
| 1935 void TearDown(); | 1960 void TearDown(); |
| 1936 | 1961 |
| 1937 // True if the space has been set up but not torn down. | 1962 // True if the space has been set up but not torn down. |
| 1938 bool HasBeenSetup() { | 1963 bool HasBeenSetup() { |
| (...skipping 603 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2542 } | 2567 } |
| 2543 // Must be small, since an iteration is used for lookup. | 2568 // Must be small, since an iteration is used for lookup. |
| 2544 static const int kMaxComments = 64; | 2569 static const int kMaxComments = 64; |
| 2545 }; | 2570 }; |
| 2546 #endif | 2571 #endif |
| 2547 | 2572 |
| 2548 | 2573 |
| 2549 } } // namespace v8::internal | 2574 } } // namespace v8::internal |
| 2550 | 2575 |
| 2551 #endif // V8_SPACES_H_ | 2576 #endif // V8_SPACES_H_ |
| OLD | NEW |