| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef PageMemory_h | 5 #ifndef PageMemory_h |
| 6 #define PageMemory_h | 6 #define PageMemory_h |
| 7 | 7 |
| 8 #include "platform/heap/HeapPage.h" | 8 #include "platform/heap/HeapPage.h" |
| 9 #include "wtf/Allocator.h" | 9 #include "wtf/Allocator.h" |
| 10 #include "wtf/Assertions.h" | 10 #include "wtf/Assertions.h" |
| 11 #include "wtf/PageAllocator.h" | 11 #include "wtf/PageAllocator.h" |
| 12 | 12 |
| 13 #if OS(POSIX) | 13 #if OS(POSIX) |
| 14 #include <sys/mman.h> | 14 #include <sys/mman.h> |
| 15 #include <unistd.h> | 15 #include <unistd.h> |
| 16 #endif | 16 #endif |
| 17 | 17 |
| 18 namespace blink { | 18 namespace blink { |
| 19 | 19 |
| 20 class RegionTree; |
| 21 class RegionTreeNode; |
| 22 |
| 20 class MemoryRegion { | 23 class MemoryRegion { |
| 21 USING_FAST_MALLOC(MemoryRegion); | 24 USING_FAST_MALLOC(MemoryRegion); |
| 22 public: | 25 public: |
| 23 MemoryRegion(Address base, size_t size) | 26 MemoryRegion(Address base, size_t size) |
| 24 : m_base(base) | 27 : m_base(base) |
| 25 , m_size(size) | 28 , m_size(size) |
| 26 { | 29 { |
| 27 ASSERT(size > 0); | 30 ASSERT(size > 0); |
| 28 } | 31 } |
| 29 | 32 |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 65 { | 68 { |
| 66 ASSERT(!m_inUse[index(page)]); | 69 ASSERT(!m_inUse[index(page)]); |
| 67 m_inUse[index(page)] = true; | 70 m_inUse[index(page)] = true; |
| 68 } | 71 } |
| 69 | 72 |
| 70 void markPageUnused(Address page) | 73 void markPageUnused(Address page) |
| 71 { | 74 { |
| 72 m_inUse[index(page)] = false; | 75 m_inUse[index(page)] = false; |
| 73 } | 76 } |
| 74 | 77 |
| 75 static PageMemoryRegion* allocateLargePage(size_t size) | 78 static PageMemoryRegion* allocateLargePage(size_t size, RegionTree* regionTr
ee) |
| 76 { | 79 { |
| 77 return allocate(size, 1); | 80 return allocate(size, 1, regionTree); |
| 78 } | 81 } |
| 79 | 82 |
| 80 static PageMemoryRegion* allocateNormalPages() | 83 static PageMemoryRegion* allocateNormalPages(RegionTree* regionTree) |
| 81 { | 84 { |
| 82 return allocate(blinkPageSize * blinkPagesPerRegion, blinkPagesPerRegion
); | 85 return allocate(blinkPageSize * blinkPagesPerRegion, blinkPagesPerRegion
, regionTree); |
| 83 } | 86 } |
| 84 | 87 |
| 85 BasePage* pageFromAddress(Address address) | 88 BasePage* pageFromAddress(Address address) |
| 86 { | 89 { |
| 87 ASSERT(contains(address)); | 90 ASSERT(contains(address)); |
| 88 if (!m_inUse[index(address)]) | 91 if (!m_inUse[index(address)]) |
| 89 return nullptr; | 92 return nullptr; |
| 90 if (m_isLargePage) | 93 if (m_isLargePage) |
| 91 return pageFromObject(base()); | 94 return pageFromObject(base()); |
| 92 return pageFromObject(address); | 95 return pageFromObject(address); |
| 93 } | 96 } |
| 94 | 97 |
| 95 private: | 98 private: |
| 96 PageMemoryRegion(Address base, size_t, unsigned numPages); | 99 PageMemoryRegion(Address base, size_t, unsigned numPages, RegionTree*); |
| 97 | 100 |
| 98 unsigned index(Address address) const | 101 unsigned index(Address address) const |
| 99 { | 102 { |
| 100 ASSERT(contains(address)); | 103 ASSERT(contains(address)); |
| 101 if (m_isLargePage) | 104 if (m_isLargePage) |
| 102 return 0; | 105 return 0; |
| 103 size_t offset = blinkPageAddress(address) - base(); | 106 size_t offset = blinkPageAddress(address) - base(); |
| 104 ASSERT(offset % blinkPageSize == 0); | 107 ASSERT(offset % blinkPageSize == 0); |
| 105 return offset / blinkPageSize; | 108 return offset / blinkPageSize; |
| 106 } | 109 } |
| 107 | 110 |
| 108 static PageMemoryRegion* allocate(size_t, unsigned numPages); | 111 static PageMemoryRegion* allocate(size_t, unsigned numPages, RegionTree*); |
| 109 | 112 |
| 110 const bool m_isLargePage; | 113 const bool m_isLargePage; |
| 111 // A thread owns a page, but not a region. Represent the in-use | 114 // A thread owns a page, but not a region. Represent the in-use |
| 112 // bitmap such that thread non-interference comes for free. | 115 // bitmap such that thread non-interference comes for free. |
| 113 bool m_inUse[blinkPagesPerRegion]; | 116 bool m_inUse[blinkPagesPerRegion]; |
| 114 int m_numPages; | 117 int m_numPages; |
| 118 RegionTree* m_regionTree; |
| 115 }; | 119 }; |
| 116 | 120 |
| 117 // A RegionTree is a simple binary search tree of PageMemoryRegions sorted | 121 // A RegionTree is a simple binary search tree of PageMemoryRegions sorted |
| 118 // by base addresses. | 122 // by base addresses. |
| 119 class RegionTree { | 123 class RegionTree { |
| 120 USING_FAST_MALLOC(RegionTree); | 124 USING_FAST_MALLOC(RegionTree); |
| 121 public: | 125 public: |
| 122 explicit RegionTree(PageMemoryRegion* region) | 126 RegionTree() : m_root(nullptr) { } |
| 127 |
| 128 void add(PageMemoryRegion*); |
| 129 void remove(PageMemoryRegion*); |
| 130 PageMemoryRegion* lookup(Address); |
| 131 |
| 132 private: |
| 133 Mutex m_mutex; |
| 134 RegionTreeNode* m_root; |
| 135 }; |
| 136 |
| 137 class RegionTreeNode { |
| 138 USING_FAST_MALLOC(RegionTreeNode); |
| 139 public: |
| 140 explicit RegionTreeNode(PageMemoryRegion* region) |
| 123 : m_region(region) | 141 : m_region(region) |
| 124 , m_left(nullptr) | 142 , m_left(nullptr) |
| 125 , m_right(nullptr) | 143 , m_right(nullptr) |
| 126 { | 144 { |
| 127 } | 145 } |
| 128 | 146 |
| 129 ~RegionTree() | 147 ~RegionTreeNode() |
| 130 { | 148 { |
| 131 delete m_left; | 149 delete m_left; |
| 132 delete m_right; | 150 delete m_right; |
| 133 } | 151 } |
| 134 | 152 |
| 135 PageMemoryRegion* lookup(Address); | 153 void addTo(RegionTreeNode** context); |
| 136 static void add(RegionTree*, RegionTree**); | |
| 137 static void remove(PageMemoryRegion*, RegionTree**); | |
| 138 | 154 |
| 139 private: | 155 private: |
| 140 PageMemoryRegion* m_region; | 156 PageMemoryRegion* m_region; |
| 141 RegionTree* m_left; | 157 RegionTreeNode* m_left; |
| 142 RegionTree* m_right; | 158 RegionTreeNode* m_right; |
| 143 | 159 |
| 144 static RegionTree* s_regionTree; | 160 friend RegionTree; |
| 145 }; | 161 }; |
| 146 | 162 |
| 147 // Representation of the memory used for a Blink heap page. | 163 // Representation of the memory used for a Blink heap page. |
| 148 // | 164 // |
| 149 // The representation keeps track of two memory regions: | 165 // The representation keeps track of two memory regions: |
| 150 // | 166 // |
| 151 // 1. The virtual memory reserved from the system in order to be able | 167 // 1. The virtual memory reserved from the system in order to be able |
| 152 // to free all the virtual memory reserved. Multiple PageMemory | 168 // to free all the virtual memory reserved. Multiple PageMemory |
| 153 // instances can share the same reserved memory region and | 169 // instances can share the same reserved memory region and |
| 154 // therefore notify the reserved memory region on destruction so | 170 // therefore notify the reserved memory region on destruction so |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 189 static PageMemory* setupPageMemoryInRegion(PageMemoryRegion*, size_t pageOff
set, size_t payloadSize); | 205 static PageMemory* setupPageMemoryInRegion(PageMemoryRegion*, size_t pageOff
set, size_t payloadSize); |
| 190 | 206 |
| 191 // Allocate a virtual address space for one blink page with the | 207 // Allocate a virtual address space for one blink page with the |
| 192 // following layout: | 208 // following layout: |
| 193 // | 209 // |
| 194 // [ guard os page | ... payload ... | guard os page ] | 210 // [ guard os page | ... payload ... | guard os page ] |
| 195 // ^---{ aligned to blink page size } | 211 // ^---{ aligned to blink page size } |
| 196 // | 212 // |
| 197 // The returned page memory region will be zeroed. | 213 // The returned page memory region will be zeroed. |
| 198 // | 214 // |
| 199 static PageMemory* allocate(size_t payloadSize); | 215 static PageMemory* allocate(size_t payloadSize, RegionTree*); |
| 200 | 216 |
| 201 private: | 217 private: |
| 202 PageMemory(PageMemoryRegion* reserved, const MemoryRegion& writable); | 218 PageMemory(PageMemoryRegion* reserved, const MemoryRegion& writable); |
| 203 | 219 |
| 204 PageMemoryRegion* m_reserved; | 220 PageMemoryRegion* m_reserved; |
| 205 MemoryRegion m_writable; | 221 MemoryRegion m_writable; |
| 206 }; | 222 }; |
| 207 | 223 |
| 208 } // namespace blink | 224 } // namespace blink |
| 209 | 225 |
| 210 #endif | 226 #endif |
| OLD | NEW |