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

Refactoring

DeltaJIT passes tests now
This commit is contained in:
dreamstalker 2015-05-22 02:50:39 +04:00 committed by Andrey
parent 7fdb4f73bc
commit 5bb896dcee
5 changed files with 256 additions and 275 deletions

View File

@ -360,14 +360,14 @@ void DELTA_SetField(struct delta_s *pFields, const char *fieldname)
if (index != -1) if (index != -1)
DELTA_SetFieldByIndex(pFields, index); DELTA_SetFieldByIndex(pFields, index);
#else // REHLDS_OPT_PEDANTIC || REHLDS_FIXES #else
delta_description_t *pTest = DELTA_FindField(pFields, fieldname); delta_description_t *pTest = DELTA_FindField(pFields, fieldname);
if (pTest) if (pTest)
{ {
pTest->flags |= FDT_MARK; pTest->flags |= FDT_MARK;
} }
#endif // REHLDS_OPT_PEDANTIC || REHLDS_FIXES #endif
} }
/* <240b2> ../engine/delta.c:411 */ /* <240b2> ../engine/delta.c:411 */
@ -378,40 +378,34 @@ void DELTA_UnsetField(struct delta_s *pFields, const char *fieldname)
if (index != -1) if (index != -1)
DELTA_UnsetFieldByIndex(pFields, index); DELTA_UnsetFieldByIndex(pFields, index);
#else // REHLDS_OPT_PEDANTIC || REHLDS_FIXES #else
delta_description_t *pTest = DELTA_FindField(pFields, fieldname); delta_description_t *pTest = DELTA_FindField(pFields, fieldname);
if (pTest) if (pTest)
{ {
pTest->flags &= ~FDT_MARK; pTest->flags &= ~FDT_MARK;
} }
#endif // REHLDS_OPT_PEDANTIC || REHLDS_FIXES #endif
} }
/* <24132> ../engine/delta.c:429 */ /* <24132> ../engine/delta.c:429 */
void DELTA_SetFieldByIndex(struct delta_s *pFields, int fieldNumber) void DELTA_SetFieldByIndex(struct delta_s *pFields, int fieldNumber)
{ {
#if defined(REHLDS_OPT_PEDANTIC) || defined(REHLDS_FIXES) #if defined(REHLDS_OPT_PEDANTIC) || defined(REHLDS_FIXES)
if (fieldNumber > 31) DELTAJit_SetFieldByIndex(pFields, fieldNumber);
pFields->markbits[1] |= (1 << (fieldNumber & 0x1F)); #else
else
pFields->markbits[0] |= (1 << fieldNumber);
#else // REHLDS_OPT_PEDANTIC || REHLDS_FIXES
pFields->pdd[fieldNumber].flags |= FDT_MARK; pFields->pdd[fieldNumber].flags |= FDT_MARK;
#endif // REHLDS_OPT_PEDANTIC || REHLDS_FIXES #endif
} }
/* <2416a> ../engine/delta.c:441 */ /* <2416a> ../engine/delta.c:441 */
void DELTA_UnsetFieldByIndex(struct delta_s *pFields, int fieldNumber) void DELTA_UnsetFieldByIndex(struct delta_s *pFields, int fieldNumber)
{ {
#if defined(REHLDS_OPT_PEDANTIC) || defined(REHLDS_FIXES) #if defined(REHLDS_OPT_PEDANTIC) || defined(REHLDS_FIXES)
if (fieldNumber > 31) DELTA_UnsetFieldByIndex(pFields, fieldNumber);
pFields->markbits[1] &= ~(1 << (fieldNumber & 0x1F)); #else
else
pFields->markbits[0] &= ~(1 << fieldNumber);
#else // REHLDS_OPT_PEDANTIC || REHLDS_FIXES
pFields->pdd[fieldNumber].flags &= ~FDT_MARK; pFields->pdd[fieldNumber].flags &= ~FDT_MARK;
#endif // REHLDS_OPT_PEDANTIC || REHLDS_FIXES #endif
} }
/* <23cc4> ../engine/delta.c:453 */ /* <23cc4> ../engine/delta.c:453 */
@ -596,23 +590,23 @@ void DELTA_SetSendFlagBits(delta_t *pFields, int *bits, int *bytecount)
} }
#ifdef REHLDS_FIXES #ifdef REHLDS_FIXES
// fix potencial buffer overflow in force mode if lastbit == -1 // fix for bad bytecount when no fields are marked
*bytecount = ((lastbit + 7) & ~7) >> 3; if (lastbit == -1) {
#else // REHLDS_FIXES *bytecount = 0;
return;
}
#endif
*bytecount = (lastbit >> 3) + 1; *bytecount = (lastbit >> 3) + 1;
#endif // REHLDS_FIXES
} }
qboolean DELTA_IsFieldMarked(delta_t* pFields, int fieldNumber) qboolean DELTA_IsFieldMarked(delta_t* pFields, int fieldNumber)
{ {
#ifdef REHLDS_FIXES #if defined(REHLDS_OPT_PEDANTIC) || defined(REHLDS_FIXES)
if (fieldNumber > 31) return DELTAJit_IsFieldMarked(pFields, fieldNumber);
return pFields->markbits[1] & (1 << (fieldNumber & 0x1F)); #else
return pFields->markbits[0] & (1 << fieldNumber);
#else // REHLDS_FIXES
return pFields->pdd[fieldNumber].flags & FDT_MARK; return pFields->pdd[fieldNumber].flags & FDT_MARK;
#endif // REHLDS_FIXES #endif
} }
/* <2456d> ../engine/delta.c:782 */ /* <2456d> ../engine/delta.c:782 */
@ -754,36 +748,17 @@ NOINLINE qboolean DELTA_WriteDelta(unsigned char *from, unsigned char *to, qbool
int bytecount; int bytecount;
#if defined(REHLDS_OPT_PEDANTIC) || defined(REHLDS_FIXES) #if defined(REHLDS_OPT_PEDANTIC) || defined(REHLDS_FIXES)
DELTAJit_ClearAndMarkSendFields(from, to, pFields, pFields->markbits, &bytecount, force); sendfields = DELTAJit_Feilds_Clear_Mark_Check(from, to, pFields);
_DELTA_WriteDelta(from, to, pFields, pFields->markbits, bytecount);
sendfields = bytecount;
#else // REHLDS_OPT_PEDANTIC || REHLDS_FIXES #else // REHLDS_OPT_PEDANTIC || REHLDS_FIXES
int bits[2];
DELTA_ClearFlags(pFields); DELTA_ClearFlags(pFields);
DELTA_MarkSendFields(from, to, pFields); DELTA_MarkSendFields(from, to, pFields);
sendfields = DELTA_CountSendFields(pFields); sendfields = DELTA_CountSendFields(pFields);
_DELTA_WriteDelta(from, to, force, pFields, callback, sendfields);
#endif // REHLDS_OPT_PEDANTIC || REHLDS_FIXES #endif // REHLDS_OPT_PEDANTIC || REHLDS_FIXES
_DELTA_WriteDelta(from, to, force, pFields, callback, sendfields);
return sendfields; return sendfields;
} }
#if defined(REHLDS_OPT_PEDANTIC) || defined(REHLDS_FIXES)
int _DELTA_WriteDelta(unsigned char *from, unsigned char *to, delta_t *pFields, int* bits, int bytecount)
{
int i;
MSG_WriteBits(bytecount, 3);
for (i = 0; i < bytecount; i++)
{
MSG_WriteBits(( (byte*)bits )[i], 8);
}
DELTA_WriteMarkedFields(from, to, pFields);
return 1;
}
#else // REHLDS_OPT_PEDANTIC || REHLDS_FIXES
/* <24760> ../engine/delta.c:963 */
int _DELTA_WriteDelta(unsigned char *from, unsigned char *to, qboolean force, delta_t *pFields, void(*callback)( void ), int sendfields) int _DELTA_WriteDelta(unsigned char *from, unsigned char *to, qboolean force, delta_t *pFields, void(*callback)( void ), int sendfields)
{ {
int i; int i;
@ -792,15 +767,15 @@ int _DELTA_WriteDelta(unsigned char *from, unsigned char *to, qboolean force, de
if (sendfields || force) if (sendfields || force)
{ {
#if defined(REHLDS_OPT_PEDANTIC) || defined(REHLDS_FIXES)
DELTAJit_SetSendFlagBits(pFields, bits, &bytecount);
#else
DELTA_SetSendFlagBits(pFields, bits, &bytecount); DELTA_SetSendFlagBits(pFields, bits, &bytecount);
#endif
if (callback) if (callback)
callback(); callback();
#ifdef REHLDS_FIXES
bytecount &= 7; // max fields is 56, not 64
#endif // REHLDS_FIXES
MSG_WriteBits(bytecount, 3); MSG_WriteBits(bytecount, 3);
for (i = 0; i < bytecount; i++) for (i = 0; i < bytecount; i++)
{ {
@ -812,7 +787,7 @@ int _DELTA_WriteDelta(unsigned char *from, unsigned char *to, qboolean force, de
return 1; return 1;
} }
#endif // REHLDS_OPT_PEDANTIC || REHLDS_FIXES
/* <24aa0> ../engine/delta.c:1010 */ /* <24aa0> ../engine/delta.c:1010 */
int DELTA_ParseDelta(unsigned char *from, unsigned char *to, delta_t *pFields) int DELTA_ParseDelta(unsigned char *from, unsigned char *to, delta_t *pFields)

View File

@ -81,8 +81,6 @@ typedef struct delta_s
#ifdef REHLDS_FIXES #ifdef REHLDS_FIXES
CDeltaJit* jit; CDeltaJit* jit;
int markbits[2];
int sse_highbits[2];
#endif #endif
} delta_t; } delta_t;
@ -140,11 +138,7 @@ qboolean DELTA_IsFieldMarked(delta_t* pFields, int fieldNumber);
void DELTA_WriteMarkedFields(unsigned char *from, unsigned char *to, delta_t *pFields); 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_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 ));
#if defined(REHLDS_OPT_PEDANTIC) || defined(REHLDS_FIXES)
qboolean _DELTA_WriteDelta(unsigned char *from, unsigned char *to, delta_t *pFields, int* bits, int bytecount);
#else // REHLDS_OPT_PEDANTIC || REHLDS_FIXES
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), int sendfields);
#endif // REHLDS_OPT_PEDANTIC || REHLDS_FIXES
int DELTA_ParseDelta(unsigned char *from, unsigned char *to, delta_t *pFields); 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_AddEncoder(char *name, void(*conditionalencode)(struct delta_s *, const unsigned char *, const unsigned char *));
void DELTA_ClearEncoders(void); void DELTA_ClearEncoders(void);

View File

@ -107,21 +107,40 @@ void DELTAJIT_CreateDescription(delta_t* delta, deltajitdata_t &jitdesc) {
} }
class CDeltaClearMarkFieldsJIT : public jitasm::function<int, CDeltaClearMarkFieldsJIT, void*, void*, void*, void*, void*, int> { class CDeltaClearMarkFieldsJIT;
class CDeltaJit {
public:
CDeltaClearMarkFieldsJIT* cleanMarkCheckFunc;
delta_t* delta;
int markedFieldsMaskSize;
int marked_fields_mask[2];
int sse_highbits[2]; //High 64 bits for manipulating marked_fields_mask via SSE registers
CDeltaJit(delta_t* _delta, CDeltaClearMarkFieldsJIT* _cleanMarkCheckFunc);
virtual ~CDeltaJit();
};
class CDeltaClearMarkFieldsJIT : public jitasm::function<int, CDeltaClearMarkFieldsJIT, void*, void*, void*> {
public: public:
deltajitdata_t *jitdesc; deltajitdata_t *jitdesc;
deltajit_marked_count_type_t countType; deltajit_marked_count_type_t countType;
XmmReg marked_fields_mask = xmm5;
CDeltaClearMarkFieldsJIT(deltajitdata_t *_jitdesc, deltajit_marked_count_type_t _countType) CDeltaClearMarkFieldsJIT(deltajitdata_t *_jitdesc, deltajit_marked_count_type_t _countType)
: jitdesc(_jitdesc), countType(_countType) { : jitdesc(_jitdesc), countType(_countType) {
} }
void checkFieldMask(jitasm::Frontend::Reg32& mask, deltajit_memblock_field* jitField); void checkFieldMask(jitasm::Frontend::Reg32& mask, deltajit_memblock_field* jitField);
Result main(Addr src, Addr dst, Addr delta, Addr bits, Addr bytecount, Addr force); Result main(Addr src, Addr dst, Addr deltaJit);
void processStrings(Addr src, Addr dst, Addr delta); void processStrings(Addr src, Addr dst);
void callConditionalEncoder(Addr src, Addr dst, Addr delta); void callConditionalEncoder(Addr src, Addr dst, Addr deltaJit);
void calculateBytecount(Addr bits, Addr bytecount); void calculateBytecount();
}; };
void CDeltaClearMarkFieldsJIT::checkFieldMask(jitasm::Frontend::Reg32& mask, deltajit_memblock_field* jitField) { void CDeltaClearMarkFieldsJIT::checkFieldMask(jitasm::Frontend::Reg32& mask, deltajit_memblock_field* jitField) {
@ -130,14 +149,16 @@ void CDeltaClearMarkFieldsJIT::checkFieldMask(jitasm::Frontend::Reg32& mask, del
movzx(edx, al); movzx(edx, al);
} }
void CDeltaClearMarkFieldsJIT::callConditionalEncoder(Addr src, Addr dst, Addr delta) { void CDeltaClearMarkFieldsJIT::callConditionalEncoder(Addr src, Addr dst, Addr deltaJit) {
//This generator expects that following registers are already initialized: //This generator expects that following registers are already initialized:
// esi = src // esi = src
// edi = dst // edi = dst
int deltaOffset = (offsetof(CDeltaJit, delta));
int condEncoderOffset = (offsetof(delta_t, conditionalencode)); int condEncoderOffset = (offsetof(delta_t, conditionalencode));
mov(eax, ptr[delta]); mov(eax, ptr[deltaJit]);
or_(ecx, dword_ptr[eax + condEncoderOffset]); mov(eax, ptr[eax + deltaOffset]);
mov(ecx, dword_ptr[eax + condEncoderOffset]);
If(ecx != 0); If(ecx != 0);
push(edi); push(edi);
push(esi); push(esi);
@ -148,72 +169,81 @@ void CDeltaClearMarkFieldsJIT::callConditionalEncoder(Addr src, Addr dst, Addr d
EndIf(); EndIf();
} }
void CDeltaClearMarkFieldsJIT::calculateBytecount(Addr bits, Addr bytecount) { void CDeltaClearMarkFieldsJIT::calculateBytecount() {
mov(eax, ptr[bits]); //This generator expects that following registers are already initialized:
xor_(ecx, ecx); //ebx = delta
xor_(edi, edi);
size_t delta_markbits_offset = offsetof(CDeltaJit, marked_fields_mask);
mov(eax, dword_ptr[ebx + delta_markbits_offset]);
xor_(edx, edx);
// 0-7 // 0-7
inc(ecx); mov(ecx, 1);
test(eax, 0xFF); test(eax, 0xFF);
cmovnz(edi, ecx); cmovnz(edx, ecx);
// 8-15 // 8-15
if (jitdesc->numFields > 7) if (jitdesc->numFields > 7)
{ {
inc(ecx); mov(ecx, 2);
test(eax, 0xFF00); test(eax, 0xFF00);
cmovnz(edi, ecx); cmovnz(edx, ecx);
} }
// 16-23 // 16-23
if (jitdesc->numFields > 15) if (jitdesc->numFields > 15)
{ {
inc(ecx); mov(ecx, 3);
test(eax, 0xFF0000); test(eax, 0xFF0000);
cmovnz(edi, ecx); cmovnz(edx, ecx);
} }
// 24-31 // 24-31
if (jitdesc->numFields > 23) if (jitdesc->numFields > 23)
{ {
inc(ecx); mov(ecx, 4);
test(eax, 0xFF000000); test(eax, 0xFF000000);
cmovnz(edi, ecx); cmovnz(edx, ecx);
} }
if (jitdesc->numFields > 31) if (jitdesc->numFields > 31)
{ {
mov(eax, ptr[bits + 4]); mov(eax, dword_ptr[ebx + delta_markbits_offset + 4]);
// 32-39 // 32-39
inc(ecx); mov(ecx, 5);
test(eax, 0xFF); test(eax, 0xFF);
cmovnz(edi, ecx); cmovnz(edx, ecx);
// 40-47 // 40-47
if (jitdesc->numFields > 39) if (jitdesc->numFields > 39)
{ {
inc(ecx); mov(ecx, 6);
test(eax, 0xFF00); test(eax, 0xFF00);
cmovnz(edi, ecx); cmovnz(edx, ecx);
} }
// 48-55 // 48-55
if (jitdesc->numFields > 47) if (jitdesc->numFields > 47)
{ {
inc(ecx); mov(ecx, 7);
test(eax, 0xFF0000); test(eax, 0xFF0000);
cmovnz(edi, ecx); cmovnz(edx, ecx);
}
if (jitdesc->numFields > 55)
{
mov(ecx, 8);
test(eax, 0xFF000000);
cmovnz(edx, ecx);
} }
} }
mov(eax, ptr[bytecount]); size_t delta_masksize_offset = offsetof(CDeltaJit, markedFieldsMaskSize);
mov(ptr[eax], edi); mov(dword_ptr[ebx + delta_masksize_offset], edx);
mov(eax, edi);
} }
CDeltaClearMarkFieldsJIT::Result CDeltaClearMarkFieldsJIT::main(Addr src, Addr dst, Addr delta, Addr bits, Addr bytecount, Addr force) CDeltaClearMarkFieldsJIT::Result CDeltaClearMarkFieldsJIT::main(Addr src, Addr dst, Addr deltaJit)
{ {
#ifndef REHLDS_FIXES #ifndef REHLDS_FIXES
sub(esp, 12); //some local storage is required for precise DT_TIMEWINDOW marking sub(esp, 12); //some local storage is required for precise DT_TIMEWINDOW marking
@ -227,14 +257,11 @@ CDeltaClearMarkFieldsJIT::Result CDeltaClearMarkFieldsJIT::main(Addr src, Addr d
movdqu(xmm3, xmmword_ptr[esi]); movdqu(xmm3, xmmword_ptr[esi]);
movdqu(xmm4, xmmword_ptr[edi]); movdqu(xmm4, xmmword_ptr[edi]);
auto zero_xmm = xmm2;
pxor(zero_xmm, zero_xmm);
auto mask = ecx; auto mask = ecx;
xor_(mask, mask); xor_(mask, mask);
auto mark = xmm5;
pxor(mark, mark); pxor(marked_fields_mask, marked_fields_mask);
for (unsigned int i = 0; i < jitdesc->numblocks; i++) { for (unsigned int i = 0; i < jitdesc->numblocks; i++) {
movdqa(xmm0, xmm3); movdqa(xmm0, xmm3);
@ -246,8 +273,7 @@ CDeltaClearMarkFieldsJIT::Result CDeltaClearMarkFieldsJIT::main(Addr src, Addr d
movdqu(xmm4, xmmword_ptr[edi + ((i + 1) * 16)]); movdqu(xmm4, xmmword_ptr[edi + ((i + 1) * 16)]);
} }
pxor(xmm0, xmm1); pcmpeqb(xmm0, xmm1);
pcmpeqb(xmm0, zero_xmm);
pmovmskb(mask, xmm0); pmovmskb(mask, xmm0);
not_(mask); not_(mask);
@ -285,58 +311,51 @@ CDeltaClearMarkFieldsJIT::Result CDeltaClearMarkFieldsJIT::main(Addr src, Addr d
} else { } else {
checkFieldMask(mask, jitField); checkFieldMask(mask, jitField);
} }
/*int flagsOffset = ( jitField->field->id * sizeof(delta_description_t) + offsetof(delta_description_t, flags) );
if (jitField->first) {
mov(word_ptr[ebx + flagsOffset], dx);
}
else {
or_(word_ptr[ebx + flagsOffset], dx);
}*/
#else #else
checkFieldMask(mask, jitField); checkFieldMask(mask, jitField);
#endif #endif
// set bit in send mask // set bit in send mask
movd(xmm0, edx); movd(xmm0, edx);
pslldq(xmm0, j); psllq(xmm0, jitField->field->id);
por(mark, xmm0); por(marked_fields_mask, xmm0);
} }
} }
processStrings(src, dst, delta); processStrings(src, dst);
size_t markbits_offset = offsetof(delta_t, markbits); size_t delta_markbits_offset = offsetof(CDeltaJit, marked_fields_mask);
mov(eax, ptr[delta]); //Before calling the condition encoder we have to save 'marked fields' mask
movdqu(xmmword_ptr[eax + markbits_offset], mark); //from SSE register into the CDeltaJit::marked_fields_mask, because conditional encoder can modify the mask
pcmpeqq(mark, zero_xmm); // SSE 4.1 instruction mov(ebx, ptr[deltaJit]);
cvttss2si(eax, mark); movdqu(xmmword_ptr[ebx + delta_markbits_offset], marked_fields_mask);
or_(eax, ptr[force]); // if(sendfields || force)
If(eax != 0); //emit conditional encoder call
callConditionalEncoder(src, dst, delta); callConditionalEncoder(src, dst, deltaJit);
EndIf();
// 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);
mov(eax, ptr[delta]); If(edi != 0);
movdqu(mark, xmmword_ptr[eax + markbits_offset]); calculateBytecount();
pcmpeqq(mark, zero_xmm); Else();
cvttss2si(eax, mark); //set maskSize to 0 if there are no marked fields
size_t delta_masksize_offset = offsetof(CDeltaJit, markedFieldsMaskSize);
If(eax != 0); mov(dword_ptr[ebx + delta_masksize_offset], 0);
calculateBytecount(bits, bytecount);
EndIf(); EndIf();
#ifndef REHLDS_FIXES #ifndef REHLDS_FIXES
add(esp, 12); //some local storage is required for precise DT_TIMEWINDOW marking add(esp, 12); //some local storage is required for precise DT_TIMEWINDOW marking
#endif // REHLDS_FIXES #endif // REHLDS_FIXES
return eax; return edi;
} }
void CDeltaClearMarkFieldsJIT::processStrings(Addr src, Addr dst, Addr delta) { void CDeltaClearMarkFieldsJIT::processStrings(Addr src, Addr dst) {
//This generator expects that following registers are already initialized: //This generator expects that following registers are already initialized:
// ebx = delta->pdd
// esi = src // esi = src
// edi = dst // edi = dst
@ -360,34 +379,23 @@ void CDeltaClearMarkFieldsJIT::processStrings(Addr src, Addr dst, Addr delta) {
setnz(cl); setnz(cl);
movzx(ecx, cl); movzx(ecx, cl);
#ifndef REHLDS_FIXES
int flagsOffset = (jitField->id * sizeof(delta_description_t) + offsetof(delta_description_t, flags));
mov(word_ptr[ebx + flagsOffset], cx);
#else // REHLDS_FIXES
movd(xmm0, ecx); movd(xmm0, ecx);
pslldq(xmm0, i); psllq(xmm0, jitField->id);
por(xmm5, xmm0); por(xmm5, xmm0);
#endif // REHLDS_FIXES
} }
} }
class CDeltaJit { CDeltaJit::CDeltaJit(delta_t* _delta, CDeltaClearMarkFieldsJIT* _cleanMarkCheckFunc) {
public: delta = _delta;
CDeltaClearMarkFieldsJIT* cleanMarkCheckFunc; cleanMarkCheckFunc = _cleanMarkCheckFunc;
delta_t* delta; }
CDeltaJit(delta_t* _delta, CDeltaClearMarkFieldsJIT* _cleanMarkCheckFunc) { CDeltaJit::~CDeltaJit() {
delta = _delta; if (cleanMarkCheckFunc) {
cleanMarkCheckFunc = _cleanMarkCheckFunc; delete cleanMarkCheckFunc;
cleanMarkCheckFunc = NULL;
} }
}
virtual ~CDeltaJit() {
if (cleanMarkCheckFunc) {
delete cleanMarkCheckFunc;
cleanMarkCheckFunc = NULL;
}
}
};
CDeltaJitRegistry::CDeltaJitRegistry() { CDeltaJitRegistry::CDeltaJitRegistry() {
@ -424,28 +432,56 @@ void CDeltaJitRegistry::CreateAndRegisterDeltaJIT(delta_t* delta) {
RegisterDeltaJit(delta, deltaJit); RegisterDeltaJit(delta, deltaJit);
} }
NOINLINE void DELTAJit_ClearAndMarkSendFields(unsigned char *from, unsigned char *to, delta_t *pFields, int* bits, int* bytecount, int force) { CDeltaJit* DELTAJit_LookupDeltaJit(const char* callsite, delta_t *pFields) {
CDeltaJit* deltaJit = g_DeltaJitRegistry.GetJITByDelta(pFields); CDeltaJit* deltaJit = g_DeltaJitRegistry.GetJITByDelta(pFields);
if (!deltaJit) { if (!deltaJit) {
rehlds_syserror("%s: JITted delta encoder not found for delta %p", __FUNCTION__, pFields); rehlds_syserror("%s: JITted delta encoder not found for delta %p", callsite, pFields);
return; return NULL;
} }
CDeltaClearMarkFieldsJIT &func = *deltaJit->cleanMarkCheckFunc; return deltaJit;
func(from, to, pFields, bits, bytecount, force);
} }
NOINLINE int DELTAJit_Feilds_Clear_Mark_Check(unsigned char *from, unsigned char *to, delta_t *pFields) { NOINLINE int DELTAJit_Feilds_Clear_Mark_Check(unsigned char *from, unsigned char *to, delta_t *pFields) {
CDeltaJit* deltaJit = g_DeltaJitRegistry.GetJITByDelta(pFields); CDeltaJit* deltaJit = DELTAJit_LookupDeltaJit(__FUNCTION__, pFields);
if (!deltaJit) {
rehlds_syserror("%s: JITted delta encoder not found for delta %p", __FUNCTION__, pFields);
return 0;
}
int bits[2], bytecount;
CDeltaClearMarkFieldsJIT &func = *deltaJit->cleanMarkCheckFunc; CDeltaClearMarkFieldsJIT &func = *deltaJit->cleanMarkCheckFunc;
return func(from, to, pFields, bits, &bytecount, false); return func(from, to, deltaJit);
}
void DELTAJit_SetSendFlagBits(delta_t *pFields, int *bits, int *bytecount) {
CDeltaJit* deltaJit = DELTAJit_LookupDeltaJit(__FUNCTION__, pFields);
bits[0] = deltaJit->marked_fields_mask[0];
bits[1] = deltaJit->marked_fields_mask[1];
*bytecount = deltaJit->markedFieldsMaskSize;
}
void DELTAJit_SetFieldByIndex(struct delta_s *pFields, int fieldNumber) {
CDeltaJit* deltaJit = DELTAJit_LookupDeltaJit(__FUNCTION__, pFields);
if (fieldNumber > 31)
deltaJit->marked_fields_mask[1] |= (1 << (fieldNumber & 0x1F));
else
deltaJit->marked_fields_mask[0] |= (1 << fieldNumber);
}
void DELTAJit_UnsetFieldByIndex(struct delta_s *pFields, int fieldNumber) {
CDeltaJit* deltaJit = DELTAJit_LookupDeltaJit(__FUNCTION__, pFields);
if (fieldNumber > 31)
deltaJit->marked_fields_mask[1] &= ~(1 << (fieldNumber & 0x1F));
else
deltaJit->marked_fields_mask[0] &= ~(1 << fieldNumber);
}
qboolean DELTAJit_IsFieldMarked(delta_t* pFields, int fieldNumber) {
CDeltaJit* deltaJit = DELTAJit_LookupDeltaJit(__FUNCTION__, pFields);
if (fieldNumber > 31)
return deltaJit->marked_fields_mask[1] & (1 << (fieldNumber & 0x1F));
return deltaJit->marked_fields_mask[0] & (1 << fieldNumber);
} }
void CDeltaJitRegistry::Cleanup() { void CDeltaJitRegistry::Cleanup() {

View File

@ -57,5 +57,8 @@ public:
extern CDeltaJitRegistry g_DeltaJitRegistry; extern CDeltaJitRegistry g_DeltaJitRegistry;
extern void DELTAJit_ClearAndMarkSendFields(unsigned char *from, unsigned char *to, delta_t *pFields, int* bits, int* bytecount, int force);
extern int DELTAJit_Feilds_Clear_Mark_Check(unsigned char *from, unsigned char *to, delta_t *pFields); extern int DELTAJit_Feilds_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);
extern qboolean DELTAJit_IsFieldMarked(delta_t* pFields, int fieldNumber);

View File

@ -52,30 +52,38 @@ NOINLINE void _FillTestDelta(delta_test_struct_t* data, char val) {
data->wb_20 = (float)val; data->wb_20 = (float)val;
} }
NOINLINE qboolean _DoMarkFields(void* src, void* dst, delta_t* delta, int* bits, int* bytecount, bool force, bool useJit) { NOINLINE qboolean _DoMarkFields(void* src, void* dst, delta_t* delta, bool useJit) {
qboolean sendfields; qboolean sendfields;
if (useJit) { if (useJit) {
DELTAJit_ClearAndMarkSendFields((unsigned char*)src, (unsigned char*)dst, delta, bits, bytecount, force); DELTA_ClearFlags(delta);
sendfields = *bytecount; return DELTAJit_Feilds_Clear_Mark_Check((unsigned char*)src, (unsigned char*)dst, delta);
} else { } else {
DELTA_ClearFlags(delta); DELTA_ClearFlags(delta);
DELTA_MarkSendFields((unsigned char*)src, (unsigned char*)dst, delta); DELTA_MarkSendFields((unsigned char*)src, (unsigned char*)dst, delta);
sendfields = DELTA_CountSendFields(delta); sendfields = DELTA_CountSendFields(delta);
DELTA_SetSendFlagBits(delta, bits, bytecount);
} }
return sendfields; return sendfields;
} }
NOINLINE void _EnsureFieldsChanged(const char* callsite, const char* action, bool changed, bool markmask, delta_t* delta, ...) { NOINLINE bool _CheckFieldMarked(delta_t* delta, int fieldIdx, int usejit) {
if (usejit) {
return DELTAJit_IsFieldMarked(delta, fieldIdx) != 0;
} else {
return delta->pdd[fieldIdx].flags & FDT_MARK;
}
}
NOINLINE void _EnsureFieldsChanged(const char* callsite, const char* action, int usejit, bool changed, delta_t* delta, ...) {
va_list vargs; va_list vargs;
va_start(vargs, delta); va_start(vargs, delta);
const char* fieldName = va_arg(vargs, const char*); const char* fieldName = va_arg(vargs, const char*);
while (fieldName) { while (fieldName) {
delta_description_t* field = NULL; delta_description_t* field = NULL;
for (int i = 0; i < delta->fieldCount; i++) { int idx = 0;
if (!strcmp(fieldName, delta->pdd[i].fieldName)) { for (; idx < delta->fieldCount; idx++) {
field = &delta->pdd[i]; if (!strcmp(fieldName, delta->pdd[idx].fieldName)) {
field = &delta->pdd[idx];
break; break;
} }
} }
@ -88,16 +96,9 @@ NOINLINE void _EnsureFieldsChanged(const char* callsite, const char* action, boo
rehlds_syserror("%s: %s: Field '%s' is marked as processed", callsite, action, fieldName); rehlds_syserror("%s: %s: Field '%s' is marked as processed", callsite, action, fieldName);
} }
if (markmask) {
int index = field - delta->pdd; if (_CheckFieldMarked(delta, idx, usejit) ^ changed) {
if ((DELTA_IsFieldMarked(delta, index)?1:0) ^ changed) { rehlds_syserror("%s: %s: Field '%s' is expected to be marked", callsite, action, fieldName);
rehlds_syserror("%s: %s: Field '%s' is expected to be marked", callsite, action, fieldName);
}
}
else {
if ((field->flags == 1) ^ changed) {
rehlds_syserror("%s: %s: Field '%s' is expected to be marked", callsite, action, fieldName);
}
} }
field->flags |= 0x80; field->flags |= 0x80;
@ -110,23 +111,16 @@ NOINLINE void _EnsureFieldsChanged(const char* callsite, const char* action, boo
if (field->flags & 0x80) if (field->flags & 0x80)
continue; continue;
if (markmask) { if (_CheckFieldMarked(delta, i, usejit) ^ !changed) {
int index = field - delta->pdd; rehlds_syserror("%s: %s: Field '%s' is expected to be unmarked", callsite, action, field->fieldName);
if ((DELTA_IsFieldMarked(delta, index)?1:0) ^ !changed) {
rehlds_syserror("%s: %s: Field '%s' is expected to be unmarked", callsite, action, field->fieldName);
}
}
else {
if ((field->flags == 1) ^ !changed) {
rehlds_syserror("%s: %s: Field '%s' is expected to be unmarked", callsite, action, field->fieldName);
}
} }
} }
} }
NOINLINE delta_t* _CreateTestDeltaDesc() { NOINLINE delta_t* _CreateTestDeltaDesc() {
delta_test_struct_t d;
static delta_description_t _fields[32]; static delta_description_t _fields[32];
delta_test_struct_t d;
_InitDeltaField(&_fields[0], 0x00, DT_BYTE, "b_00", offsetof(delta_test_struct_t, b_00), 1, 8, 1.0f, 1.0f); _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); _InitDeltaField(&_fields[1], 0x01, DT_BYTE, "b_01", offsetof(delta_test_struct_t, b_01), 1, 8, 1.0f, 1.0f);
@ -183,60 +177,55 @@ TEST(MarkFieldsTest_Simple_Primitives, Delta, 1000) {
delta_test_struct_t d1; delta_test_struct_t d1;
delta_test_struct_t d2; delta_test_struct_t d2;
int bits[2], bytecount;
int *pbits;
for (int usejit = 0; usejit <= 1; usejit++) { for (int usejit = 0; usejit <= 1; usejit++) {
pbits = usejit ? delta->markbits : bits;
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71); _FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71);
_DoMarkFields(&d1, &d2, delta, pbits, &bytecount, false, usejit != 0); _DoMarkFields(&d1, &d2, delta, usejit != 0);
_EnsureFieldsChanged(__FUNCTION__, "SimpleUnchangedAll", true, usejit, delta, NULL); _EnsureFieldsChanged(__FUNCTION__, "SimpleUnchangedAll", usejit, true, delta, NULL);
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x72); _FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x72);
_DoMarkFields(&d1, &d2, delta, pbits, &bytecount, false, usejit != 0); _DoMarkFields(&d1, &d2, delta, usejit != 0);
_EnsureFieldsChanged(__FUNCTION__, "SimpleUnchangedAll", false, usejit, delta, NULL); _EnsureFieldsChanged(__FUNCTION__, "SimpleUnchangedAll", usejit, false, delta, NULL);
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71); _FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71);
d2.b_01 = 0; d2.b_01 = 0;
_DoMarkFields(&d1, &d2, delta, pbits, &bytecount, false, usejit != 0); _DoMarkFields(&d1, &d2, delta, usejit != 0);
_EnsureFieldsChanged(__FUNCTION__, "Byte_0BlockCheck", true, usejit, delta, "b_01", NULL); _EnsureFieldsChanged(__FUNCTION__, "Byte_0BlockCheck", usejit, true, delta, "b_01", NULL);
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71); _FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71);
d2.b_11 = 0; d2.b_11 = 0;
_DoMarkFields(&d1, &d2, delta, pbits, &bytecount, false, usejit != 0); _DoMarkFields(&d1, &d2, delta, usejit != 0);
_EnsureFieldsChanged(__FUNCTION__, "Byte_1BlockCheck", true, usejit, delta, "b_11", NULL); _EnsureFieldsChanged(__FUNCTION__, "Byte_1BlockCheck", usejit, true, delta, "b_11", NULL);
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71); _FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71);
d2.s_02 = 0; d2.s_02 = 0;
_DoMarkFields(&d1, &d2, delta, pbits, &bytecount, false, usejit != 0); _DoMarkFields(&d1, &d2, delta, usejit != 0);
_EnsureFieldsChanged(__FUNCTION__, "Short_0BlockCheck", true, usejit, delta, "s_02", NULL); _EnsureFieldsChanged(__FUNCTION__, "Short_0BlockCheck", usejit, true, delta, "s_02", NULL);
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71); _FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71);
d2.s_12 = 0; d2.s_12 = 0;
_DoMarkFields(&d1, &d2, delta, pbits, &bytecount, false, usejit != 0); _DoMarkFields(&d1, &d2, delta, usejit != 0);
_EnsureFieldsChanged(__FUNCTION__, "Short_1BlockCheck", true, usejit, delta, "s_12", NULL); _EnsureFieldsChanged(__FUNCTION__, "Short_1BlockCheck", usejit, true, delta, "s_12", NULL);
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71); _FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71);
d2.i_04 = 0; d2.i_04 = 0;
_DoMarkFields(&d1, &d2, delta, pbits, &bytecount, false, usejit != 0); _DoMarkFields(&d1, &d2, delta, usejit != 0);
_EnsureFieldsChanged(__FUNCTION__, "Int_0BlockCheck", true, usejit, delta, "i_04", NULL); _EnsureFieldsChanged(__FUNCTION__, "Int_0BlockCheck", usejit, true, delta, "i_04", NULL);
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71); _FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71);
d2.i_14 = 0; d2.i_14 = 0;
_DoMarkFields(&d1, &d2, delta, pbits, &bytecount, false, usejit != 0); _DoMarkFields(&d1, &d2, delta, usejit != 0);
_EnsureFieldsChanged(__FUNCTION__, "Int_1BlockCheck", true, usejit, delta, "i_14", NULL); _EnsureFieldsChanged(__FUNCTION__, "Int_1BlockCheck", usejit, true, delta, "i_14", NULL);
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71); _FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71);
d2.f_08 = 0; d2.f_08 = 0;
_DoMarkFields(&d1, &d2, delta, pbits, &bytecount, false, usejit != 0); _DoMarkFields(&d1, &d2, delta, usejit != 0);
_EnsureFieldsChanged(__FUNCTION__, "Float_0BlockCheck", true, usejit, delta, "f_08", NULL); _EnsureFieldsChanged(__FUNCTION__, "Float_0BlockCheck", usejit, true, delta, "f_08", NULL);
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71); _FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71);
d2.f_18 = 0; d2.f_18 = 0;
_DoMarkFields(&d1, &d2, delta, pbits, &bytecount, false, usejit != 0); _DoMarkFields(&d1, &d2, delta, usejit != 0);
_EnsureFieldsChanged(__FUNCTION__, "Float_0BlockCheck", true, usejit, delta, "f_18", NULL); _EnsureFieldsChanged(__FUNCTION__, "Float_0BlockCheck", usejit, true, delta, "f_18", NULL);
} }
SV_Shutdown(); SV_Shutdown();
@ -254,85 +243,79 @@ TEST(MarkFieldsTest_InterBlock, Delta, 1000) {
delta_test_struct_t d1; delta_test_struct_t d1;
delta_test_struct_t d2; delta_test_struct_t d2;
int bits[2], bytecount;
int *pbits;
for (int usejit = 0; usejit <= 1; usejit++) { for (int usejit = 0; usejit <= 1; usejit++) {
pbits = usejit ? delta->markbits : bits;
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71); _FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71);
d2.b_4D = d2.b_52 = 0; d2.b_4D = d2.b_52 = 0;
_DoMarkFields(&d1, &d2, delta, pbits, &bytecount, true, usejit != 0); _DoMarkFields(&d1, &d2, delta, usejit != 0);
_EnsureFieldsChanged(__FUNCTION__, "Interblock1_guards", true, usejit, delta, "b_4D", "b_52", NULL); _EnsureFieldsChanged(__FUNCTION__, "Interblock1_guards", usejit, true, delta, "b_4D", "b_52", NULL);
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71); _FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71);
d2.b_4D = d2.b_52 = 0; d2.b_4D = d2.b_52 = 0;
d2.i_4E = 0; d2.i_4E = 0;
_DoMarkFields(&d1, &d2, delta, pbits, &bytecount, true, usejit != 0); _DoMarkFields(&d1, &d2, delta, usejit != 0);
_EnsureFieldsChanged(__FUNCTION__, "Interblock1_guards_and_val", true, usejit, delta, "b_4D", "b_52", "i_4E", NULL); _EnsureFieldsChanged(__FUNCTION__, "Interblock1_guards_and_val", usejit, true, delta, "b_4D", "b_52", "i_4E", NULL);
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71); _FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71);
d2.i_4E = 0; d2.i_4E = 0;
_DoMarkFields(&d1, &d2, delta, pbits, &bytecount, true, usejit != 0); _DoMarkFields(&d1, &d2, delta, usejit != 0);
_EnsureFieldsChanged(__FUNCTION__, "Interblock1_val", true, usejit, delta, "i_4E", NULL); _EnsureFieldsChanged(__FUNCTION__, "Interblock1_val", usejit, true, delta, "i_4E", NULL);
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71); _FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71);
d2.i_4E &= 0xFFFFFF00; d2.i_4E &= 0xFFFFFF00;
_DoMarkFields(&d1, &d2, delta, pbits, &bytecount, true, usejit != 0); _DoMarkFields(&d1, &d2, delta, usejit != 0);
_EnsureFieldsChanged(__FUNCTION__, "Interblock1_val_0b", true, usejit, delta, "i_4E", NULL); _EnsureFieldsChanged(__FUNCTION__, "Interblock1_val_0b", usejit, true, delta, "i_4E", NULL);
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71); _FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71);
d2.i_4E &= 0xFFFF00FF; d2.i_4E &= 0xFFFF00FF;
_DoMarkFields(&d1, &d2, delta, pbits, &bytecount, true, usejit != 0); _DoMarkFields(&d1, &d2, delta, usejit != 0);
_EnsureFieldsChanged(__FUNCTION__, "Interblock1_val_1b", true, usejit, delta, "i_4E", NULL); _EnsureFieldsChanged(__FUNCTION__, "Interblock1_val_1b", usejit, true, delta, "i_4E", NULL);
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71); _FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71);
d2.i_4E &= 0xFF00FFFF; d2.i_4E &= 0xFF00FFFF;
_DoMarkFields(&d1, &d2, delta, pbits, &bytecount, true, usejit != 0); _DoMarkFields(&d1, &d2, delta, usejit != 0);
_EnsureFieldsChanged(__FUNCTION__, "Interblock1_val_2b", true, usejit, delta, "i_4E", NULL); _EnsureFieldsChanged(__FUNCTION__, "Interblock1_val_2b", usejit, true, delta, "i_4E", NULL);
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71); _FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71);
d2.i_4E &= 0x00FFFFFF; d2.i_4E &= 0x00FFFFFF;
_DoMarkFields(&d1, &d2, delta, pbits, &bytecount, true, usejit != 0); _DoMarkFields(&d1, &d2, delta, usejit != 0);
_EnsureFieldsChanged(__FUNCTION__, "Interblock1_val_3b", true, usejit, delta, "i_4E", NULL); _EnsureFieldsChanged(__FUNCTION__, "Interblock1_val_3b", usejit, true, delta, "i_4E", NULL);
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71); _FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71);
d2.b_5C = d2.b_61 = 0; d2.b_5C = d2.b_61 = 0;
_DoMarkFields(&d1, &d2, delta, pbits, &bytecount, true, usejit != 0); _DoMarkFields(&d1, &d2, delta, usejit != 0);
_EnsureFieldsChanged(__FUNCTION__, "Interblock2_guards", true, usejit, delta, "b_5C", "b_61", NULL); _EnsureFieldsChanged(__FUNCTION__, "Interblock2_guards", usejit, true, delta, "b_5C", "b_61", NULL);
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71); _FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71);
d2.b_5C = d2.b_61 = 0; d2.b_5C = d2.b_61 = 0;
d2.i_5D = 0; d2.i_5D = 0;
_DoMarkFields(&d1, &d2, delta, pbits, &bytecount, true, usejit != 0); _DoMarkFields(&d1, &d2, delta, usejit != 0);
_EnsureFieldsChanged(__FUNCTION__, "Interblock2_guards_and_val", true, usejit, delta, "b_5C", "b_61", "i_5D", NULL); _EnsureFieldsChanged(__FUNCTION__, "Interblock2_guards_and_val", usejit, true, delta, "b_5C", "b_61", "i_5D", NULL);
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71); _FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71);
d2.i_5D = 0; d2.i_5D = 0;
_DoMarkFields(&d1, &d2, delta, pbits, &bytecount, true, usejit != 0); _DoMarkFields(&d1, &d2, delta, usejit != 0);
_EnsureFieldsChanged(__FUNCTION__, "Interblock2_val", true, usejit, delta, "i_5D", NULL); _EnsureFieldsChanged(__FUNCTION__, "Interblock2_val", usejit, true, delta, "i_5D", NULL);
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71); _FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71);
d2.i_5D &= 0xFFFFFF00; d2.i_5D &= 0xFFFFFF00;
_DoMarkFields(&d1, &d2, delta, pbits, &bytecount, true, usejit != 0); _DoMarkFields(&d1, &d2, delta, usejit != 0);
_EnsureFieldsChanged(__FUNCTION__, "Interblock2_val_0b", true, usejit, delta, "i_5D", NULL); _EnsureFieldsChanged(__FUNCTION__, "Interblock2_val_0b", usejit, true, delta, "i_5D", NULL);
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71); _FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71);
d2.i_5D &= 0xFFFF00FF; d2.i_5D &= 0xFFFF00FF;
_DoMarkFields(&d1, &d2, delta, pbits, &bytecount, true, usejit != 0); _DoMarkFields(&d1, &d2, delta, usejit != 0);
_EnsureFieldsChanged(__FUNCTION__, "Interblock2_val_1b", true, usejit, delta, "i_5D", NULL); _EnsureFieldsChanged(__FUNCTION__, "Interblock2_val_1b", usejit, true, delta, "i_5D", NULL);
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71); _FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71);
d2.i_5D &= 0xFF00FFFF; d2.i_5D &= 0xFF00FFFF;
_DoMarkFields(&d1, &d2, delta, pbits, &bytecount, true, usejit != 0); _DoMarkFields(&d1, &d2, delta, usejit != 0);
_EnsureFieldsChanged(__FUNCTION__, "Interblock2_val_2b", true, usejit, delta, "i_5D", NULL); _EnsureFieldsChanged(__FUNCTION__, "Interblock2_val_2b", usejit, true, delta, "i_5D", NULL);
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71); _FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71);
d2.i_5D &= 0x00FFFFFF; d2.i_5D &= 0x00FFFFFF;
_DoMarkFields(&d1, &d2, delta, pbits, &bytecount, true, usejit != 0); _DoMarkFields(&d1, &d2, delta, usejit != 0);
_EnsureFieldsChanged(__FUNCTION__, "Interblock2_val_3b", true, usejit, delta, "i_5D", NULL); _EnsureFieldsChanged(__FUNCTION__, "Interblock2_val_3b", usejit, true, delta, "i_5D", NULL);
} }
@ -350,34 +333,29 @@ TEST(MarkFieldsTest_Strings, Delta, 1000) {
delta_test_struct_t d1; delta_test_struct_t d1;
delta_test_struct_t d2; delta_test_struct_t d2;
int *pbits;
int bits[2], bytecount;
for (int usejit = 0; usejit <= 1; usejit++) { for (int usejit = 0; usejit <= 1; usejit++) {
pbits = usejit ? delta->markbits : bits;
_FillTestDelta(&d1, 'c'); _FillTestDelta(&d2, 'c'); _FillTestDelta(&d1, 'c'); _FillTestDelta(&d2, 'c');
d2.s_24[0] = 0; d2.s_24[0] = 0;
_DoMarkFields(&d1, &d2, delta, pbits, &bytecount, true, usejit != 0); _DoMarkFields(&d1, &d2, delta, usejit != 0);
_EnsureFieldsChanged(__FUNCTION__, "Str_empty", true, usejit, delta, "s_24", NULL); _EnsureFieldsChanged(__FUNCTION__, "Str_empty", usejit, true, delta, "s_24", NULL);
_FillTestDelta(&d1, 'c'); _FillTestDelta(&d2, 'c'); _FillTestDelta(&d1, 'c'); _FillTestDelta(&d2, 'c');
d1.s_24[0] = 0; d1.s_24[0] = 0;
_DoMarkFields(&d1, &d2, delta, pbits, &bytecount, true, usejit != 0); _DoMarkFields(&d1, &d2, delta, usejit != 0);
_EnsureFieldsChanged(__FUNCTION__, "Str_empty2", true, usejit, delta, "s_24", NULL); _EnsureFieldsChanged(__FUNCTION__, "Str_empty2", usejit, true, delta, "s_24", NULL);
_FillTestDelta(&d1, 'c'); _FillTestDelta(&d2, 'c'); _FillTestDelta(&d1, 'c'); _FillTestDelta(&d2, 'c');
d1.s_24[0] = d2.s_24[0] = 0; d1.s_24[0] = d2.s_24[0] = 0;
d1.s_24[1] = 'd'; d2.s_24[1] = 'e'; d1.s_24[1] = 'd'; d2.s_24[1] = 'e';
_DoMarkFields(&d1, &d2, delta, pbits, &bytecount, true, usejit != 0); _DoMarkFields(&d1, &d2, delta, usejit != 0);
_EnsureFieldsChanged(__FUNCTION__, "Str_both_empty_with_garbage", true, usejit, delta, NULL); _EnsureFieldsChanged(__FUNCTION__, "Str_both_empty_with_garbage", usejit, true, delta, NULL);
_FillTestDelta(&d1, 'c'); _FillTestDelta(&d2, 'c'); _FillTestDelta(&d1, 'c'); _FillTestDelta(&d2, 'c');
d1.s_24[1] = 'C'; d1.s_24[1] = 'C';
_DoMarkFields(&d1, &d2, delta, pbits, &bytecount, true, usejit != 0); _DoMarkFields(&d1, &d2, delta, usejit != 0);
_EnsureFieldsChanged(__FUNCTION__, "Str_case_check", true, usejit, delta, NULL); _EnsureFieldsChanged(__FUNCTION__, "Str_case_check", usejit, true, delta, NULL);
} }
SV_Shutdown(); SV_Shutdown();
@ -395,27 +373,22 @@ TEST(MarkFieldsTest_TimeWindow, Delta, 1000) {
delta_test_struct_t d1; delta_test_struct_t d1;
delta_test_struct_t d2; delta_test_struct_t d2;
int bits[2], bytecount;
int* pbits;
for (int usejit = 0; usejit <= 1; usejit++) { for (int usejit = 0; usejit <= 1; usejit++) {
pbits = usejit ? delta->markbits : bits;
_FillTestDelta(&d1, 'c'); _FillTestDelta(&d2, 'c'); _FillTestDelta(&d1, 'c'); _FillTestDelta(&d2, 'c');
d2.w8_1C = 0.001f; d1.w8_1C = 0.0011f; d2.w8_1C = 0.001f; d1.w8_1C = 0.0011f;
_DoMarkFields(&d1, &d2, delta, pbits, &bytecount, true, usejit != 0); _DoMarkFields(&d1, &d2, delta, usejit != 0);
_EnsureFieldsChanged(__FUNCTION__, "TimeWindow_Below_Precision", true, usejit, delta, rehds_fixes ? "w8_1C" : NULL, NULL); _EnsureFieldsChanged(__FUNCTION__, "TimeWindow_Below_Precision", usejit, true, delta, rehds_fixes ? "w8_1C" : NULL, NULL);
_FillTestDelta(&d1, 'c'); _FillTestDelta(&d2, 'c'); _FillTestDelta(&d1, 'c'); _FillTestDelta(&d2, 'c');
d2.w8_1C = 0.1f; d1.w8_1C = 0.11f; //precision check, 0.11f is actually 0.10999 d2.w8_1C = 0.1f; d1.w8_1C = 0.11f; //precision check, 0.11f is actually 0.10999
_DoMarkFields(&d1, &d2, delta, pbits, &bytecount, true, usejit != 0); _DoMarkFields(&d1, &d2, delta, usejit != 0);
_EnsureFieldsChanged(__FUNCTION__, "TimeWindow_Above_Precision", true, usejit, delta, rehds_fixes ? "w8_1C" : NULL, NULL); _EnsureFieldsChanged(__FUNCTION__, "TimeWindow_Above_Precision1", usejit, true, delta, rehds_fixes ? "w8_1C" : NULL, NULL);
_FillTestDelta(&d1, 'c'); _FillTestDelta(&d2, 'c'); _FillTestDelta(&d1, 'c'); _FillTestDelta(&d2, 'c');
d2.w8_1C = 0.1f; d1.w8_1C = 0.12f; d2.w8_1C = 0.1f; d1.w8_1C = 0.12f;
_DoMarkFields(&d1, &d2, delta, pbits, &bytecount, true, usejit != 0); _DoMarkFields(&d1, &d2, delta, usejit != 0);
_EnsureFieldsChanged(__FUNCTION__, "TimeWindow_Above_Precision", true, usejit, delta, "w8_1C", NULL); _EnsureFieldsChanged(__FUNCTION__, "TimeWindow_Above_Precision2", usejit, true, delta, "w8_1C", NULL);
} }