Bug 1125202 - SpiderMonkey: Replace AssemblerBuffer's internals with mozilla::Vector r=sstangl

This commit is contained in:
Dan Gohman 2015-01-30 16:05:55 -08:00
Родитель 69618e3989
Коммит 2742e5d193
3 изменённых файлов: 41 добавлений и 119 удалений

Просмотреть файл

@ -91,7 +91,7 @@ AssemblerX86Shared::trace(JSTracer *trc)
}
if (dataRelocations_.length()) {
CompactBufferReader reader(dataRelocations_);
::TraceDataRelocations(trc, masm.buffer(), reader);
::TraceDataRelocations(trc, masm.data(), reader);
}
}

Просмотреть файл

@ -75,96 +75,78 @@ namespace js {
namespace jit {
class AssemblerBuffer {
static const size_t inlineCapacity = 256;
public:
AssemblerBuffer()
: m_buffer(m_inlineBuffer)
, m_capacity(inlineCapacity)
, m_size(0)
, m_allocSize(0)
, m_oom(false)
: m_oom(false)
{
}
~AssemblerBuffer()
{
if (m_buffer != m_inlineBuffer)
js_free(m_buffer);
}
void ensureSpace(size_t space)
{
if (m_size > m_capacity - space)
grow();
if (MOZ_UNLIKELY(!m_buffer.reserve(m_buffer.length() + space)))
oomDetected();
}
bool isAligned(size_t alignment) const
{
return !(m_size & (alignment - 1));
return !(m_buffer.length() & (alignment - 1));
}
void putByteUnchecked(int value)
{
MOZ_ASSERT(!(m_size > m_capacity - 4));
m_buffer[m_size] = char(value);
m_size++;
m_buffer.infallibleAppend(char(value));
}
void putByte(int value)
{
if (m_size > m_capacity - 4)
grow();
putByteUnchecked(value);
if (MOZ_UNLIKELY(!m_buffer.append(char(value))))
oomDetected();
}
void putShortUnchecked(int value)
{
MOZ_ASSERT(!(m_size > m_capacity - 4));
*reinterpret_cast<short*>(&m_buffer[m_size]) = short(value);
m_size += 2;
m_buffer.infallibleGrowByUninitialized(2);
memcpy(m_buffer.end() - 2, &value, 2);
}
void putShort(int value)
{
if (m_size > m_capacity - 4)
grow();
putShortUnchecked(value);
if (MOZ_UNLIKELY(!m_buffer.growByUninitialized(2))) {
oomDetected();
return;
}
memcpy(m_buffer.end() - 2, &value, 2);
}
void putIntUnchecked(int value)
{
MOZ_ASSERT(!(m_size > m_capacity - 4));
*reinterpret_cast<int*>(&m_buffer[m_size]) = value;
m_size += 4;
m_buffer.infallibleGrowByUninitialized(4);
memcpy(m_buffer.end() - 4, &value, 4);
}
void putInt64Unchecked(int64_t value)
{
MOZ_ASSERT(!(m_size > m_capacity - 8));
*reinterpret_cast<int64_t*>(&m_buffer[m_size]) = value;
m_size += 8;
m_buffer.infallibleGrowByUninitialized(8);
memcpy(m_buffer.end() - 8, &value, 8);
}
void putInt(int value)
{
if (m_size > m_capacity - 4)
grow();
putIntUnchecked(value);
if (MOZ_UNLIKELY(!m_buffer.growByUninitialized(4))) {
oomDetected();
return;
}
memcpy(m_buffer.end() - 4, &value, 4);
}
void* data() const
unsigned char *data()
{
return m_buffer;
return m_buffer.begin();
}
size_t size() const
{
return m_size;
}
size_t allocSize() const
{
return m_allocSize;
return m_buffer.length();
}
bool oom() const
@ -172,91 +154,32 @@ namespace jit {
return m_oom;
}
unsigned char *buffer() const {
const unsigned char *buffer() const {
MOZ_ASSERT(!m_oom);
return reinterpret_cast<unsigned char *>(m_buffer);
return m_buffer.begin();
}
protected:
void append(const char* data, size_t size)
{
if (m_size > m_capacity - size)
grow(size);
// If we OOM and size > inlineCapacity, this would crash.
if (m_oom)
return;
memcpy(m_buffer + m_size, data, size);
m_size += size;
}
/*
* OOM handling: This class can OOM in the grow() method trying to
* allocate a new buffer. In response to an OOM, we need to avoid
* OOM handling: This class can OOM in the ensureSpace() method trying
* to allocate a new buffer. In response to an OOM, we need to avoid
* crashing and report the error. We also want to make it so that
* users of this class need to check for OOM only at certain points
* and not after every operation.
*
* Our strategy for handling an OOM is to set m_oom, and then set
* m_size to 0, preserving the current buffer. This way, the user
* Our strategy for handling an OOM is to set m_oom, and then clear (but
* not free) m_buffer, preserving the current buffer. This way, the user
* can continue assembling into the buffer, deferring OOM checking
* until the user wants to read code out of the buffer.
*
* See also the |buffer| method.
*/
void grow(size_t extraCapacity = 0)
{
char* newBuffer;
/*
* If |extraCapacity| is zero (as it almost always is) this is an
* allocator-friendly doubling growth strategy.
*/
size_t doubleCapacity = m_capacity + m_capacity;
// Check for overflow.
if (doubleCapacity < m_capacity) {
m_size = 0;
m_oom = true;
return;
}
size_t newCapacity = doubleCapacity + extraCapacity;
// Check for overflow.
if (newCapacity < doubleCapacity) {
m_size = 0;
m_oom = true;
return;
}
if (m_buffer == m_inlineBuffer) {
newBuffer = static_cast<char*>(js_malloc(newCapacity));
if (!newBuffer) {
m_size = 0;
m_oom = true;
return;
}
memcpy(newBuffer, m_buffer, m_size);
} else {
newBuffer = static_cast<char*>(js_realloc(m_buffer, newCapacity));
if (!newBuffer) {
m_size = 0;
m_oom = true;
return;
}
}
m_buffer = newBuffer;
m_capacity = newCapacity;
void oomDetected() {
m_oom = true;
m_buffer.clear();
}
char m_inlineBuffer[inlineCapacity];
char* m_buffer;
size_t m_capacity;
size_t m_size;
size_t m_allocSize;
mozilla::Vector<unsigned char, 256, SystemAllocPolicy> m_buffer;
bool m_oom;
};

Просмотреть файл

@ -627,8 +627,8 @@ public:
};
size_t size() const { return m_formatter.size(); }
size_t allocSize() const { return m_formatter.allocSize(); }
unsigned char *buffer() const { return m_formatter.buffer(); }
const unsigned char *buffer() const { return m_formatter.buffer(); }
unsigned char *data() { return m_formatter.data(); }
bool oom() const { return m_formatter.oom(); }
void nop()
@ -5292,11 +5292,10 @@ private:
// Administrative methods:
size_t size() const { return m_buffer.size(); }
size_t allocSize() const { return m_buffer.allocSize(); }
unsigned char *buffer() const { return m_buffer.buffer(); }
const unsigned char *buffer() const { return m_buffer.buffer(); }
bool oom() const { return m_buffer.oom(); }
bool isAligned(int alignment) const { return m_buffer.isAligned(alignment); }
void* data() const { return m_buffer.data(); }
unsigned char *data() { return m_buffer.data(); }
private: