BlockAllocator should use regions as its VM allocation abstraction
[WebKit-https.git] / Source / JavaScriptCore / heap / CopiedBlock.h
1 /*
2  * Copyright (C) 2011 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 CopiedBlock_h
27 #define CopiedBlock_h
28
29 #include "BlockAllocator.h"
30 #include "HeapBlock.h"
31 #include "JSValue.h"
32 #include "JSValueInlineMethods.h"
33
34 namespace JSC {
35
36 class CopiedSpace;
37
38 class CopiedBlock : public HeapBlock<CopiedBlock> {
39     friend class CopiedSpace;
40     friend class CopiedAllocator;
41 public:
42     static CopiedBlock* create(DeadBlock*);
43     static CopiedBlock* createNoZeroFill(DeadBlock*);
44
45     // The payload is the region of the block that is usable for allocations.
46     char* payload();
47     char* payloadEnd();
48     size_t payloadCapacity();
49     
50     // The data is the region of the block that has been used for allocations.
51     char* data();
52     char* dataEnd();
53     size_t dataSize();
54     
55     // The wilderness is the region of the block that is usable for allocations
56     // but has not been so used.
57     char* wilderness();
58     char* wildernessEnd();
59     size_t wildernessSize();
60     
61     size_t size();
62     size_t capacity();
63
64     static const size_t blockSize = 64 * KB;
65
66 private:
67     CopiedBlock(Region*);
68     void zeroFillWilderness(); // Can be called at any time to zero-fill to the end of the block.
69
70     size_t m_remaining;
71     uintptr_t m_isPinned;
72 };
73
74 inline CopiedBlock* CopiedBlock::createNoZeroFill(DeadBlock* block)
75 {
76     Region* region = block->region();
77     return new(NotNull, block) CopiedBlock(region);
78 }
79
80 inline CopiedBlock* CopiedBlock::create(DeadBlock* block)
81 {
82     CopiedBlock* newBlock = createNoZeroFill(block);
83     newBlock->zeroFillWilderness();
84     return newBlock;
85 }
86
87 inline void CopiedBlock::zeroFillWilderness()
88 {
89 #if USE(JSVALUE64)
90     memset(wilderness(), 0, wildernessSize());
91 #else
92     JSValue emptyValue;
93     JSValue* limit = reinterpret_cast_ptr<JSValue*>(wildernessEnd());
94     for (JSValue* currentValue = reinterpret_cast<JSValue*>(wilderness()); currentValue < limit; currentValue++)
95         *currentValue = emptyValue;
96 #endif
97 }
98
99 inline CopiedBlock::CopiedBlock(Region* region)
100     : HeapBlock<CopiedBlock>(region)
101     , m_remaining(payloadCapacity())
102     , m_isPinned(false)
103 {
104     ASSERT(is8ByteAligned(reinterpret_cast<void*>(m_remaining)));
105 }
106
107 inline char* CopiedBlock::payload()
108 {
109     return reinterpret_cast<char*>(this) + ((sizeof(CopiedBlock) + 7) & ~7);
110 }
111
112 inline char* CopiedBlock::payloadEnd()
113 {
114     return reinterpret_cast<char*>(this) + region()->blockSize();
115 }
116
117 inline size_t CopiedBlock::payloadCapacity()
118 {
119     return payloadEnd() - payload();
120 }
121
122 inline char* CopiedBlock::data()
123 {
124     return payload();
125 }
126
127 inline char* CopiedBlock::dataEnd()
128 {
129     return payloadEnd() - m_remaining;
130 }
131
132 inline size_t CopiedBlock::dataSize()
133 {
134     return dataEnd() - data();
135 }
136
137 inline char* CopiedBlock::wilderness()
138 {
139     return dataEnd();
140 }
141
142 inline char* CopiedBlock::wildernessEnd()
143 {
144     return payloadEnd();
145 }
146
147 inline size_t CopiedBlock::wildernessSize()
148 {
149     return wildernessEnd() - wilderness();
150 }
151
152 inline size_t CopiedBlock::size()
153 {
154     return dataSize();
155 }
156
157 inline size_t CopiedBlock::capacity()
158 {
159     return region()->blockSize();
160 }
161
162 } // namespace JSC
163
164 #endif