OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
442 size_t payloadSize() | 442 size_t payloadSize() |
443 { | 443 { |
444 return (blinkPagePayloadSize() - pageHeaderSize()) & ~allocationMask; | 444 return (blinkPagePayloadSize() - pageHeaderSize()) & ~allocationMask; |
445 } | 445 } |
446 Address payloadEnd() { return payload() + payloadSize(); } | 446 Address payloadEnd() { return payload() + payloadSize(); } |
447 bool containedInObjectPayload(Address address) | 447 bool containedInObjectPayload(Address address) |
448 { | 448 { |
449 return payload() <= address && address < payloadEnd(); | 449 return payload() <= address && address < payloadEnd(); |
450 } | 450 } |
451 | 451 |
452 virtual size_t objectPayloadSizeForTesting() override; | 452 size_t objectPayloadSizeForTesting() override; |
453 virtual bool isEmpty() override; | 453 bool isEmpty() override; |
454 virtual void removeFromHeap() override; | 454 void removeFromHeap() override; |
455 virtual void sweep() override; | 455 void sweep() override; |
456 virtual void makeConsistentForGC() override; | 456 void makeConsistentForGC() override; |
457 virtual void makeConsistentForMutator() override; | 457 void makeConsistentForMutator() override; |
458 #if defined(ADDRESS_SANITIZER) | 458 #if defined(ADDRESS_SANITIZER) |
459 virtual void poisonObjects(ThreadState::ObjectsToPoison, ThreadState::Poison
ing) override; | 459 void poisonObjects(ThreadState::ObjectsToPoison, ThreadState::Poisoning) ove
rride; |
460 #endif | 460 #endif |
461 virtual void checkAndMarkPointer(Visitor*, Address) override; | 461 void checkAndMarkPointer(Visitor*, Address) override; |
462 virtual void markOrphaned() override; | 462 void markOrphaned() override; |
463 | 463 |
464 void takeSnapshot(String dumpBaseName, size_t pageIndex, size_t* outFreeSize
, size_t* outFreeCount) override; | 464 void takeSnapshot(String dumpBaseName, size_t pageIndex, size_t* outFreeSize
, size_t* outFreeCount) override; |
465 #if ENABLE(GC_PROFILING) | 465 #if ENABLE(GC_PROFILING) |
466 const GCInfo* findGCInfo(Address) override; | 466 const GCInfo* findGCInfo(Address) override; |
467 void snapshot(TracedValue*, ThreadState::SnapshotInfo*) override; | 467 void snapshot(TracedValue*, ThreadState::SnapshotInfo*) override; |
468 void incrementMarkedObjectsAge() override; | 468 void incrementMarkedObjectsAge() override; |
469 void countMarkedObjects(ClassAgeCountsMap&) override; | 469 void countMarkedObjects(ClassAgeCountsMap&) override; |
470 void countObjectsToSweep(ClassAgeCountsMap&) override; | 470 void countObjectsToSweep(ClassAgeCountsMap&) override; |
471 #endif | 471 #endif |
472 #if ENABLE(ASSERT) || ENABLE(GC_PROFILING) | 472 #if ENABLE(ASSERT) || ENABLE(GC_PROFILING) |
473 // Returns true for the whole blinkPageSize page that the page is on, even | 473 // Returns true for the whole blinkPageSize page that the page is on, even |
474 // for the header, and the unmapped guard page at the start. That ensures | 474 // for the header, and the unmapped guard page at the start. That ensures |
475 // the result can be used to populate the negative page cache. | 475 // the result can be used to populate the negative page cache. |
476 virtual bool contains(Address) override; | 476 bool contains(Address) override; |
477 #endif | 477 #endif |
478 virtual size_t size() override { return blinkPageSize; } | 478 size_t size() override { return blinkPageSize; } |
479 static size_t pageHeaderSize() | 479 static size_t pageHeaderSize() |
480 { | 480 { |
481 // Compute the amount of padding we have to add to a header to make | 481 // Compute the amount of padding we have to add to a header to make |
482 // the size of the header plus the padding a multiple of 8 bytes. | 482 // the size of the header plus the padding a multiple of 8 bytes. |
483 size_t paddingSize = (sizeof(NormalPage) + allocationGranularity - (size
of(HeapObjectHeader) % allocationGranularity)) % allocationGranularity; | 483 size_t paddingSize = (sizeof(NormalPage) + allocationGranularity - (size
of(HeapObjectHeader) % allocationGranularity)) % allocationGranularity; |
484 return sizeof(NormalPage) + paddingSize; | 484 return sizeof(NormalPage) + paddingSize; |
485 } | 485 } |
486 | 486 |
487 | 487 |
488 NormalPageHeap* heapForNormalPage(); | 488 NormalPageHeap* heapForNormalPage(); |
(...skipping 18 matching lines...) Expand all Loading... |
507 LargeObjectPage(PageMemory*, BaseHeap*, size_t); | 507 LargeObjectPage(PageMemory*, BaseHeap*, size_t); |
508 | 508 |
509 Address payload() { return heapObjectHeader()->payload(); } | 509 Address payload() { return heapObjectHeader()->payload(); } |
510 size_t payloadSize() { return m_payloadSize; } | 510 size_t payloadSize() { return m_payloadSize; } |
511 Address payloadEnd() { return payload() + payloadSize(); } | 511 Address payloadEnd() { return payload() + payloadSize(); } |
512 bool containedInObjectPayload(Address address) | 512 bool containedInObjectPayload(Address address) |
513 { | 513 { |
514 return payload() <= address && address < payloadEnd(); | 514 return payload() <= address && address < payloadEnd(); |
515 } | 515 } |
516 | 516 |
517 virtual size_t objectPayloadSizeForTesting() override; | 517 size_t objectPayloadSizeForTesting() override; |
518 virtual bool isEmpty() override; | 518 bool isEmpty() override; |
519 virtual void removeFromHeap() override; | 519 void removeFromHeap() override; |
520 virtual void sweep() override; | 520 void sweep() override; |
521 virtual void makeConsistentForGC() override; | 521 void makeConsistentForGC() override; |
522 virtual void makeConsistentForMutator() override; | 522 void makeConsistentForMutator() override; |
523 #if defined(ADDRESS_SANITIZER) | 523 #if defined(ADDRESS_SANITIZER) |
524 virtual void poisonObjects(ThreadState::ObjectsToPoison, ThreadState::Poison
ing) override; | 524 void poisonObjects(ThreadState::ObjectsToPoison, ThreadState::Poisoning) ove
rride; |
525 #endif | 525 #endif |
526 virtual void checkAndMarkPointer(Visitor*, Address) override; | 526 void checkAndMarkPointer(Visitor*, Address) override; |
527 virtual void markOrphaned() override; | 527 void markOrphaned() override; |
528 | 528 |
529 void takeSnapshot(String dumpBaseName, size_t pageIndex, size_t* outFreeSize
, size_t* outFreeCount) override; | 529 void takeSnapshot(String dumpBaseName, size_t pageIndex, size_t* outFreeSize
, size_t* outFreeCount) override; |
530 #if ENABLE(GC_PROFILING) | 530 #if ENABLE(GC_PROFILING) |
531 const GCInfo* findGCInfo(Address) override; | 531 const GCInfo* findGCInfo(Address) override; |
532 void snapshot(TracedValue*, ThreadState::SnapshotInfo*) override; | 532 void snapshot(TracedValue*, ThreadState::SnapshotInfo*) override; |
533 void incrementMarkedObjectsAge() override; | 533 void incrementMarkedObjectsAge() override; |
534 void countMarkedObjects(ClassAgeCountsMap&) override; | 534 void countMarkedObjects(ClassAgeCountsMap&) override; |
535 void countObjectsToSweep(ClassAgeCountsMap&) override; | 535 void countObjectsToSweep(ClassAgeCountsMap&) override; |
536 #endif | 536 #endif |
537 #if ENABLE(ASSERT) || ENABLE(GC_PROFILING) | 537 #if ENABLE(ASSERT) || ENABLE(GC_PROFILING) |
538 // Returns true for any address that is on one of the pages that this | 538 // Returns true for any address that is on one of the pages that this |
539 // large object uses. That ensures that we can use a negative result to | 539 // large object uses. That ensures that we can use a negative result to |
540 // populate the negative page cache. | 540 // populate the negative page cache. |
541 virtual bool contains(Address) override; | 541 bool contains(Address) override; |
542 #endif | 542 #endif |
543 virtual size_t size() | 543 virtual size_t size() |
544 { | 544 { |
545 return pageHeaderSize() + sizeof(HeapObjectHeader) + m_payloadSize; | 545 return pageHeaderSize() + sizeof(HeapObjectHeader) + m_payloadSize; |
546 } | 546 } |
547 static size_t pageHeaderSize() | 547 static size_t pageHeaderSize() |
548 { | 548 { |
549 // Compute the amount of padding we have to add to a header to make | 549 // Compute the amount of padding we have to add to a header to make |
550 // the size of the header plus the padding a multiple of 8 bytes. | 550 // the size of the header plus the padding a multiple of 8 bytes. |
551 size_t paddingSize = (sizeof(LargeObjectPage) + allocationGranularity -
(sizeof(HeapObjectHeader) % allocationGranularity)) % allocationGranularity; | 551 size_t paddingSize = (sizeof(LargeObjectPage) + allocationGranularity -
(sizeof(HeapObjectHeader) % allocationGranularity)) % allocationGranularity; |
552 return sizeof(LargeObjectPage) + paddingSize; | 552 return sizeof(LargeObjectPage) + paddingSize; |
553 } | 553 } |
554 virtual bool isLargeObjectPage() override { return true; } | 554 bool isLargeObjectPage() override { return true; } |
555 | 555 |
556 HeapObjectHeader* heapObjectHeader() | 556 HeapObjectHeader* heapObjectHeader() |
557 { | 557 { |
558 Address headerAddress = address() + pageHeaderSize(); | 558 Address headerAddress = address() + pageHeaderSize(); |
559 return reinterpret_cast<HeapObjectHeader*>(headerAddress); | 559 return reinterpret_cast<HeapObjectHeader*>(headerAddress); |
560 } | 560 } |
561 | 561 |
562 #ifdef ANNOTATE_CONTIGUOUS_CONTAINER | 562 #ifdef ANNOTATE_CONTIGUOUS_CONTAINER |
563 void setIsVectorBackingPage() { m_isVectorBackingPage = true; } | 563 void setIsVectorBackingPage() { m_isVectorBackingPage = true; } |
564 bool isVectorBackingPage() const { return m_isVectorBackingPage; } | 564 bool isVectorBackingPage() const { return m_isVectorBackingPage; } |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
724 | 724 |
725 class PLATFORM_EXPORT NormalPageHeap final : public BaseHeap { | 725 class PLATFORM_EXPORT NormalPageHeap final : public BaseHeap { |
726 public: | 726 public: |
727 NormalPageHeap(ThreadState*, int); | 727 NormalPageHeap(ThreadState*, int); |
728 void addToFreeList(Address address, size_t size) | 728 void addToFreeList(Address address, size_t size) |
729 { | 729 { |
730 ASSERT(findPageFromAddress(address)); | 730 ASSERT(findPageFromAddress(address)); |
731 ASSERT(findPageFromAddress(address + size - 1)); | 731 ASSERT(findPageFromAddress(address + size - 1)); |
732 m_freeList.addToFreeList(address, size); | 732 m_freeList.addToFreeList(address, size); |
733 } | 733 } |
734 virtual void clearFreeLists() override; | 734 void clearFreeLists() override; |
735 #if ENABLE(ASSERT) | 735 #if ENABLE(ASSERT) |
736 virtual bool isConsistentForGC() override; | 736 bool isConsistentForGC() override; |
737 bool pagesToBeSweptContains(Address); | 737 bool pagesToBeSweptContains(Address); |
738 #endif | 738 #endif |
739 void takeFreelistSnapshot(const String& dumpBaseName) override; | 739 void takeFreelistSnapshot(const String& dumpBaseName) override; |
740 #if ENABLE(GC_PROFILING) | 740 #if ENABLE(GC_PROFILING) |
741 void snapshotFreeList(TracedValue&) override; | 741 void snapshotFreeList(TracedValue&) override; |
742 #endif | 742 #endif |
743 | 743 |
744 Address allocateObject(size_t allocationSize, size_t gcInfoIndex); | 744 Address allocateObject(size_t allocationSize, size_t gcInfoIndex); |
745 | 745 |
746 void freePage(NormalPage*); | 746 void freePage(NormalPage*); |
747 | 747 |
748 bool coalesce(); | 748 bool coalesce(); |
749 void promptlyFreeObject(HeapObjectHeader*); | 749 void promptlyFreeObject(HeapObjectHeader*); |
750 bool expandObject(HeapObjectHeader*, size_t); | 750 bool expandObject(HeapObjectHeader*, size_t); |
751 bool shrinkObject(HeapObjectHeader*, size_t); | 751 bool shrinkObject(HeapObjectHeader*, size_t); |
752 void decreasePromptlyFreedSize(size_t size) { m_promptlyFreedSize -= size; } | 752 void decreasePromptlyFreedSize(size_t size) { m_promptlyFreedSize -= size; } |
753 | 753 |
754 private: | 754 private: |
755 void allocatePage(); | 755 void allocatePage(); |
756 virtual Address lazySweepPages(size_t, size_t gcInfoIndex) override; | 756 Address lazySweepPages(size_t, size_t gcInfoIndex) override; |
757 Address outOfLineAllocate(size_t allocationSize, size_t gcInfoIndex); | 757 Address outOfLineAllocate(size_t allocationSize, size_t gcInfoIndex); |
758 Address currentAllocationPoint() const { return m_currentAllocationPoint; } | 758 Address currentAllocationPoint() const { return m_currentAllocationPoint; } |
759 size_t remainingAllocationSize() const { return m_remainingAllocationSize; } | 759 size_t remainingAllocationSize() const { return m_remainingAllocationSize; } |
760 bool hasCurrentAllocationArea() const { return currentAllocationPoint() && r
emainingAllocationSize(); } | 760 bool hasCurrentAllocationArea() const { return currentAllocationPoint() && r
emainingAllocationSize(); } |
761 void setAllocationPoint(Address, size_t); | 761 void setAllocationPoint(Address, size_t); |
762 void updateRemainingAllocationSize(); | 762 void updateRemainingAllocationSize(); |
763 Address allocateFromFreeList(size_t, size_t gcInfoIndex); | 763 Address allocateFromFreeList(size_t, size_t gcInfoIndex); |
764 | 764 |
765 FreeList m_freeList; | 765 FreeList m_freeList; |
766 Address m_currentAllocationPoint; | 766 Address m_currentAllocationPoint; |
767 size_t m_remainingAllocationSize; | 767 size_t m_remainingAllocationSize; |
768 size_t m_lastRemainingAllocationSize; | 768 size_t m_lastRemainingAllocationSize; |
769 | 769 |
770 // The size of promptly freed objects in the heap. | 770 // The size of promptly freed objects in the heap. |
771 size_t m_promptlyFreedSize; | 771 size_t m_promptlyFreedSize; |
772 | 772 |
773 #if ENABLE(GC_PROFILING) | 773 #if ENABLE(GC_PROFILING) |
774 size_t m_cumulativeAllocationSize; | 774 size_t m_cumulativeAllocationSize; |
775 size_t m_allocationCount; | 775 size_t m_allocationCount; |
776 size_t m_inlineAllocationCount; | 776 size_t m_inlineAllocationCount; |
777 #endif | 777 #endif |
778 }; | 778 }; |
779 | 779 |
780 class LargeObjectHeap final : public BaseHeap { | 780 class LargeObjectHeap final : public BaseHeap { |
781 public: | 781 public: |
782 LargeObjectHeap(ThreadState*, int); | 782 LargeObjectHeap(ThreadState*, int); |
783 Address allocateLargeObjectPage(size_t, size_t gcInfoIndex); | 783 Address allocateLargeObjectPage(size_t, size_t gcInfoIndex); |
784 void freeLargeObjectPage(LargeObjectPage*); | 784 void freeLargeObjectPage(LargeObjectPage*); |
785 #if ENABLE(ASSERT) | 785 #if ENABLE(ASSERT) |
786 virtual bool isConsistentForGC() override { return true; } | 786 bool isConsistentForGC() override { return true; } |
787 #endif | 787 #endif |
788 private: | 788 private: |
789 Address doAllocateLargeObjectPage(size_t, size_t gcInfoIndex); | 789 Address doAllocateLargeObjectPage(size_t, size_t gcInfoIndex); |
790 virtual Address lazySweepPages(size_t, size_t gcInfoIndex) override; | 790 Address lazySweepPages(size_t, size_t gcInfoIndex) override; |
791 }; | 791 }; |
792 | 792 |
793 // Mask an address down to the enclosing oilpan heap base page. All oilpan heap | 793 // Mask an address down to the enclosing oilpan heap base page. All oilpan heap |
794 // pages are aligned at blinkPageBase plus an OS page size. | 794 // pages are aligned at blinkPageBase plus an OS page size. |
795 // FIXME: Remove PLATFORM_EXPORT once we get a proper public interface to our | 795 // FIXME: Remove PLATFORM_EXPORT once we get a proper public interface to our |
796 // typed heaps. This is only exported to enable tests in HeapTest.cpp. | 796 // typed heaps. This is only exported to enable tests in HeapTest.cpp. |
797 PLATFORM_EXPORT inline BasePage* pageFromObject(const void* object) | 797 PLATFORM_EXPORT inline BasePage* pageFromObject(const void* object) |
798 { | 798 { |
799 Address address = reinterpret_cast<Address>(const_cast<void*>(object)); | 799 Address address = reinterpret_cast<Address>(const_cast<void*>(object)); |
800 BasePage* page = reinterpret_cast<BasePage*>(blinkPageAddress(address) + WTF
::kSystemPageSize); | 800 BasePage* page = reinterpret_cast<BasePage*>(blinkPageAddress(address) + WTF
::kSystemPageSize); |
(...skipping 580 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1381 size_t copySize = previousHeader->payloadSize(); | 1381 size_t copySize = previousHeader->payloadSize(); |
1382 if (copySize > size) | 1382 if (copySize > size) |
1383 copySize = size; | 1383 copySize = size; |
1384 memcpy(address, previous, copySize); | 1384 memcpy(address, previous, copySize); |
1385 return address; | 1385 return address; |
1386 } | 1386 } |
1387 | 1387 |
1388 } // namespace blink | 1388 } // namespace blink |
1389 | 1389 |
1390 #endif // Heap_h | 1390 #endif // Heap_h |
OLD | NEW |