Home | History | Annotate | Download | only in assembler
      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 
     38 namespace 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