From 8003bde03d8155e3438b1afa5323bb63892a4db9 Mon Sep 17 00:00:00 2001 From: Ali Mohammad Pur Date: Mon, 11 Mar 2024 16:55:29 +0100 Subject: [PATCH] AK+LibRegex+LibWasm: Remove the non-const COWVector::operator[] This was copying the vector behind our backs, let's remove it and make the copying explicit by putting it behind COWVector::mutable_at(). This is a further 64% performance improvement on Wasm validation. --- AK/COWVector.h | 9 +-------- Userland/Libraries/LibRegex/RegexByteCode.cpp | 16 ++++++++-------- Userland/Libraries/LibRegex/RegexMatcher.cpp | 8 ++++---- .../LibWasm/AbstractMachine/Validator.cpp | 3 +-- 4 files changed, 14 insertions(+), 22 deletions(-) diff --git a/AK/COWVector.h b/AK/COWVector.h index 23bc8da0c9d..0b92259773f 100644 --- a/AK/COWVector.h +++ b/AK/COWVector.h @@ -110,7 +110,7 @@ public: m_detail->m_members.clear(); } - T& at(size_t index) + T& mutable_at(size_t index) { // We're handing out a mutable reference, so make sure we own the data exclusively. copy(); @@ -122,13 +122,6 @@ public: return m_detail->m_members.at(index); } - T& operator[](size_t index) - { - // We're handing out a mutable reference, so make sure we own the data exclusively. - copy(); - return m_detail->m_members[index]; - } - T const& operator[](size_t index) const { return m_detail->m_members[index]; diff --git a/Userland/Libraries/LibRegex/RegexByteCode.cpp b/Userland/Libraries/LibRegex/RegexByteCode.cpp index c2205d39ab5..f8bdf1a3c1f 100644 --- a/Userland/Libraries/LibRegex/RegexByteCode.cpp +++ b/Userland/Libraries/LibRegex/RegexByteCode.cpp @@ -332,7 +332,7 @@ ALWAYS_INLINE ExecutionResult OpCode_CheckEnd::execute(MatchInput const& input, ALWAYS_INLINE ExecutionResult OpCode_ClearCaptureGroup::execute(MatchInput const& input, MatchState& state) const { if (input.match_index < state.capture_group_matches.size()) { - auto& group = state.capture_group_matches[input.match_index]; + auto& group = state.capture_group_matches.mutable_at(input.match_index); auto group_id = id(); if (group_id >= group.size()) group.resize(group_id + 1); @@ -352,19 +352,19 @@ ALWAYS_INLINE ExecutionResult OpCode_SaveLeftCaptureGroup::execute(MatchInput co } if (id() >= state.capture_group_matches.at(input.match_index).size()) { - state.capture_group_matches.at(input.match_index).ensure_capacity(id()); + state.capture_group_matches.mutable_at(input.match_index).ensure_capacity(id()); auto capacity = state.capture_group_matches.at(input.match_index).capacity(); for (size_t i = state.capture_group_matches.at(input.match_index).size(); i <= capacity; ++i) - state.capture_group_matches.at(input.match_index).empend(); + state.capture_group_matches.mutable_at(input.match_index).empend(); } - state.capture_group_matches.at(input.match_index).at(id()).left_column = state.string_position; + state.capture_group_matches.mutable_at(input.match_index).at(id()).left_column = state.string_position; return ExecutionResult::Continue; } ALWAYS_INLINE ExecutionResult OpCode_SaveRightCaptureGroup::execute(MatchInput const& input, MatchState& state) const { - auto& match = state.capture_group_matches.at(input.match_index).at(id()); + auto& match = state.capture_group_matches.mutable_at(input.match_index).at(id()); auto start_position = match.left_column; if (state.string_position < start_position) { dbgln("Right capture group {} is before left capture group {}!", state.string_position, start_position); @@ -391,7 +391,7 @@ ALWAYS_INLINE ExecutionResult OpCode_SaveRightCaptureGroup::execute(MatchInput c ALWAYS_INLINE ExecutionResult OpCode_SaveRightNamedCaptureGroup::execute(MatchInput const& input, MatchState& state) const { - auto& match = state.capture_group_matches.at(input.match_index).at(id()); + auto& match = state.capture_group_matches.mutable_at(input.match_index).at(id()); auto start_position = match.left_column; if (state.string_position < start_position) return ExecutionResult::Failed_ExecuteLowPrioForks; @@ -1051,7 +1051,7 @@ ALWAYS_INLINE ExecutionResult OpCode_Repeat::execute(MatchInput const&, MatchSta if (id() >= state.repetition_marks.size()) state.repetition_marks.resize(id() + 1); - auto& repetition_mark = state.repetition_marks.at(id()); + auto& repetition_mark = state.repetition_marks.mutable_at(id()); if (repetition_mark == count() - 1) { repetition_mark = 0; @@ -1068,7 +1068,7 @@ ALWAYS_INLINE ExecutionResult OpCode_ResetRepeat::execute(MatchInput const&, Mat if (id() >= state.repetition_marks.size()) state.repetition_marks.resize(id() + 1); - state.repetition_marks.at(id()) = 0; + state.repetition_marks.mutable_at(id()) = 0; return ExecutionResult::Continue; } diff --git a/Userland/Libraries/LibRegex/RegexMatcher.cpp b/Userland/Libraries/LibRegex/RegexMatcher.cpp index b4b9910b9e0..e14d04bfecb 100644 --- a/Userland/Libraries/LibRegex/RegexMatcher.cpp +++ b/Userland/Libraries/LibRegex/RegexMatcher.cpp @@ -157,9 +157,9 @@ RegexResult Matcher::match(Vector const& views, Optiona for (size_t j = 0; j < c_match_preallocation_count; ++j) { state.matches.empend(); state.capture_group_matches.empend(); - state.capture_group_matches.at(j).ensure_capacity(capture_groups_count); + state.capture_group_matches.mutable_at(j).ensure_capacity(capture_groups_count); for (size_t k = 0; k < capture_groups_count; ++k) - state.capture_group_matches.at(j).unchecked_append({}); + state.capture_group_matches.mutable_at(j).unchecked_append({}); } } @@ -169,9 +169,9 @@ RegexResult Matcher::match(Vector const& views, Optiona VERIFY(start_position + state.string_position - start_position <= input.view.length()); if (input.regex_options.has_flag_set(AllFlags::StringCopyMatches)) { - state.matches.at(input.match_index) = { input.view.substring_view(start_position, state.string_position - start_position).to_byte_string(), input.line, start_position, input.global_offset + start_position }; + state.matches.mutable_at(input.match_index) = { input.view.substring_view(start_position, state.string_position - start_position).to_byte_string(), input.line, start_position, input.global_offset + start_position }; } else { // let the view point to the original string ... - state.matches.at(input.match_index) = { input.view.substring_view(start_position, state.string_position - start_position), input.line, start_position, input.global_offset + start_position }; + state.matches.mutable_at(input.match_index) = { input.view.substring_view(start_position, state.string_position - start_position), input.line, start_position, input.global_offset + start_position }; } }; diff --git a/Userland/Libraries/LibWasm/AbstractMachine/Validator.cpp b/Userland/Libraries/LibWasm/AbstractMachine/Validator.cpp index eb994d49e3f..3795ce2b547 100644 --- a/Userland/Libraries/LibWasm/AbstractMachine/Validator.cpp +++ b/Userland/Libraries/LibWasm/AbstractMachine/Validator.cpp @@ -38,8 +38,7 @@ ErrorOr Validator::validate(Module& module) m_context = {}; module.for_each_section_of_type([this](TypeSection const& section) { - for (auto& type : section.types()) - m_context.types.append(type); + m_context.types.extend(section.types()); }); module.for_each_section_of_type([&](ImportSection const& section) {