initial import
[vuplus_webkit] / 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 "JSGlobalData.h"
32 #include "stdint.h"
33 #include <string.h>
34 #include <jit/ExecutableAllocator.h>
35 #include <wtf/Assertions.h>
36 #include <wtf/FastMalloc.h>
37 #include <wtf/StdLibExtras.h>
38
39 namespace JSC {
40
41     struct AssemblerLabel {
42         AssemblerLabel()
43             : m_offset(std::numeric_limits<uint32_t>::max())
44         {
45         }
46
47         explicit AssemblerLabel(uint32_t offset)
48             : m_offset(offset)
49         {
50         }
51
52         bool isSet() const { return (m_offset != std::numeric_limits<uint32_t>::max()); }
53
54         AssemblerLabel labelAtOffset(int offset) const
55         {
56             return AssemblerLabel(m_offset + offset);
57         }
58
59         uint32_t m_offset;
60     };
61
62     class AssemblerBuffer {
63         static const int inlineCapacity = 128;
64     public:
65         AssemblerBuffer()
66             : m_storage(inlineCapacity)
67             , m_buffer(m_storage.begin())
68             , m_capacity(inlineCapacity)
69             , m_index(0)
70         {
71         }
72
73         ~AssemblerBuffer()
74         {
75         }
76
77         bool isAvailable(int space)
78         {
79             return m_index + space <= m_capacity;
80         }
81
82         void ensureSpace(int space)
83         {
84             if (!isAvailable(space))
85                 grow();
86         }
87
88         bool isAligned(int alignment) const
89         {
90             return !(m_index & (alignment - 1));
91         }
92
93         template<typename IntegralType>
94         void putIntegral(IntegralType value)
95         {
96             ensureSpace(sizeof(IntegralType));
97             putIntegralUnchecked(value);
98         }
99
100         template<typename IntegralType>
101         void putIntegralUnchecked(IntegralType value)
102         {
103             ASSERT(isAvailable(sizeof(IntegralType)));
104             *reinterpret_cast_ptr<IntegralType*>(m_buffer + m_index) = value;
105             m_index += sizeof(IntegralType);
106         }
107
108         void putByteUnchecked(int8_t value) { putIntegralUnchecked(value); }
109         void putByte(int8_t value) { putIntegral(value); }
110         void putShortUnchecked(int16_t value) { putIntegralUnchecked(value); }
111         void putShort(int16_t value) { putIntegral(value); }
112         void putIntUnchecked(int32_t value) { putIntegralUnchecked(value); }
113         void putInt(int32_t value) { putIntegral(value); }
114         void putInt64Unchecked(int64_t value) { putIntegralUnchecked(value); }
115         void putInt64(int64_t value) { putIntegral(value); }
116
117         void* data() const
118         {
119             return m_buffer;
120         }
121
122         size_t codeSize() const
123         {
124             return m_index;
125         }
126
127         AssemblerLabel label() const
128         {
129             return AssemblerLabel(m_index);
130         }
131
132         PassRefPtr<ExecutableMemoryHandle> executableCopy(JSGlobalData& globalData)
133         {
134             if (!m_index)
135                 return 0;
136
137             RefPtr<ExecutableMemoryHandle> result = globalData.executableAllocator.allocate(globalData, m_index);
138
139             if (!result)
140                 return 0;
141
142             ExecutableAllocator::makeWritable(result->start(), result->sizeInBytes());
143
144             memcpy(result->start(), m_buffer, m_index);
145             
146             return result.release();
147         }
148
149         void rewindToLabel(AssemblerLabel label)
150         {
151             m_index = label.m_offset;
152         }
153
154 #ifndef NDEBUG
155         unsigned debugOffset() { return m_index; }
156 #endif
157
158     protected:
159         void append(const char* data, int size)
160         {
161             if (!isAvailable(size))
162                 grow(size);
163
164             memcpy(m_buffer + m_index, data, size);
165             m_index += size;
166         }
167
168         void grow(int extraCapacity = 0)
169         {
170             m_capacity += m_capacity / 2 + extraCapacity;
171
172             m_storage.grow(m_capacity);
173             m_buffer = m_storage.begin();
174         }
175
176     private:
177         Vector<char, inlineCapacity> m_storage;
178         char* m_buffer;
179         int m_capacity;
180         int m_index;
181     };
182
183 } // namespace JSC
184
185 #endif // ENABLE(ASSEMBLER)
186
187 #endif // AssemblerBuffer_h