updated to trunk code sourcemod-1.1.0
authorDavid Anderson <dvander@alliedmods.net>
Thu Mar 13 17:04:25 2008 +0000 (2008-03-13)
branchsourcemod-1.1.0
changeset 193012f08d51439c
parent 1919 fe6181f4b9d2
child 1931 e0187c4811c5
updated to trunk code
sourcepawn/compiler/Makefile
sourcepawn/compiler/sc1.c
sourcepawn/compiler/sc3.c
sourcepawn/jit/x86/Makefile
sourcepawn/jit/x86/dll_exports.cpp
sourcepawn/jit/x86/jit_x86.cpp
sourcepawn/jit/x86/jit_x86.h
     1.1 --- a/sourcepawn/compiler/Makefile	Tue Mar 04 23:18:16 2008 +0000
     1.2 +++ b/sourcepawn/compiler/Makefile	Thu Mar 13 17:04:25 2008 +0000
     1.3 @@ -36,7 +36,7 @@
     1.4  	CPPFLAGS += $(OPT_CPP_FLAGS)
     1.5  endif
     1.6  
     1.7 -CFLAGS += -DLINUX -DNDEBUG -DHAVE_STDINT_H -DAMX_ANSIONLY -DENABLE_BINRELOC
     1.8 +CFLAGS += -DLINUX -DNDEBUG -DHAVE_STDINT_H -DAMX_ANSIONLY -DENABLE_BINRELOC -m32
     1.9  CPPFLAGS += -Wno-deprecated -fno-exceptions -fno-rtti
    1.10  
    1.11  OBJ_LINUX := $(OBJECTS:%.cpp=$(BIN_DIR)/%.o)
    1.12 @@ -53,7 +53,7 @@
    1.13  	$(MAKE) spcomp
    1.14  
    1.15  spcomp: $(OBJ_LINUX)
    1.16 -	$(CPP) $(INCLUDE) $(CFLAGS) $(CPPFLAGS) $(OBJ_LINUX) $(LINK) -ldl -lm -o$(BIN_DIR)/$(BINARY)
    1.17 +	$(CPP) $(INCLUDE) $(CFLAGS) $(CPPFLAGS) $(OBJ_LINUX) $(LINK) -m32 -ldl -lm -o$(BIN_DIR)/$(BINARY)
    1.18  
    1.19  debug: 
    1.20  	$(MAKE) all DEBUG=true
     2.1 --- a/sourcepawn/compiler/sc1.c	Tue Mar 04 23:18:16 2008 +0000
     2.2 +++ b/sourcepawn/compiler/sc1.c	Thu Mar 13 17:04:25 2008 +0000
     2.3 @@ -4136,6 +4136,8 @@
     2.4    /* "declargs()" found the ")"; if a ";" appears after this, it was a
     2.5     * prototype */
     2.6    if (matchtoken(';')) {
     2.7 +    if (sym->usage & uPUBLIC)
     2.8 +      error(10);
     2.9      sym->usage|=uFORWARD;
    2.10      if (!sc_needsemicolon)
    2.11        error(10);       /* old style prototypes used with optional semicolumns */
     3.1 --- a/sourcepawn/compiler/sc3.c	Tue Mar 04 23:18:16 2008 +0000
     3.2 +++ b/sourcepawn/compiler/sc3.c	Thu Mar 13 17:04:25 2008 +0000
     3.3 @@ -1207,7 +1207,7 @@
     3.4        } /* if */
     3.5      } /* if */
     3.6      if (lval3.sym->dim.array.level!=level)
     3.7 -      return error(48); /* array dimensions must match */
     3.8 +      return error(47); /* array dimensions must match */
     3.9      else if (ltlength<val || exactmatch && ltlength>val || val==0)
    3.10        return error(47); /* array sizes must match */
    3.11      else if (lval3.ident!=iARRAYCELL && !matchtag(lval3.sym->x.tags.index,idxtag,TRUE))
    3.12 @@ -1217,6 +1217,7 @@
    3.13        symbol *sym1 = lval3.sym;
    3.14        symbol *sym2 = lval2.sym;
    3.15        int i;
    3.16 +      error(23);
    3.17        assert(sym1!=NULL && sym2!=NULL);
    3.18        /* ^^^ sym2 must be valid, because only variables can be
    3.19         *     multi-dimensional (there are no multi-dimensional literals),
    3.20 @@ -1328,7 +1329,9 @@
    3.21      array1= (lval->ident==iARRAY || lval->ident==iREFARRAY);
    3.22      array2= (lval2.ident==iARRAY || lval2.ident==iREFARRAY);
    3.23      if (array1 && !array2) {
    3.24 -      char *ptr=(lval->sym->name!=NULL) ? lval->sym->name : "-unknown-";
    3.25 +      const char *ptr = "-unknown-";
    3.26 +	  if (lval->sym != NULL && lval->sym->name != NULL)
    3.27 +        ptr = lval->sym->name;
    3.28        error(33,ptr);            /* array must be indexed */
    3.29      } else if (!array1 && array2) {
    3.30        char *ptr=(lval2.sym->name!=NULL) ? lval2.sym->name : "-unknown-";
    3.31 @@ -1569,7 +1572,7 @@
    3.32  	  if (level>sym->dim.array.level+1) {
    3.33          error(28,sym->name);  /* invalid subscript */
    3.34        } else if (level==sym->dim.array.level+1) {
    3.35 -        lval->constval= (idxsym!=NULL && idxsym->dim.array.length>0) ? idxsym->dim.array.length : 1;
    3.36 +        lval->constval=(idxsym!=NULL && idxsym->dim.array.length>0) ? idxsym->dim.array.length : 1;
    3.37        } else {
    3.38          lval->constval=array_levelsize(sym,level);
    3.39        }
    3.40 @@ -2365,7 +2368,7 @@
    3.41           */
    3.42        } else {
    3.43          arglist[argpos]=ARG_DONE; /* flag argument as "present" */
    3.44 -        if (arg[argidx].numtags==1)     /* set the expected tag, if any */
    3.45 +        if (arg[argidx].ident!=0 && arg[argidx].numtags==1)     /* set the expected tag, if any */
    3.46            lval.cmptag=arg[argidx].tags[0];
    3.47          lvalue=hier14(&lval);
    3.48          assert(sc_status==statFIRST || arg[argidx].tags!=NULL);
     4.1 --- a/sourcepawn/jit/x86/Makefile	Tue Mar 04 23:18:16 2008 +0000
     4.2 +++ b/sourcepawn/jit/x86/Makefile	Thu Mar 13 17:04:25 2008 +0000
     4.3 @@ -32,7 +32,10 @@
     4.4  
     4.5  GCC_VERSION := $(shell $(CPP) -dumpversion >&1 | cut -b1)
     4.6  
     4.7 -CFLAGS += -D_LINUX -DNDEBUG -Dstricmp=strcasecmp -D_stricmp=strcasecmp -D_strnicmp=strncasecmp -Dstrnicmp=strncasecmp -D_snprintf=snprintf -D_vsnprintf=vsnprintf -D_alloca=alloca -Dstrcmpi=strcasecmp -Wall -Wno-non-virtual-dtor -Werror -fPIC -fno-exceptions -fno-rtti -msse -DHAVE_STDINT_H
     4.8 +CFLAGS += -D_LINUX -DNDEBUG -Dstricmp=strcasecmp -D_stricmp=strcasecmp -D_strnicmp=strncasecmp \
     4.9 +	-Dstrnicmp=strncasecmp -D_snprintf=snprintf -D_vsnprintf=vsnprintf -D_alloca=alloca \
    4.10 +	-Dstrcmpi=strcasecmp -Wall -Wno-non-virtual-dtor -Werror -fno-exceptions -fno-rtti \
    4.11 +	-DHAVE_STDINT_H -m32
    4.12  
    4.13  ifeq "$(GCC_VERSION)" "4"
    4.14  	CFLAGS += $(GCC4_FLAGS)
    4.15 @@ -52,7 +55,7 @@
    4.16  	ln -sf $(BIN_DIR)/$(BINARY) $(BINARY)
    4.17  
    4.18  binary: $(OBJ_LINUX)
    4.19 -	$(CPP) $(INCLUDE) $(CFLAGS) $(OBJ_LINUX) $(LINK) -shared -ldl -lm -o$(BIN_DIR)/$(BINARY)
    4.20 +	$(CPP) $(INCLUDE) $(CFLAGS) $(OBJ_LINUX) $(LINK) -m32 -shared -ldl -lm -o$(BIN_DIR)/$(BINARY)
    4.21  
    4.22  debug:	
    4.23  	$(MAKE) all DEBUG=true
     5.1 --- a/sourcepawn/jit/x86/dll_exports.cpp	Tue Mar 04 23:18:16 2008 +0000
     5.2 +++ b/sourcepawn/jit/x86/dll_exports.cpp	Thu Mar 13 17:04:25 2008 +0000
     5.3 @@ -25,7 +25,7 @@
     5.4  {
     5.5  	engine = engine_p;
     5.6  
     5.7 -	if (api_version > SOURCEPAWN_ENGINE_API_VERSION)
     5.8 +	if (api_version > SOURCEPAWN_ENGINE_API_VERSION || api_version < 2)
     5.9  	{
    5.10  		return SP_ERROR_PARAM;
    5.11  	}
     6.1 --- a/sourcepawn/jit/x86/jit_x86.cpp	Tue Mar 04 23:18:16 2008 +0000
     6.2 +++ b/sourcepawn/jit/x86/jit_x86.cpp	Thu Mar 13 17:04:25 2008 +0000
     6.3 @@ -1278,12 +1278,99 @@
     6.4  	IA32_Return(jit);
     6.5  }
     6.6  
     6.7 +void ProfCallGate_Begin(sp_context_t *ctx, const char *name)
     6.8 +{
     6.9 +	ctx->profiler->OnFunctionBegin(ctx->context, name);
    6.10 +}
    6.11 +
    6.12 +void ProfCallGate_End(sp_context_t *ctx)
    6.13 +{
    6.14 +	ctx->profiler->OnFunctionEnd();
    6.15 +}
    6.16 +
    6.17 +const char *find_func_name(sp_plugin_t *plugin, uint32_t offs)
    6.18 +{
    6.19 +	uint32_t max, iter;
    6.20 +	sp_fdbg_symbol_t *sym;
    6.21 +	sp_fdbg_arraydim_t *arr;
    6.22 +	uint8_t *cursor = (uint8_t *)(plugin->debug.symbols);
    6.23 +
    6.24 +	max = plugin->debug.syms_num;
    6.25 +	for (iter = 0; iter < max; iter++)
    6.26 +	{
    6.27 +		sym = (sp_fdbg_symbol_t *)cursor;
    6.28 +
    6.29 +		if (sym->ident == SP_SYM_FUNCTION
    6.30 +			&& sym->codestart <= offs 
    6.31 +			&& sym->codeend > offs)
    6.32 +		{
    6.33 +			return plugin->debug.stringbase + sym->name;
    6.34 +		}
    6.35 +
    6.36 +		if (sym->dimcount > 0)
    6.37 +		{
    6.38 +			cursor += sizeof(sp_fdbg_symbol_t);
    6.39 +			arr = (sp_fdbg_arraydim_t *)cursor;
    6.40 +			cursor += sizeof(sp_fdbg_arraydim_t) * sym->dimcount;
    6.41 +			continue;
    6.42 +		}
    6.43 +
    6.44 +		cursor += sizeof(sp_fdbg_symbol_t);
    6.45 +	}
    6.46 +
    6.47 +	return NULL;
    6.48 +}
    6.49 +
    6.50  inline void WriteOp_Call(JitWriter *jit)
    6.51  {
    6.52 -	cell_t offs = jit->read_cell();
    6.53 -
    6.54 -	jitoffs_t jmp = IA32_Call_Imm32(jit, 0);
    6.55 -	IA32_Write_Jump32(jit, jmp, RelocLookup(jit, offs, false));
    6.56 +	cell_t offs;
    6.57 +	jitoffs_t jmp;
    6.58 +	CompData *data;
    6.59 +		
    6.60 +	data = (CompData *)jit->data; 
    6.61 +	offs = jit->read_cell();
    6.62 +
    6.63 +	if ((data->profile & SP_PROF_FUNCTIONS) == SP_PROF_FUNCTIONS)
    6.64 +	{
    6.65 +		const char *name;
    6.66 +
    6.67 +		/* Find the function name */
    6.68 +		if ((name = find_func_name(data->plugin, offs)) == NULL)
    6.69 +		{
    6.70 +			name = "unknown";
    6.71 +		}
    6.72 +
    6.73 +		//push name
    6.74 +		//push [esi+context] 
    6.75 +		//call ProfCallGate_Begin
    6.76 +		//add esp, 8
    6.77 +		IA32_Push_Imm32(jit, (jit_int32_t)(intptr_t)name);
    6.78 +		IA32_Push_Rm_Disp8(jit, AMX_REG_INFO, AMX_INFO_CONTEXT);
    6.79 +		jmp = IA32_Call_Imm32(jit, 0);
    6.80 +		IA32_Write_Jump32_Abs(jit, jmp, (void *)ProfCallGate_Begin);
    6.81 +		IA32_Add_Rm_Imm8(jit, REG_ESP, 8, MOD_REG);
    6.82 +
    6.83 +		//call <addr>
    6.84 +		//push eax
    6.85 +		jmp = IA32_Call_Imm32(jit, 0);
    6.86 +		IA32_Write_Jump32(jit, jmp, RelocLookup(jit, offs, false));
    6.87 +		IA32_Push_Reg(jit, REG_EAX);
    6.88 +
    6.89 +		//push [esi+context]
    6.90 +		//call ProfCallGate_End
    6.91 +		//add esp, 4
    6.92 +		//pop eax
    6.93 +		IA32_Push_Rm_Disp8(jit, AMX_REG_INFO, AMX_INFO_CONTEXT);
    6.94 +		jmp = IA32_Call_Imm32(jit, 0);
    6.95 +		IA32_Write_Jump32_Abs(jit, jmp, (void *)ProfCallGate_End);
    6.96 +		IA32_Add_Rm_Imm8(jit, REG_ESP, 4, MOD_REG);
    6.97 +		IA32_Pop_Reg(jit, REG_EAX);
    6.98 +	}
    6.99 +	else
   6.100 +	{
   6.101 +		jmp = IA32_Call_Imm32(jit, 0);
   6.102 +		IA32_Write_Jump32(jit, jmp, RelocLookup(jit, offs, false));
   6.103 +	}
   6.104  }
   6.105  
   6.106  inline void WriteOp_Bounds(JitWriter *jit)
   6.107 @@ -1653,9 +1740,25 @@
   6.108  	jitoffs_t call = IA32_Call_Imm32(jit, 0);
   6.109  	if (!data->debug)
   6.110  	{
   6.111 -		IA32_Write_Jump32_Abs(jit, call, (void *)NativeCallback);
   6.112 -	} else {
   6.113 -		IA32_Write_Jump32_Abs(jit, call, (void *)NativeCallback_Debug);
   6.114 +		if ((data->profile & SP_PROF_NATIVES) == SP_PROF_NATIVES)
   6.115 +		{
   6.116 +			IA32_Write_Jump32_Abs(jit, call, (void *)NativeCallback_Profile);
   6.117 +		}
   6.118 +		else
   6.119 +		{
   6.120 +			IA32_Write_Jump32_Abs(jit, call, (void *)NativeCallback);
   6.121 +		}
   6.122 +	}
   6.123 +	else
   6.124 +	{
   6.125 +		if ((data->profile & SP_PROF_NATIVES) == SP_PROF_NATIVES)
   6.126 +		{
   6.127 +			IA32_Write_Jump32_Abs(jit, call, (void *)NativeCallback_Debug_Profile);
   6.128 +		}
   6.129 +		else
   6.130 +		{
   6.131 +			IA32_Write_Jump32_Abs(jit, call, (void *)NativeCallback_Debug);
   6.132 +		}
   6.133  	}
   6.134  	
   6.135  	/* check for errors */
   6.136 @@ -2122,7 +2225,9 @@
   6.137  
   6.138  cell_t NativeCallback(sp_context_t *ctx, ucell_t native_idx, cell_t *params)
   6.139  {
   6.140 -	sp_native_t *native = &ctx->natives[native_idx];
   6.141 +	sp_native_t *native;
   6.142 +	
   6.143 +	native = &ctx->natives[native_idx];
   6.144  
   6.145  	ctx->n_idx = native_idx;
   6.146  	
   6.147 @@ -2136,12 +2241,27 @@
   6.148  	return native->pfn(ctx->context, params);
   6.149  }
   6.150  
   6.151 -static cell_t InvalidNative(IPluginContext *pCtx, const cell_t *params)
   6.152 +cell_t NativeCallback_Profile(sp_context_t *ctx, ucell_t native_idx, cell_t *params)
   6.153  {
   6.154 -	sp_context_t *ctx = pCtx->GetContext();
   6.155 -	ctx->n_err = SP_ERROR_INVALID_NATIVE;
   6.156 -
   6.157 -	return 0;
   6.158 +	cell_t val;
   6.159 +	sp_native_t *native;
   6.160 +
   6.161 +	native = &ctx->natives[native_idx];
   6.162 +
   6.163 +	ctx->n_idx = native_idx;
   6.164 +
   6.165 +	/* Technically both aren't needed, I guess */
   6.166 +	if (native->status == SP_NATIVE_UNBOUND)
   6.167 +	{
   6.168 +		ctx->n_err = SP_ERROR_INVALID_NATIVE;
   6.169 +		return 0;
   6.170 +	}
   6.171 +
   6.172 +	ctx->profiler->OnNativeBegin(ctx->context, native);
   6.173 +	val = native->pfn(ctx->context, params);
   6.174 +	ctx->profiler->OnNativeEnd();
   6.175 +
   6.176 +	return val;
   6.177  }
   6.178  
   6.179  cell_t NativeCallback_Debug(sp_context_t *ctx, ucell_t native_idx, cell_t *params)
   6.180 @@ -2170,7 +2290,7 @@
   6.181  	}
   6.182  
   6.183  	cell_t result = NativeCallback(ctx, native_idx, params);
   6.184 -	
   6.185 +
   6.186  	if (ctx->n_err != SP_ERROR_NONE)
   6.187  	{
   6.188  		return result;
   6.189 @@ -2180,7 +2300,9 @@
   6.190  	{
   6.191  		ctx->n_err = SP_ERROR_STACKLEAK;
   6.192  		return result;
   6.193 -	} else if (save_hp != ctx->hp) {
   6.194 +	}
   6.195 +	else if (save_hp != ctx->hp)
   6.196 +	{
   6.197  		ctx->n_err = SP_ERROR_HEAPLEAK;
   6.198  		return result;
   6.199  	}
   6.200 @@ -2188,6 +2310,60 @@
   6.201  	return result;
   6.202  }
   6.203  
   6.204 +cell_t NativeCallback_Debug_Profile(sp_context_t *ctx, ucell_t native_idx, cell_t *params)
   6.205 +{
   6.206 +	cell_t save_sp = ctx->sp;
   6.207 +	cell_t save_hp = ctx->hp;
   6.208 +
   6.209 +	ctx->n_idx = native_idx;
   6.210 +
   6.211 +	if (ctx->hp < ctx->heap_base)
   6.212 +	{
   6.213 +		ctx->n_err = SP_ERROR_HEAPMIN;
   6.214 +		return 0;
   6.215 +	}
   6.216 +
   6.217 +	if (ctx->hp + STACK_MARGIN > ctx->sp)
   6.218 +	{
   6.219 +		ctx->n_err = SP_ERROR_STACKLOW;
   6.220 +		return 0;
   6.221 +	}
   6.222 +
   6.223 +	if ((uint32_t)ctx->sp >= ctx->mem_size)
   6.224 +	{
   6.225 +		ctx->n_err = SP_ERROR_STACKMIN;
   6.226 +		return 0;
   6.227 +	}
   6.228 +
   6.229 +	cell_t result = NativeCallback_Profile(ctx, native_idx, params);
   6.230 +
   6.231 +	if (ctx->n_err != SP_ERROR_NONE)
   6.232 +	{
   6.233 +		return result;
   6.234 +	}
   6.235 +
   6.236 +	if (save_sp != ctx->sp)
   6.237 +	{
   6.238 +		ctx->n_err = SP_ERROR_STACKLEAK;
   6.239 +		return result;
   6.240 +	}
   6.241 +	else if (save_hp != ctx->hp)
   6.242 +	{
   6.243 +		ctx->n_err = SP_ERROR_HEAPLEAK;
   6.244 +		return result;
   6.245 +	}
   6.246 +
   6.247 +	return result;
   6.248 +}
   6.249 +
   6.250 +static cell_t InvalidNative(IPluginContext *pCtx, const cell_t *params)
   6.251 +{
   6.252 +	sp_context_t *ctx = pCtx->GetContext();
   6.253 +	ctx->n_err = SP_ERROR_INVALID_NATIVE;
   6.254 +
   6.255 +	return 0;
   6.256 +}
   6.257 +
   6.258  jitoffs_t RelocLookup(JitWriter *jit, cell_t pcode_offs, bool relative)
   6.259  {
   6.260  	if (jit->outptr)
   6.261 @@ -2204,7 +2380,9 @@
   6.262  		assert(pcode_offs >= 0 && (uint32_t)pcode_offs <= data->codesize);
   6.263  		/* Do the lookup in the native dictionary. */
   6.264  		return *(jitoffs_t *)(data->rebase + pcode_offs);
   6.265 -	} else {
   6.266 +	}
   6.267 +	else
   6.268 +	{
   6.269  		return 0;
   6.270  	}
   6.271  }
   6.272 @@ -2380,7 +2558,8 @@
   6.273  
   6.274  		/* the total codesize is now known! */
   6.275  		codemem = writer.get_outputpos();
   6.276 -		writer.outbase = (jitcode_t)engine->ExecAlloc(codemem);
   6.277 +		writer.outbase = (jitcode_t)engine->AllocatePageMemory(codemem);
   6.278 +		engine->SetReadWrite(writer.outbase);
   6.279  		writer.outptr = writer.outbase;
   6.280  		/* go back for third pass */
   6.281  		goto jit_rewind;
   6.282 @@ -2398,6 +2577,8 @@
   6.283  		}
   6.284  		/* Write these last because error jumps should be unpredicted, and thus forward */
   6.285  		WriteErrorRoutines(data, jit);
   6.286 +
   6.287 +		engine->SetReadExecute(writer.outbase);
   6.288  	}
   6.289  
   6.290  	/*************
   6.291 @@ -2420,6 +2601,7 @@
   6.292  	ctx->heap_base = plugin->data_size;
   6.293  	ctx->hp = ctx->heap_base;
   6.294  	ctx->sp = ctx->mem_size - sizeof(cell_t);
   6.295 +	ctx->prof_flags = data->profile;
   6.296  
   6.297  	const char *strbase = plugin->info.stringbase;
   6.298  	uint32_t max, iter;
   6.299 @@ -2605,22 +2787,25 @@
   6.300  	if (jw.outbase == NULL)
   6.301  	{
   6.302  		/* Second pass: Actually write */
   6.303 -		jw.outbase = (jitcode_t)engine->ExecAlloc(jw.get_outputpos());
   6.304 +		jw.outbase = (jitcode_t)engine->AllocatePageMemory(jw.get_outputpos());
   6.305  		if (!jw.outbase)
   6.306  		{
   6.307  			return NULL;
   6.308  		}
   6.309 +		engine->SetReadWrite(jw.outbase);
   6.310  		jw.outptr = jw.outbase;
   6.311  	
   6.312  		goto rewind;
   6.313  	}
   6.314 -	
   6.315 +
   6.316 +	engine->SetReadExecute(jw.outbase);
   6.317 +
   6.318  	return (SPVM_NATIVE_FUNC)jw.outbase;
   6.319  }
   6.320  
   6.321  void JITX86::DestroyFakeNative(SPVM_NATIVE_FUNC func)
   6.322  {
   6.323 -	engine->ExecFree((void *)func);
   6.324 +	engine->FreePageMemory((void *)func);
   6.325  }
   6.326  
   6.327  const char *JITX86::GetVMName()
   6.328 @@ -2637,7 +2822,7 @@
   6.329  
   6.330  void JITX86::FreeContext(sp_context_t *ctx)
   6.331  {
   6.332 -	engine->ExecFree(ctx->codebase);
   6.333 +	engine->FreePageMemory(ctx->codebase);
   6.334  	delete [] ctx->memory;
   6.335  	delete [] ctx->files;
   6.336  	delete [] ctx->lines;
   6.337 @@ -2720,7 +2905,7 @@
   6.338  {
   6.339  	CompData *data = (CompData *)co;
   6.340  
   6.341 -	if (strcmp(key, "debug") == 0)
   6.342 +	if (strcmp(key, SP_JITCONF_DEBUG) == 0)
   6.343  	{
   6.344  		if ((atoi(val) == 1) || !strcmp(val, "yes"))
   6.345  		{
   6.346 @@ -2735,6 +2920,18 @@
   6.347  		}
   6.348  		return true;
   6.349  	}
   6.350 +	else if (strcmp(key, SP_JITCONF_PROFILE) == 0)
   6.351 +	{
   6.352 +		data->profile = atoi(val);
   6.353 +
   6.354 +		/** Callbacks must be profiled to profile functions! */
   6.355 +		if ((data->profile & SP_PROF_FUNCTIONS) == SP_PROF_FUNCTIONS)
   6.356 +		{
   6.357 +			data->profile |= SP_PROF_CALLBACKS;
   6.358 +		}
   6.359 +
   6.360 +		return true;
   6.361 +	}
   6.362  
   6.363  	return false;
   6.364  }
     7.1 --- a/sourcepawn/jit/x86/jit_x86.h	Tue Mar 04 23:18:16 2008 +0000
     7.2 +++ b/sourcepawn/jit/x86/jit_x86.h	Thu Mar 13 17:04:25 2008 +0000
     7.3 @@ -67,13 +67,14 @@
     7.4  {
     7.5  public:
     7.6  	CompData() : plugin(NULL), 
     7.7 -		debug(false), inline_level(0), rebase(NULL),
     7.8 +		debug(false), profile(0), inline_level(0), rebase(NULL),
     7.9  		error_set(SP_ERROR_NONE), func_idx(0)
    7.10  	{
    7.11  	};
    7.12  public:
    7.13  	sp_plugin_t *plugin;			/* plugin handle */
    7.14  	bool debug;						/* whether to compile debug mode */
    7.15 +	int profile;					/* profiling flags */
    7.16  	int inline_level;				/* inline optimization level */
    7.17  	jitcode_t rebase;				/* relocation map */
    7.18  	int error_set;					/* error code to halt process */
    7.19 @@ -121,6 +122,8 @@
    7.20  
    7.21  cell_t NativeCallback(sp_context_t *ctx, ucell_t native_idx, cell_t *params);
    7.22  cell_t NativeCallback_Debug(sp_context_t *ctx, ucell_t native_idx, cell_t *params);
    7.23 +cell_t NativeCallback_Debug_Profile(sp_context_t *ctx, ucell_t native_idx, cell_t *params);
    7.24 +cell_t NativeCallback_Profile(sp_context_t *ctx, ucell_t native_idx, cell_t *params);
    7.25  jitoffs_t RelocLookup(JitWriter *jit, cell_t pcode_offs, bool relative=false);
    7.26  
    7.27  #define AMX_REG_PRI		REG_EAX