added amb256 - (nice number), profiler complete with gui to show files

--HG--
extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%401914
This commit is contained in:
David Anderson
2008-03-02 06:40:59 +00:00
parent f4e23a14dd
commit 0817bd0b8b
23 changed files with 1874 additions and 34 deletions
+1 -1
View File
@@ -25,7 +25,7 @@ EXPORTFUNC int GiveEnginePointer2(SourcePawn::ISourcePawnEngine *engine_p, unsig
{
engine = engine_p;
if (api_version > SOURCEPAWN_ENGINE_API_VERSION)
if (api_version > SOURCEPAWN_ENGINE_API_VERSION || api_version < 2)
{
return SP_ERROR_PARAM;
}
+202 -15
View File
@@ -1278,12 +1278,95 @@ inline void WriteOp_Retn(JitWriter *jit)
IA32_Return(jit);
}
void ProfCallGate_Begin(sp_context_t *ctx, const char *name)
{
ctx->profiler->OnFunctionBegin(ctx->context, name);
}
void ProfCallGate_End(sp_context_t *ctx)
{
ctx->profiler->OnFunctionEnd();
}
const char *find_func_name(sp_plugin_t *plugin, uint32_t offs)
{
uint32_t max, iter;
sp_fdbg_symbol_t *sym;
sp_fdbg_arraydim_t *arr;
uint8_t *cursor = (uint8_t *)(plugin->debug.symbols);
max = plugin->debug.syms_num;
for (iter = 0; iter < max; iter++)
{
sym = (sp_fdbg_symbol_t *)cursor;
if (sym->ident == SP_SYM_FUNCTION
&& sym->codestart <= offs
&& sym->codeend > offs)
{
return plugin->debug.stringbase + sym->name;
}
if (sym->dimcount > 0)
{
cursor += sizeof(sp_fdbg_symbol_t);
arr = (sp_fdbg_arraydim_t *)cursor;
cursor += sizeof(sp_fdbg_arraydim_t) * sym->dimcount;
continue;
}
cursor += sizeof(sp_fdbg_symbol_t);
}
return NULL;
}
inline void WriteOp_Call(JitWriter *jit)
{
cell_t offs = jit->read_cell();
cell_t offs;
jitoffs_t jmp;
CompData *data;
data = (CompData *)jit->data;
offs = jit->read_cell();
jitoffs_t jmp = IA32_Call_Imm32(jit, 0);
IA32_Write_Jump32(jit, jmp, RelocLookup(jit, offs, false));
if ((data->profile & SP_PROF_FUNCTIONS) == SP_PROF_FUNCTIONS)
{
const char *name;
/* Find the function name */
if ((name = find_func_name(data->plugin, offs)) == NULL)
{
name = "unknown";
}
//push name
//push [esi+context]
//call ProfCallGate_Begin
//add esp, 8
IA32_Push_Imm32(jit, (jit_int32_t)(intptr_t)name);
IA32_Push_Rm_Disp8(jit, AMX_REG_INFO, AMX_INFO_CONTEXT);
jmp = IA32_Call_Imm32(jit, 0);
IA32_Write_Jump32_Abs(jit, jmp, (void *)ProfCallGate_Begin);
IA32_Add_Rm_Imm8(jit, REG_ESP, 8, MOD_REG);
//call <addr>
jmp = IA32_Call_Imm32(jit, 0);
IA32_Write_Jump32(jit, jmp, RelocLookup(jit, offs, false));
//push [esi+context]
//call ProfCallGate_End
//add esp, 4
IA32_Push_Rm_Disp8(jit, AMX_REG_INFO, AMX_INFO_CONTEXT);
jmp = IA32_Call_Imm32(jit, 0);
IA32_Write_Jump32_Abs(jit, jmp, (void *)ProfCallGate_End);
IA32_Add_Rm_Imm8(jit, REG_ESP, 4, MOD_REG);
}
else
{
jmp = IA32_Call_Imm32(jit, 0);
IA32_Write_Jump32(jit, jmp, RelocLookup(jit, offs, false));
}
}
inline void WriteOp_Bounds(JitWriter *jit)
@@ -1653,9 +1736,25 @@ inline void WriteOp_Sysreq_N(JitWriter *jit)
jitoffs_t call = IA32_Call_Imm32(jit, 0);
if (!data->debug)
{
IA32_Write_Jump32_Abs(jit, call, (void *)NativeCallback);
} else {
IA32_Write_Jump32_Abs(jit, call, (void *)NativeCallback_Debug);
if ((data->profile & SP_PROF_NATIVES) == SP_PROF_NATIVES)
{
IA32_Write_Jump32_Abs(jit, call, (void *)NativeCallback_Profile);
}
else
{
IA32_Write_Jump32_Abs(jit, call, (void *)NativeCallback);
}
}
else
{
if ((data->profile & SP_PROF_NATIVES) == SP_PROF_NATIVES)
{
IA32_Write_Jump32_Abs(jit, call, (void *)NativeCallback_Debug_Profile);
}
else
{
IA32_Write_Jump32_Abs(jit, call, (void *)NativeCallback_Debug);
}
}
/* check for errors */
@@ -2122,7 +2221,9 @@ inline void WriteOp_FloatCompare(JitWriter *jit)
cell_t NativeCallback(sp_context_t *ctx, ucell_t native_idx, cell_t *params)
{
sp_native_t *native = &ctx->natives[native_idx];
sp_native_t *native;
native = &ctx->natives[native_idx];
ctx->n_idx = native_idx;
@@ -2136,12 +2237,27 @@ cell_t NativeCallback(sp_context_t *ctx, ucell_t native_idx, cell_t *params)
return native->pfn(ctx->context, params);
}
static cell_t InvalidNative(IPluginContext *pCtx, const cell_t *params)
cell_t NativeCallback_Profile(sp_context_t *ctx, ucell_t native_idx, cell_t *params)
{
sp_context_t *ctx = pCtx->GetContext();
ctx->n_err = SP_ERROR_INVALID_NATIVE;
cell_t val;
sp_native_t *native;
return 0;
native = &ctx->natives[native_idx];
ctx->n_idx = native_idx;
/* Technically both aren't needed, I guess */
if (native->status == SP_NATIVE_UNBOUND)
{
ctx->n_err = SP_ERROR_INVALID_NATIVE;
return 0;
}
ctx->profiler->OnNativeBegin(ctx->context, native);
val = native->pfn(ctx->context, params);
ctx->profiler->OnNativeEnd();
return val;
}
cell_t NativeCallback_Debug(sp_context_t *ctx, ucell_t native_idx, cell_t *params)
@@ -2170,7 +2286,7 @@ cell_t NativeCallback_Debug(sp_context_t *ctx, ucell_t native_idx, cell_t *param
}
cell_t result = NativeCallback(ctx, native_idx, params);
if (ctx->n_err != SP_ERROR_NONE)
{
return result;
@@ -2180,7 +2296,9 @@ cell_t NativeCallback_Debug(sp_context_t *ctx, ucell_t native_idx, cell_t *param
{
ctx->n_err = SP_ERROR_STACKLEAK;
return result;
} else if (save_hp != ctx->hp) {
}
else if (save_hp != ctx->hp)
{
ctx->n_err = SP_ERROR_HEAPLEAK;
return result;
}
@@ -2188,6 +2306,60 @@ cell_t NativeCallback_Debug(sp_context_t *ctx, ucell_t native_idx, cell_t *param
return result;
}
cell_t NativeCallback_Debug_Profile(sp_context_t *ctx, ucell_t native_idx, cell_t *params)
{
cell_t save_sp = ctx->sp;
cell_t save_hp = ctx->hp;
ctx->n_idx = native_idx;
if (ctx->hp < ctx->heap_base)
{
ctx->n_err = SP_ERROR_HEAPMIN;
return 0;
}
if (ctx->hp + STACK_MARGIN > ctx->sp)
{
ctx->n_err = SP_ERROR_STACKLOW;
return 0;
}
if ((uint32_t)ctx->sp >= ctx->mem_size)
{
ctx->n_err = SP_ERROR_STACKMIN;
return 0;
}
cell_t result = NativeCallback_Profile(ctx, native_idx, params);
if (ctx->n_err != SP_ERROR_NONE)
{
return result;
}
if (save_sp != ctx->sp)
{
ctx->n_err = SP_ERROR_STACKLEAK;
return result;
}
else if (save_hp != ctx->hp)
{
ctx->n_err = SP_ERROR_HEAPLEAK;
return result;
}
return result;
}
static cell_t InvalidNative(IPluginContext *pCtx, const cell_t *params)
{
sp_context_t *ctx = pCtx->GetContext();
ctx->n_err = SP_ERROR_INVALID_NATIVE;
return 0;
}
jitoffs_t RelocLookup(JitWriter *jit, cell_t pcode_offs, bool relative)
{
if (jit->outptr)
@@ -2204,7 +2376,9 @@ jitoffs_t RelocLookup(JitWriter *jit, cell_t pcode_offs, bool relative)
assert(pcode_offs >= 0 && (uint32_t)pcode_offs <= data->codesize);
/* Do the lookup in the native dictionary. */
return *(jitoffs_t *)(data->rebase + pcode_offs);
} else {
}
else
{
return 0;
}
}
@@ -2423,6 +2597,7 @@ jit_rewind:
ctx->heap_base = plugin->data_size;
ctx->hp = ctx->heap_base;
ctx->sp = ctx->mem_size - sizeof(cell_t);
ctx->prof_flags = data->profile;
const char *strbase = plugin->info.stringbase;
uint32_t max, iter;
@@ -2726,7 +2901,7 @@ bool JITX86::SetCompilationOption(ICompilation *co, const char *key, const char
{
CompData *data = (CompData *)co;
if (strcmp(key, "debug") == 0)
if (strcmp(key, SP_JITCONF_DEBUG) == 0)
{
if ((atoi(val) == 1) || !strcmp(val, "yes"))
{
@@ -2741,6 +2916,18 @@ bool JITX86::SetCompilationOption(ICompilation *co, const char *key, const char
}
return true;
}
else if (strcmp(key, SP_JITCONF_PROFILE) == 0)
{
data->profile = atoi(val);
/** Callbacks must be profiled to profile functions! */
if ((data->profile & SP_PROF_FUNCTIONS) == SP_PROF_FUNCTIONS)
{
data->profile |= SP_PROF_CALLBACKS;
}
return true;
}
return false;
}
+4 -1
View File
@@ -67,13 +67,14 @@ class CompData : public ICompilation
{
public:
CompData() : plugin(NULL),
debug(false), inline_level(0), rebase(NULL),
debug(false), profile(0), inline_level(0), rebase(NULL),
error_set(SP_ERROR_NONE), func_idx(0)
{
};
public:
sp_plugin_t *plugin; /* plugin handle */
bool debug; /* whether to compile debug mode */
int profile; /* profiling flags */
int inline_level; /* inline optimization level */
jitcode_t rebase; /* relocation map */
int error_set; /* error code to halt process */
@@ -121,6 +122,8 @@ public:
cell_t NativeCallback(sp_context_t *ctx, ucell_t native_idx, cell_t *params);
cell_t NativeCallback_Debug(sp_context_t *ctx, ucell_t native_idx, cell_t *params);
cell_t NativeCallback_Debug_Profile(sp_context_t *ctx, ucell_t native_idx, cell_t *params);
cell_t NativeCallback_Profile(sp_context_t *ctx, ucell_t native_idx, cell_t *params);
jitoffs_t RelocLookup(JitWriter *jit, cell_t pcode_offs, bool relative=false);
#define AMX_REG_PRI REG_EAX