private DynarecFunction _GenerateForPC(uint PC)
{
var Memory = CpuProcessor.Memory;
if (_DynarecConfig.DebugFunctionCreation)
{
Console.Write("PC=0x{0:X8}...", PC);
}
//var Stopwatch = new Logger.Stopwatch();
var Time0 = DateTime.UtcNow;
var DynarecFunction = CpuProcessor.DynarecFunctionCompiler.CreateFunction(new InstructionStreamReader(new PspMemoryStream(Memory)), PC);
if (DynarecFunction.EntryPC != PC) throw (new Exception("Unexpected error"));
if (_DynarecConfig.AllowCreatingUsedFunctionsInBackground)
{
foreach (var CallingPC in DynarecFunction.CallingPCs)
{
if (PspMemory.IsAddressValid(CallingPC))
{
AddPCLater(CallingPC);
}
}
}
var Time1 = DateTime.UtcNow;
if (_DynarecConfig.ImmediateLinking)
{
try
{
if (Platform.IsMono) Marshal.Prelink(DynarecFunction.Delegate.Method);
DynarecFunction.Delegate(null);
}
catch (InvalidProgramException InvalidProgramException)
{
Console.Error.WriteLine("Invalid delegate:");
Console.Error.WriteLine(DynarecFunction.AstNode.ToCSharpString());
Console.Error.WriteLine(DynarecFunction.AstNode.ToILString<Action<CpuThreadState>>());
throw (InvalidProgramException);
}
}
var Time2 = DateTime.UtcNow;
DynarecFunction.TimeLinking = Time2 - Time1;
var TimeAstGeneration = Time1 - Time0;
if (_DynarecConfig.DebugFunctionCreation)
{
ConsoleUtils.SaveRestoreConsoleColor(((TimeAstGeneration + DynarecFunction.TimeLinking).TotalMilliseconds > 10) ? ConsoleColor.Red : ConsoleColor.Gray, () =>
{
Console.WriteLine(
"({0}): (analyze: {1}, generateAST: {2}, optimize: {3}, generateIL: {4}, createDelegate: {5}, link: {6}): ({1}, {2}, {3}, {4}, {5}, {6}) : {7} ms",
(DynarecFunction.MaxPC - DynarecFunction.MinPC) / 4,
(int)DynarecFunction.TimeAnalyzeBranches.TotalMilliseconds,
(int)DynarecFunction.TimeGenerateAst.TotalMilliseconds,
(int)DynarecFunction.TimeOptimize.TotalMilliseconds,
(int)DynarecFunction.TimeGenerateIL.TotalMilliseconds,
(int)DynarecFunction.TimeCreateDelegate.TotalMilliseconds,
(int)DynarecFunction.TimeLinking.TotalMilliseconds,
(int)(TimeAstGeneration + DynarecFunction.TimeLinking).TotalMilliseconds
);
});
}
//DynarecFunction.AstNode = DynarecFunction.AstNode.Optimize(CpuProcessor);
#if DEBUG_FUNCTION_CREATION
CpuProcessor.DebugFunctionCreation = true;
#endif
//if (CpuProcessor.DebugFunctionCreation)
//{
// Console.WriteLine("-------------------------------------");
// Console.WriteLine("Created function for PC=0x{0:X8}", PC);
// Console.WriteLine("-------------------------------------");
// CpuThreadState.DumpRegistersCpu(Console.Out);
// Console.WriteLine("-------------------------------------");
// Console.WriteLine(DynarecFunction.AstNode.ToCSharpString());
// Console.WriteLine("-------------------------------------");
//}
return DynarecFunction;
}