Sign in to follow this  
Jason Goepel

JIT Compiler Suspend / BlindMindStudios

Recommended Posts

When using the BlindMindStudio JIT compiler, functions that suspect the active context are called twice.  The first time within a JIT block, the second from the AngelScript VM, and with the stack not properly set up for the call.

 

I suspect this issue is a bug in BlindMindStudio's JIT compiler rather than in AngelScript, but I don't know quite enough yet to be sure.

 

When a context is suspended from a function called with a JIT block, it appears that the program pointer doesn't properly advance to the "next line."  The VM advances from the asBC_JitEntry instruction to the asBC_CALLSYS instruction.  If I remove the call to asIScriptContext::Suspend, then the VM doesn't ever process the asBC_CALLSYS instruction.

 

I have included an example below that demonstrates the problem.

#include <iostream>
#include "angelscript.h"
#include "as_jit.h"
using namespace std;

void Yield(int arg)
{
	cout << "Performing Yield... arg = " << arg << endl;
	asGetActiveContext()->Suspend();
}

int main(int argc, char* argv[])
{
	asIScriptEngine* engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
	asCJITCompiler* jit = new asCJITCompiler(0);
	engine->SetEngineProperty(asEP_INCLUDE_JIT_INSTRUCTIONS, 1);
	engine->SetJITCompiler(jit);

	int r;
	r = engine->RegisterGlobalFunction("void Yield(int)", asFUNCTION(Yield), asCALL_CDECL);
	asIScriptModule* mod = engine->GetModule("module", asGM_ALWAYS_CREATE);

	const char* sz_code = "int main() { Yield(5); return 0; }";

	mod->AddScriptSection("main", sz_code);
	r = mod->Build();

	asIScriptContext* ctx = engine->CreateContext();
	asIScriptFunction* func = mod->GetFunctionByName("main");
	ctx->Prepare(func);
	do
	{
		r = ctx->Execute();
	} while (r == asEXECUTION_SUSPENDED);

	int return_value = ctx->GetReturnDWord();
	ctx->Release();

	engine->Release();
	delete jit;
	return return_value;
}

Share this post


Link to post
Share on other sites

Thanks for the detailed report and the reproduction case. It was indeed returning control to the VM at the wrong instruction (before the call instead of after) when suspending.

 

I've pushed a fix into the jit repository. It passes the test case you posted, tell me if you see any other problems with suspending contexts.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this