Move the tracker from sp_context_t to PluginContext.

This commit is contained in:
dvander@alliedmods.net 2015-02-24 15:43:41 -08:00
parent deedc1aaa6
commit 5502fbbdc1
6 changed files with 86 additions and 69 deletions

View File

@ -95,48 +95,6 @@ CheckAddress(const sp_plugin_t *plugin, sp_context_t *ctx, cell_t *stk, cell_t a
return true; return true;
} }
int
PopTrackerAndSetHeap(PluginRuntime *rt)
{
sp_context_t *ctx = rt->GetBaseContext()->GetCtx();
tracker_t *trk = ctx->tracker;
assert(trk->pCur > trk->pBase);
trk->pCur--;
if (trk->pCur < trk->pBase)
return SP_ERROR_TRACKER_BOUNDS;
ucell_t amt = *trk->pCur;
if (amt > (ctx->hp - rt->plugin()->data_size))
return SP_ERROR_HEAPMIN;
ctx->hp -= amt;
return SP_ERROR_NONE;
}
int
PushTracker(sp_context_t *ctx, size_t amount)
{
tracker_t *trk = ctx->tracker;
if ((size_t)(trk->pCur - trk->pBase) >= trk->size)
return SP_ERROR_TRACKER_BOUNDS;
if (trk->pCur + 1 - (trk->pBase + trk->size) == 0) {
size_t disp = trk->size - 1;
trk->size *= 2;
trk->pBase = (ucell_t *)realloc(trk->pBase, trk->size * sizeof(cell_t));
if (!trk->pBase)
return SP_ERROR_TRACKER_BOUNDS;
trk->pCur = trk->pBase + disp;
}
*trk->pCur++ = amount;
return SP_ERROR_NONE;
}
cell_t cell_t
NativeCallback(sp_context_t *ctx, ucell_t native_idx, cell_t *params) NativeCallback(sp_context_t *ctx, ucell_t native_idx, cell_t *params)
{ {
@ -211,7 +169,7 @@ GenerateArray(PluginRuntime *rt, sp_context_t *ctx, cell_t dims, cell_t *stk, bo
return false; return false;
} }
if ((ctx->err = PushTracker(ctx, bytes)) != SP_ERROR_NONE) if ((ctx->err = rt->GetBaseContext()->pushTracker(bytes)) != SP_ERROR_NONE)
return false; return false;
if (autozero) if (autozero)
@ -849,7 +807,7 @@ Interpret(PluginRuntime *rt, uint32_t aCodeStart, cell_t *rval)
case OP_TRACKER_PUSH_C: case OP_TRACKER_PUSH_C:
{ {
cell_t amount = *cip++; cell_t amount = *cip++;
int error = PushTracker(ctx, amount * 4); int error = cx->pushTracker(amount * 4);
if (error != SP_ERROR_NONE) { if (error != SP_ERROR_NONE) {
ctx->err = error; ctx->err = error;
goto error; goto error;
@ -859,7 +817,7 @@ Interpret(PluginRuntime *rt, uint32_t aCodeStart, cell_t *rval)
case OP_TRACKER_POP_SETHEAP: case OP_TRACKER_POP_SETHEAP:
{ {
int error = PopTrackerAndSetHeap(rt); int error = cx->popTrackerAndSetHeap();
if (error != SP_ERROR_NONE) { if (error != SP_ERROR_NONE) {
ctx->err = error; ctx->err = error;
goto error; goto error;

View File

@ -22,19 +22,10 @@
#include "plugin-runtime.h" #include "plugin-runtime.h"
#include "plugin-context.h" #include "plugin-context.h"
struct tracker_t
{
size_t size;
ucell_t *pBase;
ucell_t *pCur;
};
int Interpret(PluginRuntime *rt, uint32_t aCodeStart, cell_t *rval); int Interpret(PluginRuntime *rt, uint32_t aCodeStart, cell_t *rval);
int GenerateFullArray(PluginRuntime *rt, uint32_t argc, cell_t *argv, int autozero); int GenerateFullArray(PluginRuntime *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); cell_t BoundNativeCallback(sp_context_t *ctx, SPVM_NATIVE_FUNC pfn, cell_t *params);
int PopTrackerAndSetHeap(PluginRuntime *rt);
int PushTracker(sp_context_t *ctx, size_t amount);
#endif // _include_sourcepawn_interpreter_h_ #endif // _include_sourcepawn_interpreter_h_

View File

@ -68,7 +68,6 @@ namespace SourcePawn
} sp_plugin_t; } sp_plugin_t;
} }
struct tracker_t;
class PluginContext; class PluginContext;
typedef struct sp_context_s typedef struct sp_context_s
@ -81,7 +80,6 @@ typedef struct sp_context_s
int32_t err; /**< Error last set by interpreter */ int32_t err; /**< Error last set by interpreter */
int32_t n_err; /**< Error code set by a native */ int32_t n_err; /**< Error code set by a native */
uint32_t n_idx; /**< Current native index being executed */ uint32_t n_idx; /**< Current native index being executed */
tracker_t *tracker;
sp_plugin_t *plugin; sp_plugin_t *plugin;
PluginContext *basecx; PluginContext *basecx;
} sp_context_t; } sp_context_t;

View File

@ -58,18 +58,16 @@ PluginContext::PluginContext(PluginRuntime *pRuntime)
m_ctx.n_idx = SP_ERROR_NONE; m_ctx.n_idx = SP_ERROR_NONE;
rp_ = 0; rp_ = 0;
m_ctx.tracker = new tracker_t; tracker_.pBase = (ucell_t *)malloc(1024);
m_ctx.tracker->pBase = (ucell_t *)malloc(1024); tracker_.pCur = tracker_.pBase;
m_ctx.tracker->pCur = m_ctx.tracker->pBase; tracker_.size = 1024 / sizeof(cell_t);
m_ctx.tracker->size = 1024 / sizeof(cell_t);
m_ctx.basecx = this; m_ctx.basecx = this;
m_ctx.plugin = const_cast<sp_plugin_t *>(pRuntime->plugin()); m_ctx.plugin = const_cast<sp_plugin_t *>(pRuntime->plugin());
} }
PluginContext::~PluginContext() PluginContext::~PluginContext()
{ {
free(m_ctx.tracker->pBase); free(tracker_.pBase);
delete m_ctx.tracker;
} }
IVirtualMachine * IVirtualMachine *
@ -814,3 +812,41 @@ PluginContext::ClearLastNativeError()
{ {
m_ctx.n_err = SP_ERROR_NONE; m_ctx.n_err = SP_ERROR_NONE;
} }
int
PluginContext::popTrackerAndSetHeap()
{
assert(tracker_.pCur > tracker_.pBase);
tracker_.pCur--;
if (tracker_.pCur < tracker_.pBase)
return SP_ERROR_TRACKER_BOUNDS;
ucell_t amt = *tracker_.pCur;
if (amt > (m_ctx.hp - m_pRuntime->plugin()->data_size))
return SP_ERROR_HEAPMIN;
m_ctx.hp -= amt;
return SP_ERROR_NONE;
}
int
PluginContext::pushTracker(uint32_t amount)
{
if ((size_t)(tracker_.pCur - tracker_.pBase) >= tracker_.size)
return SP_ERROR_TRACKER_BOUNDS;
if (tracker_.pCur + 1 - (tracker_.pBase + tracker_.size) == 0) {
size_t disp = tracker_.size - 1;
tracker_.size *= 2;
tracker_.pBase = (ucell_t *)realloc(tracker_.pBase, tracker_.size * sizeof(cell_t));
if (!tracker_.pBase)
return SP_ERROR_TRACKER_BOUNDS;
tracker_.pCur = tracker_.pBase + disp;
}
*tracker_.pCur++ = amount;
return SP_ERROR_NONE;
}

View File

@ -18,6 +18,18 @@
#include "plugin-runtime.h" #include "plugin-runtime.h"
#include "jit_shared.h" #include "jit_shared.h"
struct HeapTracker
{
HeapTracker()
: size(0),
pBase(nullptr),
pCur(nullptr)
{}
size_t size;
ucell_t *pBase;
ucell_t *pCur;
};
class PluginContext : public IPluginContext class PluginContext : public IPluginContext
{ {
public: public:
@ -82,6 +94,9 @@ class PluginContext : public IPluginContext
static inline size_t offsetOfRstkCips() { static inline size_t offsetOfRstkCips() {
return offsetof(PluginContext, rstk_cips_); return offsetof(PluginContext, rstk_cips_);
} }
static inline size_t offsetOfTracker() {
return offsetof(PluginContext, tracker_);
}
bool pushReturnCip(cell_t cip) { bool pushReturnCip(cell_t cip) {
if (rp_ >= SP_MAX_RETURN_STACK) if (rp_ >= SP_MAX_RETURN_STACK)
@ -101,6 +116,9 @@ class PluginContext : public IPluginContext
return rstk_cips_[index]; return rstk_cips_[index];
} }
int popTrackerAndSetHeap();
int pushTracker(uint32_t amount);
private: private:
void SetErrorMessage(const char *msg, va_list ap); void SetErrorMessage(const char *msg, va_list ap);
void _SetErrorMessage(const char *msg, ...); void _SetErrorMessage(const char *msg, ...);
@ -116,6 +134,9 @@ class PluginContext : public IPluginContext
void *m_keys[4]; void *m_keys[4];
bool m_keys_set[4]; bool m_keys_set[4];
// Tracker for local HEA growth.
HeapTracker tracker_;
// Return stack. // Return stack.
cell_t rp_; cell_t rp_;
cell_t rstk_cips_[SP_MAX_RETURN_STACK]; cell_t rstk_cips_[SP_MAX_RETURN_STACK];

View File

@ -187,7 +187,7 @@ GenerateFullArray(PluginRuntime *rt, uint32_t argc, cell_t *argv, int autozero)
if (dat_hp >= argv - STACK_MARGIN) if (dat_hp >= argv - STACK_MARGIN)
return SP_ERROR_HEAPLOW; return SP_ERROR_HEAPLOW;
if (int err = PushTracker(rt->GetBaseContext()->GetCtx(), bytes)) if (int err = rt->GetBaseContext()->pushTracker(bytes))
return err; return err;
cell_t *base = reinterpret_cast<cell_t *>(rt->plugin()->memory + ctx->hp); cell_t *base = reinterpret_cast<cell_t *>(rt->plugin()->memory + ctx->hp);
@ -384,6 +384,19 @@ Compiler::emit(int *errp)
return new CompiledFunction(code, pcode_start_, edges.take()); return new CompiledFunction(code, pcode_start_, edges.take());
} }
// Helpers for invoking context members.
static int
InvokePushTracker(PluginContext *cx, uint32_t amount)
{
return cx->pushTracker(amount);
}
static int
InvokePopTrackerAndSetHeap(PluginContext *cx)
{
return cx->popTrackerAndSetHeap();
}
bool bool
Compiler::emitOp(OPCODE op) Compiler::emitOp(OPCODE op)
{ {
@ -1258,8 +1271,8 @@ Compiler::emitOp(OPCODE op)
__ push(alt); __ push(alt);
__ push(amount * 4); __ push(amount * 4);
__ push(intptr_t(rt_->GetBaseContext()->GetCtx())); __ push(intptr_t(rt_->GetBaseContext()));
__ call(ExternalAddress((void *)PushTracker)); __ call(ExternalAddress((void *)InvokePushTracker));
__ addl(esp, 8); __ addl(esp, 8);
__ testl(eax, eax); __ testl(eax, eax);
__ j(not_zero, &extern_error_); __ j(not_zero, &extern_error_);
@ -1276,8 +1289,8 @@ Compiler::emitOp(OPCODE op)
__ push(alt); __ push(alt);
// Get the context pointer and call the sanity checker. // Get the context pointer and call the sanity checker.
__ push(intptr_t(rt_)); __ push(intptr_t(rt_->GetBaseContext()));
__ call(ExternalAddress((void *)PopTrackerAndSetHeap)); __ call(ExternalAddress((void *)InvokePopTrackerAndSetHeap));
__ addl(esp, 4); __ addl(esp, 4);
__ testl(eax, eax); __ testl(eax, eax);
__ j(not_zero, &extern_error_); __ j(not_zero, &extern_error_);
@ -1405,8 +1418,8 @@ Compiler::emitGenArray(bool autozero)
__ shll(tmp, 2); __ shll(tmp, 2);
__ push(tmp); __ push(tmp);
__ push(intptr_t(rt_->GetBaseContext()->GetCtx())); __ push(intptr_t(rt_->GetBaseContext()));
__ call(ExternalAddress((void *)PushTracker)); __ call(ExternalAddress((void *)InvokePushTracker));
__ addl(esp, 4); __ addl(esp, 4);
__ pop(tmp); __ pop(tmp);
__ shrl(tmp, 2); __ shrl(tmp, 2);