6717a68351d9303ad55f5ec6650d26cc18177846
[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 "HeapBlock.h"
30 #include "JSValue.h"
31 #include "JSValueInlineMethods.h"
32
33 namespace JSC {
34
35 class CopiedSpace;
36
37 class CopiedBlock : public HeapBlock {
38     friend class CopiedSpace;
39     friend class CopiedAllocator;
40 public:
41     static CopiedBlock* create(const PageAllocationAligned&);
42     static CopiedBlock* createNoZeroFill(const PageAllocationAligned&);
43     static PageAllocationAligned destroy(CopiedBlock*);
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 private:
65     CopiedBlock(const PageAllocationAligned&);
66     void zeroFillWilderness(); // Can be called at any time to zero-fill to the end of the block.
67
68     size_t m_remaining;
69     uintptr_t m_isPinned;
70 };
71
72 inline CopiedBlock* CopiedBlock::createNoZeroFill(const PageAllocationAligned& allocation)
73 {
74     return new(NotNull, allocation.base()) CopiedBlock(allocation);
75 }
76
77 inline CopiedBlock* CopiedBlock::create(const PageAllocationAligned& allocation)
78 {
79     CopiedBlock* block = createNoZeroFill(allocation);
80     block->zeroFillWilderness();
81     return block;
82 }
83
84 inline void CopiedBlock::zeroFillWilderness()
85 {
86 #if USE(JSVALUE64)
87     memset(wilderness(), 0, wildernessSize());
88 #else
89     JSValue emptyValue;
90     JSValue* limit = reinterpret_cast_ptr<JSValue*>(wildernessEnd());
91     for (JSValue* currentValue = reinterpret_cast<JSValue*>(wilderness()); currentValue < limit; currentValue++)
92         *currentValue = emptyValue;
93 #endif
94 }
95
96 inline PageAllocationAligned CopiedBlock::destroy(CopiedBlock* block)
97 {
98     PageAllocationAligned allocation;
99     swap(allocation, block->m_allocation);
100
101     block->~CopiedBlock();
102     return allocation;
103 }
104
105 inline CopiedBlock::CopiedBlock(const PageAllocationAligned& allocation)
106     : HeapBlock(allocation)
107     , m_remaining(payloadCapacity())
108     , m_isPinned(false)
109 {
110     ASSERT(is8ByteAligned(reinterpret_cast<void*>(m_remaining)));
111 }
112
113 inline char* CopiedBlock::payload()
114 {
115     return reinterpret_cast<char*>(this) + ((sizeof(CopiedBlock) + 7) & ~7);
116 }
117
118 inline char* CopiedBlock::payloadEnd()
119 {
120     return reinterpret_cast<char*>(this) + m_allocation.size();
121 }
122
123 inline size_t CopiedBlock::payloadCapacity()
124 {
125     return payloadEnd() - payload();
126 }
127
128 inline char* CopiedBlock::data()
129 {
130     return payload();
131 }
132
133 inline char* CopiedBlock::dataEnd()
134 {
135     return payloadEnd() - m_remaining;
136 }
137
138 inline size_t CopiedBlock::dataSize()
139 {
140     return dataEnd() - data();
141 }
142
143 inline char* CopiedBlock::wilderness()
144 {
145     return dataEnd();
146 }
147
148 inline char* CopiedBlock::wildernessEnd()
149 {
150     return payloadEnd();
151 }
152
153 inline size_t CopiedBlock::wildernessSize()
154 {
155     return wildernessEnd() - wilderness();
156 }
157
158 inline size_t CopiedBlock::size()
159 {
160     return dataSize();
161 }
162
163 inline size_t CopiedBlock::capacity()
164 {
165     return m_allocation.size();
166 }
167
168 } // namespace JSC
169
170 #endif