sourcepawn/jit/BaseRuntime.cpp
author David Anderson <dvander@alliedmods.net>
Fri Aug 15 05:22:26 2008 +0000 (2008-08-15)
changeset 2226 d10b38524be3
parent 2195 5b70179559f9
child 2249 a1ce7e3f08b7
permissions -rw-r--r--
Landed sourcepawn-1.2. The big changes:

1) JIT compilation/optimization now occurs per-function, and only when functions are first used. We're now officially a whole-method JIT rather than an AOT compiler (albiet, still a simple JIT). This has two implications: Functions are now much better abstracted internally, and loading a plugin is now much less expensive. If a function contains calls to other functions, THOSE functions are only compiled when they're invoked as well.

2) I've removed debug mode. We always show full backtraces now, as there was a very cheap way to implement this which really cleaned up everything. This is great for a number of reasons -- there's less code, the JIT is better designed, we don't need to relocate debug tables, and best of all we no longer have to tell users to enable debug mode at their own expense.
dvander@2193
     1
#include <stdio.h>
dvander@2193
     2
#include <stdlib.h>
dvander@2193
     3
#include <string.h>
dvander@2226
     4
#include <assert.h>
dvander@2193
     5
#include "BaseRuntime.h"
dvander@2193
     6
#include "sp_vm_engine.h"
dvander@2193
     7
#include "x86/jit_x86.h"
dvander@2193
     8
#include "sp_vm_basecontext.h"
dvander@2193
     9
#include "engine2.h"
dvander@2193
    10
dvander@2193
    11
using namespace SourcePawn;
dvander@2193
    12
dvander@2226
    13
BaseRuntime::BaseRuntime() : m_Debug(&m_plugin), m_pPlugin(&m_plugin), m_pCtx(NULL), 
dvander@2226
    14
m_PubFuncs(NULL), m_PubJitFuncs(NULL), m_pCo(NULL), m_CompSerial(0)
dvander@2193
    15
{
dvander@2226
    16
	memset(&m_plugin, 0, sizeof(m_plugin));
dvander@2193
    17
dvander@2226
    18
	m_FuncCache = NULL;
dvander@2226
    19
	m_MaxFuncs = 0;
dvander@2226
    20
	m_NumFuncs = 0;
dvander@2193
    21
}
dvander@2193
    22
dvander@2193
    23
BaseRuntime::~BaseRuntime()
dvander@2193
    24
{
dvander@2226
    25
	for (uint32_t i = 0; i < m_pPlugin->num_publics; i++)
dvander@2193
    26
	{
dvander@2193
    27
		delete m_PubFuncs[i];
dvander@2193
    28
		m_PubFuncs[i] = NULL;
dvander@2193
    29
	}
dvander@2193
    30
	delete [] m_PubFuncs;
dvander@2226
    31
	delete [] m_PubJitFuncs;
dvander@2193
    32
dvander@2226
    33
	for (unsigned int i = 0; i < m_NumFuncs; i++)
dvander@2226
    34
	{
dvander@2226
    35
		delete m_FuncCache[i];
dvander@2226
    36
	}
dvander@2226
    37
	free(m_FuncCache);
dvander@2226
    38
dvander@2226
    39
	delete m_pCtx;
dvander@2226
    40
	delete m_pCo;
dvander@2193
    41
dvander@2193
    42
	free(m_pPlugin->base);
dvander@2193
    43
	delete [] m_pPlugin->memory;
dvander@2226
    44
	delete [] m_pPlugin->publics;
dvander@2226
    45
	delete [] m_pPlugin->pubvars;
dvander@2195
    46
	delete [] m_pPlugin->natives;
dvander@2226
    47
	free(m_pPlugin->name);
dvander@2226
    48
}
dvander@2226
    49
dvander@2226
    50
static cell_t InvalidNative(IPluginContext *pCtx, const cell_t *params)
dvander@2226
    51
{
dvander@2226
    52
	return pCtx->ThrowNativeErrorEx(SP_ERROR_INVALID_NATIVE, "Invalid native");
dvander@2193
    53
}
dvander@2193
    54
dvander@2226
    55
int BaseRuntime::CreateFromMemory(sp_file_hdr_t *hdr, uint8_t *base)
dvander@2193
    56
{
dvander@2226
    57
	int set_err;
dvander@2226
    58
	char *nameptr;
dvander@2226
    59
	uint8_t sectnum = 0;
dvander@2226
    60
	sp_plugin_t *plugin = m_pPlugin;
dvander@2226
    61
	sp_file_section_t *secptr = (sp_file_section_t *)(base + sizeof(sp_file_hdr_t));
dvander@2226
    62
dvander@2226
    63
	memset(plugin, 0, sizeof(sp_plugin_t));
dvander@2226
    64
dvander@2226
    65
	plugin->base = base;
dvander@2226
    66
	plugin->base_size = hdr->imagesize;
dvander@2226
    67
	set_err = SP_ERROR_NONE;
dvander@2226
    68
dvander@2226
    69
	/* We have to read the name section first */
dvander@2226
    70
	for (sectnum = 0; sectnum < hdr->sections; sectnum++)
dvander@2226
    71
	{
dvander@2226
    72
		nameptr = (char *)(base + hdr->stringtab + secptr[sectnum].nameoffs);
dvander@2226
    73
		if (strcmp(nameptr, ".names") == 0)
dvander@2226
    74
		{
dvander@2226
    75
			plugin->stringbase = (const char *)(base + secptr[sectnum].dataoffs);
dvander@2226
    76
			break;
dvander@2226
    77
		}
dvander@2226
    78
	}
dvander@2226
    79
dvander@2226
    80
	sectnum = 0;
dvander@2226
    81
dvander@2226
    82
	/* Now read the rest of the sections */
dvander@2226
    83
	while (sectnum < hdr->sections)
dvander@2226
    84
	{
dvander@2226
    85
		nameptr = (char *)(base + hdr->stringtab + secptr->nameoffs);
dvander@2226
    86
dvander@2226
    87
		if (!(plugin->pcode) && !strcmp(nameptr, ".code"))
dvander@2226
    88
		{
dvander@2226
    89
			sp_file_code_t *cod = (sp_file_code_t *)(base + secptr->dataoffs);
dvander@2226
    90
dvander@2226
    91
			if (cod->codeversion < SP_CODEVERS_JIT1)
dvander@2226
    92
			{
dvander@2226
    93
				return SP_ERROR_CODE_TOO_OLD;
dvander@2226
    94
			}
dvander@2226
    95
			else if (cod->codeversion > SP_CODEVERS_JIT2)
dvander@2226
    96
			{
dvander@2226
    97
				return SP_ERROR_CODE_TOO_NEW;
dvander@2226
    98
			}
dvander@2226
    99
dvander@2226
   100
			plugin->pcode = base + secptr->dataoffs + cod->code;
dvander@2226
   101
			plugin->pcode_size = cod->codesize;
dvander@2226
   102
			plugin->flags = cod->flags;
dvander@2226
   103
			plugin->pcode_version = cod->codeversion;
dvander@2226
   104
		}
dvander@2226
   105
		else if (!(plugin->data) && !strcmp(nameptr, ".data"))
dvander@2226
   106
		{
dvander@2226
   107
			sp_file_data_t *dat = (sp_file_data_t *)(base + secptr->dataoffs);
dvander@2226
   108
			plugin->data = base + secptr->dataoffs + dat->data;
dvander@2226
   109
			plugin->data_size = dat->datasize;
dvander@2226
   110
			plugin->mem_size = dat->memsize;
dvander@2226
   111
			plugin->memory = new uint8_t[plugin->mem_size];
dvander@2226
   112
			memcpy(plugin->memory, plugin->data, plugin->data_size);
dvander@2226
   113
		}
dvander@2226
   114
		else if ((plugin->publics == NULL) && !strcmp(nameptr, ".publics"))
dvander@2226
   115
		{
dvander@2226
   116
			sp_file_publics_t *publics;
dvander@2226
   117
dvander@2226
   118
			publics = (sp_file_publics_t *)(base + secptr->dataoffs);
dvander@2226
   119
			plugin->num_publics = secptr->size / sizeof(sp_file_publics_t);
dvander@2226
   120
dvander@2226
   121
			if (plugin->num_publics > 0)
dvander@2226
   122
			{
dvander@2226
   123
				plugin->publics = new sp_public_t[plugin->num_publics];
dvander@2226
   124
dvander@2226
   125
				for (uint32_t i = 0; i < plugin->num_publics; i++)
dvander@2226
   126
				{
dvander@2226
   127
					plugin->publics[i].code_offs = publics[i].address;
dvander@2226
   128
					plugin->publics[i].funcid = (i << 1) | 1;
dvander@2226
   129
					plugin->publics[i].name = plugin->stringbase + publics[i].name;
dvander@2226
   130
				}
dvander@2226
   131
			}
dvander@2226
   132
		}
dvander@2226
   133
		else if ((plugin->pubvars == NULL) && !strcmp(nameptr, ".pubvars"))
dvander@2226
   134
		{
dvander@2226
   135
			sp_file_pubvars_t *pubvars;
dvander@2226
   136
dvander@2226
   137
			pubvars = (sp_file_pubvars_t *)(base + secptr->dataoffs);
dvander@2226
   138
			plugin->num_pubvars = secptr->size / sizeof(sp_file_pubvars_t);
dvander@2226
   139
dvander@2226
   140
			if (plugin->num_pubvars > 0)
dvander@2226
   141
			{
dvander@2226
   142
				plugin->pubvars = new sp_pubvar_t[plugin->num_pubvars];
dvander@2226
   143
dvander@2226
   144
				for (uint32_t i = 0; i < plugin->num_pubvars; i++)
dvander@2226
   145
				{
dvander@2226
   146
					plugin->pubvars[i].name = plugin->stringbase + pubvars[i].name;
dvander@2226
   147
					plugin->pubvars[i].offs = (cell_t *)(plugin->memory + pubvars[i].address);
dvander@2226
   148
				}
dvander@2226
   149
			}
dvander@2226
   150
		}
dvander@2226
   151
		else if ((plugin->natives == NULL) && !strcmp(nameptr, ".natives"))
dvander@2226
   152
		{
dvander@2226
   153
			sp_file_natives_t *natives;
dvander@2226
   154
dvander@2226
   155
			natives = (sp_file_natives_t *)(base + secptr->dataoffs);
dvander@2226
   156
			plugin->num_natives = secptr->size / sizeof(sp_file_natives_t);
dvander@2226
   157
dvander@2226
   158
			if (plugin->num_natives > 0)
dvander@2226
   159
			{
dvander@2226
   160
				plugin->natives = new sp_native_t[plugin->num_natives];
dvander@2226
   161
dvander@2226
   162
				for (uint32_t i = 0; i < plugin->num_natives; i++)
dvander@2226
   163
				{
dvander@2226
   164
					plugin->natives[i].flags = 0;
dvander@2226
   165
					plugin->natives[i].pfn = InvalidNative;
dvander@2226
   166
					plugin->natives[i].status = SP_NATIVE_UNBOUND;
dvander@2226
   167
					plugin->natives[i].user = NULL;
dvander@2226
   168
					plugin->natives[i].name = plugin->stringbase + natives[i].name;
dvander@2226
   169
				}
dvander@2226
   170
			}
dvander@2226
   171
		}
dvander@2226
   172
		else if (!(plugin->debug.files) && !strcmp(nameptr, ".dbg.files"))
dvander@2226
   173
		{
dvander@2226
   174
			plugin->debug.files = (sp_fdbg_file_t *)(base + secptr->dataoffs);
dvander@2226
   175
		}
dvander@2226
   176
		else if (!(plugin->debug.lines) && !strcmp(nameptr, ".dbg.lines"))
dvander@2226
   177
		{
dvander@2226
   178
			plugin->debug.lines = (sp_fdbg_line_t *)(base + secptr->dataoffs);
dvander@2226
   179
		}
dvander@2226
   180
		else if (!(plugin->debug.symbols) && !strcmp(nameptr, ".dbg.symbols"))
dvander@2226
   181
		{
dvander@2226
   182
			plugin->debug.symbols = (sp_fdbg_symbol_t *)(base + secptr->dataoffs);
dvander@2226
   183
		}
dvander@2226
   184
		else if (!(plugin->debug.lines_num) && !strcmp(nameptr, ".dbg.info"))
dvander@2226
   185
		{
dvander@2226
   186
			sp_fdbg_info_t *inf = (sp_fdbg_info_t *)(base + secptr->dataoffs);
dvander@2226
   187
			plugin->debug.files_num = inf->num_files;
dvander@2226
   188
			plugin->debug.lines_num = inf->num_lines;
dvander@2226
   189
			plugin->debug.syms_num = inf->num_syms;
dvander@2226
   190
		}
dvander@2226
   191
		else if (!(plugin->debug.stringbase) && !strcmp(nameptr, ".dbg.strings"))
dvander@2226
   192
		{
dvander@2226
   193
			plugin->debug.stringbase = (const char *)(base + secptr->dataoffs);
dvander@2226
   194
		}
dvander@2226
   195
dvander@2226
   196
		secptr++;
dvander@2226
   197
		sectnum++;
dvander@2226
   198
	}
dvander@2226
   199
dvander@2226
   200
	if (plugin->pcode == NULL || plugin->data == NULL)
dvander@2226
   201
	{
dvander@2226
   202
		return SP_ERROR_FILE_FORMAT;
dvander@2226
   203
	}
dvander@2226
   204
dvander@2226
   205
	if ((plugin->flags & SP_FLAG_DEBUG) && (!(plugin->debug.files) || !(plugin->debug.lines) || !(plugin->debug.symbols)))
dvander@2226
   206
	{
dvander@2226
   207
		return SP_ERROR_FILE_FORMAT;
dvander@2226
   208
	}
dvander@2226
   209
dvander@2226
   210
	if (m_pPlugin->num_publics > 0)
dvander@2226
   211
	{
dvander@2226
   212
		m_PubFuncs = new CFunction *[m_pPlugin->num_publics];
dvander@2226
   213
		memset(m_PubFuncs, 0, sizeof(CFunction *) * m_pPlugin->num_publics);
dvander@2226
   214
		m_PubJitFuncs = new JitFunction *[m_pPlugin->num_publics];
dvander@2226
   215
		memset(m_PubJitFuncs, 0, sizeof(JitFunction *) * m_pPlugin->num_publics);
dvander@2226
   216
	}
dvander@2226
   217
dvander@2226
   218
	m_pPlugin->profiler = g_engine2.GetProfiler();
dvander@2226
   219
	m_pCtx = new BaseContext(this);
dvander@2226
   220
	m_pCo = g_Jit.StartCompilation(this);
dvander@2226
   221
dvander@2226
   222
	return SP_ERROR_NONE;
dvander@2193
   223
}
dvander@2193
   224
dvander@2193
   225
int BaseRuntime::FindNativeByName(const char *name, uint32_t *index)
dvander@2193
   226
{
dvander@2193
   227
	int high;
dvander@2193
   228
dvander@2226
   229
	high = m_pPlugin->num_natives - 1;
dvander@2193
   230
dvander@2226
   231
	for (uint32_t i=0; i<m_pPlugin->num_natives; i++)
dvander@2193
   232
	{
dvander@2193
   233
		if (strcmp(m_pPlugin->natives[i].name, name) == 0)
dvander@2193
   234
		{
dvander@2193
   235
			if (index)
dvander@2193
   236
			{
dvander@2193
   237
				*index = i;
dvander@2193
   238
			}
dvander@2193
   239
			return SP_ERROR_NONE;
dvander@2193
   240
		}
dvander@2193
   241
	}
dvander@2193
   242
dvander@2193
   243
	return SP_ERROR_NOT_FOUND;
dvander@2193
   244
}
dvander@2193
   245
dvander@2193
   246
int BaseRuntime::GetNativeByIndex(uint32_t index, sp_native_t **native)
dvander@2193
   247
{
dvander@2226
   248
	if (index >= m_pPlugin->num_natives)
dvander@2193
   249
	{
dvander@2193
   250
		return SP_ERROR_INDEX;
dvander@2193
   251
	}
dvander@2193
   252
dvander@2193
   253
	if (native)
dvander@2193
   254
	{
dvander@2193
   255
		*native = &(m_pPlugin->natives[index]);
dvander@2193
   256
	}
dvander@2193
   257
dvander@2193
   258
	return SP_ERROR_NONE;
dvander@2193
   259
}
dvander@2193
   260
dvander@2193
   261
dvander@2193
   262
uint32_t BaseRuntime::GetNativesNum()
dvander@2193
   263
{
dvander@2226
   264
	return m_pPlugin->num_natives;
dvander@2193
   265
}
dvander@2193
   266
dvander@2193
   267
int BaseRuntime::FindPublicByName(const char *name, uint32_t *index)
dvander@2193
   268
{
dvander@2193
   269
	int diff, high, low;
dvander@2193
   270
	uint32_t mid;
dvander@2193
   271
dvander@2226
   272
	high = m_pPlugin->num_publics - 1;
dvander@2193
   273
	low = 0;
dvander@2193
   274
dvander@2193
   275
	while (low <= high)
dvander@2193
   276
	{
dvander@2193
   277
		mid = (low + high) / 2;
dvander@2193
   278
		diff = strcmp(m_pPlugin->publics[mid].name, name);
dvander@2193
   279
		if (diff == 0)
dvander@2193
   280
		{
dvander@2193
   281
			if (index)
dvander@2193
   282
			{
dvander@2193
   283
				*index = mid;
dvander@2193
   284
			}
dvander@2193
   285
			return SP_ERROR_NONE;
dvander@2193
   286
		} else if (diff < 0) {
dvander@2193
   287
			low = mid + 1;
dvander@2193
   288
		} else {
dvander@2193
   289
			high = mid - 1;
dvander@2193
   290
		}
dvander@2193
   291
	}
dvander@2193
   292
dvander@2193
   293
	return SP_ERROR_NOT_FOUND;
dvander@2193
   294
}
dvander@2193
   295
dvander@2193
   296
int BaseRuntime::GetPublicByIndex(uint32_t index, sp_public_t **pblic)
dvander@2193
   297
{
dvander@2226
   298
	if (index >= m_pPlugin->num_publics)
dvander@2193
   299
	{
dvander@2193
   300
		return SP_ERROR_INDEX;
dvander@2193
   301
	}
dvander@2193
   302
dvander@2193
   303
	if (pblic)
dvander@2193
   304
	{
dvander@2193
   305
		*pblic = &(m_pPlugin->publics[index]);
dvander@2193
   306
	}
dvander@2193
   307
dvander@2193
   308
	return SP_ERROR_NONE;
dvander@2193
   309
}
dvander@2193
   310
dvander@2193
   311
uint32_t BaseRuntime::GetPublicsNum()
dvander@2193
   312
{
dvander@2226
   313
	return m_pPlugin->num_publics;
dvander@2193
   314
}
dvander@2193
   315
dvander@2193
   316
int BaseRuntime::GetPubvarByIndex(uint32_t index, sp_pubvar_t **pubvar)
dvander@2193
   317
{
dvander@2226
   318
	if (index >= m_pPlugin->num_pubvars)
dvander@2193
   319
	{
dvander@2193
   320
		return SP_ERROR_INDEX;
dvander@2193
   321
	}
dvander@2193
   322
dvander@2193
   323
	if (pubvar)
dvander@2193
   324
	{
dvander@2193
   325
		*pubvar = &(m_pPlugin->pubvars[index]);
dvander@2193
   326
	}
dvander@2193
   327
dvander@2193
   328
	return SP_ERROR_NONE;
dvander@2193
   329
}
dvander@2193
   330
dvander@2193
   331
int BaseRuntime::FindPubvarByName(const char *name, uint32_t *index)
dvander@2193
   332
{
dvander@2193
   333
	int diff, high, low;
dvander@2193
   334
	uint32_t mid;
dvander@2193
   335
dvander@2226
   336
	high = m_pPlugin->num_pubvars - 1;
dvander@2193
   337
	low = 0;
dvander@2193
   338
dvander@2193
   339
	while (low <= high)
dvander@2193
   340
	{
dvander@2193
   341
		mid = (low + high) / 2;
dvander@2193
   342
		diff = strcmp(m_pPlugin->pubvars[mid].name, name);
dvander@2193
   343
		if (diff == 0)
dvander@2193
   344
		{
dvander@2193
   345
			if (index)
dvander@2193
   346
			{
dvander@2193
   347
				*index = mid;
dvander@2193
   348
			}
dvander@2193
   349
			return SP_ERROR_NONE;
dvander@2226
   350
		}
dvander@2226
   351
		else if (diff < 0)
dvander@2226
   352
		{
dvander@2193
   353
			low = mid + 1;
dvander@2226
   354
		}
dvander@2226
   355
		else
dvander@2226
   356
		{
dvander@2193
   357
			high = mid - 1;
dvander@2193
   358
		}
dvander@2193
   359
	}
dvander@2193
   360
dvander@2193
   361
	return SP_ERROR_NOT_FOUND;
dvander@2193
   362
}
dvander@2193
   363
dvander@2193
   364
int BaseRuntime::GetPubvarAddrs(uint32_t index, cell_t *local_addr, cell_t **phys_addr)
dvander@2193
   365
{
dvander@2226
   366
	if (index >= m_pPlugin->num_pubvars)
dvander@2193
   367
	{
dvander@2193
   368
		return SP_ERROR_INDEX;
dvander@2193
   369
	}
dvander@2193
   370
dvander@2226
   371
	*local_addr = (uint8_t *)m_pPlugin->pubvars[index].offs - m_pPlugin->memory;
dvander@2193
   372
	*phys_addr = m_pPlugin->pubvars[index].offs;
dvander@2193
   373
dvander@2193
   374
	return SP_ERROR_NONE;
dvander@2193
   375
}
dvander@2193
   376
dvander@2193
   377
uint32_t BaseRuntime::GetPubVarsNum()
dvander@2193
   378
{
dvander@2226
   379
	return m_pPlugin->num_pubvars;
dvander@2193
   380
}
dvander@2193
   381
dvander@2193
   382
IPluginContext *BaseRuntime::GetDefaultContext()
dvander@2193
   383
{
dvander@2193
   384
	return m_pCtx;
dvander@2193
   385
}
dvander@2193
   386
dvander@2193
   387
IPluginDebugInfo *BaseRuntime::GetDebugInfo()
dvander@2193
   388
{
dvander@2193
   389
	return &m_Debug;
dvander@2193
   390
}
dvander@2193
   391
dvander@2193
   392
IPluginFunction *BaseRuntime::GetFunctionById(funcid_t func_id)
dvander@2193
   393
{
dvander@2193
   394
	CFunction *pFunc = NULL;
dvander@2193
   395
dvander@2193
   396
	if (func_id & 1)
dvander@2193
   397
	{
dvander@2193
   398
		func_id >>= 1;
dvander@2226
   399
		if (func_id >= m_pPlugin->num_publics)
dvander@2193
   400
		{
dvander@2193
   401
			return NULL;
dvander@2193
   402
		}
dvander@2193
   403
		pFunc = m_PubFuncs[func_id];
dvander@2193
   404
		if (!pFunc)
dvander@2193
   405
		{
dvander@2226
   406
			m_PubFuncs[func_id] = new CFunction(this, 
dvander@2193
   407
				(func_id << 1) | 1,
dvander@2193
   408
				func_id);
dvander@2193
   409
			pFunc = m_PubFuncs[func_id];
dvander@2193
   410
		}
dvander@2193
   411
	}
dvander@2193
   412
dvander@2193
   413
	return pFunc;
dvander@2193
   414
}
dvander@2193
   415
dvander@2193
   416
IPluginFunction *BaseRuntime::GetFunctionByName(const char *public_name)
dvander@2193
   417
{
dvander@2193
   418
	uint32_t index;
dvander@2193
   419
dvander@2193
   420
	if (FindPublicByName(public_name, &index) != SP_ERROR_NONE)
dvander@2193
   421
	{
dvander@2193
   422
		return NULL;
dvander@2193
   423
	}
dvander@2193
   424
dvander@2193
   425
	CFunction *pFunc = m_PubFuncs[index];
dvander@2193
   426
	if (!pFunc)
dvander@2193
   427
	{
dvander@2193
   428
		sp_public_t *pub = NULL;
dvander@2193
   429
		GetPublicByIndex(index, &pub);
dvander@2193
   430
		if (pub)
dvander@2193
   431
		{
dvander@2226
   432
			m_PubFuncs[index] = new CFunction(this, (index << 1) | 1, index);
dvander@2193
   433
		}
dvander@2193
   434
		pFunc = m_PubFuncs[index];
dvander@2193
   435
	}
dvander@2193
   436
dvander@2193
   437
	return pFunc;
dvander@2193
   438
}
dvander@2193
   439
dvander@2193
   440
bool BaseRuntime::IsDebugging()
dvander@2193
   441
{
dvander@2226
   442
	return true;
dvander@2193
   443
}
dvander@2193
   444
dvander@2193
   445
void BaseRuntime::SetPauseState(bool paused)
dvander@2193
   446
{
dvander@2193
   447
	if (paused)
dvander@2193
   448
	{
dvander@2193
   449
		m_pPlugin->run_flags |= SPFLAG_PLUGIN_PAUSED;
dvander@2193
   450
	}
dvander@2193
   451
	else
dvander@2193
   452
	{
dvander@2193
   453
		m_pPlugin->run_flags &= ~SPFLAG_PLUGIN_PAUSED;
dvander@2193
   454
	}
dvander@2193
   455
}
dvander@2193
   456
dvander@2193
   457
bool BaseRuntime::IsPaused()
dvander@2193
   458
{
dvander@2193
   459
	return ((m_pPlugin->run_flags & SPFLAG_PLUGIN_PAUSED) == SPFLAG_PLUGIN_PAUSED);
dvander@2193
   460
}
dvander@2193
   461
dvander@2193
   462
size_t BaseRuntime::GetMemUsage()
dvander@2193
   463
{
dvander@2193
   464
	size_t mem = 0;
dvander@2193
   465
dvander@2193
   466
	mem += sizeof(this);
dvander@2193
   467
	mem += sizeof(sp_plugin_t);
dvander@2193
   468
	mem += sizeof(BaseContext);
dvander@2193
   469
	mem += m_pPlugin->base_size;
dvander@2193
   470
dvander@2193
   471
	return mem;
dvander@2193
   472
}
dvander@2193
   473
dvander@2193
   474
BaseContext *BaseRuntime::GetBaseContext()
dvander@2193
   475
{
dvander@2193
   476
	return m_pCtx;
dvander@2193
   477
}
dvander@2193
   478
dvander@2226
   479
int BaseRuntime::ApplyCompilationOptions(ICompilation *co)
dvander@2226
   480
{
dvander@2226
   481
	if (co == NULL)
dvander@2226
   482
	{
dvander@2226
   483
		return SP_ERROR_NONE;
dvander@2226
   484
	}
dvander@2226
   485
dvander@2226
   486
	m_pCo = g_Jit.ApplyOptions(m_pCo, co);
dvander@2226
   487
dvander@2226
   488
	return SP_ERROR_NONE;
dvander@2226
   489
}
dvander@2226
   490
dvander@2226
   491
JitFunction *BaseRuntime::GetJittedFunction(uint32_t idx)
dvander@2226
   492
{
dvander@2226
   493
	assert(idx <= m_NumFuncs);
dvander@2226
   494
dvander@2226
   495
	if (idx == 0 || idx > m_NumFuncs)
dvander@2226
   496
	{
dvander@2226
   497
		return NULL;
dvander@2226
   498
	}
dvander@2226
   499
dvander@2226
   500
	return m_FuncCache[idx - 1];
dvander@2226
   501
}
dvander@2226
   502
dvander@2226
   503
uint32_t BaseRuntime::AddJittedFunction(JitFunction *fn)
dvander@2226
   504
{
dvander@2226
   505
	if (m_NumFuncs + 1 > m_MaxFuncs)
dvander@2226
   506
	{
dvander@2226
   507
		if (m_MaxFuncs == 0)
dvander@2226
   508
		{
dvander@2226
   509
			m_MaxFuncs = 8;
dvander@2226
   510
		}
dvander@2226
   511
		else
dvander@2226
   512
		{
dvander@2226
   513
			m_MaxFuncs *= 2;
dvander@2226
   514
		}
dvander@2226
   515
dvander@2226
   516
		m_FuncCache = (JitFunction **)realloc(
dvander@2226
   517
			m_FuncCache,
dvander@2226
   518
			sizeof(JitFunction *) * m_MaxFuncs);
dvander@2226
   519
	}
dvander@2226
   520
dvander@2226
   521
	m_FuncCache[m_NumFuncs++] = fn;
dvander@2226
   522
dvander@2226
   523
	return m_NumFuncs;
dvander@2226
   524
}