diff options
| author | Maxime Coste <mawww@kakoune.org> | 2024-03-07 20:40:24 +1100 |
|---|---|---|
| committer | Maxime Coste <mawww@kakoune.org> | 2024-03-07 20:40:24 +1100 |
| commit | a1c52e08a4e01ec48f920b7577dcf7486123fa5e (patch) | |
| tree | 76b7026fdd6dab7a7a1a3aedd6be90b902ab69f8 /src | |
| parent | c81266d4f6e5ddff861dc245d86600cb8f68b9e8 (diff) | |
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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/regex_impl.hh | 42 |
1 files changed, 20 insertions, 22 deletions
diff --git a/src/regex_impl.hh b/src/regex_impl.hh index d7e7554c..1e8296b5 100644 --- a/src/regex_impl.hh +++ b/src/regex_impl.hh @@ -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; |
