]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - assembler/AssemblerBuffer.h
JavaScriptCore-903.tar.gz
[apple/javascriptcore.git] / assembler / AssemblerBuffer.h
index e2fb8a1cc68d019c0ed4305e9e5c0b3611bafd69..b98503d0876e96bec8181eb9c261eedb07e059c5 100644 (file)
 #include <jit/ExecutableAllocator.h>
 #include <wtf/Assertions.h>
 #include <wtf/FastMalloc.h>
+#include <wtf/StdLibExtras.h>
 
 namespace JSC {
 
-    class AssemblerBuffer {
-        static const int inlineCapacity = 256;
-    public:
-        AssemblerBuffer()
-            : m_buffer(m_inlineBuffer)
-            , m_capacity(inlineCapacity)
-            , m_size(0)
+    struct AssemblerLabel {
+        AssemblerLabel()
+            : m_offset(std::numeric_limits<uint32_t>::max())
         {
         }
 
-        ~AssemblerBuffer()
+        explicit AssemblerLabel(uint32_t offset)
+            : m_offset(offset)
         {
-            if (m_buffer != m_inlineBuffer)
-                fastFree(m_buffer);
         }
 
-        void ensureSpace(int space)
-        {
-            if (m_size > m_capacity - space)
-                grow();
-        }
+        bool isSet() const { return (m_offset != std::numeric_limits<uint32_t>::max()); }
 
-        bool isAligned(int alignment) const
+        AssemblerLabel labelAtOffset(int offset) const
         {
-            return !(m_size & (alignment - 1));
+            return AssemblerLabel(m_offset + offset);
         }
 
-        void putByteUnchecked(int value)
+        uint32_t m_offset;
+    };
+
+    class AssemblerBuffer {
+        static const int inlineCapacity = 128;
+    public:
+        AssemblerBuffer()
+            : m_storage(inlineCapacity)
+            , m_buffer(m_storage.begin())
+            , m_capacity(inlineCapacity)
+            , m_index(0)
         {
-            ASSERT(!(m_size > m_capacity - 4));
-            m_buffer[m_size] = value;
-            m_size++;
         }
 
-        void putByte(int value)
+        ~AssemblerBuffer()
         {
-            if (m_size > m_capacity - 4)
-                grow();
-            putByteUnchecked(value);
         }
 
-        void putShortUnchecked(int value)
+        bool isAvailable(int space)
         {
-            ASSERT(!(m_size > m_capacity - 4));
-            *reinterpret_cast<short*>(&m_buffer[m_size]) = value;
-            m_size += 2;
+            return m_index + space <= m_capacity;
         }
 
-        void putShort(int value)
+        void ensureSpace(int space)
         {
-            if (m_size > m_capacity - 4)
+            if (!isAvailable(space))
                 grow();
-            putShortUnchecked(value);
         }
 
-        void putIntUnchecked(int value)
+        bool isAligned(int alignment) const
         {
-            ASSERT(!(m_size > m_capacity - 4));
-            *reinterpret_cast<int*>(&m_buffer[m_size]) = value;
-            m_size += 4;
+            return !(m_index & (alignment - 1));
         }
 
-        void putInt64Unchecked(int64_t value)
+        template<typename IntegralType>
+        void putIntegral(IntegralType value)
         {
-            ASSERT(!(m_size > m_capacity - 8));
-            *reinterpret_cast<int64_t*>(&m_buffer[m_size]) = value;
-            m_size += 8;
+            ensureSpace(sizeof(IntegralType));
+            putIntegralUnchecked(value);
         }
 
-        void putInt(int value)
+        template<typename IntegralType>
+        void putIntegralUnchecked(IntegralType value)
         {
-            if (m_size > m_capacity - 4)
-                grow();
-            putIntUnchecked(value);
+            ASSERT(isAvailable(sizeof(IntegralType)));
+            *reinterpret_cast_ptr<IntegralType*>(m_buffer + m_index) = value;
+            m_index += sizeof(IntegralType);
         }
 
+        void putByteUnchecked(int8_t value) { putIntegralUnchecked(value); }
+        void putByte(int8_t value) { putIntegral(value); }
+        void putShortUnchecked(int16_t value) { putIntegralUnchecked(value); }
+        void putShort(int16_t value) { putIntegral(value); }
+        void putIntUnchecked(int32_t value) { putIntegralUnchecked(value); }
+        void putInt(int32_t value) { putIntegral(value); }
+        void putInt64Unchecked(int64_t value) { putIntegralUnchecked(value); }
+        void putInt64(int64_t value) { putIntegral(value); }
+
         void* data() const
         {
             return m_buffer;
         }
 
-        int size() const
+        size_t codeSize() const
         {
-            return m_size;
+            return m_index;
         }
 
-        void* executableCopy(ExecutablePool* allocator)
+        AssemblerLabel label() const
         {
-            if (!m_size)
+            return AssemblerLabel(m_index);
+        }
+
+        void* executableCopy(JSGlobalData& globalData, ExecutablePool* allocator)
+        {
+            if (!m_index)
                 return 0;
 
-            void* result = allocator->alloc(m_size);
+            void* result = allocator->alloc(globalData, m_index);
 
             if (!result)
                 return 0;
 
-            ExecutableAllocator::makeWritable(result, m_size);
+            ExecutableAllocator::makeWritable(result, m_index);
 
-            return memcpy(result, m_buffer, m_size);
+            return memcpy(result, m_buffer, m_index);
         }
 
+        void rewindToLabel(AssemblerLabel label)
+        {
+            m_index = label.m_offset;
+        }
+
+#ifndef NDEBUG
+        unsigned debugOffset() { return m_index; }
+#endif
+
     protected:
         void append(const char* data, int size)
         {
-            if (m_size > m_capacity - size)
+            if (!isAvailable(size))
                 grow(size);
 
-            memcpy(m_buffer + m_size, data, size);
-            m_size += size;
+            memcpy(m_buffer + m_index, data, size);
+            m_index += size;
         }
 
         void grow(int extraCapacity = 0)
         {
             m_capacity += m_capacity / 2 + extraCapacity;
 
-            if (m_buffer == m_inlineBuffer) {
-                char* newBuffer = static_cast<char*>(fastMalloc(m_capacity));
-                m_buffer = static_cast<char*>(memcpy(newBuffer, m_buffer, m_size));
-            } else
-                m_buffer = static_cast<char*>(fastRealloc(m_buffer, m_capacity));
+            m_storage.grow(m_capacity);
+            m_buffer = m_storage.begin();
         }
 
-        char m_inlineBuffer[inlineCapacity];
+    private:
+        Vector<char, inlineCapacity> m_storage;
         char* m_buffer;
         int m_capacity;
-        int m_size;
+        int m_index;
     };
 
 } // namespace JSC