Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1415)

Side by Side Diff: Source/platform/heap/Heap.h

Issue 616483002: Oilpan: Replace the positive heap-contains cache with a binary search tree of memory regions. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: lookup assert Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | Source/platform/heap/Heap.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 555 matching lines...) Expand 10 before | Expand all | Expand 10 after
566 intptr_t padding() const { return m_padding; } 566 intptr_t padding() const { return m_padding; }
567 567
568 HeapPage<Header>* m_next; 568 HeapPage<Header>* m_next;
569 intptr_t m_padding; // Preserve 8-byte alignment on 32-bit systems. 569 intptr_t m_padding; // Preserve 8-byte alignment on 32-bit systems.
570 bool m_objectStartBitMapComputed; 570 bool m_objectStartBitMapComputed;
571 uint8_t m_objectStartBitMap[reservedForObjectBitMap]; 571 uint8_t m_objectStartBitMap[reservedForObjectBitMap];
572 572
573 friend class ThreadHeap<Header>; 573 friend class ThreadHeap<Header>;
574 }; 574 };
575 575
576 class AddressEntry { 576 // A HeapDoesNotContainCache provides a fast way of taking an arbitrary
577 // pointer-sized word, and determining whether it cannot be interpreted
578 // as a pointer to an area that is managed by the garbage collected
579 // Blink heap. This is a cache of 'pages' that have previously been
580 // determined to be wholly outside of the heap. The size of these pages must be
581 // smaller than the allocation alignment of the heap pages. We determine
582 // off-heap-ness by rounding down the pointer to the nearest page and looking up
583 // the page in the cache. If there is a miss in the cache we can determine the
584 // status of the pointer precisely using the heap RegionTree.
585 //
586 // The HeapDoesNotContainCache is a negative cache, so it must be
587 // flushed when memory is added to the heap.
588 class HeapDoesNotContainCache {
577 public: 589 public:
578 AddressEntry() : m_address(0) { } 590 HeapDoesNotContainCache()
579 591 : m_entries(adoptArrayPtr(new Address[HeapDoesNotContainCache::numberOfE ntries]))
580 explicit AddressEntry(Address address) : m_address(address) { } 592 , m_hasEntries(true)
581
582 Address address() const { return m_address; }
583
584 private:
585 Address m_address;
586 };
587
588 class PositiveEntry : public AddressEntry {
589 public:
590 PositiveEntry()
591 : AddressEntry()
592 , m_containingPage(0)
593 { 593 {
594 } 594 // Start by flushing the cache in a non-empty state to initialize all th e cache entries.
595 595 flush();
596 PositiveEntry(Address address, BaseHeapPage* containingPage)
597 : AddressEntry(address)
598 , m_containingPage(containingPage)
599 {
600 }
601
602 BaseHeapPage* result() const { return m_containingPage; }
603
604 typedef BaseHeapPage* LookupResult;
605
606 private:
607 BaseHeapPage* m_containingPage;
608 };
609
610 class NegativeEntry : public AddressEntry {
611 public:
612 NegativeEntry() : AddressEntry() { }
613
614 NegativeEntry(Address address, bool) : AddressEntry(address) { }
615
616 bool result() const { return true; }
617
618 typedef bool LookupResult;
619 };
620
621 // A HeapExtentCache provides a fast way of taking an arbitrary
622 // pointer-sized word, and determining whether it can be interpreted
623 // as a pointer to an area that is managed by the garbage collected
624 // Blink heap. There is a cache of 'pages' that have previously been
625 // determined to be wholly inside the heap. The size of these pages must be
626 // smaller than the allocation alignment of the heap pages. We determine
627 // on-heap-ness by rounding down the pointer to the nearest page and looking up
628 // the page in the cache. If there is a miss in the cache we can ask the heap
629 // to determine the status of the pointer by iterating over all of the heap.
630 // The result is then cached in the two-way associative page cache.
631 //
632 // A HeapContainsCache is a positive cache. Therefore, it must be flushed when
633 // memory is removed from the Blink heap. The HeapDoesNotContainCache is a
634 // negative cache, so it must be flushed when memory is added to the heap.
635 template<typename Entry>
636 class HeapExtentCache {
637 public:
638 HeapExtentCache()
639 : m_entries(adoptArrayPtr(new Entry[HeapExtentCache::numberOfEntries]))
640 , m_hasEntries(false)
641 {
642 } 596 }
643 597
644 void flush(); 598 void flush();
645 bool contains(Address);
646 bool isEmpty() { return !m_hasEntries; } 599 bool isEmpty() { return !m_hasEntries; }
647 600
648 // Perform a lookup in the cache. 601 // Perform a lookup in the cache.
649 // 602 //
650 // If lookup returns null/false the argument address was not found in 603 // If lookup returns false, the argument address was not found in
651 // the cache and it is unknown if the address is in the Blink 604 // the cache and it is unknown if the address is in the Blink
652 // heap. 605 // heap.
653 // 606 //
654 // If lookup returns true/a page, the argument address was found in the 607 // If lookup returns true, the argument address was found in the
655 // cache. For the HeapContainsCache this means the address is in the heap. 608 // cache which means the address is not in the heap.
656 // For the HeapDoesNotContainCache this means the address is not in the 609 PLATFORM_EXPORT bool lookup(Address);
657 // heap.
658 PLATFORM_EXPORT typename Entry::LookupResult lookup(Address);
659 610
660 // Add an entry to the cache. 611 // Add an entry to the cache.
661 PLATFORM_EXPORT void addEntry(Address, typename Entry::LookupResult); 612 PLATFORM_EXPORT void addEntry(Address);
662 613
663 private: 614 private:
664 static const int numberOfEntriesLog2 = 12; 615 static const int numberOfEntriesLog2 = 12;
665 static const int numberOfEntries = 1 << numberOfEntriesLog2; 616 static const int numberOfEntries = 1 << numberOfEntriesLog2;
666 617
667 static size_t hash(Address); 618 static size_t hash(Address);
668 619
669 WTF::OwnPtr<Entry[]> m_entries; 620 WTF::OwnPtr<Address[]> m_entries;
670 bool m_hasEntries; 621 bool m_hasEntries;
671
672 friend class ThreadState;
673 }; 622 };
674 623
675 // Normally these would be typedefs instead of subclasses, but that makes them
676 // very hard to forward declare.
677 class HeapContainsCache : public HeapExtentCache<PositiveEntry> {
678 public:
679 BaseHeapPage* lookup(Address);
680 void addEntry(Address, BaseHeapPage*);
681 };
682
683 class HeapDoesNotContainCache : public HeapExtentCache<NegativeEntry> { };
684
685 // FIXME: This is currently used by the WebAudio code. 624 // FIXME: This is currently used by the WebAudio code.
686 // We should attempt to restructure the WebAudio code so that the main thread 625 // We should attempt to restructure the WebAudio code so that the main thread
687 // alone determines life-time and receives messages about life-time from the 626 // alone determines life-time and receives messages about life-time from the
688 // audio thread. 627 // audio thread.
689 template<typename T> 628 template<typename T>
690 class ThreadSafeRefCountedGarbageCollected : public GarbageCollectedFinalized<T> , public WTF::ThreadSafeRefCountedBase { 629 class ThreadSafeRefCountedGarbageCollected : public GarbageCollectedFinalized<T> , public WTF::ThreadSafeRefCountedBase {
691 WTF_MAKE_NONCOPYABLE(ThreadSafeRefCountedGarbageCollected); 630 WTF_MAKE_NONCOPYABLE(ThreadSafeRefCountedGarbageCollected);
692 631
693 public: 632 public:
694 ThreadSafeRefCountedGarbageCollected() 633 ThreadSafeRefCountedGarbageCollected()
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
868 virtual void makeConsistentForSweeping(); 807 virtual void makeConsistentForSweeping();
869 808
870 #if ENABLE(ASSERT) 809 #if ENABLE(ASSERT)
871 virtual bool isConsistentForSweeping(); 810 virtual bool isConsistentForSweeping();
872 811
873 virtual void getScannedStats(HeapStats&); 812 virtual void getScannedStats(HeapStats&);
874 #endif 813 #endif
875 814
876 ThreadState* threadState() { return m_threadState; } 815 ThreadState* threadState() { return m_threadState; }
877 HeapStats& stats() { return m_threadState->stats(); } 816 HeapStats& stats() { return m_threadState->stats(); }
878 void flushHeapContainsCache()
879 {
880 m_threadState->heapContainsCache()->flush();
881 }
882 817
883 inline Address allocate(size_t, const GCInfo*); 818 inline Address allocate(size_t, const GCInfo*);
884 void addToFreeList(Address, size_t); 819 void addToFreeList(Address, size_t);
885 inline static size_t roundedAllocationSize(size_t size) 820 inline static size_t roundedAllocationSize(size_t size)
886 { 821 {
887 return allocationSizeFromSize(size) - sizeof(Header); 822 return allocationSizeFromSize(size) - sizeof(Header);
888 } 823 }
889 824
890 virtual void prepareHeapForTermination(); 825 virtual void prepareHeapForTermination();
891 826
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
1065 static void flushHeapDoesNotContainCache(); 1000 static void flushHeapDoesNotContainCache();
1066 static bool heapDoesNotContainCacheIsEmpty() { return s_heapDoesNotContainCa che->isEmpty(); } 1001 static bool heapDoesNotContainCacheIsEmpty() { return s_heapDoesNotContainCa che->isEmpty(); }
1067 1002
1068 // Return true if the last GC found a pointer into a heap page 1003 // Return true if the last GC found a pointer into a heap page
1069 // during conservative scanning. 1004 // during conservative scanning.
1070 static bool lastGCWasConservative() { return s_lastGCWasConservative; } 1005 static bool lastGCWasConservative() { return s_lastGCWasConservative; }
1071 1006
1072 static FreePagePool* freePagePool() { return s_freePagePool; } 1007 static FreePagePool* freePagePool() { return s_freePagePool; }
1073 static OrphanedPagePool* orphanedPagePool() { return s_orphanedPagePool; } 1008 static OrphanedPagePool* orphanedPagePool() { return s_orphanedPagePool; }
1074 1009
1010 // This look-up uses the region search tree and a negative contains cache to
1011 // provide an efficient mapping from arbitrary addresses to the containing
1012 // heap-page if one exists.
1013 static BaseHeapPage* lookup(Address);
1014 static void addPageMemoryRegion(PageMemoryRegion*);
1015 static void removePageMemoryRegion(PageMemoryRegion*);
1016
1075 private: 1017 private:
1018 // A RegionTree is a simple binary search tree of PageMemoryRegions sorted
1019 // by base addresses.
1020 class RegionTree {
1021 public:
1022 explicit RegionTree(PageMemoryRegion* region) : m_region(region), m_left (0), m_right(0) { }
1023 ~RegionTree()
1024 {
1025 delete m_left;
1026 delete m_right;
1027 }
1028 PageMemoryRegion* lookup(Address);
1029 static void add(RegionTree*, RegionTree**);
1030 static void remove(PageMemoryRegion*, RegionTree**);
1031 private:
1032 PageMemoryRegion* m_region;
1033 RegionTree* m_left;
1034 RegionTree* m_right;
1035 };
1036
1076 static Visitor* s_markingVisitor; 1037 static Visitor* s_markingVisitor;
1077 static Vector<OwnPtr<blink::WebThread> >* s_markingThreads; 1038 static Vector<OwnPtr<blink::WebThread> >* s_markingThreads;
1078 static CallbackStack* s_markingStack; 1039 static CallbackStack* s_markingStack;
1079 static CallbackStack* s_postMarkingCallbackStack; 1040 static CallbackStack* s_postMarkingCallbackStack;
1080 static CallbackStack* s_weakCallbackStack; 1041 static CallbackStack* s_weakCallbackStack;
1081 static CallbackStack* s_ephemeronStack; 1042 static CallbackStack* s_ephemeronStack;
1082 static HeapDoesNotContainCache* s_heapDoesNotContainCache; 1043 static HeapDoesNotContainCache* s_heapDoesNotContainCache;
1083 static bool s_shutdownCalled; 1044 static bool s_shutdownCalled;
1084 static bool s_lastGCWasConservative; 1045 static bool s_lastGCWasConservative;
1085 static FreePagePool* s_freePagePool; 1046 static FreePagePool* s_freePagePool;
1086 static OrphanedPagePool* s_orphanedPagePool; 1047 static OrphanedPagePool* s_orphanedPagePool;
1048 static RegionTree* s_regionTree;
1087 friend class ThreadState; 1049 friend class ThreadState;
1088 }; 1050 };
1089 1051
1090 // The NoAllocationScope class is used in debug mode to catch unwanted 1052 // The NoAllocationScope class is used in debug mode to catch unwanted
1091 // allocations. E.g. allocations during GC. 1053 // allocations. E.g. allocations during GC.
1092 template<ThreadAffinity Affinity> 1054 template<ThreadAffinity Affinity>
1093 class NoAllocationScope { 1055 class NoAllocationScope {
1094 public: 1056 public:
1095 NoAllocationScope() : m_active(true) { enter(); } 1057 NoAllocationScope() : m_active(true) { enter(); }
1096 1058
(...skipping 1391 matching lines...) Expand 10 before | Expand all | Expand 10 after
2488 }; 2450 };
2489 2451
2490 template<typename T> 2452 template<typename T>
2491 struct IfWeakMember<WeakMember<T> > { 2453 struct IfWeakMember<WeakMember<T> > {
2492 static bool isDead(Visitor* visitor, const WeakMember<T>& t) { return !visit or->isAlive(t.get()); } 2454 static bool isDead(Visitor* visitor, const WeakMember<T>& t) { return !visit or->isAlive(t.get()); }
2493 }; 2455 };
2494 2456
2495 } 2457 }
2496 2458
2497 #endif // Heap_h 2459 #endif // Heap_h
OLDNEW
« no previous file with comments | « no previous file | Source/platform/heap/Heap.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698