diff --git a/configs/core.cfg b/configs/core.cfg index 19b726f1..dfa35525 100644 --- a/configs/core.cfg +++ b/configs/core.cfg @@ -145,5 +145,15 @@ * Disable this option at your own risk. */ "FollowCSGOServerGuidelines" "yes" -} + /** + * Controls whether the SourcePawn runtime will generate additional metadata about + * JIT-compiled functions for performance profiling or debugging purposes. + * + * "none" - Don't generate any additional JIT metadata + * "default" - Generate basic perf metadata (on Linux) and delete it automatically on quit + * "perf" - Generate basic perf metadata (Linux only - function names) + * "jitdump" - Generate extended perf metadata (Linux only - function names, bytecode, and source information) + */ + "JITMetadata" "default" +} diff --git a/core/sourcemod.cpp b/core/sourcemod.cpp index 75f0b14a..3af647a8 100644 --- a/core/sourcemod.cpp +++ b/core/sourcemod.cpp @@ -68,6 +68,7 @@ IGameConfig *g_pGameConf = NULL; bool g_Loaded = false; bool sm_show_debug_spew = false; bool sm_disable_jit = false; +int jit_metadata_flags = JIT_DEBUG_DELETE_ON_EXIT | JIT_DEBUG_PERF_BASIC; SMGlobalClass *SMGlobalClass::head = nullptr; #ifdef PLATFORM_WINDOWS @@ -130,8 +131,36 @@ ConfigResult SourceModBase::OnSourceModConfigChanged(const char *key, else if (strcasecmp(key, "DisableJIT") == 0) { sm_disable_jit = (strcasecmp(value, "yes") == 0) ? true : false; - if (g_pSourcePawn2) + + if (g_pSourcePawn2) { g_pSourcePawn2->SetJitEnabled(!sm_disable_jit); + } + + return ConfigResult_Accept; + } + else if (strcasecmp(key, "JITMetadata") == 0) + { + /* TODO: Support a comma-separated list of the flags */ + if (strcasecmp(value, "none") == 0) { + jit_metadata_flags = 0; + } + else if (strcasecmp(value, "default") == 0) { + jit_metadata_flags = JIT_DEBUG_DELETE_ON_EXIT | JIT_DEBUG_PERF_BASIC; + } + else if (strcasecmp(value, "perf") == 0) { + jit_metadata_flags = JIT_DEBUG_PERF_BASIC; + } + else if (strcasecmp(value, "jitdump") == 0) { + jit_metadata_flags = JIT_DEBUG_PERF_BASIC | JIT_DEBUG_PERF_JITDUMP; + } + else { + ke::SafeStrcpy(error, maxlength, "Invalid value: must be \"none\", \"default\", \"perf\", or \"jitdump\""); + return ConfigResult_Reject; + } + + if (g_pPawnEnv) { + g_pPawnEnv->SetDebugMetadataFlags(jit_metadata_flags); + } return ConfigResult_Accept; } @@ -242,6 +271,8 @@ bool SourceModBase::InitializeSourceMod(char *error, size_t maxlength, bool late if (sm_disable_jit) g_pSourcePawn2->SetJitEnabled(!sm_disable_jit); + g_pPawnEnv->SetDebugMetadataFlags(jit_metadata_flags); + sSourceModInitialized = true; /* Hook this now so we can detect startup without calling StartSourceMod() */