Optimize native call if statically bound (bug 5842, r=ds,fyren f=dvander).
Original patch written by David Anderson (original r from Fyren). - Updated to function with the current JIT compiler. - Took in clean-ups from later-dated patches.
This commit is contained in:
parent
b4ff034ac2
commit
9c62e94239
@ -331,6 +331,13 @@ void ShareSystem::BindNativeToPlugin(CPlugin *pPlugin, sp_native_t *native, uint
|
|||||||
native->status = SP_NATIVE_BOUND;
|
native->status = SP_NATIVE_BOUND;
|
||||||
native->pfn = pEntry->func();
|
native->pfn = pEntry->func();
|
||||||
|
|
||||||
|
if (pEntry->fake)
|
||||||
|
{
|
||||||
|
/* This native is not necessarily optional, but we don't guarantee
|
||||||
|
* that its address is long-lived. */
|
||||||
|
native->flags |= SP_NTVFLAG_EPHEMERAL;
|
||||||
|
}
|
||||||
|
|
||||||
/* We don't bother with dependency crap if the owner is Core. */
|
/* We don't bother with dependency crap if the owner is Core. */
|
||||||
if (pEntry->owner != &g_CoreNatives)
|
if (pEntry->owner != &g_CoreNatives)
|
||||||
{
|
{
|
||||||
|
@ -148,6 +148,7 @@ typedef struct sp_pubvar_s
|
|||||||
#define SP_NATIVE_BOUND (1) /**< Native is bound */
|
#define SP_NATIVE_BOUND (1) /**< Native is bound */
|
||||||
|
|
||||||
#define SP_NTVFLAG_OPTIONAL (1<<0) /**< Native is optional */
|
#define SP_NTVFLAG_OPTIONAL (1<<0) /**< Native is optional */
|
||||||
|
#define SP_NTVFLAG_EPHEMERAL (1<<1) /**< Native can be unbound */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Native lookup table, by default names point back to the sp_plugin_infotab_t structure.
|
* @brief Native lookup table, by default names point back to the sp_plugin_infotab_t structure.
|
||||||
|
@ -355,6 +355,12 @@ BaseRuntime::GetNativeByIndex(uint32_t index, sp_native_t **native)
|
|||||||
return SP_ERROR_NONE;
|
return SP_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sp_native_t *
|
||||||
|
BaseRuntime::GetNativeByIndex(uint32_t index)
|
||||||
|
{
|
||||||
|
assert(index < m_plugin.num_natives);
|
||||||
|
return &m_plugin.natives[index];
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t
|
uint32_t
|
||||||
BaseRuntime::GetNativesNum()
|
BaseRuntime::GetNativesNum()
|
||||||
|
@ -49,6 +49,7 @@ class BaseRuntime
|
|||||||
virtual IPluginDebugInfo *GetDebugInfo();
|
virtual IPluginDebugInfo *GetDebugInfo();
|
||||||
virtual int FindNativeByName(const char *name, uint32_t *index);
|
virtual int FindNativeByName(const char *name, uint32_t *index);
|
||||||
virtual int GetNativeByIndex(uint32_t index, sp_native_t **native);
|
virtual int GetNativeByIndex(uint32_t index, sp_native_t **native);
|
||||||
|
virtual sp_native_t *GetNativeByIndex(uint32_t index);
|
||||||
virtual uint32_t GetNativesNum();
|
virtual uint32_t GetNativesNum();
|
||||||
virtual int FindPublicByName(const char *name, uint32_t *index);
|
virtual int FindPublicByName(const char *name, uint32_t *index);
|
||||||
virtual int GetPublicByIndex(uint32_t index, sp_public_t **publicptr);
|
virtual int GetPublicByIndex(uint32_t index, sp_public_t **publicptr);
|
||||||
|
@ -167,6 +167,29 @@ NativeCallback(sp_context_t *ctx, ucell_t native_idx, cell_t *params)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cell_t
|
||||||
|
BoundNativeCallback(sp_context_t *ctx, SPVM_NATIVE_FUNC pfn, cell_t *params)
|
||||||
|
{
|
||||||
|
cell_t save_sp = ctx->sp;
|
||||||
|
cell_t save_hp = ctx->hp;
|
||||||
|
|
||||||
|
cell_t result = pfn(ctx->basecx, params);
|
||||||
|
|
||||||
|
if (ctx->n_err != SP_ERROR_NONE)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
if (save_sp != ctx->sp) {
|
||||||
|
ctx->n_err = SP_ERROR_STACKLEAK;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
if (save_hp != ctx->hp) {
|
||||||
|
ctx->n_err = SP_ERROR_HEAPLEAK;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
GenerateArray(BaseRuntime *rt, sp_context_t *ctx, cell_t dims, cell_t *stk, bool autozero)
|
GenerateArray(BaseRuntime *rt, sp_context_t *ctx, cell_t dims, cell_t *stk, bool autozero)
|
||||||
{
|
{
|
||||||
|
@ -33,6 +33,7 @@ int Interpret(BaseRuntime *rt, uint32_t aCodeStart, cell_t *rval);
|
|||||||
|
|
||||||
int GenerateFullArray(BaseRuntime *rt, uint32_t argc, cell_t *argv, int autozero);
|
int GenerateFullArray(BaseRuntime *rt, uint32_t argc, cell_t *argv, int autozero);
|
||||||
cell_t NativeCallback(sp_context_t *ctx, ucell_t native_idx, cell_t *params);
|
cell_t NativeCallback(sp_context_t *ctx, ucell_t native_idx, cell_t *params);
|
||||||
|
cell_t BoundNativeCallback(sp_context_t *ctx, SPVM_NATIVE_FUNC pfn, cell_t *params);
|
||||||
int PopTrackerAndSetHeap(BaseRuntime *rt);
|
int PopTrackerAndSetHeap(BaseRuntime *rt);
|
||||||
int PushTracker(sp_context_t *ctx, size_t amount);
|
int PushTracker(sp_context_t *ctx, size_t amount);
|
||||||
|
|
||||||
|
@ -1579,9 +1579,8 @@ Compiler::emitNativeCall(OPCODE op)
|
|||||||
// Save registers.
|
// Save registers.
|
||||||
__ push(edx);
|
__ push(edx);
|
||||||
|
|
||||||
// Push the parameters for the C++ function.
|
// Push the last parameter for the C++ function.
|
||||||
__ push(stk);
|
__ push(stk);
|
||||||
__ push(native_index);
|
|
||||||
|
|
||||||
// Relocate our absolute stk to be dat-relative, and update the context's
|
// Relocate our absolute stk to be dat-relative, and update the context's
|
||||||
// view.
|
// view.
|
||||||
@ -1589,9 +1588,23 @@ Compiler::emitNativeCall(OPCODE op)
|
|||||||
__ subl(stk, dat);
|
__ subl(stk, dat);
|
||||||
__ movl(Operand(eax, offsetof(sp_context_t, sp)), stk);
|
__ movl(Operand(eax, offsetof(sp_context_t, sp)), stk);
|
||||||
|
|
||||||
// Push context and make the call.
|
__ movl(Operand(eax, offsetof(sp_context_t, n_idx)), native_index);
|
||||||
|
|
||||||
|
sp_native_t *native = rt_->GetNativeByIndex(native_index);
|
||||||
|
if ((native->status != SP_NATIVE_BOUND) ||
|
||||||
|
(native->flags & (SP_NTVFLAG_OPTIONAL | SP_NTVFLAG_EPHEMERAL)))
|
||||||
|
{
|
||||||
|
// The native is either unbound, or it could become unbound in the
|
||||||
|
// future. Invoke the slower native callback.
|
||||||
|
__ push(native_index);
|
||||||
__ push(eax);
|
__ push(eax);
|
||||||
__ call(ExternalAddress((void *)NativeCallback));
|
__ call(ExternalAddress((void *)NativeCallback));
|
||||||
|
} else {
|
||||||
|
// The native is bound so we have a few more guarantees.
|
||||||
|
__ push(intptr_t(native->pfn));
|
||||||
|
__ push(eax);
|
||||||
|
__ call(ExternalAddress((void *)BoundNativeCallback));
|
||||||
|
}
|
||||||
|
|
||||||
// Check for errors.
|
// Check for errors.
|
||||||
__ movl(ecx, intptr_t(rt_->GetBaseContext()->GetCtx()));
|
__ movl(ecx, intptr_t(rt_->GetBaseContext()->GetCtx()));
|
||||||
|
Loading…
Reference in New Issue
Block a user