1
1
mirror of https://github.com/mawww/kakoune.git synced 2024-08-16 16:20:38 +03:00

Reduce Save access indirections

Most Save access are to modify the refcount. Now that the freelist
is index based it is not necessary to keep Save objects at fixed
memory locations.
This commit is contained in:
Maxime Coste 2024-03-07 20:40:24 +11:00
parent c81266d4f6
commit a1c52e08a4

View File

@ -233,12 +233,11 @@ public:
~ThreadedRegexVM()
{
for (auto* saves : m_saves)
for (auto& saves : m_saves)
{
for (size_t i = m_program.save_count-1; i > 0; --i)
saves->pos[i].~Iterator();
saves->~Saves();
operator delete(saves);
for (int i = m_program.save_count-1; i >= 0; --i)
saves.pos[i].~Iterator();
operator delete(saves.pos, m_program.save_count * sizeof(Iterator));
}
}
@ -289,16 +288,16 @@ public:
ArrayView<const Iterator> captures() const
{
if (m_captures >= 0)
return { m_saves[m_captures]->pos, m_program.save_count };
return { m_saves[m_captures].pos, m_program.save_count };
return {};
}
private:
struct Saves
{
int16_t refcount;
int16_t next_free;
Iterator pos[1];
int32_t refcount;
int32_t next_free;
Iterator* pos;
};
template<bool copy>
@ -309,7 +308,7 @@ private:
if (m_first_free >= 0)
{
const int16_t res = m_first_free;
Saves& saves = *m_saves[res];
Saves& saves = m_saves[res];
m_first_free = saves.next_free;
kak_assert(saves.refcount == 1);
if (copy)
@ -320,11 +319,10 @@ private:
return res;
}
void* ptr = operator new (sizeof(Saves) + (count-1) * sizeof(Iterator));
Saves* saves = new (ptr) Saves{1, 0, {copy ? pos[0] : Iterator{}}};
for (size_t i = 1; i < count; ++i)
new (&saves->pos[i]) Iterator{copy ? pos[i] : Iterator{}};
m_saves.push_back(saves);
auto* new_pos = reinterpret_cast<Iterator*>(operator new (count * sizeof(Iterator)));
for (size_t i = 0; i < count; ++i)
new (new_pos+i) Iterator{copy ? pos[i] : Iterator{}};
m_saves.push_back({1, 0, new_pos});
return static_cast<int16_t>(m_saves.size() - 1);
}
@ -332,7 +330,7 @@ private:
{
if (index < 0)
return;
auto& saves = *m_saves[index];
auto& saves = m_saves[index];
if (saves.refcount == 1)
{
saves.next_free = m_first_free;
@ -414,7 +412,7 @@ private:
break;
if (thread.saves >= 0)
++m_saves[thread.saves]->refcount;
++m_saves[thread.saves].refcount;
if (inst.param.split.prioritize_parent)
m_threads.push_current({inst.param.split.target, thread.saves});
@ -429,12 +427,12 @@ private:
break;
if (thread.saves < 0)
thread.saves = new_saves<false>(nullptr);
else if (m_saves[thread.saves]->refcount > 1)
else if (m_saves[thread.saves].refcount > 1)
{
--m_saves[thread.saves]->refcount;
thread.saves = new_saves<true>(m_saves[thread.saves]->pos);
--m_saves[thread.saves].refcount;
thread.saves = new_saves<true>(m_saves[thread.saves].pos);
}
m_saves[thread.saves]->pos[inst.param.save_index] = pos;
m_saves[thread.saves].pos[inst.param.save_index] = pos;
break;
case CompiledRegex::CharClass:
if (pos == config.end)
@ -709,7 +707,7 @@ private:
static constexpr bool forward = mode & RegexMode::Forward;
DualThreadStack m_threads;
Vector<Saves*, MemoryDomain::Regex> m_saves;
Vector<Saves, MemoryDomain::Regex> m_saves;
int16_t m_first_free = -1;
int16_t m_captures = -1;
bool m_found_match = false;