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;
}
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
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;
}
if ((ctx->err = PushTracker(ctx, bytes)) != SP_ERROR_NONE)
if ((ctx->err = rt->GetBaseContext()->pushTracker(bytes)) != SP_ERROR_NONE)
return false;
if (autozero)
@ -849,7 +807,7 @@ Interpret(PluginRuntime *rt, uint32_t aCodeStart, cell_t *rval)
case OP_TRACKER_PUSH_C:
{
cell_t amount = *cip++;
int error = PushTracker(ctx, amount * 4);
int error = cx->pushTracker(amount * 4);
if (error != SP_ERROR_NONE) {
ctx->err = error;
goto error;
@ -859,7 +817,7 @@ Interpret(PluginRuntime *rt, uint32_t aCodeStart, cell_t *rval)
case OP_TRACKER_POP_SETHEAP:
{
int error = PopTrackerAndSetHeap(rt);
int error = cx->popTrackerAndSetHeap();
if (error != SP_ERROR_NONE) {
ctx->err = error;
goto error;

View File

@ -22,19 +22,10 @@
#include "plugin-runtime.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 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 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_

View File

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

View File

@ -58,18 +58,16 @@ PluginContext::PluginContext(PluginRuntime *pRuntime)
m_ctx.n_idx = SP_ERROR_NONE;
rp_ = 0;
m_ctx.tracker = new tracker_t;
m_ctx.tracker->pBase = (ucell_t *)malloc(1024);
m_ctx.tracker->pCur = m_ctx.tracker->pBase;
m_ctx.tracker->size = 1024 / sizeof(cell_t);
tracker_.pBase = (ucell_t *)malloc(1024);
tracker_.pCur = tracker_.pBase;
tracker_.size = 1024 / sizeof(cell_t);
m_ctx.basecx = this;
m_ctx.plugin = const_cast<sp_plugin_t *>(pRuntime->plugin());
}
PluginContext::~PluginContext()
{
free(m_ctx.tracker->pBase);
delete m_ctx.tracker;
free(tracker_.pBase);
}
IVirtualMachine *
@ -814,3 +812,41 @@ PluginContext::ClearLastNativeError()
{
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 "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
{
public:
@ -82,6 +94,9 @@ class PluginContext : public IPluginContext
static inline size_t offsetOfRstkCips() {
return offsetof(PluginContext, rstk_cips_);
}
static inline size_t offsetOfTracker() {
return offsetof(PluginContext, tracker_);
}
bool pushReturnCip(cell_t cip) {
if (rp_ >= SP_MAX_RETURN_STACK)
@ -101,6 +116,9 @@ class PluginContext : public IPluginContext
return rstk_cips_[index];
}
int popTrackerAndSetHeap();
int pushTracker(uint32_t amount);
private:
void SetErrorMessage(const char *msg, va_list ap);
void _SetErrorMessage(const char *msg, ...);
@ -116,6 +134,9 @@ class PluginContext : public IPluginContext
void *m_keys[4];
bool m_keys_set[4];
// Tracker for local HEA growth.
HeapTracker tracker_;
// Return stack.
cell_t rp_;
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)
return SP_ERROR_HEAPLOW;
if (int err = PushTracker(rt->GetBaseContext()->GetCtx(), bytes))
if (int err = rt->GetBaseContext()->pushTracker(bytes))
return err;
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());
}
// 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
Compiler::emitOp(OPCODE op)
{
@ -1258,8 +1271,8 @@ Compiler::emitOp(OPCODE op)
__ push(alt);
__ push(amount * 4);
__ push(intptr_t(rt_->GetBaseContext()->GetCtx()));
__ call(ExternalAddress((void *)PushTracker));
__ push(intptr_t(rt_->GetBaseContext()));
__ call(ExternalAddress((void *)InvokePushTracker));
__ addl(esp, 8);
__ testl(eax, eax);
__ j(not_zero, &extern_error_);
@ -1276,8 +1289,8 @@ Compiler::emitOp(OPCODE op)
__ push(alt);
// Get the context pointer and call the sanity checker.
__ push(intptr_t(rt_));
__ call(ExternalAddress((void *)PopTrackerAndSetHeap));
__ push(intptr_t(rt_->GetBaseContext()));
__ call(ExternalAddress((void *)InvokePopTrackerAndSetHeap));
__ addl(esp, 4);
__ testl(eax, eax);
__ j(not_zero, &extern_error_);
@ -1405,8 +1418,8 @@ Compiler::emitGenArray(bool autozero)
__ shll(tmp, 2);
__ push(tmp);
__ push(intptr_t(rt_->GetBaseContext()->GetCtx()));
__ call(ExternalAddress((void *)PushTracker));
__ push(intptr_t(rt_->GetBaseContext()));
__ call(ExternalAddress((void *)InvokePushTracker));
__ addl(esp, 4);
__ pop(tmp);
__ shrl(tmp, 2);