AssemblerBuffer.h revision 2daae5fd11344eaa88a0d92b0f6d65f8d2255c00
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 38namespace 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 199