bmalloc: Merge the large and xlarge allocators
[WebKit-https.git] / Source / bmalloc / bmalloc / Chunk.h
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 Chunk_h
27 #define Chunk_h
28
29 #include "Object.h"
30 #include "Sizes.h"
31 #include "SmallLine.h"
32 #include "SmallPage.h"
33 #include "VMAllocate.h"
34 #include <array>
35
36 namespace bmalloc {
37
38 class Chunk {
39 public:
40     static Chunk* get(void*);
41
42     Chunk(std::lock_guard<StaticMutex>&);
43
44     size_t offset(void*);
45
46     char* object(size_t offset);
47     SmallPage* page(size_t offset);
48     SmallLine* line(size_t offset);
49
50     char* bytes() { return reinterpret_cast<char*>(this); }
51     SmallLine* lines() { return m_lines.begin(); }
52     SmallPage* pages() { return m_pages.begin(); }
53
54 private:
55     std::array<SmallLine, chunkSize / smallLineSize> m_lines;
56     std::array<SmallPage, chunkSize / smallPageSize> m_pages;
57 };
58
59 static_assert(sizeof(Chunk) + largeMax <= chunkSize, "largeMax is too big");
60
61 struct ChunkHash {
62     static unsigned hash(Chunk* key)
63     {
64         return static_cast<unsigned>(
65             reinterpret_cast<uintptr_t>(key) / chunkSize);
66     }
67 };
68
69 inline Chunk::Chunk(std::lock_guard<StaticMutex>&)
70 {
71 }
72
73 inline Chunk* Chunk::get(void* object)
74 {
75     return static_cast<Chunk*>(mask(object, chunkMask));
76 }
77
78 inline size_t Chunk::offset(void* object)
79 {
80     BASSERT(object >= this);
81     BASSERT(object < bytes() + chunkSize);
82     return static_cast<char*>(object) - bytes();
83 }
84
85 inline char* Chunk::object(size_t offset)
86 {
87     return bytes() + offset;
88 }
89
90 inline SmallPage* Chunk::page(size_t offset)
91 {
92     size_t pageNumber = offset / smallPageSize;
93     SmallPage* page = &m_pages[pageNumber];
94     return page - page->slide();
95 }
96
97 inline SmallLine* Chunk::line(size_t offset)
98 {
99     size_t lineNumber = offset / smallLineSize;
100     return &m_lines[lineNumber];
101 }
102
103 inline char* SmallLine::begin()
104 {
105     Chunk* chunk = Chunk::get(this);
106     size_t lineNumber = this - chunk->lines();
107     size_t offset = lineNumber * smallLineSize;
108     return &reinterpret_cast<char*>(chunk)[offset];
109 }
110
111 inline char* SmallLine::end()
112 {
113     return begin() + smallLineSize;
114 }
115
116 inline SmallLine* SmallPage::begin()
117 {
118     BASSERT(!m_slide);
119     Chunk* chunk = Chunk::get(this);
120     size_t pageNumber = this - chunk->pages();
121     size_t lineNumber = pageNumber * smallPageLineCount;
122     return &chunk->lines()[lineNumber];
123 }
124
125 inline Object::Object(void* object)
126     : m_chunk(Chunk::get(object))
127     , m_offset(m_chunk->offset(object))
128 {
129 }
130
131 inline Object::Object(Chunk* chunk, void* object)
132     : m_chunk(chunk)
133     , m_offset(m_chunk->offset(object))
134 {
135     BASSERT(chunk == Chunk::get(object));
136 }
137
138 inline char* Object::begin()
139 {
140     return m_chunk->object(m_offset);
141 }
142
143 inline SmallLine* Object::line()
144 {
145     return m_chunk->line(m_offset);
146 }
147
148 inline SmallPage* Object::page()
149 {
150     return m_chunk->page(m_offset);
151 }
152
153 }; // namespace bmalloc
154
155 #endif // Chunk