2
0
mirror of https://github.com/rehlds/rehlds.git synced 2025-01-30 15:38:05 +03:00

Fixed demo tests passing.

Don't generate any JIT code for empty delta memblocks.
Added bits, bytecount and sendfields checks to delta unit tests.
Small optimizations and fixes.
This commit is contained in:
asmodai 2015-05-23 00:55:26 +03:00
parent 5bb896dcee
commit 4071c13e3a
6 changed files with 210 additions and 109 deletions

View File

@ -402,7 +402,7 @@ void DELTA_SetFieldByIndex(struct delta_s *pFields, int fieldNumber)
void DELTA_UnsetFieldByIndex(struct delta_s *pFields, int fieldNumber)
{
#if defined(REHLDS_OPT_PEDANTIC) || defined(REHLDS_FIXES)
DELTA_UnsetFieldByIndex(pFields, fieldNumber);
DELTAJit_UnsetFieldByIndex(pFields, fieldNumber);
#else
pFields->pdd[fieldNumber].flags &= ~FDT_MARK;
#endif
@ -450,12 +450,20 @@ int DELTA_TestDelta(unsigned char *from, unsigned char *to, delta_t *pFields)
case DT_ANGLE:
different = *(uint32 *)&from[pTest->fieldOffset] != *(uint32 *)&to[pTest->fieldOffset];
break;
#ifdef REHLDS_FIXES
// don't use multiplier when checking, to increase performance
case DT_TIMEWINDOW_8:
case DT_TIMEWINDOW_BIG:
different = (int32)(*(float *)&from[pTest->fieldOffset]) != (int32)(*(float *)&to[pTest->fieldOffset]);
break;
#else
case DT_TIMEWINDOW_8:
different = (int32)(*(float *)&from[pTest->fieldOffset] * 100.0) != (int32)(*(float *)&to[pTest->fieldOffset] * 100.0);
break;
case DT_TIMEWINDOW_BIG:
different = (int32)(*(float *)&from[pTest->fieldOffset] * 1000.0) != (int32)(*(float *)&to[pTest->fieldOffset] * 1000.0);
break;
#endif
case DT_STRING:
st1 = (char*)&from[pTest->fieldOffset];
st2 = (char*)&to[pTest->fieldOffset];
@ -571,21 +579,17 @@ void DELTA_SetSendFlagBits(delta_t *pFields, int *bits, int *bytecount)
delta_description_t *pTest;
int i;
int lastbit = -1;
int bitnumber;
int fieldCount = pFields->fieldCount;
Q_memset(bits, 0, 8);
lastbit = -1;
bitnumber = -1;
for (i = fieldCount - 1, pTest = &pFields->pdd[i]; i >= 0; i--, pTest--)
{
if (pTest->flags & FDT_MARK)
{
if (lastbit == -1)
bitnumber = i;
lastbit = i;
bits[i > 31 ? 1 : 0] |= 1 << (i & 0x1F);
lastbit = bitnumber;
}
}
@ -622,13 +626,13 @@ void DELTA_WriteMarkedFields(unsigned char *from, unsigned char *to, delta_t *pF
for (i = 0, pTest = pFields->pdd; i < fieldCount; i++, pTest++)
{
#ifndef REHLDS_FIXES
if (!(pTest->flags & FDT_MARK))
continue;
#else // REHLDS_FIXES
#if defined (REHLDS_OPT_PEDANTIC) || defined (REHLDS_FIXES)
if (!DELTA_IsFieldMarked(pFields, i))
continue;
#endif // REHLDS_FIXES
#else
if (!(pTest->flags & FDT_MARK))
continue;
#endif
fieldSign = pTest->fieldType & DT_SIGNED;
fieldType = pTest->fieldType & ~DT_SIGNED;
@ -728,15 +732,15 @@ void DELTA_WriteMarkedFields(unsigned char *from, unsigned char *to, delta_t *pF
/* <2467e> ../engine/delta.c:924 */
qboolean DELTA_CheckDelta(unsigned char *from, unsigned char *to, delta_t *pFields)
{
int sendfields;
qboolean sendfields;
#if defined(REHLDS_OPT_PEDANTIC) || defined(REHLDS_FIXES)
sendfields = DELTAJit_Feilds_Clear_Mark_Check(from, to, pFields);
sendfields = DELTAJit_Fields_Clear_Mark_Check(from, to, pFields);
#else
DELTA_ClearFlags(pFields);
DELTA_MarkSendFields(from, to, pFields);
#endif
sendfields = DELTA_CountSendFields(pFields);
#endif
return sendfields;
}
@ -748,7 +752,7 @@ NOINLINE qboolean DELTA_WriteDelta(unsigned char *from, unsigned char *to, qbool
int bytecount;
#if defined(REHLDS_OPT_PEDANTIC) || defined(REHLDS_FIXES)
sendfields = DELTAJit_Feilds_Clear_Mark_Check(from, to, pFields);
sendfields = DELTAJit_Fields_Clear_Mark_Check(from, to, pFields);
#else // REHLDS_OPT_PEDANTIC || REHLDS_FIXES
DELTA_ClearFlags(pFields);
DELTA_MarkSendFields(from, to, pFields);
@ -759,11 +763,11 @@ NOINLINE qboolean DELTA_WriteDelta(unsigned char *from, unsigned char *to, qbool
return sendfields;
}
int _DELTA_WriteDelta(unsigned char *from, unsigned char *to, qboolean force, delta_t *pFields, void(*callback)( void ), int sendfields)
qboolean _DELTA_WriteDelta(unsigned char *from, unsigned char *to, qboolean force, delta_t *pFields, void(*callback)( void ), qboolean sendfields)
{
int i;
int bytecount;
int bits[2]; // this is a limit with 64 fields max in delta
int bits[2];
if (sendfields || force)
{
@ -1090,6 +1094,12 @@ delta_t *DELTA_BuildFromLinks(delta_link_t **pplinks)
DELTA_ReverseLinks(pplinks);
count = DELTA_CountLinks(*pplinks);
#ifdef REHLDS_FIXES
if (count > DELTA_MAX_FIELDS)
Sys_Error(__FUNCTION__ ": Too many fields in delta description %i (MAX %i)\n", count, DELTA_MAX_FIELDS);
#endif
pdesc = (delta_description_t *)Mem_ZeroMalloc(sizeof(delta_description_t) * count);
for (p = *pplinks, pcur = pdesc; p != NULL; p = p->next, pcur++)

View File

@ -29,6 +29,8 @@
#include "maintypes.h"
#define DELTA_MAX_FIELDS 56 // 7*8
#define DT_BYTE BIT(0) // A byte
#define DT_SHORT BIT(1) // 2 byte field
#define DT_FLOAT BIT(2) // A floating point field
@ -137,8 +139,8 @@ void DELTA_SetSendFlagBits(delta_t *pFields, int *bits, int *bytecount);
qboolean DELTA_IsFieldMarked(delta_t* pFields, int fieldNumber);
void DELTA_WriteMarkedFields(unsigned char *from, unsigned char *to, delta_t *pFields);
qboolean DELTA_CheckDelta(unsigned char *from, unsigned char *to, delta_t *pFields);
qboolean DELTA_WriteDelta(unsigned char *from, unsigned char *to, qboolean force, delta_t *pFields, void(*callback)( void ));
qboolean _DELTA_WriteDelta(unsigned char *from, unsigned char *to, qboolean force, delta_t *pFields, void(*callback)(void), int sendfields);
qboolean DELTA_WriteDelta(unsigned char *from, unsigned char *to, qboolean force, delta_t *pFields, void(*callback)(void));
qboolean _DELTA_WriteDelta(unsigned char *from, unsigned char *to, qboolean force, delta_t *pFields, void(*callback)(void), qboolean sendfields);
int DELTA_ParseDelta(unsigned char *from, unsigned char *to, delta_t *pFields);
void DELTA_AddEncoder(char *name, void(*conditionalencode)(struct delta_s *, const unsigned char *, const unsigned char *));
void DELTA_ClearEncoders(void);

View File

@ -3,6 +3,20 @@
CDeltaJitRegistry g_DeltaJitRegistry;
bool deltajit_memblock::isEmpty() const
{
if (numFields == 0)
return true;
for (size_t i = 0; i < numFields; i++)
{
if (fields[i].mask != 0)
return false;
}
return true;
}
uint32 DELTAJIT_CreateMask(int startBit, int endBit) {
if (startBit < 0) startBit = 0;
if (endBit < 0) endBit = 0;
@ -185,9 +199,9 @@ void CDeltaClearMarkFieldsJIT::calculateBytecount() {
// 8-15
if (jitdesc->numFields > 7)
{
mov(ecx, 2);
mov(esi, 2);
test(eax, 0xFF00);
cmovnz(edx, ecx);
cmovnz(edx, esi);
}
// 16-23
@ -201,9 +215,9 @@ void CDeltaClearMarkFieldsJIT::calculateBytecount() {
// 24-31
if (jitdesc->numFields > 23)
{
mov(ecx, 4);
mov(esi, 4);
test(eax, 0xFF000000);
cmovnz(edx, ecx);
cmovnz(edx, esi);
}
if (jitdesc->numFields > 31)
@ -218,9 +232,9 @@ void CDeltaClearMarkFieldsJIT::calculateBytecount() {
// 40-47
if (jitdesc->numFields > 39)
{
mov(ecx, 6);
mov(esi, 6);
test(eax, 0xFF00);
cmovnz(edx, ecx);
cmovnz(edx, esi);
}
// 48-55
@ -231,12 +245,7 @@ void CDeltaClearMarkFieldsJIT::calculateBytecount() {
cmovnz(edx, ecx);
}
if (jitdesc->numFields > 55)
{
mov(ecx, 8);
test(eax, 0xFF000000);
cmovnz(edx, ecx);
}
// maxfields is 56
}
size_t delta_masksize_offset = offsetof(CDeltaJit, markedFieldsMaskSize);
@ -251,33 +260,42 @@ CDeltaClearMarkFieldsJIT::Result CDeltaClearMarkFieldsJIT::main(Addr src, Addr d
mov(esi, ptr[src]);
mov(edi, ptr[dst]);
//mov(ebx, ptr[delta]);
//int fieldsOffset = (offsetof(delta_t, pdd));
//mov(ebx, dword_ptr[ebx + fieldsOffset]);
movdqu(xmm3, xmmword_ptr[esi]);
movdqu(xmm4, xmmword_ptr[edi]);
for (unsigned int i = 0; i < jitdesc->numblocks; i++) {
if (!jitdesc->blocks[i].isEmpty()) {
movdqu(xmm3, xmmword_ptr[esi + (i * 16)]);
movdqu(xmm4, xmmword_ptr[edi + (i * 16)]);
break;
}
}
auto mask = ecx;
xor_(mask, mask);
pxor(marked_fields_mask, marked_fields_mask);
for (unsigned int i = 0; i < jitdesc->numblocks; i++) {
auto block = &jitdesc->blocks[i];
if (block->isEmpty())
continue;
movdqa(xmm0, xmm3);
movdqa(xmm1, xmm4);
//prefetch next blocks
if (i + 1 < jitdesc->numblocks) {
movdqu(xmm3, xmmword_ptr[esi + ((i + 1) * 16)]);
movdqu(xmm4, xmmword_ptr[edi + ((i + 1) * 16)]);
for (unsigned int j = i + 1; j < jitdesc->numblocks; j++) {
if (!jitdesc->blocks[j].isEmpty()) {
movdqu(xmm3, xmmword_ptr[esi + (j * 16)]);
movdqu(xmm4, xmmword_ptr[edi + (j * 16)]);
break;
}
}
pcmpeqb(xmm0, xmm1);
pmovmskb(mask, xmm0);
not_(mask);
auto block = &jitdesc->blocks[i];
for (unsigned int j = 0; j < block->numFields; j++) {
auto jitField = &block->fields[j];
@ -322,8 +340,6 @@ CDeltaClearMarkFieldsJIT::Result CDeltaClearMarkFieldsJIT::main(Addr src, Addr d
}
}
processStrings(src, dst);
size_t delta_markbits_offset = offsetof(CDeltaJit, marked_fields_mask);
//Before calling the condition encoder we have to save 'marked fields' mask
@ -331,33 +347,38 @@ CDeltaClearMarkFieldsJIT::Result CDeltaClearMarkFieldsJIT::main(Addr src, Addr d
mov(ebx, ptr[deltaJit]);
movdqu(xmmword_ptr[ebx + delta_markbits_offset], marked_fields_mask);
processStrings(src, dst);
//emit conditional encoder call
callConditionalEncoder(src, dst, deltaJit);
// check if mask is empty
mov(edi, dword_ptr[ebx + delta_markbits_offset]);
mov(edx, dword_ptr[ebx + delta_markbits_offset + 4]);
or_(edi, edx);
or_(edi, dword_ptr[ebx + delta_markbits_offset + 4]);
If(edi != 0);
calculateBytecount();
Else();
//set maskSize to 0 if there are no marked fields
size_t delta_masksize_offset = offsetof(CDeltaJit, markedFieldsMaskSize);
mov(dword_ptr[ebx + delta_masksize_offset], 0);
xor_(edx, edx);
mov(dword_ptr[ebx + delta_masksize_offset], edx);
EndIf();
#ifndef REHLDS_FIXES
add(esp, 12); //some local storage is required for precise DT_TIMEWINDOW marking
#endif // REHLDS_FIXES
return edi;
return edx;
}
void CDeltaClearMarkFieldsJIT::processStrings(Addr src, Addr dst) {
//This generator expects that following registers are already initialized:
// esi = src
// edi = dst
// ebx = deltaJit
size_t delta_markbits_offset = offsetof(CDeltaJit, marked_fields_mask);
//strings
for (unsigned int i = 0; i < jitdesc->numFields; i++) {
@ -365,23 +386,21 @@ void CDeltaClearMarkFieldsJIT::processStrings(Addr src, Addr dst) {
if (jitField->type != DT_STRING)
continue;
mov(eax, esi);
mov(edx, edi);
add(eax, jitField->offset);
add(edx, jitField->offset);
// will be parallel
lea(eax, ptr[esi + jitField->offset]);
lea(edx, ptr[edi + jitField->offset]);
push(eax);
push(edx);
mov(ecx, (size_t)&Q_stricmp);
call(ecx);
add(esp, 8);
xor_(ecx, ecx);
test(eax, eax);
setnz(cl);
movzx(ecx, cl);
movd(xmm0, ecx);
psllq(xmm0, jitField->id);
por(xmm5, xmm0);
shl(ecx, jitField->id & 31);
or_(ptr[ebx + delta_markbits_offset + ((jitField->id > 31) ? 4 : 0)], ecx);
}
}
@ -442,7 +461,7 @@ CDeltaJit* DELTAJit_LookupDeltaJit(const char* callsite, delta_t *pFields) {
return deltaJit;
}
NOINLINE int DELTAJit_Feilds_Clear_Mark_Check(unsigned char *from, unsigned char *to, delta_t *pFields) {
NOINLINE int DELTAJit_Fields_Clear_Mark_Check(unsigned char *from, unsigned char *to, delta_t *pFields) {
CDeltaJit* deltaJit = DELTAJit_LookupDeltaJit(__FUNCTION__, pFields);
CDeltaClearMarkFieldsJIT &func = *deltaJit->cleanMarkCheckFunc;
return func(from, to, deltaJit);

View File

@ -23,6 +23,7 @@ struct deltajit_memblock_field {
struct deltajit_memblock {
unsigned int numFields;
deltajit_memblock_field fields[24];
bool isEmpty() const;
};
struct deltajitdata_t {
@ -57,7 +58,7 @@ public:
extern CDeltaJitRegistry g_DeltaJitRegistry;
extern int DELTAJit_Feilds_Clear_Mark_Check(unsigned char *from, unsigned char *to, delta_t *pFields);
extern int DELTAJit_Fields_Clear_Mark_Check(unsigned char *from, unsigned char *to, delta_t *pFields);
extern void DELTAJit_SetSendFlagBits(delta_t *pFields, int *bits, int *bytecount);
extern void DELTAJit_SetFieldByIndex(struct delta_s *pFields, int fieldNumber);
extern void DELTAJit_UnsetFieldByIndex(struct delta_s *pFields, int fieldNumber);

View File

@ -1387,11 +1387,17 @@ void SV_WriteClientdataToMessage(client_t *client, sizebuf_t *msg)
else
fdata = &host_client->frames[bits].weapondata[i];
if (DELTA_CheckDelta((byte *)fdata, (byte *)tdata, (delta_t *)g_pweapondelta))
if (DELTA_CheckDelta((byte *)fdata, (byte *)tdata, g_pweapondelta))
{
MSG_WriteBits(1, 1);
MSG_WriteBits(i, 6);
DELTA_WriteDelta((byte *)fdata, (byte *)tdata, TRUE, (delta_t *)g_pweapondelta, NULL);
#if defined (REHLDS_OPT_PEDANTIC) || defined (REHLDS_FIXES)
// all calculations are already done
_DELTA_WriteDelta((byte *)fdata, (byte *)tdata, TRUE, g_pweapondelta, NULL, TRUE);
#else
DELTA_WriteDelta((byte *)fdata, (byte *)tdata, TRUE, g_pweapondelta, NULL);
#endif
}
}
}

View File

@ -27,6 +27,13 @@ struct delta_test_struct_t {
};
#pragma pack(pop)
struct delta_res_t
{
qboolean sendfields;
int bits[2];
int bytecount;
};
NOINLINE void _InitDeltaField(delta_description_t* fieldDesc, int expectedOffset, int type, const char* name, int off, short sz, int bits, float preMult, float postMult) {
if (expectedOffset != off) {
rehlds_syserror("%s: Expected and real offset mismatch (%d != %d)", expectedOffset, off);
@ -56,7 +63,7 @@ NOINLINE qboolean _DoMarkFields(void* src, void* dst, delta_t* delta, bool useJi
qboolean sendfields;
if (useJit) {
DELTA_ClearFlags(delta);
return DELTAJit_Feilds_Clear_Mark_Check((unsigned char*)src, (unsigned char*)dst, delta);
return DELTAJit_Fields_Clear_Mark_Check((unsigned char*)src, (unsigned char*)dst, delta);
} else {
DELTA_ClearFlags(delta);
DELTA_MarkSendFields((unsigned char*)src, (unsigned char*)dst, delta);
@ -118,9 +125,31 @@ NOINLINE void _EnsureFieldsChanged(const char* callsite, const char* action, int
}
}
NOINLINE void _GetBitmaskAndBytecount(delta_t* delta, int* bits, int* bytecount, int usejit) {
if (usejit) {
DELTAJit_SetSendFlagBits(delta, bits, bytecount);
}
else {
DELTA_SetSendFlagBits(delta, bits, bytecount);
}
}
NOINLINE void _CompareDeltaResults(const char* callsite, delta_res_t* def, delta_res_t* jit, int testscount)
{
for (int i = 0; i < testscount; i++)
{
if (!!def[i].sendfields != !!jit[i].sendfields)
rehlds_syserror("%s: Test %i: !!sendfields not equals %i|%i", callsite, i, !!def[i].sendfields, !!jit[i].sendfields);
if (memcmp(def[i].bits, jit[i].bits, 8))
rehlds_syserror("%s: Test %i: bits not equals %p.%p|%p.%p", callsite, i, def[i].bits[0], def[i].bits[1], jit[i].bits[0], jit[i].bits[1]);
if (def[i].bytecount != jit[i].bytecount)
rehlds_syserror("%s: Test %i: bytecount not equal %i|%i", callsite, i, def[i].bytecount, jit[i].bytecount);
}
}
NOINLINE delta_t* _CreateTestDeltaDesc() {
static delta_description_t _fields[32];
delta_test_struct_t d;
delta_test_struct_t d; d; // "use" d variable
_InitDeltaField(&_fields[0], 0x00, DT_BYTE, "b_00", offsetof(delta_test_struct_t, b_00), 1, 8, 1.0f, 1.0f);
_InitDeltaField(&_fields[1], 0x01, DT_BYTE, "b_01", offsetof(delta_test_struct_t, b_01), 1, 8, 1.0f, 1.0f);
@ -166,198 +195,225 @@ NOINLINE delta_t* _CreateTestDeltaDesc() {
};
TEST(MarkFieldsTest_Simple_Primitives, Delta, 1000) {
#ifdef REHLDS_FIXES
bool rehds_fixes = true;
#else
bool rehds_fixes = false;
#endif
delta_t* delta = _CreateTestDeltaDesc();
delta_test_struct_t d1;
delta_test_struct_t d2;
delta_res_t res[2][10];
memset(res[0], 0xCC, sizeof(res) / 2);
memset(res[1], 0xDD, sizeof(res) / 2);
for (int usejit = 0; usejit <= 1; usejit++) {
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71);
_DoMarkFields(&d1, &d2, delta, usejit != 0);
res[usejit][0].sendfields = _DoMarkFields(&d1, &d2, delta, usejit != 0);
_GetBitmaskAndBytecount(delta, res[usejit][0].bits, &res[usejit][0].bytecount, usejit);
_EnsureFieldsChanged(__FUNCTION__, "SimpleUnchangedAll", usejit, true, delta, NULL);
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x72);
_DoMarkFields(&d1, &d2, delta, usejit != 0);
res[usejit][1].sendfields = _DoMarkFields(&d1, &d2, delta, usejit != 0);
_GetBitmaskAndBytecount(delta, res[usejit][1].bits, &res[usejit][1].bytecount, usejit);
_EnsureFieldsChanged(__FUNCTION__, "SimpleUnchangedAll", usejit, false, delta, NULL);
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71);
d2.b_01 = 0;
_DoMarkFields(&d1, &d2, delta, usejit != 0);
res[usejit][2].sendfields = _DoMarkFields(&d1, &d2, delta, usejit != 0);
_GetBitmaskAndBytecount(delta, res[usejit][2].bits, &res[usejit][2].bytecount, usejit);
_EnsureFieldsChanged(__FUNCTION__, "Byte_0BlockCheck", usejit, true, delta, "b_01", NULL);
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71);
d2.b_11 = 0;
_DoMarkFields(&d1, &d2, delta, usejit != 0);
res[usejit][3].sendfields = _DoMarkFields(&d1, &d2, delta, usejit != 0);
_GetBitmaskAndBytecount(delta, res[usejit][3].bits, &res[usejit][3].bytecount, usejit);
_EnsureFieldsChanged(__FUNCTION__, "Byte_1BlockCheck", usejit, true, delta, "b_11", NULL);
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71);
d2.s_02 = 0;
_DoMarkFields(&d1, &d2, delta, usejit != 0);
res[usejit][4].sendfields = _DoMarkFields(&d1, &d2, delta, usejit != 0);
_GetBitmaskAndBytecount(delta, res[usejit][4].bits, &res[usejit][4].bytecount, usejit);
_EnsureFieldsChanged(__FUNCTION__, "Short_0BlockCheck", usejit, true, delta, "s_02", NULL);
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71);
d2.s_12 = 0;
_DoMarkFields(&d1, &d2, delta, usejit != 0);
res[usejit][5].sendfields = _DoMarkFields(&d1, &d2, delta, usejit != 0);
_GetBitmaskAndBytecount(delta, res[usejit][5].bits, &res[usejit][5].bytecount, usejit);
_EnsureFieldsChanged(__FUNCTION__, "Short_1BlockCheck", usejit, true, delta, "s_12", NULL);
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71);
d2.i_04 = 0;
_DoMarkFields(&d1, &d2, delta, usejit != 0);
res[usejit][6].sendfields = _DoMarkFields(&d1, &d2, delta, usejit != 0);
_GetBitmaskAndBytecount(delta, res[usejit][6].bits, &res[usejit][6].bytecount, usejit);
_EnsureFieldsChanged(__FUNCTION__, "Int_0BlockCheck", usejit, true, delta, "i_04", NULL);
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71);
d2.i_14 = 0;
_DoMarkFields(&d1, &d2, delta, usejit != 0);
res[usejit][7].sendfields = _DoMarkFields(&d1, &d2, delta, usejit != 0);
_GetBitmaskAndBytecount(delta, res[usejit][7].bits, &res[usejit][7].bytecount, usejit);
_EnsureFieldsChanged(__FUNCTION__, "Int_1BlockCheck", usejit, true, delta, "i_14", NULL);
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71);
d2.f_08 = 0;
_DoMarkFields(&d1, &d2, delta, usejit != 0);
res[usejit][8].sendfields = _DoMarkFields(&d1, &d2, delta, usejit != 0);
_GetBitmaskAndBytecount(delta, res[usejit][8].bits, &res[usejit][8].bytecount, usejit);
_EnsureFieldsChanged(__FUNCTION__, "Float_0BlockCheck", usejit, true, delta, "f_08", NULL);
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71);
d2.f_18 = 0;
_DoMarkFields(&d1, &d2, delta, usejit != 0);
res[usejit][9].sendfields = _DoMarkFields(&d1, &d2, delta, usejit != 0);
_GetBitmaskAndBytecount(delta, res[usejit][9].bits, &res[usejit][9].bytecount, usejit);
_EnsureFieldsChanged(__FUNCTION__, "Float_0BlockCheck", usejit, true, delta, "f_18", NULL);
}
_CompareDeltaResults(__FUNCTION__, res[0], res[1], 10);
SV_Shutdown();
}
TEST(MarkFieldsTest_InterBlock, Delta, 1000) {
#ifdef REHLDS_FIXES
bool rehds_fixes = true;
#else
bool rehds_fixes = false;
#endif
delta_t* delta = _CreateTestDeltaDesc();
delta_test_struct_t d1;
delta_test_struct_t d2;
delta_res_t res[2][14];
memset(res[0], 0xCC, sizeof(res) / 2);
memset(res[1], 0xDD, sizeof(res) / 2);
for (int usejit = 0; usejit <= 1; usejit++) {
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71);
d2.b_4D = d2.b_52 = 0;
_DoMarkFields(&d1, &d2, delta, usejit != 0);
res[usejit][0].sendfields = _DoMarkFields(&d1, &d2, delta, usejit != 0);
_GetBitmaskAndBytecount(delta, res[usejit][0].bits, &res[usejit][0].bytecount, usejit);
_EnsureFieldsChanged(__FUNCTION__, "Interblock1_guards", usejit, true, delta, "b_4D", "b_52", NULL);
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71);
d2.b_4D = d2.b_52 = 0;
d2.i_4E = 0;
_DoMarkFields(&d1, &d2, delta, usejit != 0);
res[usejit][1].sendfields = _DoMarkFields(&d1, &d2, delta, usejit != 0);
_GetBitmaskAndBytecount(delta, res[usejit][1].bits, &res[usejit][1].bytecount, usejit);
_EnsureFieldsChanged(__FUNCTION__, "Interblock1_guards_and_val", usejit, true, delta, "b_4D", "b_52", "i_4E", NULL);
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71);
d2.i_4E = 0;
_DoMarkFields(&d1, &d2, delta, usejit != 0);
res[usejit][2].sendfields = _DoMarkFields(&d1, &d2, delta, usejit != 0);
_GetBitmaskAndBytecount(delta, res[usejit][2].bits, &res[usejit][2].bytecount, usejit);
_EnsureFieldsChanged(__FUNCTION__, "Interblock1_val", usejit, true, delta, "i_4E", NULL);
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71);
d2.i_4E &= 0xFFFFFF00;
_DoMarkFields(&d1, &d2, delta, usejit != 0);
res[usejit][3].sendfields = _DoMarkFields(&d1, &d2, delta, usejit != 0);
_GetBitmaskAndBytecount(delta, res[usejit][3].bits, &res[usejit][3].bytecount, usejit);
_EnsureFieldsChanged(__FUNCTION__, "Interblock1_val_0b", usejit, true, delta, "i_4E", NULL);
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71);
d2.i_4E &= 0xFFFF00FF;
_DoMarkFields(&d1, &d2, delta, usejit != 0);
res[usejit][4].sendfields = _DoMarkFields(&d1, &d2, delta, usejit != 0);
_GetBitmaskAndBytecount(delta, res[usejit][4].bits, &res[usejit][4].bytecount, usejit);
_EnsureFieldsChanged(__FUNCTION__, "Interblock1_val_1b", usejit, true, delta, "i_4E", NULL);
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71);
d2.i_4E &= 0xFF00FFFF;
_DoMarkFields(&d1, &d2, delta, usejit != 0);
res[usejit][5].sendfields = _DoMarkFields(&d1, &d2, delta, usejit != 0);
_GetBitmaskAndBytecount(delta, res[usejit][5].bits, &res[usejit][5].bytecount, usejit);
_EnsureFieldsChanged(__FUNCTION__, "Interblock1_val_2b", usejit, true, delta, "i_4E", NULL);
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71);
d2.i_4E &= 0x00FFFFFF;
_DoMarkFields(&d1, &d2, delta, usejit != 0);
res[usejit][6].sendfields = _DoMarkFields(&d1, &d2, delta, usejit != 0);
_GetBitmaskAndBytecount(delta, res[usejit][6].bits, &res[usejit][6].bytecount, usejit);
_EnsureFieldsChanged(__FUNCTION__, "Interblock1_val_3b", usejit, true, delta, "i_4E", NULL);
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71);
d2.b_5C = d2.b_61 = 0;
_DoMarkFields(&d1, &d2, delta, usejit != 0);
res[usejit][7].sendfields = _DoMarkFields(&d1, &d2, delta, usejit != 0);
_GetBitmaskAndBytecount(delta, res[usejit][7].bits, &res[usejit][7].bytecount, usejit);
_EnsureFieldsChanged(__FUNCTION__, "Interblock2_guards", usejit, true, delta, "b_5C", "b_61", NULL);
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71);
d2.b_5C = d2.b_61 = 0;
d2.i_5D = 0;
_DoMarkFields(&d1, &d2, delta, usejit != 0);
res[usejit][8].sendfields = _DoMarkFields(&d1, &d2, delta, usejit != 0);
_GetBitmaskAndBytecount(delta, res[usejit][8].bits, &res[usejit][8].bytecount, usejit);
_EnsureFieldsChanged(__FUNCTION__, "Interblock2_guards_and_val", usejit, true, delta, "b_5C", "b_61", "i_5D", NULL);
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71);
d2.i_5D = 0;
_DoMarkFields(&d1, &d2, delta, usejit != 0);
res[usejit][9].sendfields = _DoMarkFields(&d1, &d2, delta, usejit != 0);
_GetBitmaskAndBytecount(delta, res[usejit][9].bits, &res[usejit][9].bytecount, usejit);
_EnsureFieldsChanged(__FUNCTION__, "Interblock2_val", usejit, true, delta, "i_5D", NULL);
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71);
d2.i_5D &= 0xFFFFFF00;
_DoMarkFields(&d1, &d2, delta, usejit != 0);
res[usejit][10].sendfields = _DoMarkFields(&d1, &d2, delta, usejit != 0);
_GetBitmaskAndBytecount(delta, res[usejit][10].bits, &res[usejit][10].bytecount, usejit);
_EnsureFieldsChanged(__FUNCTION__, "Interblock2_val_0b", usejit, true, delta, "i_5D", NULL);
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71);
d2.i_5D &= 0xFFFF00FF;
_DoMarkFields(&d1, &d2, delta, usejit != 0);
res[usejit][11].sendfields = _DoMarkFields(&d1, &d2, delta, usejit != 0);
_GetBitmaskAndBytecount(delta, res[usejit][11].bits, &res[usejit][11].bytecount, usejit);
_EnsureFieldsChanged(__FUNCTION__, "Interblock2_val_1b", usejit, true, delta, "i_5D", NULL);
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71);
d2.i_5D &= 0xFF00FFFF;
_DoMarkFields(&d1, &d2, delta, usejit != 0);
res[usejit][12].sendfields = _DoMarkFields(&d1, &d2, delta, usejit != 0);
_GetBitmaskAndBytecount(delta, res[usejit][12].bits, &res[usejit][12].bytecount, usejit);
_EnsureFieldsChanged(__FUNCTION__, "Interblock2_val_2b", usejit, true, delta, "i_5D", NULL);
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71);
d2.i_5D &= 0x00FFFFFF;
_DoMarkFields(&d1, &d2, delta, usejit != 0);
res[usejit][13].sendfields = _DoMarkFields(&d1, &d2, delta, usejit != 0);
_GetBitmaskAndBytecount(delta, res[usejit][13].bits, &res[usejit][13].bytecount, usejit);
_EnsureFieldsChanged(__FUNCTION__, "Interblock2_val_3b", usejit, true, delta, "i_5D", NULL);
}
_CompareDeltaResults(__FUNCTION__, res[0], res[1], 14);
SV_Shutdown();
}
TEST(MarkFieldsTest_Strings, Delta, 1000) {
#ifdef REHLDS_FIXES
bool rehds_fixes = true;
#else
bool rehds_fixes = false;
#endif
delta_t* delta = _CreateTestDeltaDesc();
delta_test_struct_t d1;
delta_test_struct_t d2;
delta_res_t res[2][4];
memset(res[0], 0xCC, sizeof(res) / 2);
memset(res[1], 0xDD, sizeof(res) / 2);
for (int usejit = 0; usejit <= 1; usejit++) {
_FillTestDelta(&d1, 'c'); _FillTestDelta(&d2, 'c');
d2.s_24[0] = 0;
_DoMarkFields(&d1, &d2, delta, usejit != 0);
res[usejit][0].sendfields = _DoMarkFields(&d1, &d2, delta, usejit != 0);
_GetBitmaskAndBytecount(delta, res[usejit][0].bits, &res[usejit][0].bytecount, usejit);
_EnsureFieldsChanged(__FUNCTION__, "Str_empty", usejit, true, delta, "s_24", NULL);
_FillTestDelta(&d1, 'c'); _FillTestDelta(&d2, 'c');
d1.s_24[0] = 0;
_DoMarkFields(&d1, &d2, delta, usejit != 0);
res[usejit][1].sendfields = _DoMarkFields(&d1, &d2, delta, usejit != 0);
_GetBitmaskAndBytecount(delta, res[usejit][1].bits, &res[usejit][1].bytecount, usejit);
_EnsureFieldsChanged(__FUNCTION__, "Str_empty2", usejit, true, delta, "s_24", NULL);
_FillTestDelta(&d1, 'c'); _FillTestDelta(&d2, 'c');
d1.s_24[0] = d2.s_24[0] = 0;
d1.s_24[1] = 'd'; d2.s_24[1] = 'e';
_DoMarkFields(&d1, &d2, delta, usejit != 0);
res[usejit][2].sendfields = _DoMarkFields(&d1, &d2, delta, usejit != 0);
_GetBitmaskAndBytecount(delta, res[usejit][2].bits, &res[usejit][2].bytecount, usejit);
_EnsureFieldsChanged(__FUNCTION__, "Str_both_empty_with_garbage", usejit, true, delta, NULL);
_FillTestDelta(&d1, 'c'); _FillTestDelta(&d2, 'c');
d1.s_24[1] = 'C';
_DoMarkFields(&d1, &d2, delta, usejit != 0);
res[usejit][3].sendfields = _DoMarkFields(&d1, &d2, delta, usejit != 0);
_GetBitmaskAndBytecount(delta, res[usejit][3].bits, &res[usejit][3].bytecount, usejit);
_EnsureFieldsChanged(__FUNCTION__, "Str_case_check", usejit, true, delta, NULL);
}
_CompareDeltaResults(__FUNCTION__, res[0], res[1], 4);
SV_Shutdown();
}
@ -372,25 +428,32 @@ TEST(MarkFieldsTest_TimeWindow, Delta, 1000) {
delta_test_struct_t d1;
delta_test_struct_t d2;
delta_res_t res[2][3];
memset(res[0], 0xCC, sizeof(res) / 2);
memset(res[1], 0xDD, sizeof(res) / 2);
for (int usejit = 0; usejit <= 1; usejit++) {
_FillTestDelta(&d1, 'c'); _FillTestDelta(&d2, 'c');
d2.w8_1C = 0.001f; d1.w8_1C = 0.0011f;
_DoMarkFields(&d1, &d2, delta, usejit != 0);
res[usejit][0].sendfields = _DoMarkFields(&d1, &d2, delta, usejit != 0);
_GetBitmaskAndBytecount(delta, res[usejit][0].bits, &res[usejit][0].bytecount, usejit);
_EnsureFieldsChanged(__FUNCTION__, "TimeWindow_Below_Precision", usejit, true, delta, rehds_fixes ? "w8_1C" : NULL, NULL);
_FillTestDelta(&d1, 'c'); _FillTestDelta(&d2, 'c');
d2.w8_1C = 0.1f; d1.w8_1C = 0.11f; //precision check, 0.11f is actually 0.10999
_DoMarkFields(&d1, &d2, delta, usejit != 0);
res[usejit][1].sendfields = _DoMarkFields(&d1, &d2, delta, usejit != 0);
_GetBitmaskAndBytecount(delta, res[usejit][1].bits, &res[usejit][1].bytecount, usejit);
_EnsureFieldsChanged(__FUNCTION__, "TimeWindow_Above_Precision1", usejit, true, delta, rehds_fixes ? "w8_1C" : NULL, NULL);
_FillTestDelta(&d1, 'c'); _FillTestDelta(&d2, 'c');
d2.w8_1C = 0.1f; d1.w8_1C = 0.12f;
_DoMarkFields(&d1, &d2, delta, usejit != 0);
res[usejit][2].sendfields = _DoMarkFields(&d1, &d2, delta, usejit != 0);
_GetBitmaskAndBytecount(delta, res[usejit][2].bits, &res[usejit][2].bytecount, usejit);
_EnsureFieldsChanged(__FUNCTION__, "TimeWindow_Above_Precision2", usejit, true, delta, "w8_1C", NULL);
}
_CompareDeltaResults(__FUNCTION__, res[0], res[1], 3);
SV_Shutdown();
}