Skip to content

Commit

Permalink
Store type together with pointers to allow safe substitution
Browse files Browse the repository at this point in the history
  • Loading branch information
RicardoLuis0 committed Mar 13, 2024
1 parent 4682b71 commit a01e378
Show file tree
Hide file tree
Showing 5 changed files with 208 additions and 166 deletions.
120 changes: 74 additions & 46 deletions src/common/objects/dobject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -363,54 +363,49 @@ size_t DObject::PropagateMark()
const PClass *info = GetClass();
if (!PClass::bShutdown)
{
const size_t *offsets = info->FlatPointers;
if (offsets == NULL)
if (info->FlatPointers == nullptr)
{
const_cast<PClass *>(info)->BuildFlatPointers();
offsets = info->FlatPointers;
info->BuildFlatPointers();
assert(info->FlatPointers);
}
while (*offsets != ~(size_t)0)

for(size_t i = 0; i < info->FlatPointersSize; i++)
{
GC::Mark((DObject **)((uint8_t *)this + *offsets));
offsets++;
GC::Mark((DObject **)((uint8_t *)this + info->FlatPointers[i].first));
}

offsets = info->ArrayPointers;
if (offsets == NULL)
if (info->ArrayPointers == nullptr)
{
const_cast<PClass *>(info)->BuildArrayPointers();
offsets = info->ArrayPointers;
info->BuildArrayPointers();
assert(info->ArrayPointers);
}
while (*offsets != ~(size_t)0)

for(size_t i = 0; i < info->ArrayPointersSize; i++)
{
auto aray = (TArray<DObject*>*)((uint8_t *)this + *offsets);
auto aray = (TArray<DObject*>*)((uint8_t *)this + info->ArrayPointers[i].first);
for (auto &p : *aray)
{
GC::Mark(&p);
}
offsets++;
}

if (info->MapPointers == nullptr)
{
const std::pair<size_t,PType *> *maps = info->MapPointers;
if (maps == NULL)
{
const_cast<PClass *>(info)->BuildMapPointers();
maps = info->MapPointers;
info->BuildMapPointers();
assert(info->MapPointers);
}

for(size_t i = 0; i < info->MapPointersSize; i++)
{
PMap * type = static_cast<PMap*>(info->MapPointers[i].second);
if(type->KeyType->RegType == REGT_STRING)
{ // FString,DObject*
PropagateMarkMap((ZSMap<FString,DObject*>*)((uint8_t *)this + info->MapPointers[i].first));
}
while (maps->first != ~(size_t)0)
{
if(maps->second->RegType == REGT_STRING)
{ // FString,DObject*
PropagateMarkMap((ZSMap<FString,DObject*>*)((uint8_t *)this + maps->first));
}
else
{ // uint32_t,DObject*
PropagateMarkMap((ZSMap<uint32_t,DObject*>*)((uint8_t *)this + maps->first));
}
maps++;
else
{ // uint32_t,DObject*
PropagateMarkMap((ZSMap<uint32_t,DObject*>*)((uint8_t *)this + info->MapPointers[i].first));
}

}
return info->Size;
}
Expand All @@ -423,35 +418,51 @@ size_t DObject::PropagateMark()
//
//==========================================================================

template<typename M>
static void MapPointerSubstitution(M *map, size_t &changed, DObject *old, DObject *notOld)
{
TMapIterator<typename M::KeyType, DObject*> it(*map);
typename M::Pair * p;
while(it.NextPair(p))
{
if (p->Value == old)
{
p->Value = notOld;
changed++;
}
}
}

size_t DObject::PointerSubstitution (DObject *old, DObject *notOld)
{
const PClass *info = GetClass();
const size_t *offsets = info->FlatPointers;
size_t changed = 0;
if (offsets == NULL)
if (info->FlatPointers == nullptr)
{
const_cast<PClass *>(info)->BuildFlatPointers();
offsets = info->FlatPointers;
info->BuildFlatPointers();
assert(info->FlatPointers);
}
while (*offsets != ~(size_t)0)

for(size_t i = 0; i < info->FlatPointersSize; i++)
{
if (*(DObject **)((uint8_t *)this + *offsets) == old)
size_t offset = info->FlatPointers[i].first;

if (*(DObject **)((uint8_t *)this + offset) == old)
{
*(DObject **)((uint8_t *)this + *offsets) = notOld;
*(DObject **)((uint8_t *)this + offset) = notOld;
changed++;
}
offsets++;
}

offsets = info->ArrayPointers;
if (offsets == NULL)
if (info->ArrayPointers == nullptr)
{
const_cast<PClass *>(info)->BuildArrayPointers();
offsets = info->ArrayPointers;
info->BuildArrayPointers();
assert(info->ArrayPointers);
}
while (*offsets != ~(size_t)0)

for(size_t i = 0; i < info->ArrayPointersSize; i++)
{
auto aray = (TArray<DObject*>*)((uint8_t *)this + *offsets);
auto aray = (TArray<DObject*>*)((uint8_t *)this + info->ArrayPointers[i].first);
for (auto &p : *aray)
{
if (p == old)
Expand All @@ -460,9 +471,26 @@ size_t DObject::PointerSubstitution (DObject *old, DObject *notOld)
changed++;
}
}
offsets++;
}

if (info->MapPointers == nullptr)
{
info->BuildMapPointers();
assert(info->MapPointers);
}

for(size_t i = 0; i < info->MapPointersSize; i++)
{
PMap * type = static_cast<PMap*>(info->MapPointers[i].second);
if(type->KeyType->RegType == REGT_STRING)
{ // FString,DObject*
MapPointerSubstitution((ZSMap<FString,DObject*>*)((uint8_t *)this + info->MapPointers[i].first), changed, old, notOld);
}
else
{ // uint32_t,DObject*
MapPointerSubstitution((ZSMap<uint32_t,DObject*>*)((uint8_t *)this + info->MapPointers[i].first), changed, old, notOld);
}
}

return changed;
}
Expand Down
Loading

0 comments on commit a01e378

Please sign in to comment.