Add a general profiling abstraction layer.
This commit is contained in:
@@ -292,7 +292,6 @@ int BaseRuntime::CreateFromMemory(sp_file_hdr_t *hdr, uint8_t *base)
|
||||
md5_data.finalize();
|
||||
md5_data.raw_digest(m_DataHash);
|
||||
|
||||
m_plugin.profiler = g_engine2.GetProfiler();
|
||||
m_pCtx = new BaseContext(this);
|
||||
co_ = g_Jit.StartCompilation(this);
|
||||
|
||||
@@ -491,9 +490,7 @@ BaseRuntime::GetFunctionById(funcid_t func_id)
|
||||
return NULL;
|
||||
pFunc = m_PubFuncs[func_id];
|
||||
if (!pFunc) {
|
||||
m_PubFuncs[func_id] = new CFunction(this,
|
||||
(func_id << 1) | 1,
|
||||
func_id);
|
||||
m_PubFuncs[func_id] = new CFunction(this, (func_id << 1) | 1, func_id);
|
||||
pFunc = m_PubFuncs[func_id];
|
||||
}
|
||||
}
|
||||
@@ -501,6 +498,21 @@ BaseRuntime::GetFunctionById(funcid_t func_id)
|
||||
return pFunc;
|
||||
}
|
||||
|
||||
CFunction *
|
||||
BaseRuntime::GetPublicFunction(size_t index)
|
||||
{
|
||||
CFunction *pFunc = m_PubFuncs[index];
|
||||
if (!pFunc) {
|
||||
sp_public_t *pub = NULL;
|
||||
GetPublicByIndex(index, &pub);
|
||||
if (pub)
|
||||
m_PubFuncs[index] = new CFunction(this, (index << 1) | 1, index);
|
||||
pFunc = m_PubFuncs[index];
|
||||
}
|
||||
|
||||
return pFunc;
|
||||
}
|
||||
|
||||
IPluginFunction *
|
||||
BaseRuntime::GetFunctionByName(const char *public_name)
|
||||
{
|
||||
@@ -509,16 +521,7 @@ BaseRuntime::GetFunctionByName(const char *public_name)
|
||||
if (FindPublicByName(public_name, &index) != SP_ERROR_NONE)
|
||||
return NULL;
|
||||
|
||||
CFunction *pFunc = m_PubFuncs[index];
|
||||
if (!pFunc) {
|
||||
sp_public_t *pub = NULL;
|
||||
GetPublicByIndex(index, &pub);
|
||||
if (pub)
|
||||
m_PubFuncs[index] = new CFunction(this, (index << 1) | 1, index);
|
||||
pFunc = m_PubFuncs[index];
|
||||
}
|
||||
|
||||
return pFunc;
|
||||
return GetPublicFunction(index);
|
||||
}
|
||||
|
||||
bool BaseRuntime::IsDebugging()
|
||||
@@ -594,7 +597,6 @@ BaseRuntime::CreateBlank(uint32_t heastk)
|
||||
m_plugin.mem_size = heastk;
|
||||
m_plugin.memory = new uint8_t[heastk];
|
||||
|
||||
m_plugin.profiler = g_engine2.GetProfiler();
|
||||
m_pCtx = new BaseContext(this);
|
||||
co_ = g_Jit.StartCompilation(this);
|
||||
|
||||
|
||||
@@ -71,6 +71,7 @@ class BaseRuntime
|
||||
void AddJittedFunction(JitFunction *fn);
|
||||
void SetName(const char *name);
|
||||
unsigned GetNativeReplacement(size_t index);
|
||||
CFunction *GetPublicFunction(size_t index);
|
||||
|
||||
BaseContext *GetBaseContext();
|
||||
const sp_plugin_t *plugin() const {
|
||||
|
||||
@@ -14,7 +14,7 @@ using namespace SourcePawn;
|
||||
|
||||
SourcePawnEngine2::SourcePawnEngine2()
|
||||
{
|
||||
m_Profiler = NULL;
|
||||
profiler_ = NULL;
|
||||
jit_enabled_ = true;
|
||||
}
|
||||
|
||||
@@ -147,7 +147,7 @@ void SourcePawnEngine2::DestroyFakeNative(SPVM_NATIVE_FUNC func)
|
||||
|
||||
const char *SourcePawnEngine2::GetEngineName()
|
||||
{
|
||||
return "SourcePawn 1.2, jit-x86";
|
||||
return "SourcePawn 1.3, jit-x86";
|
||||
}
|
||||
|
||||
const char *SourcePawnEngine2::GetVersionString()
|
||||
@@ -155,16 +155,6 @@ const char *SourcePawnEngine2::GetVersionString()
|
||||
return SOURCEMOD_VERSION;
|
||||
}
|
||||
|
||||
IProfiler *SourcePawnEngine2::GetProfiler()
|
||||
{
|
||||
return m_Profiler;
|
||||
}
|
||||
|
||||
void SourcePawnEngine2::SetProfiler(IProfiler *profiler)
|
||||
{
|
||||
m_Profiler = profiler;
|
||||
}
|
||||
|
||||
IDebugListener *SourcePawnEngine2::SetDebugListener(IDebugListener *listener)
|
||||
{
|
||||
return g_engine1.SetDebugListener(listener);
|
||||
|
||||
@@ -21,7 +21,6 @@ namespace SourcePawn
|
||||
SPVM_NATIVE_FUNC CreateFakeNative(SPVM_FAKENATIVE_FUNC callback, void *pData);
|
||||
void DestroyFakeNative(SPVM_NATIVE_FUNC func);
|
||||
IDebugListener *SetDebugListener(IDebugListener *listener);
|
||||
void SetProfiler(IProfiler *profiler);
|
||||
ICompilation *StartCompilation();
|
||||
const char *GetErrorString(int err);
|
||||
bool Initialize();
|
||||
@@ -37,14 +36,51 @@ namespace SourcePawn
|
||||
bool IsJitEnabled() {
|
||||
return jit_enabled_;
|
||||
}
|
||||
|
||||
void SetProfiler(IProfiler *profiler) {
|
||||
// Deprecated.
|
||||
}
|
||||
|
||||
void EnableProfiling() {
|
||||
profiling_enabled_ = !!profiler_;
|
||||
}
|
||||
void DisableProfiling() {
|
||||
profiling_enabled_ = false;
|
||||
}
|
||||
bool IsProfilingEnabled() {
|
||||
return profiling_enabled_;
|
||||
}
|
||||
void SetProfilingTool(IProfilingTool *tool) {
|
||||
profiler_ = tool;
|
||||
}
|
||||
|
||||
public:
|
||||
IProfiler *GetProfiler();
|
||||
IProfilingTool *GetProfiler() {
|
||||
return profiler_;
|
||||
}
|
||||
private:
|
||||
IProfiler *m_Profiler;
|
||||
IProfilingTool *profiler_;
|
||||
bool jit_enabled_;
|
||||
bool profiling_enabled_;
|
||||
};
|
||||
}
|
||||
|
||||
extern SourcePawn::SourcePawnEngine2 g_engine2;
|
||||
|
||||
class EnterProfileScope
|
||||
{
|
||||
public:
|
||||
EnterProfileScope(const char *group, const char *name)
|
||||
{
|
||||
if (g_engine2.IsProfilingEnabled())
|
||||
g_engine2.GetProfiler()->EnterScope(group, name);
|
||||
}
|
||||
|
||||
~EnterProfileScope()
|
||||
{
|
||||
if (g_engine2.IsProfilingEnabled())
|
||||
g_engine2.GetProfiler()->LeaveScope();
|
||||
}
|
||||
};
|
||||
|
||||
#endif //_INCLUDE_SOURCEPAWN_ENGINE_2_H_
|
||||
|
||||
@@ -59,7 +59,6 @@ namespace SourcePawn
|
||||
uint32_t num_pubvars; /**< Number of public variables */
|
||||
sp_native_t *natives; /**< Natives table */
|
||||
uint32_t num_natives; /**< Number of natives */
|
||||
IProfiler *profiler; /**< Pointer to IProfiler */
|
||||
uint32_t prof_flags; /**< Profiling flags */
|
||||
uint32_t run_flags; /**< Runtime flags */
|
||||
uint32_t pcode_version; /**< P-Code version number */
|
||||
|
||||
@@ -549,65 +549,47 @@ int BaseContext::Execute2(IPluginFunction *function, const cell_t *params, unsig
|
||||
int ir;
|
||||
int serial;
|
||||
cell_t *sp;
|
||||
funcid_t fnid;
|
||||
JitFunction *fn;
|
||||
sp_public_t *pubfunc;
|
||||
cell_t _ignore_result;
|
||||
unsigned int public_id;
|
||||
|
||||
fnid = function->GetFunctionID();
|
||||
EnterProfileScope profileScope("SourcePawn", "EnterJIT");
|
||||
|
||||
if (!g_WatchdogTimer.HandleInterrupt())
|
||||
return SP_ERROR_TIMEOUT;
|
||||
|
||||
if (fnid & 1)
|
||||
{
|
||||
public_id = fnid >> 1;
|
||||
|
||||
if (m_pRuntime->GetPublicByIndex(public_id, &pubfunc) != SP_ERROR_NONE)
|
||||
{
|
||||
return SP_ERROR_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
funcid_t fnid = function->GetFunctionID();
|
||||
if (!(fnid & 1))
|
||||
return SP_ERROR_INVALID_ADDRESS;
|
||||
}
|
||||
|
||||
unsigned public_id = fnid >> 1;
|
||||
CFunction *cfun = m_pRuntime->GetPublicFunction(public_id);
|
||||
if (!cfun)
|
||||
return SP_ERROR_NOT_FOUND;
|
||||
|
||||
if (m_pRuntime->IsPaused())
|
||||
{
|
||||
return SP_ERROR_NOT_RUNNABLE;
|
||||
}
|
||||
|
||||
if ((cell_t)(m_ctx.hp + 16*sizeof(cell_t)) > (cell_t)(m_ctx.sp - (sizeof(cell_t) * (num_params + 1))))
|
||||
{
|
||||
return SP_ERROR_STACKLOW;
|
||||
}
|
||||
|
||||
if (result == NULL)
|
||||
{
|
||||
result = &_ignore_result;
|
||||
}
|
||||
|
||||
/* We got this far. It's time to start profiling. */
|
||||
|
||||
if ((m_pRuntime->plugin()->prof_flags & SP_PROF_CALLBACKS) == SP_PROF_CALLBACKS)
|
||||
{
|
||||
serial = m_pRuntime->plugin()->profiler->OnCallbackBegin(this, pubfunc);
|
||||
}
|
||||
EnterProfileScope scriptScope("SourcePawn", cfun->FullName());
|
||||
|
||||
/* See if we have to compile the callee. */
|
||||
if (g_engine2.IsJitEnabled() && (fn = m_pRuntime->m_PubJitFuncs[public_id]) == NULL)
|
||||
{
|
||||
/* We might not have to - check pcode offset. */
|
||||
fn = m_pRuntime->GetJittedFunctionByOffset(pubfunc->code_offs);
|
||||
fn = m_pRuntime->GetJittedFunctionByOffset(cfun->Public()->code_offs);
|
||||
if (fn)
|
||||
{
|
||||
m_pRuntime->m_PubJitFuncs[public_id] = fn;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((fn = g_Jit.CompileFunction(m_pRuntime, pubfunc->code_offs, &ir)) == NULL)
|
||||
if ((fn = g_Jit.CompileFunction(m_pRuntime, cfun->Public()->code_offs, &ir)) == NULL)
|
||||
{
|
||||
return ir;
|
||||
}
|
||||
@@ -651,7 +633,7 @@ int BaseContext::Execute2(IPluginFunction *function, const cell_t *params, unsig
|
||||
if (g_engine2.IsJitEnabled())
|
||||
ir = g_Jit.InvokeFunction(m_pRuntime, fn, result);
|
||||
else
|
||||
ir = Interpret(m_pRuntime, pubfunc->code_offs, result);
|
||||
ir = Interpret(m_pRuntime, cfun->Public()->code_offs, result);
|
||||
|
||||
/* Restore some states, stop the frame tracer */
|
||||
|
||||
@@ -695,11 +677,6 @@ int BaseContext::Execute2(IPluginFunction *function, const cell_t *params, unsig
|
||||
m_ctx.hp = save_hp;
|
||||
m_ctx.rp = save_rp;
|
||||
|
||||
if ((m_pRuntime->plugin()->prof_flags & SP_PROF_CALLBACKS) == SP_PROF_CALLBACKS)
|
||||
{
|
||||
m_pRuntime->plugin()->profiler->OnCallbackEnd(serial);
|
||||
}
|
||||
|
||||
m_ctx.cip = save_cip;
|
||||
m_ctx.n_idx = save_n_idx;
|
||||
m_ctx.n_err = SP_ERROR_NONE;
|
||||
|
||||
@@ -36,12 +36,9 @@
|
||||
* FUNCTION CALLING *
|
||||
********************/
|
||||
|
||||
void CFunction::Set(BaseRuntime *runtime, funcid_t fnid, uint32_t pub_id)
|
||||
CFunction::~CFunction()
|
||||
{
|
||||
m_pRuntime = runtime;
|
||||
m_curparam = 0;
|
||||
m_errorstate = SP_ERROR_NONE;
|
||||
m_FnId = fnid;
|
||||
delete [] full_name_;
|
||||
}
|
||||
|
||||
bool CFunction::IsRunnable()
|
||||
@@ -68,6 +65,16 @@ CFunction::CFunction(BaseRuntime *runtime, funcid_t id, uint32_t pub_id) :
|
||||
m_curparam(0), m_errorstate(SP_ERROR_NONE), m_FnId(id)
|
||||
{
|
||||
m_pRuntime = runtime;
|
||||
|
||||
runtime->GetPublicByIndex(pub_id, &public_);
|
||||
|
||||
size_t rt_len = strlen(runtime->plugin()->name);
|
||||
size_t len = rt_len + strlen("::") + strlen(public_->name);
|
||||
|
||||
full_name_ = new char[len + 1];
|
||||
strcpy(full_name_, runtime->plugin()->name);
|
||||
strcpy(&full_name_[rt_len], "::");
|
||||
strcpy(&full_name_[rt_len + 2], public_->name);
|
||||
}
|
||||
|
||||
int CFunction::PushCell(cell_t cell)
|
||||
|
||||
@@ -61,6 +61,7 @@ public:
|
||||
CFunction(BaseRuntime *pRuntime,
|
||||
funcid_t fnid,
|
||||
uint32_t pub_id);
|
||||
~CFunction();
|
||||
public:
|
||||
virtual int PushCell(cell_t cell);
|
||||
virtual int PushCellByRef(cell_t *cell, int flags);
|
||||
@@ -82,7 +83,12 @@ public:
|
||||
cell_t *result);
|
||||
IPluginRuntime *GetParentRuntime();
|
||||
public:
|
||||
void Set(BaseRuntime *runtime, funcid_t fnid, uint32_t pub_id);
|
||||
const char *FullName() const {
|
||||
return full_name_;
|
||||
}
|
||||
sp_public_t *Public() const {
|
||||
return public_;
|
||||
}
|
||||
private:
|
||||
int _PushString(const char *string, int sz_flags, int cp_flags, size_t len);
|
||||
int SetError(int err);
|
||||
@@ -93,6 +99,8 @@ private:
|
||||
unsigned int m_curparam;
|
||||
int m_errorstate;
|
||||
funcid_t m_FnId;
|
||||
char *full_name_;
|
||||
sp_public_t *public_;
|
||||
};
|
||||
|
||||
#endif //_INCLUDE_SOURCEMOD_BASEFUNCTION_H_
|
||||
|
||||
@@ -1950,7 +1950,6 @@ JITX86::SetupContextVars(BaseRuntime *runtime, BaseContext *pCtx, sp_context_t *
|
||||
ctx->tracker->pCur = ctx->tracker->pBase;
|
||||
ctx->tracker->size = 1024 / sizeof(cell_t);
|
||||
ctx->basecx = pCtx;
|
||||
ctx->vm[JITVARS_PROFILER] = g_engine2.GetProfiler();
|
||||
ctx->plugin = const_cast<sp_plugin_t *>(runtime->plugin());
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user