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 Page_h 27#define Page_h 28 29#include "BAssert.h" 30#include "Mutex.h" 31#include "VMAllocate.h" 32#include <mutex> 33 34namespace bmalloc { 35 36template<typename Traits> 37class Page { 38public: 39 typedef typename Traits::Chunk Chunk; 40 typedef typename Traits::Line Line; 41 static const size_t lineSize = Traits::lineSize; 42 43 static const unsigned char maxRefCount = std::numeric_limits<unsigned char>::max(); 44 static_assert(vmPageSize / lineSize < maxRefCount, "maximum line count must fit in Page"); 45 46 static Page* get(Line*); 47 48 void ref(std::lock_guard<StaticMutex>&); 49 bool deref(std::lock_guard<StaticMutex>&); 50 unsigned refCount(std::lock_guard<StaticMutex>&) { return m_refCount; } 51 52 size_t smallSizeClass() { return m_smallSizeClass; } 53 void setSmallSizeClass(size_t smallSizeClass) { m_smallSizeClass = smallSizeClass; } 54 55 Line* begin(); 56 Line* end(); 57 58private: 59 unsigned char m_refCount; 60 unsigned char m_smallSizeClass; 61}; 62 63template<typename Traits> 64inline void Page<Traits>::ref(std::lock_guard<StaticMutex>&) 65{ 66 BASSERT(m_refCount < maxRefCount); 67 ++m_refCount; 68} 69 70template<typename Traits> 71inline bool Page<Traits>::deref(std::lock_guard<StaticMutex>&) 72{ 73 BASSERT(m_refCount); 74 --m_refCount; 75 return !m_refCount; 76} 77 78template<typename Traits> 79inline auto Page<Traits>::get(Line* line) -> Page* 80{ 81 Chunk* chunk = Chunk::get(line); 82 size_t lineNumber = line - chunk->lines(); 83 size_t pageNumber = lineNumber * lineSize / vmPageSize; 84 return &chunk->pages()[pageNumber]; 85} 86 87template<typename Traits> 88inline auto Page<Traits>::begin() -> Line* 89{ 90 Chunk* chunk = Chunk::get(this); 91 size_t pageNumber = this - chunk->pages(); 92 size_t lineNumber = pageNumber * vmPageSize / lineSize; 93 return &chunk->lines()[lineNumber]; 94} 95 96template<typename Traits> 97inline auto Page<Traits>::end() -> Line* 98{ 99 return begin() + vmPageSize / lineSize; 100} 101 102} // namespace bmalloc 103 104#endif // Page_h 105