From b9b0ec865c74bfc9ef4321f0c7527b67ef49dc8a Mon Sep 17 00:00:00 2001 From: David Anderson Date: Tue, 24 Feb 2015 23:37:23 -0800 Subject: [PATCH] Simplify the JIT function cache. --- sourcepawn/jit/plugin-context.cpp | 18 ++++++++-------- sourcepawn/jit/plugin-runtime.cpp | 32 ++++++++++------------------- sourcepawn/jit/plugin-runtime.h | 16 ++++++++++++--- sourcepawn/jit/scripted-invoker.cpp | 3 ++- sourcepawn/jit/scripted-invoker.h | 12 +++++++++++ sourcepawn/jit/x86/jit_x86.cpp | 2 +- 6 files changed, 47 insertions(+), 36 deletions(-) diff --git a/sourcepawn/jit/plugin-context.cpp b/sourcepawn/jit/plugin-context.cpp index 22dd7ef1..664eed1b 100644 --- a/sourcepawn/jit/plugin-context.cpp +++ b/sourcepawn/jit/plugin-context.cpp @@ -550,17 +550,15 @@ PluginContext::Execute2(IPluginFunction *function, const cell_t *params, unsigne EnterProfileScope scriptScope("SourcePawn", cfun->FullName()); /* See if we have to compile the callee. */ - if (Environment::get()->IsJitEnabled() && - (fn = m_pRuntime->m_PubJitFuncs[public_id]) == NULL) - { + if (Environment::get()->IsJitEnabled()) { /* We might not have to - check pcode offset. */ - fn = m_pRuntime->GetJittedFunctionByOffset(cfun->Public()->code_offs); - if (fn) { - m_pRuntime->m_PubJitFuncs[public_id] = fn; - } else { - if ((fn = CompileFunction(m_pRuntime, cfun->Public()->code_offs, &ir)) == NULL) - return ir; - m_pRuntime->m_PubJitFuncs[public_id] = fn; + if ((fn = cfun->cachedCompiledFunction()) == nullptr) { + fn = m_pRuntime->GetJittedFunctionByOffset(cfun->Public()->code_offs); + if (!fn) { + if ((fn = CompileFunction(m_pRuntime, cfun->Public()->code_offs, &ir)) == NULL) + return ir; + } + cfun->setCachedCompiledFunction(fn); } } diff --git a/sourcepawn/jit/plugin-runtime.cpp b/sourcepawn/jit/plugin-runtime.cpp index cbaed60b..751b0f2b 100644 --- a/sourcepawn/jit/plugin-runtime.cpp +++ b/sourcepawn/jit/plugin-runtime.cpp @@ -34,7 +34,6 @@ PluginRuntime::PluginRuntime() : m_Debug(&m_plugin), m_pCtx(NULL), m_PubFuncs(NULL), - m_PubJitFuncs(NULL), m_CompSerial(0) { memset(&m_plugin, 0, sizeof(m_plugin)); @@ -42,7 +41,6 @@ PluginRuntime::PluginRuntime() m_MaxFuncs = 0; m_NumFuncs = 0; float_table_ = NULL; - function_map_ = NULL; alt_pcode_ = NULL; memset(m_CodeHash, 0, sizeof(m_CodeHash)); @@ -65,9 +63,7 @@ PluginRuntime::~PluginRuntime() for (uint32_t i = 0; i < m_plugin.num_publics; i++) delete m_PubFuncs[i]; delete [] m_PubFuncs; - delete [] m_PubJitFuncs; delete [] float_table_; - delete [] function_map_; delete [] alt_pcode_; for (size_t i = 0; i < m_JitFunctions.length(); i++) @@ -286,8 +282,6 @@ int PluginRuntime::CreateFromMemory(sp_file_hdr_t *hdr, uint8_t *base) if (m_plugin.num_publics > 0) { m_PubFuncs = new ScriptedInvoker *[m_plugin.num_publics]; memset(m_PubFuncs, 0, sizeof(ScriptedInvoker *) * m_plugin.num_publics); - m_PubJitFuncs = new CompiledFunction *[m_plugin.num_publics]; - memset(m_PubJitFuncs, 0, sizeof(CompiledFunction *) * m_plugin.num_publics); } MD5 md5_pcode; @@ -303,9 +297,9 @@ int PluginRuntime::CreateFromMemory(sp_file_hdr_t *hdr, uint8_t *base) m_pCtx = new PluginContext(this); SetupFloatNativeRemapping(); - function_map_size_ = m_plugin.pcode_size / sizeof(cell_t) + 1; - function_map_ = new CompiledFunction *[function_map_size_]; - memset(function_map_, 0, function_map_size_ * sizeof(CompiledFunction *)); + + if (!function_map_.init(32)) + return SP_ERROR_OUT_OF_MEMORY; return SP_ERROR_NONE; } @@ -315,24 +309,20 @@ PluginRuntime::AddJittedFunction(CompiledFunction *fn) { m_JitFunctions.append(fn); - cell_t pcode_offset = fn->GetCodeOffset(); - assert(pcode_offset % 4 == 0); + ucell_t pcode_offset = fn->GetCodeOffset(); + FunctionMap::Insert p = function_map_.findForAdd(pcode_offset); + assert(!p.found()); - uint32_t pcode_index = pcode_offset / 4; - assert(pcode_index < function_map_size_); - - function_map_[pcode_index] = fn; + function_map_.add(p, pcode_offset, fn); } CompiledFunction * PluginRuntime::GetJittedFunctionByOffset(cell_t pcode_offset) { - assert(pcode_offset % 4 == 0); - - uint32_t pcode_index = pcode_offset / 4; - assert(pcode_index < function_map_size_); - - return function_map_[pcode_index]; + FunctionMap::Result r = function_map_.find(pcode_offset); + if (r.found()) + return r->value; + return nullptr; } int diff --git a/sourcepawn/jit/plugin-runtime.h b/sourcepawn/jit/plugin-runtime.h index 27166ae8..a3e34690 100644 --- a/sourcepawn/jit/plugin-runtime.h +++ b/sourcepawn/jit/plugin-runtime.h @@ -16,6 +16,7 @@ #include #include #include +#include #include "jit_shared.h" #include "compiled-function.h" #include "scripted-invoker.h" @@ -110,15 +111,24 @@ class PluginRuntime unsigned int m_NumFuncs; unsigned int m_MaxFuncs; floattbl_t *float_table_; - CompiledFunction **function_map_; - size_t function_map_size_; + + struct FunctionMapPolicy { + static inline uint32_t hash(ucell_t value) { + return ke::HashInteger<4>(value); + } + static inline bool matches(ucell_t a, ucell_t b) { + return a == b; + } + }; + typedef ke::HashMap FunctionMap; + + FunctionMap function_map_; ke::Vector m_JitFunctions; public: DebugInfo m_Debug; PluginContext *m_pCtx; ScriptedInvoker **m_PubFuncs; - CompiledFunction **m_PubJitFuncs; public: unsigned int m_CompSerial; diff --git a/sourcepawn/jit/scripted-invoker.cpp b/sourcepawn/jit/scripted-invoker.cpp index bf02595c..b422bac4 100644 --- a/sourcepawn/jit/scripted-invoker.cpp +++ b/sourcepawn/jit/scripted-invoker.cpp @@ -52,7 +52,8 @@ ScriptedInvoker::GetParentContext() ScriptedInvoker::ScriptedInvoker(PluginRuntime *runtime, funcid_t id, uint32_t pub_id) : m_curparam(0), m_errorstate(SP_ERROR_NONE), - m_FnId(id) + m_FnId(id), + cc_function_(nullptr) { m_pRuntime = runtime; diff --git a/sourcepawn/jit/scripted-invoker.h b/sourcepawn/jit/scripted-invoker.h index 653a5c10..077ed0b0 100644 --- a/sourcepawn/jit/scripted-invoker.h +++ b/sourcepawn/jit/scripted-invoker.h @@ -19,6 +19,10 @@ class PluginRuntime; using namespace SourcePawn; +namespace sp { +class CompiledFunction; +} + struct ParamInfo { int flags; /* Copy-back flags */ @@ -70,6 +74,13 @@ class ScriptedInvoker : public IPluginFunction return public_; } + sp::CompiledFunction *cachedCompiledFunction() const { + return cc_function_; + } + void setCachedCompiledFunction(sp::CompiledFunction *fn) { + cc_function_ = fn; + } + private: int _PushString(const char *string, int sz_flags, int cp_flags, size_t len); int SetError(int err); @@ -83,6 +94,7 @@ class ScriptedInvoker : public IPluginFunction funcid_t m_FnId; char *full_name_; sp_public_t *public_; + sp::CompiledFunction *cc_function_; }; #endif //_INCLUDE_SOURCEMOD_BASEFUNCTION_H_ diff --git a/sourcepawn/jit/x86/jit_x86.cpp b/sourcepawn/jit/x86/jit_x86.cpp index c064c8a7..a7b0a819 100644 --- a/sourcepawn/jit/x86/jit_x86.cpp +++ b/sourcepawn/jit/x86/jit_x86.cpp @@ -165,7 +165,7 @@ CompileFromThunk(PluginRuntime *runtime, cell_t pcode_offs, void **addrp, char * } #if defined JIT_SPEW - g_engine1.GetDebugHook()->OnDebugSpew( + Environment::get()->debugger()->OnDebugSpew( "Patching thunk to %s::%s\n", runtime->plugin()->name, GetFunctionName(runtime->plugin(), pcode_offs));