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

source code of qtdeclarative/src/3rdparty/masm/assembler/AssemblerBuffer.h