1/* 2 * Copyright (C) 2014 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 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. 12 * 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. 24 */ 25 26#ifndef SmallAllocator_h 27#define SmallAllocator_h 28 29#include "BAssert.h" 30#include "SmallChunk.h" 31#include "SmallLine.h" 32 33namespace bmalloc { 34 35// Helper object for allocating small objects. 36 37class SmallAllocator { 38public: 39 SmallAllocator(); 40 SmallAllocator(size_t); 41 42 bool isNull() { return !m_ptr; } 43 SmallLine* line(); 44 45 bool canAllocate() { return !!m_remaining; } 46 void* allocate(); 47 48 unsigned short objectCount(); 49 unsigned char derefCount(); 50 void refill(SmallLine*); 51 52private: 53 char* m_ptr; 54 unsigned short m_size; 55 unsigned char m_remaining; 56 unsigned char m_maxObjectCount; 57}; 58 59inline SmallAllocator::SmallAllocator() 60 : m_ptr() 61 , m_size() 62 , m_remaining() 63 , m_maxObjectCount() 64{ 65} 66 67inline SmallAllocator::SmallAllocator(size_t size) 68 : m_ptr() 69 , m_size(size) 70 , m_remaining() 71 , m_maxObjectCount(smallLineSize / size) 72{ 73} 74 75inline SmallLine* SmallAllocator::line() 76{ 77 return SmallLine::get(canAllocate() ? m_ptr : m_ptr - 1); 78} 79 80inline void* SmallAllocator::allocate() 81{ 82 BASSERT(m_remaining); 83 BASSERT(m_size >= SmallLine::minimumObjectSize); 84 85 --m_remaining; 86 char* result = m_ptr; 87 m_ptr += m_size; 88 BASSERT(isSmall(result)); 89 return result; 90} 91 92inline unsigned short SmallAllocator::objectCount() 93{ 94 return m_maxObjectCount - m_remaining; 95} 96 97inline unsigned char SmallAllocator::derefCount() 98{ 99 return SmallLine::maxRefCount - objectCount(); 100} 101 102inline void SmallAllocator::refill(SmallLine* line) 103{ 104 BASSERT(!canAllocate()); 105 line->concurrentRef(SmallLine::maxRefCount); 106 m_ptr = line->begin(); 107 m_remaining = m_maxObjectCount; 108} 109 110} // namespace bmalloc 111 112#endif // SmallAllocator_h 113