mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1210554 - Add testAssemblerBuffer to jsapi-tests. r=sstangl
Also minor fixes to the AssemblerBuffer class: - Tighten encapsulation / data hiding. - Use consistent types size_t + void* for raw byte data.
This commit is contained in:
parent
f039e968c0
commit
bd4ef415b5
@ -88,7 +88,7 @@ class BufferSlice
|
||||
next->prev_ = this;
|
||||
}
|
||||
|
||||
void putBytes(size_t numBytes, const uint8_t* source) {
|
||||
void putBytes(size_t numBytes, const void* source) {
|
||||
MOZ_ASSERT(bytelength_ + numBytes <= SliceSize);
|
||||
if (source)
|
||||
memcpy(&instructions[length()], source, numBytes);
|
||||
@ -107,7 +107,6 @@ class AssemblerBuffer
|
||||
Slice* head;
|
||||
Slice* tail;
|
||||
|
||||
public:
|
||||
bool m_oom;
|
||||
bool m_bail;
|
||||
|
||||
@ -139,6 +138,7 @@ class AssemblerBuffer
|
||||
return !(size() & (alignment - 1));
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual Slice* newSlice(LifoAlloc& a) {
|
||||
Slice* tmp = static_cast<Slice*>(a.alloc(sizeof(Slice)));
|
||||
if (!tmp) {
|
||||
@ -148,7 +148,8 @@ class AssemblerBuffer
|
||||
return new (tmp) Slice;
|
||||
}
|
||||
|
||||
bool ensureSpace(int size) {
|
||||
public:
|
||||
bool ensureSpace(size_t size) {
|
||||
// Space can exist in the most recent Slice.
|
||||
if (tail && tail->length() + size <= tail->Capacity()) {
|
||||
// Simulate allocation failure even when we don't need a new slice.
|
||||
@ -181,32 +182,32 @@ class AssemblerBuffer
|
||||
}
|
||||
|
||||
BufferOffset putByte(uint8_t value) {
|
||||
return putBytes(sizeof(value), (uint8_t*)&value);
|
||||
return putBytes(sizeof(value), &value);
|
||||
}
|
||||
|
||||
BufferOffset putShort(uint16_t value) {
|
||||
return putBytes(sizeof(value), (uint8_t*)&value);
|
||||
return putBytes(sizeof(value), &value);
|
||||
}
|
||||
|
||||
BufferOffset putInt(uint32_t value) {
|
||||
return putBytes(sizeof(value), (uint8_t*)&value);
|
||||
return putBytes(sizeof(value), &value);
|
||||
}
|
||||
|
||||
// Add instSize bytes to this buffer.
|
||||
// Add numBytes bytes to this buffer.
|
||||
// The data must fit in a single slice.
|
||||
BufferOffset putBytes(uint32_t instSize, uint8_t* inst) {
|
||||
if (!ensureSpace(instSize))
|
||||
BufferOffset putBytes(size_t numBytes, const void* inst) {
|
||||
if (!ensureSpace(numBytes))
|
||||
return BufferOffset();
|
||||
|
||||
BufferOffset ret = nextOffset();
|
||||
tail->putBytes(instSize, inst);
|
||||
tail->putBytes(numBytes, inst);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Add a potentially large amount of data to this buffer.
|
||||
// The data may be distrubuted across multiple slices.
|
||||
// Return the buffer offset of the first added byte.
|
||||
BufferOffset putBytesLarge(size_t numBytes, const uint8_t* data)
|
||||
BufferOffset putBytesLarge(size_t numBytes, const void* data)
|
||||
{
|
||||
BufferOffset ret = nextOffset();
|
||||
while (numBytes > 0) {
|
||||
@ -216,7 +217,7 @@ class AssemblerBuffer
|
||||
size_t xfer = numBytes < avail ? numBytes : avail;
|
||||
MOZ_ASSERT(xfer > 0, "ensureSpace should have allocated a slice");
|
||||
tail->putBytes(xfer, data);
|
||||
data += xfer;
|
||||
data = (const uint8_t*)data + xfer;
|
||||
numBytes -= xfer;
|
||||
}
|
||||
return ret;
|
||||
@ -239,12 +240,13 @@ class AssemblerBuffer
|
||||
m_bail = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
void update_finger(Slice* finger_, int fingerOffset_) {
|
||||
finger = finger_;
|
||||
finger_offset = fingerOffset_;
|
||||
}
|
||||
|
||||
private:
|
||||
static const unsigned SliceDistanceRequiringFingerUpdate = 3;
|
||||
|
||||
Inst* getInstForwards(BufferOffset off, Slice* start, int startOffset, bool updateFinger = false) {
|
||||
|
@ -90,6 +90,11 @@ UNIFIED_SOURCES += [
|
||||
'testXDR.cpp',
|
||||
]
|
||||
|
||||
SOURCES += [
|
||||
# There are clashing definitions of js::jit::AssemblerBuffer.
|
||||
'testAssemblerBuffer.cpp',
|
||||
]
|
||||
|
||||
if CONFIG['ENABLE_ION']:
|
||||
UNIFIED_SOURCES += [
|
||||
'testJitDCEinGVN.cpp',
|
||||
|
112
js/src/jsapi-tests/testAssemblerBuffer.cpp
Normal file
112
js/src/jsapi-tests/testAssemblerBuffer.cpp
Normal file
@ -0,0 +1,112 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "jsatom.h"
|
||||
|
||||
#include "jit/shared/IonAssemblerBufferWithConstantPools.h"
|
||||
|
||||
#include "jsapi-tests/tests.h"
|
||||
|
||||
// Tests for classes in:
|
||||
//
|
||||
// jit/shared/IonAssemblerBuffer.h
|
||||
// jit/shared/IonAssemblerBufferWithConstantPools.h
|
||||
//
|
||||
// Classes in js::jit tested:
|
||||
//
|
||||
// BufferOffset
|
||||
// BufferSlice (implicitly)
|
||||
// AssemblerBuffer
|
||||
//
|
||||
// BranchDeadlineSet
|
||||
// Pool (implicitly)
|
||||
// AssemblerBufferWithConstantPools
|
||||
//
|
||||
|
||||
BEGIN_TEST(testAssemblerBuffer_BufferOffset)
|
||||
{
|
||||
using js::jit::BufferOffset;
|
||||
|
||||
BufferOffset off1;
|
||||
BufferOffset off2(10);
|
||||
|
||||
CHECK(!off1.assigned());
|
||||
CHECK(off2.assigned());
|
||||
CHECK_EQUAL(off2.getOffset(), 10);
|
||||
off1 = off2;
|
||||
CHECK(off1.assigned());
|
||||
CHECK_EQUAL(off1.getOffset(), 10);
|
||||
|
||||
return true;
|
||||
}
|
||||
END_TEST(testAssemblerBuffer_BufferOffset)
|
||||
|
||||
BEGIN_TEST(testAssemblerBuffer_AssemblerBuffer)
|
||||
{
|
||||
using js::jit::BufferOffset;
|
||||
typedef js::jit::AssemblerBuffer<5 * sizeof(uint32_t), uint32_t> AsmBuf;
|
||||
|
||||
AsmBuf ab;
|
||||
CHECK(ab.isAligned(16));
|
||||
CHECK_EQUAL(ab.size(), 0u);
|
||||
CHECK_EQUAL(ab.nextOffset().getOffset(), 0);
|
||||
CHECK(!ab.oom());
|
||||
CHECK(!ab.bail());
|
||||
|
||||
BufferOffset off1 = ab.putInt(1000017);
|
||||
CHECK_EQUAL(off1.getOffset(), 0);
|
||||
CHECK_EQUAL(ab.size(), 4u);
|
||||
CHECK_EQUAL(ab.nextOffset().getOffset(), 4);
|
||||
CHECK(!ab.isAligned(16));
|
||||
CHECK(ab.isAligned(4));
|
||||
CHECK(ab.isAligned(1));
|
||||
CHECK_EQUAL(*ab.getInst(off1), 1000017u);
|
||||
|
||||
BufferOffset off2 = ab.putInt(1000018);
|
||||
CHECK_EQUAL(off2.getOffset(), 4);
|
||||
|
||||
BufferOffset off3 = ab.putInt(1000019);
|
||||
CHECK_EQUAL(off3.getOffset(), 8);
|
||||
|
||||
BufferOffset off4 = ab.putInt(1000020);
|
||||
CHECK_EQUAL(off4.getOffset(), 12);
|
||||
CHECK_EQUAL(ab.size(), 16u);
|
||||
CHECK_EQUAL(ab.nextOffset().getOffset(), 16);
|
||||
|
||||
// Last one in the slice.
|
||||
BufferOffset off5 = ab.putInt(1000021);
|
||||
CHECK_EQUAL(off5.getOffset(), 16);
|
||||
CHECK_EQUAL(ab.size(), 20u);
|
||||
CHECK_EQUAL(ab.nextOffset().getOffset(), 20);
|
||||
|
||||
BufferOffset off6 = ab.putInt(1000022);
|
||||
CHECK_EQUAL(off6.getOffset(), 20);
|
||||
CHECK_EQUAL(ab.size(), 24u);
|
||||
CHECK_EQUAL(ab.nextOffset().getOffset(), 24);
|
||||
|
||||
// Reference previous slice. Excercise the finger.
|
||||
CHECK_EQUAL(*ab.getInst(off1), 1000017u);
|
||||
CHECK_EQUAL(*ab.getInst(off6), 1000022u);
|
||||
CHECK_EQUAL(*ab.getInst(off1), 1000017u);
|
||||
CHECK_EQUAL(*ab.getInst(off5), 1000021u);
|
||||
|
||||
// Too much data for one slice.
|
||||
const uint32_t fixdata[] = { 2000036, 2000037, 2000038, 2000039, 2000040, 2000041 };
|
||||
|
||||
// Split payload across multiple slices.
|
||||
CHECK_EQUAL(ab.nextOffset().getOffset(), 24);
|
||||
BufferOffset good1 = ab.putBytesLarge(sizeof(fixdata), fixdata);
|
||||
CHECK_EQUAL(good1.getOffset(), 24);
|
||||
CHECK_EQUAL(ab.nextOffset().getOffset(), 48);
|
||||
CHECK_EQUAL(*ab.getInst(good1), 2000036u);
|
||||
CHECK_EQUAL(*ab.getInst(BufferOffset(32)), 2000038u);
|
||||
CHECK_EQUAL(*ab.getInst(BufferOffset(36)), 2000039u);
|
||||
CHECK_EQUAL(*ab.getInst(BufferOffset(40)), 2000040u);
|
||||
CHECK_EQUAL(*ab.getInst(BufferOffset(44)), 2000041u);
|
||||
|
||||
return true;
|
||||
}
|
||||
END_TEST(testAssemblerBuffer_AssemblerBuffer)
|
Loading…
Reference in New Issue
Block a user