Explorar o código

LibWasm: Remove `Module::functions`

`Module::functions` created clones of all of the functions in the
module. It provided a _slightly_ better API, but ended up costing around
40ms when instantiating spidermonkey.
Diego Frias hai 11 meses
pai
achega
dc52998341

+ 21 - 12
Userland/Libraries/LibWasm/AbstractMachine/AbstractMachine.cpp

@@ -14,14 +14,14 @@
 
 namespace Wasm {
 
-Optional<FunctionAddress> Store::allocate(ModuleInstance& module, Module::Function const& function)
+Optional<FunctionAddress> Store::allocate(ModuleInstance& module, CodeSection::Code const& code, TypeIndex type_index)
 {
     FunctionAddress address { m_functions.size() };
-    if (function.type().value() > module.types().size())
+    if (type_index.value() > module.types().size())
         return {};
 
-    auto& type = module.types()[function.type().value()];
-    m_functions.empend(WasmFunction { type, module, function });
+    auto& type = module.types()[type_index.value()];
+    m_functions.empend(WasmFunction { type, module, code });
     return address;
 }
 
@@ -223,15 +223,24 @@ InstantiationResult AbstractMachine::instantiate(Module const& module, Vector<Ex
             auxiliary_instance.functions().append(*ptr);
     }
 
-    Vector<FunctionAddress> module_functions;
-    module_functions.ensure_capacity(module.functions().size());
+    FunctionSection const* function_section { nullptr };
+    module.for_each_section_of_type<FunctionSection>([&](FunctionSection const& section) { function_section = &section; });
 
-    for (auto& func : module.functions()) {
-        auto address = m_store.allocate(main_module_instance, func);
-        VERIFY(address.has_value());
-        auxiliary_instance.functions().append(*address);
-        module_functions.append(*address);
-    }
+    Vector<FunctionAddress> module_functions;
+    if (function_section)
+        module_functions.ensure_capacity(function_section->types().size());
+
+    module.for_each_section_of_type<CodeSection>([&](auto& code_section) {
+        size_t i = 0;
+        for (auto& code : code_section.functions()) {
+            auto type_index = function_section->types()[i];
+            auto address = m_store.allocate(main_module_instance, code, type_index);
+            VERIFY(address.has_value());
+            auxiliary_instance.functions().append(*address);
+            module_functions.append(*address);
+            ++i;
+        }
+    });
 
     BytecodeInterpreter interpreter(m_stack_info);
 

+ 3 - 3
Userland/Libraries/LibWasm/AbstractMachine/AbstractMachine.h

@@ -329,7 +329,7 @@ private:
 
 class WasmFunction {
 public:
-    explicit WasmFunction(FunctionType const& type, ModuleInstance const& module, Module::Function const& code)
+    explicit WasmFunction(FunctionType const& type, ModuleInstance const& module, CodeSection::Code const& code)
         : m_type(type)
         , m_module(module)
         , m_code(code)
@@ -343,7 +343,7 @@ public:
 private:
     FunctionType m_type;
     ModuleInstance const& m_module;
-    Module::Function const& m_code;
+    CodeSection::Code const& m_code;
 };
 
 class HostFunction {
@@ -537,7 +537,7 @@ class Store {
 public:
     Store() = default;
 
-    Optional<FunctionAddress> allocate(ModuleInstance& module, Module::Function const& function);
+    Optional<FunctionAddress> allocate(ModuleInstance&, CodeSection::Code const&, TypeIndex);
     Optional<FunctionAddress> allocate(HostFunction&&);
     Optional<TableAddress> allocate(TableType const&);
     Optional<MemoryAddress> allocate(MemoryType const&);

+ 6 - 4
Userland/Libraries/LibWasm/AbstractMachine/Configuration.cpp

@@ -44,14 +44,16 @@ Result Configuration::call(Interpreter& interpreter, FunctionAddress address, Ve
         return Trap {};
     if (auto* wasm_function = function->get_pointer<WasmFunction>()) {
         Vector<Value> locals = move(arguments);
-        locals.ensure_capacity(locals.size() + wasm_function->code().locals().size());
-        for (auto& type : wasm_function->code().locals())
-            locals.empend(type, 0ull);
+        locals.ensure_capacity(locals.size() + wasm_function->code().func().locals().size());
+        for (auto& local : wasm_function->code().func().locals()) {
+            for (size_t i = 0; i < local.n(); ++i)
+                locals.empend(local.type(), 0ull);
+        }
 
         set_frame(Frame {
             wasm_function->module(),
             move(locals),
-            wasm_function->code().body(),
+            wasm_function->code().func().body(),
             wasm_function->type().results().size(),
         });
         m_ip = 0;

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

@@ -74,9 +74,13 @@ ErrorOr<void, ValidationError> Validator::validate(Module& module)
         return result;
     }
 
-    module.for_each_section_of_type<FunctionSection>([this, &result](FunctionSection const& section) {
-        if (result.is_error())
+    CodeSection const* code_section { nullptr };
+    module.for_each_section_of_type<CodeSection>([&](auto& section) { code_section = &section; });
+    module.for_each_section_of_type<FunctionSection>([&](FunctionSection const& section) {
+        if ((!code_section && !section.types().is_empty()) || (code_section && code_section->functions().size() != section.types().size())) {
+            result = Errors::invalid("FunctionSection"sv);
             return;
+        }
         m_context.functions.ensure_capacity(section.types().size() + m_context.functions.size());
         for (auto& index : section.types()) {
             if (m_context.types.size() > index.value()) {

+ 0 - 36
Userland/Libraries/LibWasm/Parser/Parser.cpp

@@ -1403,42 +1403,6 @@ ParseResult<Module> Module::parse(Stream& stream)
     return Module { move(sections) };
 }
 
-bool Module::populate_sections()
-{
-    auto is_ok = true;
-    FunctionSection const* function_section { nullptr };
-    bool seen_code_section = false;
-    for_each_section_of_type<FunctionSection>([&](FunctionSection const& section) { function_section = &section; });
-    for_each_section_of_type<CodeSection>([&](CodeSection const& section) {
-        if (!function_section && section.functions().is_empty()) {
-            return;
-        }
-        if (!function_section || function_section->types().size() != section.functions().size()) {
-            is_ok = false;
-            return;
-        }
-        seen_code_section = true;
-        size_t index = 0;
-        for (auto& entry : section.functions()) {
-            if (function_section->types().size() <= index) {
-                is_ok = false;
-                return;
-            }
-            auto& type_index = function_section->types()[index];
-            Vector<ValueType> locals;
-            for (auto& local : entry.func().locals()) {
-                for (size_t i = 0; i < local.n(); ++i)
-                    locals.append(local.type());
-            }
-            m_functions.empend(type_index, move(locals), entry.func().body());
-            ++index;
-        }
-    });
-    if (!seen_code_section && function_section && !function_section->types().is_empty())
-        return false;
-    return is_ok;
-}
-
 ByteString parse_error_to_byte_string(ParseError error)
 {
     switch (error) {

+ 0 - 27
Userland/Libraries/LibWasm/Printer/Printer.cpp

@@ -541,33 +541,6 @@ void Printer::print(Wasm::Module const& module)
     print(")\n");
 }
 
-void Printer::print(Wasm::Module::Function const& func)
-{
-    print_indent();
-    print("(function\n");
-    {
-        TemporaryChange change { m_indent, m_indent + 1 };
-        {
-            print_indent();
-            print("(locals\n");
-            {
-                TemporaryChange change { m_indent, m_indent + 1 };
-                for (auto& locals : func.locals())
-                    print(locals);
-            }
-            print_indent();
-            print(")\n");
-        }
-        print_indent();
-        print("(body\n");
-        print(func.body());
-        print_indent();
-        print(")\n");
-    }
-    print_indent();
-    print(")\n");
-}
-
 void Printer::print(Wasm::StartSection const& section)
 {
     print_indent();

+ 0 - 1
Userland/Libraries/LibWasm/Printer/Printer.h

@@ -50,7 +50,6 @@ struct Printer {
     void print(Wasm::MemorySection::Memory const&);
     void print(Wasm::MemoryType const&);
     void print(Wasm::Module const&);
-    void print(Wasm::Module::Function const&);
     void print(Wasm::Reference const&);
     void print(Wasm::StartSection const&);
     void print(Wasm::StartSection::StartFunction const&);

+ 0 - 26
Userland/Libraries/LibWasm/Types.h

@@ -961,25 +961,6 @@ public:
         Valid,
     };
 
-    class Function {
-    public:
-        explicit Function(TypeIndex type, Vector<ValueType> local_types, Expression body)
-            : m_type(type)
-            , m_local_types(move(local_types))
-            , m_body(move(body))
-        {
-        }
-
-        auto& type() const { return m_type; }
-        auto& locals() const { return m_local_types; }
-        auto& body() const { return m_body; }
-
-    private:
-        TypeIndex m_type;
-        Vector<ValueType> m_local_types;
-        Expression m_body;
-    };
-
     using AnySection = Variant<
         CustomSection,
         TypeSection,
@@ -1001,14 +982,9 @@ public:
     explicit Module(Vector<AnySection> sections)
         : m_sections(move(sections))
     {
-        if (!populate_sections()) {
-            m_validation_status = ValidationStatus::Invalid;
-            m_validation_error = "Failed to populate module sections"sv;
-        }
     }
 
     auto& sections() const { return m_sections; }
-    auto& functions() const { return m_functions; }
     auto& type(TypeIndex index) const
     {
         FunctionType const* type = nullptr;
@@ -1045,11 +1021,9 @@ public:
     static ParseResult<Module> parse(Stream& stream);
 
 private:
-    bool populate_sections();
     void set_validation_status(ValidationStatus status) { m_validation_status = status; }
 
     Vector<AnySection> m_sections;
-    Vector<Function> m_functions;
     ValidationStatus m_validation_status { ValidationStatus::Unchecked };
     Optional<ByteString> m_validation_error;
 };