OSDN Git Service

Merge WebKit at r84325: Initial merge by git.
[android-x86/external-webkit.git] / Source / JavaScriptCore / assembler / AssemblerBuffer.h
1 /*
2  * Copyright (C) 2008 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 AssemblerBuffer_h
27 #define AssemblerBuffer_h
28
29 #if ENABLE(ASSEMBLER)
30
31 #include "stdint.h"
32 #include <string.h>
33 #include <jit/ExecutableAllocator.h>
34 #include <wtf/Assertions.h>
35 #include <wtf/FastMalloc.h>
36 #include <wtf/StdLibExtras.h>
37
38 namespace JSC {
39
40     class AssemblerBuffer {
41         static const int inlineCapacity = 128 - sizeof(char*) - 2 * sizeof(int);
42     public:
43         AssemblerBuffer()
44             : m_buffer(m_inlineBuffer)
45             , m_capacity(inlineCapacity)
46             , m_size(0)
47         {
48             COMPILE_ASSERT(sizeof(AssemblerBuffer) == 128, AssemblerBuffer_should_be_128_bytes);
49         }
50
51         ~AssemblerBuffer()
52         {
53             if (m_buffer != m_inlineBuffer)
54                 fastFree(m_buffer);
55         }
56
57         void ensureSpace(int space)
58         {
59             if (m_size > m_capacity - space)
60                 grow();
61         }
62
63         bool isAligned(int alignment) const
64         {
65             return !(m_size & (alignment - 1));
66         }
67
68         void putByteUnchecked(int value)
69         {
70             ASSERT(!(m_size > m_capacity - 4));
71             m_buffer[m_size] = value;
72             m_size++;
73         }
74
75         void putByte(int value)
76         {
77             if (m_size > m_capacity - 4)
78                 grow();
79             putByteUnchecked(value);
80         }
81
82         void putShortUnchecked(int value)
83         {
84             ASSERT(!(m_size > m_capacity - 4));
85             *reinterpret_cast_ptr<short*>(&m_buffer[m_size]) = value;
86             m_size += 2;
87         }
88
89         void putShort(int value)
90         {
91             if (m_size > m_capacity - 4)
92                 grow();
93             putShortUnchecked(value);
94         }
95
96         void putIntUnchecked(int value)
97         {
98             ASSERT(!(m_size > m_capacity - 4));
99             *reinterpret_cast_ptr<int*>(&m_buffer[m_size]) = value;
100             m_size += 4;
101         }
102
103         void putInt64Unchecked(int64_t value)
104         {
105             ASSERT(!(m_size > m_capacity - 8));
106             *reinterpret_cast_ptr<int64_t*>(&m_buffer[m_size]) = value;
107             m_size += 8;
108         }
109
110         void putInt(int value)
111         {
112             if (m_size > m_capacity - 4)
113                 grow();
114             putIntUnchecked(value);
115         }
116
117         template<typename IntegralType>
118         void putIntegral(IntegralType value)
119         {
120             if (m_size > m_capacity - sizeof(IntegralType))
121                 grow();
122             putIntegralUnchecked(value);
123         }
124
125         template<typename IntegralType>
126         void putIntegralUnchecked(IntegralType value)
127         {
128             *reinterpret_cast_ptr<IntegralType*>(&m_buffer[m_size]) = value;
129             m_size += sizeof(IntegralType);
130         }
131
132         void* data() const
133         {
134             return m_buffer;
135         }
136
137         int size() const
138         {
139             return m_size;
140         }
141
142         void* executableCopy(ExecutablePool* allocator)
143         {
144             if (!m_size)
145                 return 0;
146
147             void* result = allocator->alloc(m_size);
148
149             if (!result)
150                 return 0;
151
152             ExecutableAllocator::makeWritable(result, m_size);
153
154             return memcpy(result, m_buffer, m_size);
155         }
156
157         void rewindToOffset(int offset)
158         {
159             ASSERT(offset >= 0);
160             m_size = offset;
161         }
162
163 #ifndef NDEBUG
164         unsigned debugOffset() { return m_size; }
165 #endif
166
167     protected:
168         void append(const char* data, int size)
169         {
170             if (m_size > m_capacity - size)
171                 grow(size);
172
173             memcpy(m_buffer + m_size, data, size);
174             m_size += size;
175         }
176
177         void grow(int extraCapacity = 0)
178         {
179             m_capacity += m_capacity / 2 + extraCapacity;
180
181             if (m_buffer == m_inlineBuffer) {
182                 char* newBuffer = static_cast<char*>(fastMalloc(m_capacity));
183                 m_buffer = static_cast<char*>(memcpy(newBuffer, m_buffer, m_size));
184             } else
185                 m_buffer = static_cast<char*>(fastRealloc(m_buffer, m_capacity));
186         }
187
188         char m_inlineBuffer[inlineCapacity];
189         char* m_buffer;
190         int m_capacity;
191         int m_size;
192     };
193
194 } // namespace JSC
195
196 #endif // ENABLE(ASSEMBLER)
197
198 #endif // AssemblerBuffer_h