Skip to content

Commit

Permalink
Fix cmake list. Use profiler by value, remove allocation. Do not atta…
Browse files Browse the repository at this point in the history
…ch hook by default, use original logics for script engine, add attach methods. Update profiler exports, add profiler type global variables. Add profiler type separation / additional methods for hook/jit based profiling. Separate env vars for different profiling.
  • Loading branch information
Neloreck committed Jan 15, 2025
1 parent 5637d59 commit b9e576f
Show file tree
Hide file tree
Showing 6 changed files with 192 additions and 88 deletions.
4 changes: 2 additions & 2 deletions src/xrScriptEngine/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ target_sources_grouped(
script_debugger_threads.hpp
script_lua_helper.cpp
script_lua_helper.hpp
script_profiler.cpp,
script_profiler.hpp,
script_profiler.cpp
script_profiler.hpp
)

target_sources_grouped(
Expand Down
68 changes: 32 additions & 36 deletions src/xrScriptEngine/ScriptEngineScript.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,36 +66,6 @@ bool is_editor()
return GEnv.ScriptEngine->is_editor();
}

void isProfilerActive()
{
GEnv.ScriptEngine->m_profiler->isActive();
}

void startProfiler()
{
GEnv.ScriptEngine->m_profiler->start();
}

void stopProfiler()
{
GEnv.ScriptEngine->m_profiler->stop();
}

void resetProfiler()
{
GEnv.ScriptEngine->m_profiler->reset();
}

void saveProfiler()
{
GEnv.ScriptEngine->m_profiler->save();
}

void logProfiler()
{
GEnv.ScriptEngine->m_profiler->log();
}

inline int bit_and(const int i, const int j) { return i & j; }
inline int bit_or(const int i, const int j) { return i | j; }
inline int bit_xor(const int i, const int j) { return i ^ j; }
Expand Down Expand Up @@ -169,6 +139,10 @@ std::ostream& operator<<(std::ostream& os, const profile_timer_script& pt) { ret
SCRIPT_EXPORT(CScriptEngine, (),
{
using namespace luabind;

globals(luaState) ["PROFILER_TYPE_HOOK"] = (u32) CScriptProfilerType::Hook;
globals(luaState) ["PROFILER_TYPE_JIT"] = (u32) CScriptProfilerType::Jit;

module(luaState)
[
class_<profile_timer_script>("profile_timer")
Expand Down Expand Up @@ -197,11 +171,33 @@ SCRIPT_EXPORT(CScriptEngine, (),

module(luaState, "profiler")
[
def("isActive", &isProfilerActive),
def("start", &startProfiler),
def("stop", &stopProfiler),
def("reset", &resetProfiler),
def("log", &logProfiler),
def("save", &saveProfiler)
def("is_active", +[]()
{
GEnv.ScriptEngine->m_profiler.isActive();
}),
def("start", +[]()
{
GEnv.ScriptEngine->m_profiler.start();
}),
def("start", +[](CScriptProfilerType hook_type)
{
GEnv.ScriptEngine->m_profiler.start(hook_type);
}),
def("stop", +[]()
{
GEnv.ScriptEngine->m_profiler.stop();
}),
def("reset", +[]()
{
GEnv.ScriptEngine->m_profiler.reset();
}),
def("log_report", +[]()
{
GEnv.ScriptEngine->m_profiler.logReport();
}),
def("save_report", +[]()
{
GEnv.ScriptEngine->m_profiler.saveReport();
})
];
});
12 changes: 2 additions & 10 deletions src/xrScriptEngine/script_engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -748,7 +748,7 @@ void CScriptEngine::disconnect_from_debugger()
}
#endif

CScriptEngine::CScriptEngine(bool is_editor)
CScriptEngine::CScriptEngine(bool is_editor) : m_profiler(this)
{
luabind::allocator = &luabind_allocator;
luabind::allocator_context = nullptr;
Expand All @@ -770,7 +770,6 @@ CScriptEngine::CScriptEngine(bool is_editor)
#endif
#endif
m_is_editor = is_editor;
m_profiler = xr_new<CScriptProfiler>();
}

CScriptEngine::~CScriptEngine()
Expand All @@ -791,8 +790,6 @@ CScriptEngine::~CScriptEngine()
#endif
if (scriptBuffer)
xr_free(scriptBuffer);

xr_free(m_profiler);
}

void CScriptEngine::unload()
Expand Down Expand Up @@ -888,7 +885,7 @@ void CScriptEngine::lua_hook_call(lua_State* L, lua_Debug* dbg)
else
scriptEngine->m_stack_is_ready = true;

scriptEngine->m_profiler->onLuaHookCall(L, dbg);
scriptEngine->m_profiler.onLuaHookCall(L, dbg);
}

#endif
Expand Down Expand Up @@ -1069,11 +1066,6 @@ void CScriptEngine::init(ExporterFunc exporterFunc, bool loadGlobalNamespace)
}
m_stack_level = lua_gettop(lua());

// todo: Hook on activation wich check.
// todo: Hook on activation wich check.
// todo: Hook on activation wich check.
lua_sethook(lua(), CScriptEngine::lua_hook_call, LUA_MASKLINE | LUA_MASKCALL | LUA_MASKRET, 0);

setvbuf(stderr, g_ca_stdout, _IOFBF, sizeof(g_ca_stdout));
}

Expand Down
2 changes: 1 addition & 1 deletion src/xrScriptEngine/script_engine.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ class XRSCRIPTENGINE_API CScriptEngine
}

public:
CScriptProfiler* m_profiler;
CScriptProfiler m_profiler;

lua_State* lua() { return m_virtual_machine; }
void current_thread(CScriptThread* thread)
Expand Down
158 changes: 125 additions & 33 deletions src/xrScriptEngine/script_profiler.cpp
Original file line number Diff line number Diff line change
@@ -1,85 +1,142 @@
#include "pch.hpp"
#include "script_profiler.hpp"
#include "xrScriptEngine/script_engine.hpp"

CScriptProfiler::CScriptProfiler()
CScriptProfiler::CScriptProfiler(CScriptEngine* engine)
{
R_ASSERT(engine != NULL);

m_engine = engine;

m_active = false;
m_profile_level = 1;
m_profiler_type = CScriptProfilerType::None;

// todo: Configuration of profile levels.
// todo: Configuration of profile levels.
// todo: Configuration of profile levels.
// todo: Configuration of profile levels for hook profiler.
// todo: Configuration of profile levels for hook profiler.
// todo: Configuration of profile levels for hook profiler.

if (strstr(Core.Params, "-lua_profiler"))
{
start();
}
else if (strstr(Core.Params, "-lua_hook_profiler"))
start(CScriptProfilerType::Hook);
else if (strstr(Core.Params, "-lua_jit_profiler"))
start(CScriptProfilerType::Jit);
}

CScriptProfiler::~CScriptProfiler()
{
}

void CScriptProfiler::start()
void CScriptProfiler::start(CScriptProfilerType profiler_type)
{
if (m_active)
{
Msg("Tried to start active profiler, operation ignored");
return;
}

Msg("Starting lua scripts profiler");

m_active = true;

// todo: Reset?
// todo: Reset?
// todo: Reset?
if (profiler_type == CScriptProfilerType::None)
{
Msg("Tried to start none profiler type");
return;
}

// todo: Check JIT and warn? Allow turn it off with parameter?
// todo: Check JIT and warn? Allow turn it off with parameter?
// todo: Check JIT and warn? Allow turn it off with parameter?

// todo: Attach hook?
// todo: Attach hook?
// todo: Attach hook?
m_profiling_portions.clear();
m_active = true;
m_profiler_type = profiler_type;

switch (profiler_type)
{
case CScriptProfilerType::Hook:
Msg("Starting lua scripts hook profiler");

attachLuaHook();

return;
case CScriptProfilerType::Jit:
{
Msg("Starting lua scripts jit profiler");

return;
}

default: NODEFAULT;
}
}

void CScriptProfiler::stop()
{
if (!m_active)
{
Msg("Tried to stop inactive profiler, operation ignored");
Msg("Tried to stop inactive profiler");
return;
}

if (m_profiler_type == CScriptProfilerType::None)
{
Msg("Tried to stop none profiler type");
return;
}

Msg("Stopping lua scripts profiler");
switch (m_profiler_type)
{
case CScriptProfilerType::Hook:
Msg("Stopping lua scripts hook profiler");

// Do not detach hook here, adding it means that it is already test run in the first place.

break;
case CScriptProfilerType::Jit:
{
Msg("Stopping lua scripts jit profiler");

break;
}

// todo: Reset?
// todo: Reset?
// todo: Reset?
default: NODEFAULT;
}

// todo: Detach hook?
// todo: Detach hook?
// todo: Detach hook?
m_active = false;
}

void CScriptProfiler::reset()
{
Msg("Reset profiler");

// todo;
// todo;
// todo;
m_profiling_portions.clear();
}

void CScriptProfiler::logReport()
{
switch (m_profiler_type)
{
case CScriptProfilerType::Hook:
return logHookReport();
case CScriptProfilerType::Jit:
return logJitReport();
default:
Msg("Nothing to report for profiler");
return;
}
}

void CScriptProfiler::log()
void CScriptProfiler::logHookReport()
{
if (m_profiling_portions.empty())
{
Msg("Nothing to report for hook profiler, data is missing");
return;
}

u64 total_count = 0;
u64 total_duration = 0;

std::vector<decltype(m_profiling_portions)::iterator> entries;
xr_vector<decltype(m_profiling_portions)::iterator> entries;
entries.reserve(m_profiling_portions.size());

for (auto it = m_profiling_portions.begin(); it != m_profiling_portions.end(); it++)
Expand All @@ -90,9 +147,8 @@ void CScriptProfiler::log()
total_duration += it->second.duration();
}


Msg("==================================================================");
Msg("= Log profiler report, %d entries", entries.size());
Msg("= Log hook profiler report, %d entries", entries.size());
Msg("==================================================================");
Msg("= By calls duration:");
Msg("====");
Expand Down Expand Up @@ -148,7 +204,14 @@ void CScriptProfiler::log()
// todo;
}

void CScriptProfiler::save()
void CScriptProfiler::logJitReport()
{
// todo;
// todo;
// todo;
}

void CScriptProfiler::saveReport()
{
Log("Save profiler report");

Expand All @@ -157,6 +220,25 @@ void CScriptProfiler::save()
// todo;
}

void CScriptProfiler::attachLuaHook()
{
lua_State* L = lua();
lua_Hook hook = lua_gethook(L);

if (hook)
{
if (hook != CScriptEngine::lua_hook_call)
{
Msg("Warning: hook already defined by something else, cannot take ownership as CScriptEngine");
}
}
else
{
Msg("Attaching lua scripts hook");
lua_sethook(L, CScriptEngine::lua_hook_call, LUA_MASKLINE | LUA_MASKCALL | LUA_MASKRET, 0);
}
}

void CScriptProfiler::onLuaHookCall(lua_State* L, lua_Debug* dbg)
{
if (!m_active || dbg->event == LUA_HOOKLINE)
Expand Down Expand Up @@ -243,6 +325,16 @@ void CScriptProfiler::onLuaHookCall(lua_State* L, lua_Debug* dbg)
}
}

lua_State* CScriptProfiler::lua() const
{
return this->m_engine->lua();
}

bool CScriptProfiler::luaIsJitProfilerDefined(lua_State* L)
{
return true;
}

// todo: Add util to get frame info
// todo: Add util to get frame info
// todo: Add util to get frame info
Loading

0 comments on commit b9e576f

Please sign in to comment.