Jump to content
  • Advertisement
Sign in to follow this  
Jason Goepel

JIT Compiler Suspend / BlindMindStudios

This topic is 835 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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
Advertisement

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
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!