mirror of
https://github.com/rehlds/rehlds.git
synced 2025-01-16 00:28:20 +03:00
DeltaJit: (#545)
Update originalMarkedFieldsMask after strings checking Refactoring
This commit is contained in:
parent
eaabafc16d
commit
7d041ea357
@ -177,7 +177,7 @@ public:
|
|||||||
CDeltaClearMarkFieldsJIT* cleanMarkCheckFunc;
|
CDeltaClearMarkFieldsJIT* cleanMarkCheckFunc;
|
||||||
CDeltaTestDeltaJIT* testDeltaFunc;
|
CDeltaTestDeltaJIT* testDeltaFunc;
|
||||||
delta_t* delta;
|
delta_t* delta;
|
||||||
delta_marked_mask_t marked_fields_mask;
|
delta_marked_mask_t markedFieldsMask;
|
||||||
delta_marked_mask_t originalMarkedFieldsMask; //mask based on data, before calling the conditional encoder
|
delta_marked_mask_t originalMarkedFieldsMask; //mask based on data, before calling the conditional encoder
|
||||||
int markedFieldsMaskSize;
|
int markedFieldsMaskSize;
|
||||||
|
|
||||||
@ -344,7 +344,7 @@ void CDeltaCheckJIT::iterateStrings(deltajitdata_t *jitdesc)
|
|||||||
// call handler
|
// call handler
|
||||||
onStringChecked(jitField);
|
onStringChecked(jitField);
|
||||||
|
|
||||||
pushed_size += 8;
|
pushed_size += sizeof(int) * 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pushed_size)
|
if (pushed_size)
|
||||||
@ -359,7 +359,7 @@ public:
|
|||||||
Result main(Addr src, Addr dst, Addr deltaJit, Addr pForceMarkMask);
|
Result main(Addr src, Addr dst, Addr deltaJit, Addr pForceMarkMask);
|
||||||
|
|
||||||
void callConditionalEncoder(Addr src, Addr dst, Addr deltaJit);
|
void callConditionalEncoder(Addr src, Addr dst, Addr deltaJit);
|
||||||
void calculateBytecount();
|
void calculateBitcount();
|
||||||
|
|
||||||
// first two virtual functions must be same as in CDeltaCheckJIT
|
// first two virtual functions must be same as in CDeltaCheckJIT
|
||||||
virtual void onFieldChecked(deltajit_field* jitField);
|
virtual void onFieldChecked(deltajit_field* jitField);
|
||||||
@ -388,30 +388,28 @@ void CDeltaClearMarkFieldsJIT::callConditionalEncoder(Addr src, Addr dst, Addr d
|
|||||||
mov(eax, ptr[eax + deltaOffset]);
|
mov(eax, ptr[eax + deltaOffset]);
|
||||||
mov(ecx, dword_ptr[eax + condEncoderOffset]);
|
mov(ecx, dword_ptr[eax + condEncoderOffset]);
|
||||||
|
|
||||||
test(ecx, ecx);
|
jecxz(no_encoder);
|
||||||
jz(no_encoder);
|
|
||||||
push(edi);
|
push(edi);
|
||||||
push(esi);
|
push(esi);
|
||||||
push(eax);
|
push(eax);
|
||||||
|
|
||||||
call(ecx);
|
call(ecx);
|
||||||
add(esp, 12);
|
add(esp, sizeof(int) * 3);
|
||||||
L(no_encoder);
|
L(no_encoder);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDeltaClearMarkFieldsJIT::calculateBytecount() {
|
void CDeltaClearMarkFieldsJIT::calculateBitcount() {
|
||||||
// This generator expects that following registers are already initialized:
|
// This generator expects that following registers are already initialized:
|
||||||
// ebx = delta
|
// ebx = delta
|
||||||
|
|
||||||
size_t delta_markbits_offset = offsetof(CDeltaJit, marked_fields_mask);
|
size_t delta_markbits_offset = offsetof(CDeltaJit, markedFieldsMask);
|
||||||
mov(eax, dword_ptr[ebx + delta_markbits_offset]);
|
mov(eax, dword_ptr[ebx + delta_markbits_offset]);
|
||||||
xor_(edx, edx);
|
|
||||||
|
|
||||||
// bits 0-7
|
// bits 0-7
|
||||||
test(al, al);
|
test(al, al);
|
||||||
setnz(dl);
|
setnz(dl);
|
||||||
|
|
||||||
for (size_t i = 1; i < DELTAJIT_MAX_FIELDS / 8; i++) {
|
for (size_t i = 1; i < DELTAJIT_MAX_FIELDS / CHAR_BIT; i++) {
|
||||||
const int byteid = i & 3;
|
const int byteid = i & 3;
|
||||||
|
|
||||||
if (byteid == 0)
|
if (byteid == 0)
|
||||||
@ -420,27 +418,26 @@ void CDeltaClearMarkFieldsJIT::calculateBytecount() {
|
|||||||
auto reg = (i & 1) ? ecx : esi;
|
auto reg = (i & 1) ? ecx : esi;
|
||||||
auto prev = (i & 1) ? esi : ecx;
|
auto prev = (i & 1) ? esi : ecx;
|
||||||
|
|
||||||
if (jitdesc->numFields > i * 8 - 1) {
|
if (jitdesc->numFields > i * CHAR_BIT - 1) {
|
||||||
mov(reg, i + 1);
|
mov(reg, i + 1);
|
||||||
if(i != 1) cmovnz(edx, prev);
|
if(i != 1) cmovnz(edx, prev);
|
||||||
|
|
||||||
switch (byteid) {
|
switch (byteid) {
|
||||||
case 0: test(al, al); break;
|
case 0: test(al, al); break;
|
||||||
case 1: test(ah, ah); break;
|
case 1: test(ah, ah); break;
|
||||||
default: test(eax, 0xFF << (byteid * 8));
|
default: test(eax, 0xFF << (byteid * CHAR_BIT));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (jitdesc->numFields > unsigned(i * 8 - 9)) {
|
else if (jitdesc->numFields > unsigned(i * CHAR_BIT - 9)) {
|
||||||
cmovnz(edx, prev);
|
cmovnz(edx, prev);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (jitdesc->numFields > DELTAJIT_MAX_FIELDS - 9) {
|
if (jitdesc->numFields > DELTAJIT_MAX_FIELDS - 9) {
|
||||||
cmovnz(edx, (DELTAJIT_MAX_FIELDS / 8 & 1) ? esi : ecx);
|
cmovnz(edx, (DELTAJIT_MAX_FIELDS / CHAR_BIT & 1) ? esi : ecx);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t delta_masksize_offset = offsetof(CDeltaJit, markedFieldsMaskSize);
|
// return bitcount in edx
|
||||||
mov(dword_ptr[ebx + delta_masksize_offset], edx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDeltaClearMarkFieldsJIT::onFieldChecked(deltajit_field* field)
|
void CDeltaClearMarkFieldsJIT::onFieldChecked(deltajit_field* field)
|
||||||
@ -459,13 +456,13 @@ void CDeltaClearMarkFieldsJIT::onStringChecked(deltajit_field* field)
|
|||||||
// eax = result of strings comparison
|
// eax = result of strings comparison
|
||||||
// ebx = deltaJit
|
// ebx = deltaJit
|
||||||
|
|
||||||
size_t delta_markbits_offset = offsetof(CDeltaJit, marked_fields_mask);
|
size_t delta_markbits_offset = offsetof(CDeltaJit, markedFieldsMask);
|
||||||
|
|
||||||
test(eax, eax);
|
test(eax, eax);
|
||||||
setnz(cl);
|
setnz(cl);
|
||||||
|
|
||||||
shl(cl, field->id & 7);
|
shl(cl, field->id & (CHAR_BIT - 1));
|
||||||
or_(byte_ptr[ebx + delta_markbits_offset + (field->id / 8)], cl);
|
or_(byte_ptr[ebx + delta_markbits_offset + (field->id / CHAR_BIT)], cl);
|
||||||
}
|
}
|
||||||
|
|
||||||
CDeltaClearMarkFieldsJIT::Result CDeltaClearMarkFieldsJIT::main(Addr src, Addr dst, Addr deltaJit, Addr pForceMarkMask)
|
CDeltaClearMarkFieldsJIT::Result CDeltaClearMarkFieldsJIT::main(Addr src, Addr dst, Addr deltaJit, Addr pForceMarkMask)
|
||||||
@ -487,7 +484,7 @@ CDeltaClearMarkFieldsJIT::Result CDeltaClearMarkFieldsJIT::main(Addr src, Addr d
|
|||||||
// check changed blocks
|
// check changed blocks
|
||||||
reinterpret_cast<CDeltaCheckJIT*>(this)->iterateBlocks(jitdesc);
|
reinterpret_cast<CDeltaCheckJIT*>(this)->iterateBlocks(jitdesc);
|
||||||
|
|
||||||
//apply 'force mark' mask if it's present
|
// apply 'force mark' mask if it's present
|
||||||
CUniqueLabel no_forcemask("no_forcemask");
|
CUniqueLabel no_forcemask("no_forcemask");
|
||||||
mov(eax, ptr[pForceMarkMask]);
|
mov(eax, ptr[pForceMarkMask]);
|
||||||
test(eax, eax);
|
test(eax, eax);
|
||||||
@ -496,37 +493,35 @@ CDeltaClearMarkFieldsJIT::Result CDeltaClearMarkFieldsJIT::main(Addr src, Addr d
|
|||||||
por(marked_fields_mask, xmm_tmp);
|
por(marked_fields_mask, xmm_tmp);
|
||||||
L(no_forcemask);
|
L(no_forcemask);
|
||||||
|
|
||||||
size_t delta_markbits_offset = offsetof(CDeltaJit, marked_fields_mask);
|
size_t delta_markbits_offset = offsetof(CDeltaJit, markedFieldsMask);
|
||||||
|
|
||||||
//Save mask from SSE register to CDeltaJit::marked_fields_mask and CDeltaJit::originalMarkedFieldsMask
|
// save mask from SSE register to CDeltaJit::markedFieldsMask because it can be overwritten in Q_stricmp
|
||||||
mov(ebx, ptr[deltaJit]);
|
mov(ebx, ptr[deltaJit]);
|
||||||
movq(qword_ptr[ebx + delta_markbits_offset], marked_fields_mask);
|
movq(qword_ptr[ebx + delta_markbits_offset], marked_fields_mask);
|
||||||
movq(qword_ptr[ebx + offsetof(CDeltaJit, originalMarkedFieldsMask)], marked_fields_mask);
|
|
||||||
|
|
||||||
// check changed strings
|
// check changed strings
|
||||||
reinterpret_cast<CDeltaCheckJIT*>(this)->iterateStrings(jitdesc);
|
reinterpret_cast<CDeltaCheckJIT*>(this)->iterateStrings(jitdesc);
|
||||||
|
|
||||||
//emit conditional encoder call
|
// save originalMarkedFieldsMask before calling conditional encoder
|
||||||
|
movq(marked_fields_mask, qword_ptr[ebx + delta_markbits_offset]);
|
||||||
|
movq(qword_ptr[ebx + offsetof(CDeltaJit, originalMarkedFieldsMask)], marked_fields_mask);
|
||||||
|
|
||||||
|
// emit conditional encoder call
|
||||||
callConditionalEncoder(src, dst, deltaJit);
|
callConditionalEncoder(src, dst, deltaJit);
|
||||||
|
|
||||||
// check if mask is empty
|
// check if mask is empty
|
||||||
mov(edi, dword_ptr[ebx + delta_markbits_offset]);
|
mov(edi, dword_ptr[ebx + delta_markbits_offset]);
|
||||||
|
xor_(edx, edx); // set size to 0
|
||||||
or_(edi, dword_ptr[ebx + delta_markbits_offset + 4]);
|
or_(edi, dword_ptr[ebx + delta_markbits_offset + 4]);
|
||||||
|
|
||||||
CUniqueLabel no_markedbits("no_markedbits");
|
CUniqueLabel no_markedbits("no_markedbits");
|
||||||
CUniqueLabel calculated("calculated");
|
|
||||||
|
|
||||||
//test(edi, edi); // flags are already set
|
// test(edi, edi); // flags are already set
|
||||||
jz(no_markedbits);
|
jz(no_markedbits);
|
||||||
calculateBytecount();
|
calculateBitcount();
|
||||||
jmp(calculated);
|
|
||||||
L(no_markedbits);
|
L(no_markedbits);
|
||||||
//set maskSize to 0 if there are no marked fields
|
|
||||||
size_t delta_masksize_offset = offsetof(CDeltaJit, markedFieldsMaskSize);
|
|
||||||
xor_(edx, edx);
|
|
||||||
mov(dword_ptr[ebx + delta_masksize_offset], edx);
|
|
||||||
L(calculated);
|
|
||||||
|
|
||||||
|
mov(dword_ptr[ebx + offsetof(CDeltaJit, markedFieldsMaskSize)], edx);
|
||||||
return edx;
|
return edx;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -727,27 +722,27 @@ NOINLINE int DELTAJit_TestDelta(unsigned char *from, unsigned char *to, delta_t
|
|||||||
void DELTAJit_SetSendFlagBits(delta_t *pFields, int *bits, int *bytecount) {
|
void DELTAJit_SetSendFlagBits(delta_t *pFields, int *bits, int *bytecount) {
|
||||||
CDeltaJit* deltaJit = DELTAJit_LookupDeltaJit(__func__, pFields);
|
CDeltaJit* deltaJit = DELTAJit_LookupDeltaJit(__func__, pFields);
|
||||||
|
|
||||||
bits[0] = deltaJit->marked_fields_mask.u32[0];
|
bits[0] = deltaJit->markedFieldsMask.u32[0];
|
||||||
bits[1] = deltaJit->marked_fields_mask.u32[1];
|
bits[1] = deltaJit->markedFieldsMask.u32[1];
|
||||||
*bytecount = deltaJit->markedFieldsMaskSize;
|
*bytecount = deltaJit->markedFieldsMaskSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DELTAJit_SetFieldByIndex(delta_t *pFields, int fieldNumber)
|
void DELTAJit_SetFieldByIndex(delta_t *pFields, int fieldNumber)
|
||||||
{
|
{
|
||||||
CDeltaJit* deltaJit = DELTAJit_LookupDeltaJit(__func__, pFields);
|
CDeltaJit* deltaJit = DELTAJit_LookupDeltaJit(__func__, pFields);
|
||||||
deltaJit->marked_fields_mask.u32[fieldNumber >> 5] |= (1 << (fieldNumber & 31));
|
deltaJit->markedFieldsMask.u32[fieldNumber >> 5] |= (1 << (fieldNumber & 31));
|
||||||
}
|
}
|
||||||
|
|
||||||
void DELTAJit_UnsetFieldByIndex(delta_t *pFields, int fieldNumber)
|
void DELTAJit_UnsetFieldByIndex(delta_t *pFields, int fieldNumber)
|
||||||
{
|
{
|
||||||
CDeltaJit* deltaJit = DELTAJit_LookupDeltaJit(__func__, pFields);
|
CDeltaJit* deltaJit = DELTAJit_LookupDeltaJit(__func__, pFields);
|
||||||
deltaJit->marked_fields_mask.u32[fieldNumber >> 5] &= ~(1 << (fieldNumber & 31));
|
deltaJit->markedFieldsMask.u32[fieldNumber >> 5] &= ~(1 << (fieldNumber & 31));
|
||||||
}
|
}
|
||||||
|
|
||||||
qboolean DELTAJit_IsFieldMarked(delta_t* pFields, int fieldNumber)
|
qboolean DELTAJit_IsFieldMarked(delta_t* pFields, int fieldNumber)
|
||||||
{
|
{
|
||||||
CDeltaJit* deltaJit = DELTAJit_LookupDeltaJit(__func__, pFields);
|
CDeltaJit* deltaJit = DELTAJit_LookupDeltaJit(__func__, pFields);
|
||||||
return deltaJit->marked_fields_mask.u32[fieldNumber >> 5] & (1 << (fieldNumber & 31));
|
return deltaJit->markedFieldsMask.u32[fieldNumber >> 5] & (1 << (fieldNumber & 31));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64 DELTAJit_GetOriginalMask(delta_t* pFields) {
|
uint64 DELTAJit_GetOriginalMask(delta_t* pFields) {
|
||||||
@ -757,7 +752,7 @@ uint64 DELTAJit_GetOriginalMask(delta_t* pFields) {
|
|||||||
|
|
||||||
uint64 DELTAJit_GetMaskU64(delta_t* pFields) {
|
uint64 DELTAJit_GetMaskU64(delta_t* pFields) {
|
||||||
CDeltaJit* deltaJit = DELTAJit_LookupDeltaJit(__func__, pFields);
|
CDeltaJit* deltaJit = DELTAJit_LookupDeltaJit(__func__, pFields);
|
||||||
return deltaJit->marked_fields_mask.u64;
|
return deltaJit->markedFieldsMask.u64;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDeltaJitRegistry::Cleanup() {
|
void CDeltaJitRegistry::Cleanup() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user