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 |