2 * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 #include "AsyncTask.h"
30 #include "FixedVector.h"
31 #include "LargeChunk.h"
32 #include "LargeObject.h"
33 #include "MediumChunk.h"
35 #include "SegregatedFreeList.h"
36 #include "SmallChunk.h"
38 #if BOS(DARWIN) && !BPLATFORM(IOS)
53 SmallPage* allocateSmallPage();
54 MediumPage* allocateMediumPage();
55 LargeObject allocateLargeObject(size_t);
56 LargeObject allocateLargeObject(size_t alignment, size_t, size_t unalignedSize);
58 void deallocateSmallPage(std::unique_lock<StaticMutex>&, SmallPage*);
59 void deallocateMediumPage(std::unique_lock<StaticMutex>&, MediumPage*);
60 void deallocateLargeObject(std::unique_lock<StaticMutex>&, LargeObject&);
63 LargeObject allocateLargeObject(LargeObject&, size_t);
66 Vector<SmallPage*> m_smallPages;
67 Vector<MediumPage*> m_mediumPages;
68 SegregatedFreeList m_largeObjects;
69 #if BOS(DARWIN) && !BPLATFORM(IOS)
74 inline SmallPage* VMHeap::allocateSmallPage()
76 if (!m_smallPages.size())
79 SmallPage* page = m_smallPages.pop();
80 vmAllocatePhysicalPages(page->begin()->begin(), vmPageSize);
84 inline MediumPage* VMHeap::allocateMediumPage()
86 if (!m_mediumPages.size())
89 MediumPage* page = m_mediumPages.pop();
90 vmAllocatePhysicalPages(page->begin()->begin(), vmPageSize);
94 inline LargeObject VMHeap::allocateLargeObject(LargeObject& largeObject, size_t size)
96 BASSERT(largeObject.isFree());
98 if (largeObject.size() - size > largeMin) {
99 std::pair<LargeObject, LargeObject> split = largeObject.split(size);
100 largeObject = split.first;
101 m_largeObjects.insert(split.second);
104 vmAllocatePhysicalPagesSloppy(largeObject.begin(), largeObject.size());
105 largeObject.setOwner(Owner::Heap);
106 return largeObject.begin();
109 inline LargeObject VMHeap::allocateLargeObject(size_t size)
111 LargeObject largeObject = m_largeObjects.take(size);
114 largeObject = m_largeObjects.take(size);
115 BASSERT(largeObject);
118 return allocateLargeObject(largeObject, size);
121 inline LargeObject VMHeap::allocateLargeObject(size_t alignment, size_t size, size_t unalignedSize)
123 LargeObject largeObject = m_largeObjects.take(alignment, size, unalignedSize);
126 largeObject = m_largeObjects.take(alignment, size, unalignedSize);
127 BASSERT(largeObject);
130 size_t alignmentMask = alignment - 1;
131 if (test(largeObject.begin(), alignmentMask))
132 return allocateLargeObject(largeObject, unalignedSize);
133 return allocateLargeObject(largeObject, size);
136 inline void VMHeap::deallocateSmallPage(std::unique_lock<StaticMutex>& lock, SmallPage* page)
139 vmDeallocatePhysicalPages(page->begin()->begin(), vmPageSize);
142 m_smallPages.push(page);
145 inline void VMHeap::deallocateMediumPage(std::unique_lock<StaticMutex>& lock, MediumPage* page)
148 vmDeallocatePhysicalPages(page->begin()->begin(), vmPageSize);
151 m_mediumPages.push(page);
154 inline void VMHeap::deallocateLargeObject(std::unique_lock<StaticMutex>& lock, LargeObject& largeObject)
156 largeObject.setOwner(Owner::VMHeap);
158 // If we couldn't merge with our neighbors before because they were in the
159 // VM heap, we can merge with them now.
160 LargeObject merged = largeObject.merge();
162 // Temporarily mark this object as allocated to prevent clients from merging
163 // with it or allocating it while we're messing with its physical pages.
164 merged.setFree(false);
167 vmDeallocatePhysicalPagesSloppy(merged.begin(), merged.size());
170 merged.setFree(true);
172 m_largeObjects.insert(merged);
175 } // namespace bmalloc