diff --git a/binding-mri/profiler-binding.cpp b/binding-mri/profiler-binding.cpp index a057d4f..34c611d 100644 --- a/binding-mri/profiler-binding.cpp +++ b/binding-mri/profiler-binding.cpp @@ -1,6 +1,3 @@ -//SOMEONE PLZ HELP ME FIX TIHIS SHITTTTTTTTTTT - - #include "binding.h" #include "binding-util.h" #include "debugwriter.h" @@ -10,8 +7,8 @@ #include #include #include - VALUE tp = Qnil; +static std::vector call_stack; // Глобальный стек вместо thread-local static uint64_t now_ns(void) { timespec ts; @@ -19,62 +16,42 @@ static uint64_t now_ns(void) { return (uint64_t)ts.tv_sec * 1000000000ull + (uint64_t)ts.tv_nsec; } -static std::string value_to_string(VALUE v, const char *fallback) { - if (NIL_P(v)) return fallback; - return std::string(StringValuePtr(v)); -} - static void tp_cb(VALUE tpval, void *) { rb_trace_arg_t *trace_arg = rb_tracearg_from_tracepoint(tpval); if (!trace_arg) return; rb_event_flag_t ev = rb_tracearg_event_flag(trace_arg); - struct Stack { - std::vector starts; - }; - static __thread Stack stack; if (ev == RUBY_EVENT_CALL) { - stack.starts.push_back(now_ns()); + call_stack.push_back(now_ns()); return; } if (ev == RUBY_EVENT_RETURN) { - if (stack.starts.empty()) return; + if (call_stack.empty()) return; uint64_t end_ns = now_ns(); - uint64_t start_ns = stack.starts.back(); - stack.starts.pop_back(); - + uint64_t start_ns = call_stack.back(); + call_stack.pop_back(); uint64_t dur_ns = end_ns - start_ns; - VALUE path = rb_tracearg_path(trace_arg); - VALUE lineno = rb_tracearg_lineno(trace_arg); - VALUE defined_class = rb_tracearg_defined_class(trace_arg); - VALUE method_id = rb_tracearg_method_id(trace_arg); + // Сохраняем VALUE в переменные ПЕРЕД StringValuePtr + VALUE path_val = rb_tracearg_path(trace_arg); + VALUE class_val = rb_tracearg_defined_class(trace_arg); + + const char *path = StringValuePtr(path_val); + const char *class_name = StringValuePtr(class_val); + long line = FIX2LONG(rb_tracearg_lineno(trace_arg)); + const char *method = rb_id2name((ID)rb_tracearg_method_id(trace_arg)); - std::string path_s = value_to_string(path, ""); - std::string class_s = value_to_string(defined_class, ""); - - std::string meth_s = ""; - if (!NIL_P(method_id)) { - const char *mn = rb_id2name((ID)method_id); - if (mn) meth_s = mn; - } - - long line = NIL_P(lineno) ? 0 : FIX2LONG(lineno); - - Debug() << "[PROFILER] " - << meth_s << ' ' - << path_s << ':' << line - << " class=" << class_s - << " dur_ns=" << dur_ns << "\n"; - return; + Debug() << "[PROFILER] " << method << " " << path << ":" << line + << " class=" << class_name << " dur_ns=" << dur_ns << "\n"; } } -static VALUE profiler(VALUE, VALUE v) { - if (tp == Qnil || NIL_P(tp)) { + +static VALUE profiler_set(VALUE, VALUE v) { + if (NIL_P(tp)) { rb_raise(rb_eRuntimeError, "Profiler not initialized"); return Qnil; } @@ -88,7 +65,6 @@ static VALUE profiler(VALUE, VALUE v) { } void ProfilerInit() { - Debug() << "[PROFILER] Initializing"; VALUE module = rb_define_module("Profiler"); tp = rb_tracepoint_new( Qnil, @@ -97,6 +73,6 @@ void ProfilerInit() { nullptr ); - rb_gc_register_address(&tp); - rb_define_singleton_method(module, "set", RUBY_METHOD_FUNC(profiler), 1); + rb_gc_register_address(&tp); + rb_define_singleton_method(module, "set", RUBY_METHOD_FUNC(profiler_set), 1); } diff --git a/scripts/Data_Settings.rb b/scripts/Data_Settings.rb index fdb81e3..b2dc8cb 100644 --- a/scripts/Data_Settings.rb +++ b/scripts/Data_Settings.rb @@ -53,6 +53,7 @@ module Settings :debug_picture_names => false, :debug_lightmap => false, :SDL_HINT_SHUTDOWN_DBUS_ON_QUIT => false, + :profiller => false, #Hidden :is_dejavu => false, @@ -564,6 +565,12 @@ class Window_Settings :parameter => :SDL_HINT_SHUTDOWN_DBUS_ON_QUIT, :icon => [1, 0], }, + { + :type => :bool, + :name => "Profiller", + :icon => [1, 0], + :parameter => :profiller + }, { :type => :sep }, { :type => :key, diff --git a/scripts/Settings_Setters.rb b/scripts/Settings_Setters.rb index ac276e4..961c454 100644 --- a/scripts/Settings_Setters.rb +++ b/scripts/Settings_Setters.rb @@ -94,6 +94,10 @@ module Settings Sunshine.setSDLHint("SDL_HINT_SHUTDOWN_DBUS_ON_QUIT", "0") end end + + def profiller(value) + Profiler.set(value) + end end end end