refac-jit is almost done i think, next comes getting core compatible.

--HG--
branch : refac-jit
extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/branches/refac-jit%402373
This commit is contained in:
David Anderson
2008-07-07 04:56:29 +00:00
parent 307adb34ab
commit 3f38171d8c
17 changed files with 1574 additions and 1397 deletions
+188 -213
View File
@@ -35,12 +35,22 @@
#include "jit_x86.h"
#include "opcode_helpers.h"
#include <x86_macros.h>
#include "jit_version.h"
#include "../jit_version.h"
#include "../sp_vm_engine.h"
#include "../engine2.h"
#if defined USE_UNGEN_OPCODES
#include "ungen_opcodes.h"
#endif
JITX86 g_Jit1;
ISourcePawnEngine *engine = &g_engine1;
inline sp_plugin_t *GETPLUGIN(sp_context_t *ctx)
{
return (sp_plugin_t *)(ctx->vm[JITVARS_PLUGIN]);
}
inline void WriteOp_Move_Pri(JitWriter *jit)
{
//mov eax, edx
@@ -1318,12 +1328,12 @@ inline void WriteOp_Retn(JitWriter *jit)
void ProfCallGate_Begin(sp_context_t *ctx, const char *name)
{
ctx->profiler->OnFunctionBegin(ctx->context, name);
((IProfiler *)ctx->vm[JITVARS_PROFILER])->OnFunctionBegin((IPluginContext *)ctx->vm[JITVARS_BASECTX], name);
}
void ProfCallGate_End(sp_context_t *ctx)
{
ctx->profiler->OnFunctionEnd();
((IProfiler *)ctx->vm[JITVARS_PROFILER])->OnFunctionEnd();
}
const char *find_func_name(sp_plugin_t *plugin, uint32_t offs)
@@ -2264,8 +2274,11 @@ inline void WriteOp_FloatCompare(JitWriter *jit)
cell_t NativeCallback(sp_context_t *ctx, ucell_t native_idx, cell_t *params)
{
sp_native_t *native;
sp_plugin_t *plugin;
plugin = (sp_plugin_t *)ctx->vm[JITVARS_PLUGIN];
native = &ctx->natives[native_idx];
native = &plugin->natives[native_idx];
ctx->n_idx = native_idx;
@@ -2276,15 +2289,18 @@ cell_t NativeCallback(sp_context_t *ctx, ucell_t native_idx, cell_t *params)
return 0;
}
return native->pfn(ctx->context, params);
return native->pfn(GET_CONTEXT(ctx), params);
}
cell_t NativeCallback_Profile(sp_context_t *ctx, ucell_t native_idx, cell_t *params)
{
cell_t val;
sp_native_t *native;
sp_plugin_t *plugin;
native = &ctx->natives[native_idx];
plugin = (sp_plugin_t *)ctx->vm[JITVARS_PLUGIN];
native = &plugin->natives[native_idx];
ctx->n_idx = native_idx;
@@ -2295,9 +2311,9 @@ cell_t NativeCallback_Profile(sp_context_t *ctx, ucell_t native_idx, cell_t *par
return 0;
}
ctx->profiler->OnNativeBegin(ctx->context, native);
val = native->pfn(ctx->context, params);
ctx->profiler->OnNativeEnd();
plugin->profiler->OnNativeBegin(GET_CONTEXT(ctx), native);
val = native->pfn(GET_CONTEXT(ctx), params);
plugin->profiler->OnNativeEnd();
return val;
}
@@ -2307,9 +2323,11 @@ cell_t NativeCallback_Debug(sp_context_t *ctx, ucell_t native_idx, cell_t *param
cell_t save_sp = ctx->sp;
cell_t save_hp = ctx->hp;
sp_plugin_t *pl = GETPLUGIN(ctx);
ctx->n_idx = native_idx;
if (ctx->hp < ctx->heap_base)
if (ctx->hp < (cell_t)pl->data_size)
{
ctx->n_err = SP_ERROR_HEAPMIN;
return 0;
@@ -2321,7 +2339,7 @@ cell_t NativeCallback_Debug(sp_context_t *ctx, ucell_t native_idx, cell_t *param
return 0;
}
if ((uint32_t)ctx->sp >= ctx->mem_size)
if ((uint32_t)ctx->sp >= pl->mem_size)
{
ctx->n_err = SP_ERROR_STACKMIN;
return 0;
@@ -2353,9 +2371,11 @@ cell_t NativeCallback_Debug_Profile(sp_context_t *ctx, ucell_t native_idx, cell_
cell_t save_sp = ctx->sp;
cell_t save_hp = ctx->hp;
sp_plugin_t *pl = GETPLUGIN(ctx);
ctx->n_idx = native_idx;
if (ctx->hp < ctx->heap_base)
if (ctx->hp < (cell_t)pl->data_size)
{
ctx->n_err = SP_ERROR_HEAPMIN;
return 0;
@@ -2367,7 +2387,7 @@ cell_t NativeCallback_Debug_Profile(sp_context_t *ctx, ucell_t native_idx, cell_
return 0;
}
if ((uint32_t)ctx->sp >= ctx->mem_size)
if ((uint32_t)ctx->sp >= pl->mem_size)
{
ctx->n_err = SP_ERROR_STACKMIN;
return 0;
@@ -2457,11 +2477,26 @@ void WriteErrorRoutines(CompData *data, JitWriter *jit)
Write_GetError(jit);
}
sp_context_t *JITX86::CompileToContext(ICompilation *co, int *err)
bool JITX86::Compile(ICompilation *co, BaseRuntime *prt, int *err)
{
CompData *data = (CompData *)co;
sp_plugin_t *plugin = data->plugin;
if (data->plugin == NULL)
{
if (data->debug && !(prt->m_pPlugin->flags & SP_FLAG_DEBUG))
{
if (err != NULL)
{
*err = SP_ERROR_NOTDEBUGGING;
}
co->Abort();
return false;
}
data->SetRuntime(prt);
}
/* The first phase is to browse */
uint8_t *code = plugin->pcode;
uint8_t *end_cip = plugin->pcode + plugin->pcode_size;
@@ -2584,8 +2619,8 @@ jit_rewind:
if (data->error_set != SP_ERROR_NONE)
{
*err = data->error_set;
AbortCompilation(co);
return NULL;
co->Abort();
return false;
}
}
/* Write these last because error jumps should be unpredicted, and thus forward */
@@ -2627,23 +2662,27 @@ jit_rewind:
* FOURTH PASS - Context Setup
*************/
sp_context_t *ctx = new sp_context_t;
memset(ctx, 0, sizeof(sp_context_t));
/* setup basics */
ctx->codebase = writer.outbase;
ctx->plugin = plugin;
ctx->vmbase = this;
ctx->flags = (data->debug ? SPFLAG_PLUGIN_DEBUG : 0);
sp_context_t *ctx = data->runtime->GetDefaultContext()->GetContext();
/* Clear out any old cruft */
if (plugin->codebase != NULL)
{
FreePluginVars(data->runtime->m_pPlugin);
FreeContextVars(ctx);
}
plugin->codebase = writer.outbase;
/* setup memory */
ctx->memory = new uint8_t[plugin->memory];
memcpy(ctx->memory, plugin->data, plugin->data_size);
ctx->mem_size = plugin->memory;
ctx->heap_base = plugin->data_size;
ctx->hp = ctx->heap_base;
ctx->sp = ctx->mem_size - sizeof(cell_t);
ctx->prof_flags = data->profile;
ctx->hp = plugin->data_size;
ctx->sp = plugin->mem_size - sizeof(cell_t);
ctx->frm = ctx->sp;
ctx->n_err = SP_ERROR_NONE;
ctx->n_idx = SP_ERROR_NONE;
plugin->prof_flags = data->profile;
plugin->flags = data->debug ? SPFLAG_PLUGIN_DEBUG : 0;
const char *strbase = plugin->info.stringbase;
uint32_t max, iter;
@@ -2651,39 +2690,39 @@ jit_rewind:
/* relocate public info */
if ((max = plugin->info.publics_num))
{
ctx->publics = new sp_public_t[max];
plugin->publics = new sp_public_t[max];
for (iter=0; iter<max; iter++)
{
ctx->publics[iter].name = strbase + plugin->info.publics[iter].name;
ctx->publics[iter].code_offs = RelocLookup(jit, plugin->info.publics[iter].address, false);
plugin->publics[iter].name = strbase + plugin->info.publics[iter].name;
plugin->publics[iter].code_offs = RelocLookup(jit, plugin->info.publics[iter].address, false);
/* Encode the ID as a straight code offset */
ctx->publics[iter].funcid = (ctx->publics[iter].code_offs << 1);
plugin->publics[iter].funcid = (plugin->publics[iter].code_offs << 1);
}
}
/* relocate pubvar info */
if ((max = plugin->info.pubvars_num))
{
uint8_t *dat = ctx->memory;
ctx->pubvars = new sp_pubvar_t[max];
uint8_t *dat = plugin->memory;
plugin->pubvars = new sp_pubvar_t[max];
for (iter=0; iter<max; iter++)
{
ctx->pubvars[iter].name = strbase + plugin->info.pubvars[iter].name;
ctx->pubvars[iter].offs = (cell_t *)(dat + plugin->info.pubvars[iter].address);
plugin->pubvars[iter].name = strbase + plugin->info.pubvars[iter].name;
plugin->pubvars[iter].offs = (cell_t *)(dat + plugin->info.pubvars[iter].address);
}
}
/* relocate native info */
if ((max = plugin->info.natives_num))
{
ctx->natives = new sp_native_t[max];
plugin->natives = new sp_native_t[max];
for (iter=0; iter<max; iter++)
{
ctx->natives[iter].name = strbase + plugin->info.natives[iter].name;
ctx->natives[iter].pfn = &InvalidNative;
ctx->natives[iter].status = SP_NATIVE_UNBOUND;
ctx->natives[iter].flags = 0;
ctx->natives[iter].user = NULL;
plugin->natives[iter].name = strbase + plugin->info.natives[iter].name;
plugin->natives[iter].pfn = &InvalidNative;
plugin->natives[iter].status = SP_NATIVE_UNBOUND;
plugin->natives[iter].flags = 0;
plugin->natives[iter].user = NULL;
}
}
@@ -2696,20 +2735,20 @@ jit_rewind:
/* relocate files */
max = plugin->debug.files_num;
ctx->files = new sp_debug_file_t[max];
plugin->files = new sp_debug_file_t[max];
for (iter=0; iter<max; iter++)
{
ctx->files[iter].addr = RelocLookup(jit, plugin->debug.files[iter].addr, false);
ctx->files[iter].name = strbase + plugin->debug.files[iter].name;
plugin->files[iter].addr = RelocLookup(jit, plugin->debug.files[iter].addr, false);
plugin->files[iter].name = strbase + plugin->debug.files[iter].name;
}
/* relocate lines */
max = plugin->debug.lines_num;
ctx->lines = new sp_debug_line_t[max];
plugin->lines = new sp_debug_line_t[max];
for (iter=0; iter<max; iter++)
{
ctx->lines[iter].addr = RelocLookup(jit, plugin->debug.lines[iter].addr, false);
ctx->lines[iter].line = plugin->debug.lines[iter].line;
plugin->lines[iter].addr = RelocLookup(jit, plugin->debug.lines[iter].addr, false);
plugin->lines[iter].line = plugin->debug.lines[iter].line;
}
/* relocate arrays */
@@ -2718,7 +2757,7 @@ jit_rewind:
uint8_t *cursor = (uint8_t *)(plugin->debug.symbols);
max = plugin->debug.syms_num;
ctx->symbols = new sp_debug_symbol_t[max];
plugin->symbols = new sp_debug_symbol_t[max];
for (iter=0; iter<max; iter++)
{
sym = (sp_fdbg_symbol_t *)cursor;
@@ -2730,52 +2769,48 @@ jit_rewind:
*/
if (sym->codestart > data->codesize)
{
ctx->symbols[iter].codestart = 0;
plugin->symbols[iter].codestart = 0;
} else {
ctx->symbols[iter].codestart = RelocLookup(jit, sym->codestart, false);
plugin->symbols[iter].codestart = RelocLookup(jit, sym->codestart, false);
}
if (sym->codeend > data->codesize)
{
ctx->symbols[iter].codeend = data->codesize;
plugin->symbols[iter].codeend = data->codesize;
} else {
ctx->symbols[iter].codeend = RelocLookup(jit, sym->codeend, false);
plugin->symbols[iter].codeend = RelocLookup(jit, sym->codeend, false);
}
ctx->symbols[iter].name = strbase + sym->name;
ctx->symbols[iter].sym = sym;
plugin->symbols[iter].name = strbase + sym->name;
plugin->symbols[iter].sym = sym;
if (sym->dimcount > 0)
{
cursor += sizeof(sp_fdbg_symbol_t);
arr = (sp_fdbg_arraydim_t *)cursor;
ctx->symbols[iter].dims = arr;
plugin->symbols[iter].dims = arr;
cursor += sizeof(sp_fdbg_arraydim_t) * sym->dimcount;
continue;
}
ctx->symbols[iter].dims = NULL;
plugin->symbols[iter].dims = NULL;
cursor += sizeof(sp_fdbg_symbol_t);
}
}
tracker_t *trk = new tracker_t;
ctx->vm[JITVARS_TRACKER] = trk;
ctx->vm[JITVARS_BASECTX] = data->runtime->GetDefaultContext();
ctx->vm[JITVARS_PROFILER] = g_engine2.GetProfiler();
ctx->vm[JITVARS_PLUGIN] = data->runtime->m_pPlugin;
trk->pBase = (ucell_t *)malloc(1024);
trk->pCur = trk->pBase;
trk->size = 1024 / sizeof(cell_t);
functracker_t *fnc = new functracker_t;
ctx->vm[JITVARS_FUNCINFO] = fnc;
ctx->vm[JITVARS_REBASE] = data->rebase;
fnc->code_size = codemem;
fnc->num_functions = data->func_idx;
/* clean up relocation+compilation memory */
data->rebase = NULL;
AbortCompilation(co);
co->Abort();
*err = SP_ERROR_NONE;
return ctx;
return true;
}
SPVM_NATIVE_FUNC JITX86::CreateFakeNative(SPVM_FAKENATIVE_FUNC callback, void *pData)
@@ -2851,126 +2886,146 @@ void JITX86::DestroyFakeNative(SPVM_NATIVE_FUNC func)
engine->FreePageMemory((void *)func);
}
const char *JITX86::GetVMName()
{
return "JIT (x86)";
}
int JITX86::ContextExecute(sp_context_t *ctx, uint32_t code_idx, cell_t *result)
int JITX86::ContextExecute(sp_plugin_t *pl, sp_context_t *ctx, uint32_t code_idx, cell_t *result)
{
typedef int (*CONTEXT_EXECUTE)(sp_context_t *, uint32_t, cell_t *);
CONTEXT_EXECUTE fn = (CONTEXT_EXECUTE)ctx->codebase;
CONTEXT_EXECUTE fn = (CONTEXT_EXECUTE)pl->codebase;
return fn(ctx, code_idx, result);
}
void JITX86::FreeContext(sp_context_t *ctx)
{
engine->FreePageMemory(ctx->codebase);
delete [] ctx->memory;
delete [] ctx->files;
delete [] ctx->lines;
delete [] ctx->natives;
delete [] ctx->publics;
delete [] ctx->pubvars;
delete [] ctx->symbols;
engine->BaseFree(ctx->vm[JITVARS_REBASE]);
free(((tracker_t *)(ctx->vm[JITVARS_TRACKER]))->pBase);
delete (tracker_t *)ctx->vm[JITVARS_TRACKER];
delete (functracker_t *)ctx->vm[JITVARS_FUNCINFO];
delete ctx;
}
ICompilation *JITX86::StartCompilation(sp_plugin_t *plugin)
ICompilation *JITX86::StartCompilation()
{
CompData *data = new CompData;
data->jit_float_table = NULL;
return data;
}
void CompData::SetRuntime(BaseRuntime *runtime)
{
uint32_t max_natives = plugin->info.natives_num;
const char *strbase = plugin->info.stringbase;
data->plugin = plugin;
data->inline_level = JIT_INLINE_ERRORCHECKS|JIT_INLINE_NATIVES;
data->error_set = SP_ERROR_NONE;
plugin = runtime->m_pPlugin;
inline_level = JIT_INLINE_ERRORCHECKS|JIT_INLINE_NATIVES;
error_set = SP_ERROR_NONE;
data->jit_float_table = new floattbl_t[max_natives];
jit_float_table = new floattbl_t[max_natives];
for (uint32_t i=0; i<max_natives; i++)
{
const char *name = strbase + plugin->info.natives[i].name;
if (!strcmp(name, "FloatAbs"))
{
data->jit_float_table[i].found = true;
data->jit_float_table[i].index = OP_FABS;
jit_float_table[i].found = true;
jit_float_table[i].index = OP_FABS;
} else if (!strcmp(name, "FloatAdd")) {
data->jit_float_table[i].found = true;
data->jit_float_table[i].index = OP_FLOATADD;
jit_float_table[i].found = true;
jit_float_table[i].index = OP_FLOATADD;
} else if (!strcmp(name, "FloatSub")) {
data->jit_float_table[i].found = true;
data->jit_float_table[i].index = OP_FLOATSUB;
jit_float_table[i].found = true;
jit_float_table[i].index = OP_FLOATSUB;
} else if (!strcmp(name, "FloatMul")) {
data->jit_float_table[i].found = true;
data->jit_float_table[i].index = OP_FLOATMUL;
jit_float_table[i].found = true;
jit_float_table[i].index = OP_FLOATMUL;
} else if (!strcmp(name, "FloatDiv")) {
data->jit_float_table[i].found = true;
data->jit_float_table[i].index = OP_FLOATDIV;
jit_float_table[i].found = true;
jit_float_table[i].index = OP_FLOATDIV;
} else if (!strcmp(name, "float")) {
data->jit_float_table[i].found = true;
data->jit_float_table[i].index = OP_FLOAT;
jit_float_table[i].found = true;
jit_float_table[i].index = OP_FLOAT;
} else if (!strcmp(name, "FloatCompare")) {
data->jit_float_table[i].found = true;
data->jit_float_table[i].index = OP_FLOATCMP;
jit_float_table[i].found = true;
jit_float_table[i].index = OP_FLOATCMP;
} else if (!strcmp(name, "RoundToZero")) {
data->jit_float_table[i].found = true;
data->jit_float_table[i].index = OP_RND_TO_ZERO;
jit_float_table[i].found = true;
jit_float_table[i].index = OP_RND_TO_ZERO;
} else if (!strcmp(name, "RoundToCeil")) {
data->jit_float_table[i].found = true;
data->jit_float_table[i].index = OP_RND_TO_CEIL;
jit_float_table[i].found = true;
jit_float_table[i].index = OP_RND_TO_CEIL;
} else if (!strcmp(name, "RoundToFloor")) {
data->jit_float_table[i].found = true;
data->jit_float_table[i].index = OP_RND_TO_FLOOR;
jit_float_table[i].found = true;
jit_float_table[i].index = OP_RND_TO_FLOOR;
} else if (!strcmp(name, "RoundToNearest")) {
data->jit_float_table[i].found = true;
data->jit_float_table[i].index = OP_RND_TO_NEAREST;
jit_float_table[i].found = true;
jit_float_table[i].index = OP_RND_TO_NEAREST;
}
}
}
ICompilation *JITX86::StartCompilation(BaseRuntime *runtime)
{
CompData *data = new CompData;
data->SetRuntime(runtime);
return data;
}
void JITX86::AbortCompilation(ICompilation *co)
void CompData::Abort()
{
if (((CompData *)co)->rebase)
if (rebase)
{
engine->BaseFree(((CompData *)co)->rebase);
engine->BaseFree(rebase);
}
delete [] ((CompData *)co)->jit_float_table;
delete (CompData *)co;
delete [] jit_float_table;
delete this;
}
bool JITX86::SetCompilationOption(ICompilation *co, const char *key, const char *val)
void JITX86::FreeContextVars(sp_context_t *ctx)
{
CompData *data = (CompData *)co;
free(((tracker_t *)(ctx->vm[JITVARS_TRACKER]))->pBase);
delete (tracker_t *)ctx->vm[JITVARS_TRACKER];
}
void JITX86::FreePluginVars(sp_plugin_t *pl)
{
delete [] pl->files;
delete [] pl->lines;
delete [] pl->natives;
delete [] pl->publics;
delete [] pl->pubvars;
delete [] pl->symbols;
if (pl->codebase != NULL)
{
g_engine1.FreePageMemory(pl->codebase);
pl->codebase = NULL;
}
pl->files = NULL;
pl->lines = NULL;
pl->natives = NULL;
pl->publics = NULL;
pl->pubvars = NULL;
pl->symbols = NULL;
}
bool CompData::SetOption(const char *key, const char *val)
{
if (strcmp(key, SP_JITCONF_DEBUG) == 0)
{
if ((atoi(val) == 1) || !strcmp(val, "yes"))
{
data->debug = true;
debug = true;
} else {
data->debug = false;
debug = false;
}
if (data->debug && !(data->plugin->flags & SP_FLAG_DEBUG))
if (debug && plugin && !(plugin->flags & SP_FLAG_DEBUG))
{
data->debug = false;
debug = false;
return false;
}
return true;
}
else if (strcmp(key, SP_JITCONF_PROFILE) == 0)
{
data->profile = atoi(val);
profile = atoi(val);
/** Callbacks must be profiled to profile functions! */
if ((data->profile & SP_PROF_FUNCTIONS) == SP_PROF_FUNCTIONS)
if ((profile & SP_PROF_FUNCTIONS) == SP_PROF_FUNCTIONS)
{
data->profile |= SP_PROF_CALLBACKS;
profile |= SP_PROF_CALLBACKS;
}
return true;
@@ -2979,83 +3034,3 @@ bool JITX86::SetCompilationOption(ICompilation *co, const char *key, const char
return false;
}
unsigned int JITX86::GetAPIVersion()
{
return SOURCEPAWN_VM_API_VERSION;
}
bool JITX86::FunctionPLookup(const sp_context_t *ctx, uint32_t code_addr, unsigned int *result)
{
uint8_t *rebase = (uint8_t *)ctx->vm[JITVARS_REBASE];
/* Is this within the pcode bounds? */
if (code_addr >= ctx->plugin->pcode_size - sizeof(uint32_t))
{
return false;
}
/* Relocate this */
code_addr = *(jitoffs_t *)(rebase + code_addr);
/* Check if this is in the relocation bounds */
functracker_t *fnc = (functracker_t *)ctx->vm[JITVARS_FUNCINFO];
if (code_addr >= fnc->code_size)
{
return false;
}
/* Get the function info and sanity check */
funcinfo_t *f = (funcinfo_t *)((char *)ctx->codebase + code_addr - sizeof(funcinfo_t));
if (f->magic != JIT_FUNCMAGIC || f->index >= fnc->num_functions)
{
return false;
}
if (result)
{
*result = f->index;
}
return true;
}
bool JITX86::FunctionLookup(const sp_context_t *ctx, uint32_t code_addr, unsigned int *result)
{
/* Check if this is in the relocation bounds */
functracker_t *fnc = (functracker_t *)ctx->vm[JITVARS_FUNCINFO];
if (code_addr >= fnc->code_size)
{
return false;
}
/* Get the function info and sanity check */
funcinfo_t *f = (funcinfo_t *)((char *)ctx->codebase + code_addr - sizeof(funcinfo_t));
if (f->magic != JIT_FUNCMAGIC || f->index >= fnc->num_functions)
{
return false;
}
if (result)
{
*result = f->index;
}
return true;
}
unsigned int JITX86::FunctionCount(const sp_context_t *ctx)
{
functracker_t *fnc = (functracker_t *)ctx->vm[JITVARS_FUNCINFO];
return fnc->num_functions;
}
const char *JITX86::GetVersionString()
{
return SVN_FULL_VERSION;
}
const char *JITX86::GetCPUOptimizations()
{
return "Generic i686";
}
+19 -17
View File
@@ -35,6 +35,8 @@
#include <sp_vm_types.h>
#include <sp_vm_api.h>
#include <jit_helpers.h>
#include "../jit_shared.h"
#include "../BaseRuntime.h"
using namespace SourcePawn;
@@ -44,11 +46,14 @@ using namespace SourcePawn;
#define JIT_FUNCMAGIC 0x214D4148 //magic function offset
#define JITVARS_TRACKER 0 //important: don't change this to avoid trouble
#define JITVARS_FUNCINFO 1 //important: don't change this aWOAWOGJQG I LIKE HAM
#define JITVARS_REBASE 2 //important: hi, i'm bail
#define JITVARS_BASECTX 1 //important: don't change this aWOAWOGJQG I LIKE HAM
#define JITVARS_PROFILER 2 //profiler
#define JITVARS_PLUGIN 3 //sp_plugin_t
#define sDIMEN_MAX 5 //this must mirror what the compiler has.
#define GET_CONTEXT(c) ((IPluginContext *)c->vm[JITVARS_BASECTX])
typedef struct tracker_s
{
size_t size;
@@ -87,7 +92,11 @@ public:
error_set(SP_ERROR_NONE), func_idx(0)
{
};
bool SetOption(const char *key, const char *val);
void SetRuntime(BaseRuntime *runtime);
void Abort();
public:
BaseRuntime *runtime; /* runtime handle */
sp_plugin_t *plugin; /* plugin handle */
bool debug; /* whether to compile debug mode */
int profile; /* profiling flags */
@@ -116,22 +125,15 @@ public:
uint32_t codesize; /* total codesize */
};
class JITX86 : public IVirtualMachine
class JITX86
{
public:
const char *GetVMName();
ICompilation *StartCompilation(sp_plugin_t *plugin);
bool SetCompilationOption(ICompilation *co, const char *key, const char *val);
sp_context_t *CompileToContext(ICompilation *co, int *err);
void AbortCompilation(ICompilation *co);
void FreeContext(sp_context_t *ctx);
int ContextExecute(sp_context_t *ctx, uint32_t code_idx, cell_t *result);
unsigned int GetAPIVersion();
bool FunctionLookup(const sp_context_t *ctx, uint32_t code_addr, unsigned int *result);
bool FunctionPLookup(const sp_context_t *ctx, uint32_t code_addr, unsigned int *result);
unsigned int FunctionCount(const sp_context_t *ctx);
const char *GetVersionString();
const char *GetCPUOptimizations();
ICompilation *StartCompilation(BaseRuntime *runtime);
ICompilation *StartCompilation();
bool Compile(ICompilation *co, BaseRuntime *runtime, int *err);
void FreePluginVars(sp_plugin_t *pl);
void FreeContextVars(sp_context_t *ctx);
int ContextExecute(sp_plugin_t *pl, sp_context_t *ctx, uint32_t code_idx, cell_t *result);
SPVM_NATIVE_FUNC CreateFakeNative(SPVM_FAKENATIVE_FUNC callback, void *pData);
void DestroyFakeNative(SPVM_NATIVE_FUNC func);
};
@@ -157,6 +159,6 @@ jitoffs_t RelocLookup(JitWriter *jit, cell_t pcode_offs, bool relative=false);
#define AMX_INFO_CONTEXT 12 //physical
#define AMX_INFO_STACKTOP 16 //relocated
extern ISourcePawnEngine *engine;
extern JITX86 g_Jit1;
#endif //_INCLUDE_SOURCEPAWN_JIT_X86_H_
+19 -16
View File
@@ -40,6 +40,7 @@
jitoffs_t Write_Execute_Function(JitWriter *jit)
{
CompData *co = (CompData *)jit->data;
/**
* The variables we're passed in:
* sp_context_t *ctx, uint32_t code_idx, cell_t *result
@@ -76,14 +77,14 @@ jitoffs_t Write_Execute_Function(JitWriter *jit)
//mov [esi+12], eax - store context into info pointer
//mov ecx, [eax+<offs>] - get heap pointer
//mov [esi+4], ecx - store heap into info pointer
//mov ebp, [eax+<offs>] - get data pointer
//mov ebp, <addr> - get data pointer
IA32_Mov_Reg_Rm_Disp8(jit, REG_EAX, REG_EBP, 16);
IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_INFO, REG_EAX, AMX_INFO_RETVAL);
IA32_Mov_Reg_Rm_Disp8(jit, REG_EAX, REG_EBP, 8);
IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_INFO, REG_EAX, AMX_INFO_CONTEXT);
IA32_Mov_Reg_Rm_Disp8(jit, REG_ECX, REG_EAX, offsetof(sp_context_t, hp));
IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_INFO, REG_ECX, AMX_INFO_HEAP);
IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_DAT, REG_EAX, offsetof(sp_context_t, memory));
IA32_Mov_Reg_Imm32(jit, AMX_REG_DAT, jit_int32_t(co->plugin->memory));
/* Frame setup */
//mov edi, [eax+<offs>] - get stack pointer
@@ -97,15 +98,23 @@ jitoffs_t Write_Execute_Function(JitWriter *jit)
//mov ecx, [eax+<offs>] - copy memsize to temp var
//add ecx, ebp - relocate
//mov [esi+x], ecx - store relocated
IA32_Mov_Reg_Rm_Disp8(jit, REG_ECX, REG_EAX, offsetof(sp_context_t, mem_size));
IA32_Mov_Reg_Imm32(jit, REG_ECX, co->plugin->mem_size);
IA32_Add_Reg_Rm(jit, AMX_REG_TMP, AMX_REG_DAT, MOD_REG);
IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_INFO, REG_ECX, AMX_INFO_STACKTOP);
/* Remaining needed vars */
//mov ecx, [esp+(4*(NUM_INFO_PARAMS+3))+12] - get code index (normally esp+12, but we have another array on the stack)
//add ecx, [eax+<offs>] - add code base to index
//push eax
//mov eax, <addr of addr of code>
//mov eax, [eax]
//add ecx, eax
//pop eax
IA32_Mov_Reg_Esp_Disp8(jit, REG_ECX, 12+(4*(NUM_INFO_PARAMS+3)));
IA32_Add_Reg_Rm_Disp8(jit, REG_ECX, REG_EAX, offsetof(sp_context_t, codebase));
IA32_Push_Reg(jit, REG_EAX);
IA32_Mov_Reg_Imm32(jit, REG_EAX, jit_int32_t(&co->plugin->codebase));
IA32_Mov_Reg_Rm(jit, REG_EAX, REG_EAX, MOD_MEM_REG);
IA32_Add_Reg_Rm(jit, REG_ECX, REG_EAX, MOD_REG);
IA32_Pop_Reg(jit, REG_EAX);
/* by now, everything is set up, so we can call into the plugin */
//call ecx
@@ -161,36 +170,30 @@ void Write_BreakDebug(JitWriter *jit)
//push edi
//mov edi, ecx
//mov ecx, [esi+ctx]
//cmp [ecx+dbreak], 0
//jnz :nocall
IA32_Push_Reg(jit, REG_EDI);
IA32_Mov_Reg_Rm(jit, REG_EDI, REG_ECX, MOD_REG);
IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_INFO, AMX_INFO_CONTEXT);
IA32_Cmp_Rm_Disp8_Imm8(jit, AMX_REG_TMP, offsetof(sp_context_t, dbreak), 0);
jitoffs_t jmp = IA32_Jump_Cond_Imm8(jit, CC_Z, 0);
//:TODO: align the stack to 16bytes like in sysreq.x
/* NOTE, Hack! PUSHAD pushes EDI last which still has the CIP */
//pushad
//push [esi+frm]
//push ctx
//mov ecx, [ecx+dbreak]
//push [ctx+basectx]
//mov ecx, <dbreak>
//call ecx
//add esp, 8
//popad
IA32_Pushad(jit);
IA32_Push_Rm_Disp8(jit, AMX_REG_INFO, AMX_INFO_FRAME); //:TODO: move to regs and push? and dont disp for 0
IA32_Push_Reg(jit, AMX_REG_TMP);
IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_TMP, offsetof(sp_context_t, dbreak));
IA32_Push_Rm_Disp8(jit, AMX_REG_TMP, offsetof(sp_context_t, vm[JITVARS_BASECTX]));
IA32_Mov_Reg_Imm32(jit, AMX_REG_TMP, jit_int32_t(((CompData *)jit->data)->plugin->dbreak));
IA32_Call_Reg(jit, AMX_REG_TMP);
IA32_Add_Rm_Imm8(jit, REG_ESP, 4*2, MOD_REG);
IA32_Popad(jit);
//:nocall
//pop edi
//ret
IA32_Pop_Reg(jit, REG_EDI);
IA32_Send_Jump8_Here(jit, jmp);
IA32_Return(jit);
}
@@ -314,7 +317,7 @@ void Write_Check_VerifyAddr(JitWriter *jit, jit_uint8_t reg)
/* Part 1: Check if we're in the memory bounds */
//cmp <reg>, <stpu>
//jae :error
IA32_Cmp_Rm_Imm32(jit, MOD_REG, reg, ((CompData *)jit->data)->plugin->memory);
IA32_Cmp_Rm_Imm32(jit, MOD_REG, reg, ((CompData *)jit->data)->plugin->mem_size);
IA32_Jump_Cond_Imm32_Abs(jit, CC_AE, ((CompData *)jit->data)->jit_error_memaccess);
/* Part 2: Check if we're in the invalid region between HP and SP */
-103
View File
@@ -1,103 +0,0 @@
// Microsoft Visual C++ generated resource script.
//
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "winres.h"
#include "jit_version.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION SVN_FILE_VERSION
PRODUCTVERSION SVN_FILE_VERSION
FILEFLAGSMASK 0x17L
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x4L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "000004b0"
BEGIN
VALUE "Comments", "SourcePawn JIT"
VALUE "FileDescription", "SourcePawn JIT/Virtual Machine"
VALUE "FileVersion", SVN_FULL_VERSION
VALUE "InternalName", "sourcemod"
VALUE "LegalCopyright", "Copyright (c) 2004-2008, AlliedModders LLC"
VALUE "OriginalFilename", "sourcepawn.jit.x86.dll"
VALUE "ProductName", "SourcePawn JIT"
VALUE "ProductVersion", SVN_FULL_VERSION
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x0, 1200
END
END
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"#include ""winres.h""\r\n"
"\0"
END
3 TEXTINCLUDE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED