]> git.saurik.com Git - apple/javascriptcore.git/blame - assembler/AssemblerBuffer.h
JavaScriptCore-1218.35.tar.gz
[apple/javascriptcore.git] / assembler / AssemblerBuffer.h
CommitLineData
9dae56ea 1/*
93a37866 2 * Copyright (C) 2008, 2012 Apple Inc. All rights reserved.
9dae56ea
A
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
9dae56ea
A
29#if ENABLE(ASSEMBLER)
30
93a37866 31#include "ExecutableAllocator.h"
6fe7ccc8 32#include "JITCompilationEffort.h"
93a37866 33#include "VM.h"
9dae56ea
A
34#include "stdint.h"
35#include <string.h>
9dae56ea
A
36#include <wtf/Assertions.h>
37#include <wtf/FastMalloc.h>
14957cd0 38#include <wtf/StdLibExtras.h>
9dae56ea
A
39
40namespace JSC {
41
14957cd0
A
42 struct AssemblerLabel {
43 AssemblerLabel()
44 : m_offset(std::numeric_limits<uint32_t>::max())
9dae56ea
A
45 {
46 }
47
14957cd0
A
48 explicit AssemblerLabel(uint32_t offset)
49 : m_offset(offset)
9dae56ea 50 {
9dae56ea
A
51 }
52
14957cd0 53 bool isSet() const { return (m_offset != std::numeric_limits<uint32_t>::max()); }
9dae56ea 54
14957cd0 55 AssemblerLabel labelAtOffset(int offset) const
9dae56ea 56 {
14957cd0 57 return AssemblerLabel(m_offset + offset);
9dae56ea
A
58 }
59
14957cd0
A
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)
9dae56ea 71 {
9dae56ea
A
72 }
73
14957cd0 74 ~AssemblerBuffer()
9dae56ea 75 {
9dae56ea
A
76 }
77
14957cd0 78 bool isAvailable(int space)
9dae56ea 79 {
14957cd0 80 return m_index + space <= m_capacity;
9dae56ea
A
81 }
82
14957cd0 83 void ensureSpace(int space)
9dae56ea 84 {
14957cd0 85 if (!isAvailable(space))
9dae56ea 86 grow();
9dae56ea
A
87 }
88
14957cd0 89 bool isAligned(int alignment) const
9dae56ea 90 {
14957cd0 91 return !(m_index & (alignment - 1));
9dae56ea
A
92 }
93
14957cd0
A
94 template<typename IntegralType>
95 void putIntegral(IntegralType value)
9dae56ea 96 {
14957cd0
A
97 ensureSpace(sizeof(IntegralType));
98 putIntegralUnchecked(value);
9dae56ea
A
99 }
100
14957cd0
A
101 template<typename IntegralType>
102 void putIntegralUnchecked(IntegralType value)
9dae56ea 103 {
14957cd0
A
104 ASSERT(isAvailable(sizeof(IntegralType)));
105 *reinterpret_cast_ptr<IntegralType*>(m_buffer + m_index) = value;
106 m_index += sizeof(IntegralType);
9dae56ea
A
107 }
108
14957cd0
A
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
9dae56ea
A
118 void* data() const
119 {
120 return m_buffer;
121 }
122
14957cd0 123 size_t codeSize() const
9dae56ea 124 {
14957cd0 125 return m_index;
9dae56ea
A
126 }
127
14957cd0 128 AssemblerLabel label() const
9dae56ea 129 {
14957cd0
A
130 return AssemblerLabel(m_index);
131 }
132
93a37866 133 PassRefPtr<ExecutableMemoryHandle> executableCopy(VM& vm, void* ownerUID, JITCompilationEffort effort)
14957cd0
A
134 {
135 if (!m_index)
9dae56ea
A
136 return 0;
137
93a37866 138 RefPtr<ExecutableMemoryHandle> result = vm.executableAllocator.allocate(vm, m_index, ownerUID, effort);
9dae56ea
A
139
140 if (!result)
141 return 0;
142
6fe7ccc8 143 ExecutableAllocator::makeWritable(result->start(), result->sizeInBytes());
ba379fdc 144
6fe7ccc8
A
145 memcpy(result->start(), m_buffer, m_index);
146
147 return result.release();
9dae56ea
A
148 }
149
14957cd0 150 unsigned debugOffset() { return m_index; }
14957cd0 151
ba379fdc
A
152 protected:
153 void append(const char* data, int size)
154 {
14957cd0 155 if (!isAvailable(size))
ba379fdc
A
156 grow(size);
157
14957cd0
A
158 memcpy(m_buffer + m_index, data, size);
159 m_index += size;
ba379fdc
A
160 }
161
162 void grow(int extraCapacity = 0)
9dae56ea 163 {
ba379fdc 164 m_capacity += m_capacity / 2 + extraCapacity;
9dae56ea 165
14957cd0
A
166 m_storage.grow(m_capacity);
167 m_buffer = m_storage.begin();
9dae56ea
A
168 }
169
14957cd0 170 private:
93a37866 171 Vector<char, inlineCapacity, UnsafeVectorOverflow> m_storage;
9dae56ea
A
172 char* m_buffer;
173 int m_capacity;
14957cd0 174 int m_index;
9dae56ea
A
175 };
176
177} // namespace JSC
178
179#endif // ENABLE(ASSEMBLER)
180
181#endif // AssemblerBuffer_h