summaryrefslogtreecommitdiff
path: root/Userland/Libraries
diff options
context:
space:
mode:
authorAli Mohammad Pur <mpfard@serenityos.org>2021-07-17 01:04:37 +0430
committerGitHub <noreply@github.com>2021-07-17 01:04:37 +0430
commit35394dbfaa23b44a293da85b20a63a10f73572c3 (patch)
tree152449f3fa61c4b32d70c6fb12896b32429aada2 /Userland/Libraries
parent3099a6bf2add35ac6a0c7ce4cbb6c794d6269d19 (diff)
downloadserenity-35394dbfaa23b44a293da85b20a63a10f73572c3.zip
LibWasm: Some more performance stuff (#8812)
* wasm: Don't try to print the function results if it traps * LibWasm: Inline some very hot functions These are mostly pretty small functions too, and they were about ~10% of runtime. * LibWasm+Everywhere: Make the instruction count limit configurable ...and enable it for LibWeb and test-wasm. Note that `wasm` will not be limited by this. * LibWasm: Remove a useless use of ScopeGuard There are no multiple exit paths in that function, so we can just put the ending logic right at the end of the function instead.
Diffstat (limited to 'Userland/Libraries')
-rw-r--r--Userland/Libraries/LibWasm/AbstractMachine/AbstractMachine.cpp10
-rw-r--r--Userland/Libraries/LibWasm/AbstractMachine/AbstractMachine.h13
-rw-r--r--Userland/Libraries/LibWasm/AbstractMachine/BytecodeInterpreter.cpp27
-rw-r--r--Userland/Libraries/LibWasm/AbstractMachine/BytecodeInterpreter.h2
-rw-r--r--Userland/Libraries/LibWasm/AbstractMachine/Configuration.h4
-rw-r--r--Userland/Libraries/LibWeb/WebAssembly/WebAssemblyObject.cpp1
6 files changed, 38 insertions, 19 deletions
diff --git a/Userland/Libraries/LibWasm/AbstractMachine/AbstractMachine.cpp b/Userland/Libraries/LibWasm/AbstractMachine/AbstractMachine.cpp
index 07a81d7fe9..d923987bdc 100644
--- a/Userland/Libraries/LibWasm/AbstractMachine/AbstractMachine.cpp
+++ b/Userland/Libraries/LibWasm/AbstractMachine/AbstractMachine.cpp
@@ -128,6 +128,8 @@ InstantiationResult AbstractMachine::instantiate(Module const& module, Vector<Ex
module.for_each_section_of_type<GlobalSection>([&](auto& global_section) {
for (auto& entry : global_section.entries()) {
Configuration config { m_store };
+ if (m_should_limit_instruction_count)
+ config.enable_instruction_count_limit();
config.set_frame(Frame {
auxiliary_instance,
Vector<Value> {},
@@ -153,6 +155,8 @@ InstantiationResult AbstractMachine::instantiate(Module const& module, Vector<Ex
Vector<Reference> references;
for (auto& entry : segment.init) {
Configuration config { m_store };
+ if (m_should_limit_instruction_count)
+ config.enable_instruction_count_limit();
config.set_frame(Frame {
main_module_instance,
Vector<Value> {},
@@ -204,6 +208,8 @@ InstantiationResult AbstractMachine::instantiate(Module const& module, Vector<Ex
return IterationDecision::Break;
}
Configuration config { m_store };
+ if (m_should_limit_instruction_count)
+ config.enable_instruction_count_limit();
config.set_frame(Frame {
main_module_instance,
Vector<Value> {},
@@ -262,6 +268,8 @@ InstantiationResult AbstractMachine::instantiate(Module const& module, Vector<Ex
segment.value().visit(
[&](DataSection::Data::Active const& data) {
Configuration config { m_store };
+ if (m_should_limit_instruction_count)
+ config.enable_instruction_count_limit();
config.set_frame(Frame {
main_module_instance,
Vector<Value> {},
@@ -439,6 +447,8 @@ Result AbstractMachine::invoke(FunctionAddress address, Vector<Value> arguments)
Result AbstractMachine::invoke(Interpreter& interpreter, FunctionAddress address, Vector<Value> arguments)
{
Configuration configuration { m_store };
+ if (m_should_limit_instruction_count)
+ configuration.enable_instruction_count_limit();
return configuration.call(interpreter, address, move(arguments));
}
diff --git a/Userland/Libraries/LibWasm/AbstractMachine/AbstractMachine.h b/Userland/Libraries/LibWasm/AbstractMachine/AbstractMachine.h
index 29d3c414b8..659a3bae78 100644
--- a/Userland/Libraries/LibWasm/AbstractMachine/AbstractMachine.h
+++ b/Userland/Libraries/LibWasm/AbstractMachine/AbstractMachine.h
@@ -130,26 +130,26 @@ public:
}
}
- Value(Value const& value)
+ ALWAYS_INLINE Value(Value const& value)
: m_value(AnyValueType { value.m_value })
, m_type(value.m_type)
{
}
- Value(Value&& value)
+ ALWAYS_INLINE Value(Value&& value)
: m_value(move(value.m_value))
, m_type(move(value.m_type))
{
}
- Value& operator=(Value&& value)
+ ALWAYS_INLINE Value& operator=(Value&& value)
{
m_value = move(value.m_value);
m_type = move(value.m_type);
return *this;
}
- Value& operator=(Value const& value)
+ ALWAYS_INLINE Value& operator=(Value const& value)
{
m_value = value.m_value;
m_type = value.m_type;
@@ -157,7 +157,7 @@ public:
}
template<typename T>
- Optional<T> to()
+ ALWAYS_INLINE Optional<T> to()
{
Optional<T> result;
m_value.visit(
@@ -505,10 +505,13 @@ public:
auto& store() const { return m_store; }
auto& store() { return m_store; }
+ void enable_instruction_count_limit() { m_should_limit_instruction_count = true; }
+
private:
Optional<InstantiationError> allocate_all_initial_phase(Module const&, ModuleInstance&, Vector<ExternValue>&, Vector<Value>& global_values);
Optional<InstantiationError> allocate_all_final_phase(Module const&, ModuleInstance&, Vector<Vector<Reference>>& elements);
Store m_store;
+ bool m_should_limit_instruction_count { false };
};
class Linker {
diff --git a/Userland/Libraries/LibWasm/AbstractMachine/BytecodeInterpreter.cpp b/Userland/Libraries/LibWasm/AbstractMachine/BytecodeInterpreter.cpp
index 06a87b010d..dedde43160 100644
--- a/Userland/Libraries/LibWasm/AbstractMachine/BytecodeInterpreter.cpp
+++ b/Userland/Libraries/LibWasm/AbstractMachine/BytecodeInterpreter.cpp
@@ -37,12 +37,15 @@ void BytecodeInterpreter::interpret(Configuration& configuration)
auto& instructions = configuration.frame().expression().instructions();
auto max_ip_value = InstructionPointer { instructions.size() };
auto& current_ip_value = configuration.ip();
+ auto const should_limit_instruction_count = configuration.should_limit_instruction_count();
u64 executed_instructions = 0;
while (current_ip_value < max_ip_value) {
- if (executed_instructions++ >= Constants::max_allowed_executed_instructions_per_call) [[unlikely]] {
- m_trap = Trap { "Exceeded maximum allowed number of instructions" };
- return;
+ if (should_limit_instruction_count) {
+ if (executed_instructions++ >= Constants::max_allowed_executed_instructions_per_call) [[unlikely]] {
+ m_trap = Trap { "Exceeded maximum allowed number of instructions" };
+ return;
+ }
}
auto& instruction = instructions[current_ip_value.value()];
auto old_ip = current_ip_value;
@@ -1123,17 +1126,15 @@ void DebuggerBytecodeInterpreter::interpret(Configuration& configuration, Instru
}
}
- ScopeGuard guard { [&] {
- if (post_interpret_hook) {
- auto result = post_interpret_hook(configuration, ip, instruction, *this);
- if (!result) {
- m_trap = Trap { "Trapped by user request" };
- return;
- }
- }
- } };
-
BytecodeInterpreter::interpret(configuration, ip, instruction);
+
+ if (post_interpret_hook) {
+ auto result = post_interpret_hook(configuration, ip, instruction, *this);
+ if (!result) {
+ m_trap = Trap { "Trapped by user request" };
+ return;
+ }
+ }
}
}
diff --git a/Userland/Libraries/LibWasm/AbstractMachine/BytecodeInterpreter.h b/Userland/Libraries/LibWasm/AbstractMachine/BytecodeInterpreter.h
index 41d2caacdb..fc4bcb5c04 100644
--- a/Userland/Libraries/LibWasm/AbstractMachine/BytecodeInterpreter.h
+++ b/Userland/Libraries/LibWasm/AbstractMachine/BytecodeInterpreter.h
@@ -50,7 +50,7 @@ protected:
T read_value(ReadonlyBytes data);
Vector<Value> pop_values(Configuration& configuration, size_t count);
- bool trap_if_not(bool value, StringView reason)
+ ALWAYS_INLINE bool trap_if_not(bool value, StringView reason)
{
if (!value)
m_trap = Trap { reason };
diff --git a/Userland/Libraries/LibWasm/AbstractMachine/Configuration.h b/Userland/Libraries/LibWasm/AbstractMachine/Configuration.h
index 04cef62746..580ad526e5 100644
--- a/Userland/Libraries/LibWasm/AbstractMachine/Configuration.h
+++ b/Userland/Libraries/LibWasm/AbstractMachine/Configuration.h
@@ -61,6 +61,9 @@ public:
Result call(Interpreter&, FunctionAddress, Vector<Value> arguments);
Result execute(Interpreter&);
+ void enable_instruction_count_limit() { m_should_limit_instruction_count = true; }
+ bool should_limit_instruction_count() const { return m_should_limit_instruction_count; }
+
void dump_stack();
private:
@@ -69,6 +72,7 @@ private:
Stack m_stack;
size_t m_depth { 0 };
InstructionPointer m_ip;
+ bool m_should_limit_instruction_count { false };
};
}
diff --git a/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyObject.cpp b/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyObject.cpp
index 96654696eb..d383994ad1 100644
--- a/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyObject.cpp
+++ b/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyObject.cpp
@@ -25,6 +25,7 @@ namespace Web::Bindings {
WebAssemblyObject::WebAssemblyObject(JS::GlobalObject& global_object)
: Object(*global_object.object_prototype())
{
+ s_abstract_machine.enable_instruction_count_limit();
}
void WebAssemblyObject::initialize(JS::GlobalObject& global_object)