/*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2012, 2014 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
#if ENABLE(ASSEMBLER)
+#include "ExecutableAllocator.h"
+#include "JITCompilationEffort.h"
#include "stdint.h"
#include <string.h>
-#include <jit/ExecutableAllocator.h>
#include <wtf/Assertions.h>
#include <wtf/FastMalloc.h>
#include <wtf/StdLibExtras.h>
uint32_t m_offset;
};
- class AssemblerBuffer {
- static const int inlineCapacity = 128;
+ class AssemblerData {
public:
- AssemblerBuffer()
- : m_storage(inlineCapacity)
- , m_buffer(m_storage.begin())
- , m_capacity(inlineCapacity)
- , m_index(0)
+ AssemblerData()
+ : m_buffer(nullptr)
+ , m_capacity(0)
{
}
- ~AssemblerBuffer()
+ AssemblerData(unsigned initialCapacity)
{
+ m_capacity = initialCapacity;
+ m_buffer = static_cast<char*>(fastMalloc(m_capacity));
}
- bool isAvailable(int space)
+ AssemblerData(AssemblerData&& other)
{
- return m_index + space <= m_capacity;
+ m_buffer = other.m_buffer;
+ other.m_buffer = nullptr;
+ m_capacity = other.m_capacity;
+ other.m_capacity = 0;
}
- void ensureSpace(int space)
+ AssemblerData& operator=(AssemblerData&& other)
{
- if (!isAvailable(space))
- grow();
+ m_buffer = other.m_buffer;
+ other.m_buffer = nullptr;
+ m_capacity = other.m_capacity;
+ other.m_capacity = 0;
+ return *this;
}
- bool isAligned(int alignment) const
+ ~AssemblerData()
{
- return !(m_index & (alignment - 1));
+ fastFree(m_buffer);
}
- template<typename IntegralType>
- void putIntegral(IntegralType value)
+ char* buffer() const { return m_buffer; }
+
+ unsigned capacity() const { return m_capacity; }
+
+ void grow(unsigned extraCapacity = 0)
{
- ensureSpace(sizeof(IntegralType));
- putIntegralUnchecked(value);
+ m_capacity = m_capacity + m_capacity / 2 + extraCapacity;
+ m_buffer = static_cast<char*>(fastRealloc(m_buffer, m_capacity));
}
- template<typename IntegralType>
- void putIntegralUnchecked(IntegralType value)
+ private:
+ char* m_buffer;
+ unsigned m_capacity;
+ };
+
+ class AssemblerBuffer {
+ static const int initialCapacity = 128;
+ public:
+ AssemblerBuffer()
+ : m_storage(initialCapacity)
+ , m_index(0)
{
- ASSERT(isAvailable(sizeof(IntegralType)));
- *reinterpret_cast_ptr<IntegralType*>(m_buffer + m_index) = value;
- m_index += sizeof(IntegralType);
+ }
+
+ bool isAvailable(int space)
+ {
+ return m_index + space <= m_storage.capacity();
+ }
+
+ void ensureSpace(int space)
+ {
+ if (!isAvailable(space))
+ grow();
+ }
+
+ bool isAligned(int alignment) const
+ {
+ return !(m_index & (alignment - 1));
}
void putByteUnchecked(int8_t value) { putIntegralUnchecked(value); }
void* data() const
{
- return m_buffer;
+ return m_storage.buffer();
}
size_t codeSize() const
return AssemblerLabel(m_index);
}
- void* executableCopy(JSGlobalData& globalData, ExecutablePool* allocator)
- {
- if (!m_index)
- return 0;
-
- void* result = allocator->alloc(globalData, m_index);
-
- if (!result)
- return 0;
+ unsigned debugOffset() { return m_index; }
- ExecutableAllocator::makeWritable(result, m_index);
+ AssemblerData releaseAssemblerData() { return WTF::move(m_storage); }
- return memcpy(result, m_buffer, m_index);
+ protected:
+ template<typename IntegralType>
+ void putIntegral(IntegralType value)
+ {
+ unsigned nextIndex = m_index + sizeof(IntegralType);
+ if (UNLIKELY(nextIndex > m_storage.capacity()))
+ grow();
+ ASSERT(isAvailable(sizeof(IntegralType)));
+ *reinterpret_cast_ptr<IntegralType*>(m_storage.buffer() + m_index) = value;
+ m_index = nextIndex;
}
- void rewindToLabel(AssemblerLabel label)
+ template<typename IntegralType>
+ void putIntegralUnchecked(IntegralType value)
{
- m_index = label.m_offset;
+ ASSERT(isAvailable(sizeof(IntegralType)));
+ *reinterpret_cast_ptr<IntegralType*>(m_storage.buffer() + m_index) = value;
+ m_index += sizeof(IntegralType);
}
-#ifndef NDEBUG
- unsigned debugOffset() { return m_index; }
-#endif
-
- protected:
void append(const char* data, int size)
{
if (!isAvailable(size))
grow(size);
- memcpy(m_buffer + m_index, data, size);
+ memcpy(m_storage.buffer() + m_index, data, size);
m_index += size;
}
void grow(int extraCapacity = 0)
{
- m_capacity += m_capacity / 2 + extraCapacity;
-
- m_storage.grow(m_capacity);
- m_buffer = m_storage.begin();
+ m_storage.grow(extraCapacity);
}
private:
- Vector<char, inlineCapacity> m_storage;
- char* m_buffer;
- int m_capacity;
- int m_index;
+ AssemblerData m_storage;
+ unsigned m_index;
};
} // namespace JSC