Browse Source

LibWasm: Avoid pointless vector copies in Validator::Context

These vector copies accounted for more than 50% of the current runtime
of the validator on a large wasm file, this commit makes them
copy-on-write to avoid the copies where possible, gaining nearly a 50%
speedup.
Ali Mohammad Pur 1 year ago
parent
commit
cced555879

+ 6 - 5
Userland/Libraries/LibWasm/AbstractMachine/Validator.cpp

@@ -38,7 +38,8 @@ ErrorOr<void, ValidationError> Validator::validate(Module& module)
     m_context = {};
 
     module.for_each_section_of_type<TypeSection>([this](TypeSection const& section) {
-        m_context.types = section.types();
+        for (auto& type : section.types())
+            m_context.types.append(type);
     });
 
     module.for_each_section_of_type<ImportSection>([&](ImportSection const& section) {
@@ -90,23 +91,23 @@ ErrorOr<void, ValidationError> Validator::validate(Module& module)
     module.for_each_section_of_type<TableSection>([this](TableSection const& section) {
         m_context.tables.ensure_capacity(m_context.tables.size() + section.tables().size());
         for (auto& table : section.tables())
-            m_context.tables.unchecked_append(table.type());
+            m_context.tables.append(table.type());
     });
     module.for_each_section_of_type<MemorySection>([this](MemorySection const& section) {
         m_context.memories.ensure_capacity(m_context.memories.size() + section.memories().size());
         for (auto& memory : section.memories())
-            m_context.memories.unchecked_append(memory.type());
+            m_context.memories.append(memory.type());
     });
 
     module.for_each_section_of_type<GlobalSection>([this](GlobalSection const& section) {
         m_context.globals.ensure_capacity(m_context.globals.size() + section.entries().size());
         for (auto& global : section.entries())
-            m_context.globals.unchecked_append(global.type());
+            m_context.globals.append(global.type());
     });
     module.for_each_section_of_type<ElementSection>([this](ElementSection const& section) {
         m_context.elements.ensure_capacity(section.segments().size());
         for (auto& segment : section.segments())
-            m_context.elements.unchecked_append(segment.type);
+            m_context.elements.append(segment.type);
     });
     module.for_each_section_of_type<DataSection>([this](DataSection const& section) {
         m_context.datas.resize(section.data().size());

+ 11 - 10
Userland/Libraries/LibWasm/AbstractMachine/Validator.h

@@ -6,6 +6,7 @@
 
 #pragma once
 
+#include <AK/COWVector.h>
 #include <AK/Debug.h>
 #include <AK/HashTable.h>
 #include <AK/SourceLocation.h>
@@ -17,15 +18,15 @@
 namespace Wasm {
 
 struct Context {
-    Vector<FunctionType> types;
-    Vector<FunctionType> functions;
-    Vector<TableType> tables;
-    Vector<MemoryType> memories;
-    Vector<GlobalType> globals;
-    Vector<ValueType> elements;
-    Vector<bool> datas;
-    Vector<ValueType> locals;
-    Vector<ResultType> labels;
+    COWVector<FunctionType> types;
+    COWVector<FunctionType> functions;
+    COWVector<TableType> tables;
+    COWVector<MemoryType> memories;
+    COWVector<GlobalType> globals;
+    COWVector<ValueType> elements;
+    COWVector<bool> datas;
+    COWVector<ValueType> locals;
+    COWVector<ResultType> labels;
     Optional<ResultType> return_;
     AK::HashTable<FunctionIndex> references;
     size_t imported_function_count { 0 };
@@ -345,7 +346,7 @@ private:
     Vector<ChildScopeKind> m_entered_scopes;
     Vector<BlockDetails> m_block_details;
     Vector<FunctionType> m_entered_blocks;
-    Vector<GlobalType> m_globals_without_internal_globals;
+    COWVector<GlobalType> m_globals_without_internal_globals;
 };
 
 }