From 7bec955df8c46e67b5f3c32e55c67348070740a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alf-Andr=C3=A9=20Walla?= Date: Tue, 17 Sep 2024 20:03:56 +0200 Subject: [PATCH] Measure accumulated Sandbox instantiation time Also, prevent loading a Sandbox with the same binary twice --- src/sandbox.cpp | 25 ++++++++++++++++++++++++- src/sandbox.h | 5 +++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/sandbox.cpp b/src/sandbox.cpp index 0d002d14..f86def21 100644 --- a/src/sandbox.cpp +++ b/src/sandbox.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include @@ -71,6 +72,9 @@ void Sandbox::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "monitor_global_exceptions", PROPERTY_HINT_NONE, "Number of exceptions thrown"), "", "get_global_exceptions"); ADD_PROPERTY(PropertyInfo(Variant::INT, "monitor_global_execution_timeouts", PROPERTY_HINT_NONE, "Number of execution timeouts"), "", "get_global_budget_overruns"); + ClassDB::bind_static_method("Sandbox", D_METHOD("get_accumulated_startup_time"), &Sandbox::get_accumulated_startup_time); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "monitor_accumulated_startup_time", PROPERTY_HINT_NONE, "Accumulated startup time of all sandbox instantiations"), "", "get_accumulated_startup_time"); + // Group for sandboxed properties. ADD_GROUP("Sandboxed Properties", "custom_"); } @@ -114,9 +118,19 @@ void Sandbox::load(PackedByteArray &&buffer, const std::vector *arg ERR_PRINT("Empty binary, cannot load program."); return; } + // If the binary sizes match, let's see if the binary is the exact same + if (buffer.size() == this->m_machine->memory.binary().size()) { + if (std::memcmp(buffer.ptr(), this->m_machine->memory.binary().data(), buffer.size()) == 0) { + // Binary is the same, no need to reload + return; + } + } this->m_binary = std::move(buffer); const std::string_view binary_view = std::string_view{ (const char *)this->m_binary.ptr(), static_cast(this->m_binary.size()) }; + // Get t0 for the startup time + double startup_t0 = Time::get_singleton()->get_ticks_usec(); + /** We can't handle exceptions until the Machine is fully constructed. Two steps. */ try { delete this->m_machine; @@ -167,6 +181,10 @@ void Sandbox::load(PackedByteArray &&buffer, const std::vector *arg for (int i = 0; i < functions.size(); i++) { this->cached_address_of(functions[i].hash(), functions[i]); } + + // Accumulate startup time + double startup_t1 = Time::get_singleton()->get_ticks_usec(); + m_accumulated_startup_time += (startup_t1 - startup_t0) / 1e6; } Variant Sandbox::vmcall_address(gaddr_t address, const Variant **args, GDExtensionInt arg_count, GDExtensionCallError &error) { @@ -665,6 +683,9 @@ bool Sandbox::get_property(const StringName &name, Variant &r_ret) { } else if (name == StringName("global_budget_overruns")) { r_ret = get_global_budget_overruns(); return true; + } else if (name == StringName("monitor_accumulated_startup_time")) { + r_ret = get_accumulated_startup_time(); + return true; } return false; } @@ -684,8 +705,10 @@ void SandboxProperty::set(Sandbox &sandbox, const Variant &value) { return; } const Variant *args[] = { &value }; + // Store use_unboxed_arguments state and restore it after the call + // It's much more convenient to use Variant arguments for properties auto old_use_unboxed_arguments = sandbox.get_use_unboxed_arguments(); - sandbox.set_use_unboxed_arguments(false); // Always use Variant for properties + sandbox.set_use_unboxed_arguments(false); sandbox.vmcall_internal(m_setter_address, args, 1); sandbox.set_use_unboxed_arguments(old_use_unboxed_arguments); } diff --git a/src/sandbox.h b/src/sandbox.h index b9b94d2d..692bc41a 100644 --- a/src/sandbox.h +++ b/src/sandbox.h @@ -120,6 +120,10 @@ class Sandbox : public Node { static uint64_t get_global_exceptions() { return m_global_exceptions; } static uint64_t get_global_calls_made() { return m_global_calls_made; } + /// @brief Get the globally accumulated startup time of all sandbox instantiations. + /// @return The accumulated startup time. + static double get_accumulated_startup_time() { return m_accumulated_startup_time; } + // -= Address Lookup =- gaddr_t address_of(std::string_view name) const; @@ -288,6 +292,7 @@ class Sandbox : public Node { static inline uint64_t m_global_budget_overruns = 0; static inline uint64_t m_global_exceptions = 0; static inline uint64_t m_global_calls_made = 0; + static inline double m_accumulated_startup_time = 0.0; }; inline void Sandbox::CurrentState::reset(unsigned index, unsigned max_refs) {