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 #include <wtf/Platform.h> 30 31 #if ENABLE(ASSEMBLER) 32 33 #include "stdint.h" 34 #include <string.h> 35 #include <jit/ExecutableAllocator.h> 36 #include <wtf/Assertions.h> 37 #include <wtf/FastMalloc.h> 38 39 namespace JSC { 40 41 class AssemblerBuffer { 42 static const int inlineCapacity = 256; 43 public: AssemblerBuffer()44 AssemblerBuffer() 45 : m_buffer(m_inlineBuffer) 46 , m_capacity(inlineCapacity) 47 , m_size(0) 48 { 49 } 50 ~AssemblerBuffer()51 ~AssemblerBuffer() 52 { 53 if (m_buffer != m_inlineBuffer) 54 fastFree(m_buffer); 55 } 56 ensureSpace(int space)57 void ensureSpace(int space) 58 { 59 if (m_size > m_capacity - space) 60 grow(); 61 } 62 isAligned(int alignment)63 bool isAligned(int alignment) const 64 { 65 return !(m_size & (alignment - 1)); 66 } 67 putByteUnchecked(int value)68 void putByteUnchecked(int value) 69 { 70 ASSERT(!(m_size > m_capacity - 4)); 71 m_buffer[m_size] = value; 72 m_size++; 73 } 74 putByte(int value)75 void putByte(int value) 76 { 77 if (m_size > m_capacity - 4) 78 grow(); 79 putByteUnchecked(value); 80 } 81 putShortUnchecked(int value)82 void putShortUnchecked(int value) 83 { 84 ASSERT(!(m_size > m_capacity - 4)); 85 *reinterpret_cast<short*>(&m_buffer[m_size]) = value; 86 m_size += 2; 87 } 88 putShort(int value)89 void putShort(int value) 90 { 91 if (m_size > m_capacity - 4) 92 grow(); 93 putShortUnchecked(value); 94 } 95 putIntUnchecked(int value)96 void putIntUnchecked(int value) 97 { 98 ASSERT(!(m_size > m_capacity - 4)); 99 *reinterpret_cast<int*>(&m_buffer[m_size]) = value; 100 m_size += 4; 101 } 102 putInt64Unchecked(int64_t value)103 void putInt64Unchecked(int64_t value) 104 { 105 ASSERT(!(m_size > m_capacity - 8)); 106 *reinterpret_cast<int64_t*>(&m_buffer[m_size]) = value; 107 m_size += 8; 108 } 109 putInt(int value)110 void putInt(int value) 111 { 112 if (m_size > m_capacity - 4) 113 grow(); 114 putIntUnchecked(value); 115 } 116 data()117 void* data() const 118 { 119 return m_buffer; 120 } 121 size()122 int size() const 123 { 124 return m_size; 125 } 126 executableCopy(ExecutablePool * allocator)127 void* executableCopy(ExecutablePool* allocator) 128 { 129 if (!m_size) 130 return 0; 131 132 void* result = allocator->alloc(m_size); 133 134 if (!result) 135 return 0; 136 137 ExecutableAllocator::makeWritable(result, m_size); 138 139 return memcpy(result, m_buffer, m_size); 140 } 141 142 protected: append(const char * data,int size)143 void append(const char* data, int size) 144 { 145 if (m_size > m_capacity - size) 146 grow(size); 147 148 memcpy(m_buffer + m_size, data, size); 149 m_size += size; 150 } 151 152 void grow(int extraCapacity = 0) 153 { 154 m_capacity += m_capacity / 2 + extraCapacity; 155 156 if (m_buffer == m_inlineBuffer) { 157 char* newBuffer = static_cast<char*>(fastMalloc(m_capacity)); 158 m_buffer = static_cast<char*>(memcpy(newBuffer, m_buffer, m_size)); 159 } else 160 m_buffer = static_cast<char*>(fastRealloc(m_buffer, m_capacity)); 161 } 162 163 char m_inlineBuffer[inlineCapacity]; 164 char* m_buffer; 165 int m_capacity; 166 int m_size; 167 }; 168 169 } // namespace JSC 170 171 #endif // ENABLE(ASSEMBLER) 172 173 #endif // AssemblerBuffer_h 174