| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104 |
- using ChocolArm64.Memory;
- using ChocolArm64.State;
- using System;
- using System.Reflection;
- using System.Reflection.Emit;
- namespace ChocolArm64.Translation
- {
- delegate long ArmSubroutine(CpuThreadState state, MemoryManager memory);
- class TranslatedSub
- {
- //This is the minimum amount of calls needed for the method
- //to be retranslated with higher quality code. It's only worth
- //doing that for hot code.
- private const int MinCallCountForOpt = 30;
- public ArmSubroutine Delegate { get; private set; }
- public static int StateArgIdx { get; }
- public static int MemoryArgIdx { get; }
- public static Type[] FixedArgTypes { get; }
- public DynamicMethod Method { get; }
- public TranslationTier Tier { get; }
- public long IntNiRegsMask { get; }
- public long VecNiRegsMask { get; }
- private bool _isWorthOptimizing;
- private int _callCount;
- public TranslatedSub(
- DynamicMethod method,
- long intNiRegsMask,
- long vecNiRegsMask,
- TranslationTier tier,
- bool isWorthOptimizing)
- {
- Method = method ?? throw new ArgumentNullException(nameof(method));;
- IntNiRegsMask = intNiRegsMask;
- VecNiRegsMask = vecNiRegsMask;
- _isWorthOptimizing = isWorthOptimizing;
- Tier = tier;
- }
- static TranslatedSub()
- {
- MethodInfo mthdInfo = typeof(ArmSubroutine).GetMethod("Invoke");
- ParameterInfo[] Params = mthdInfo.GetParameters();
- FixedArgTypes = new Type[Params.Length];
- for (int index = 0; index < Params.Length; index++)
- {
- Type argType = Params[index].ParameterType;
- FixedArgTypes[index] = argType;
- if (argType == typeof(CpuThreadState))
- {
- StateArgIdx = index;
- }
- else if (argType == typeof(MemoryManager))
- {
- MemoryArgIdx = index;
- }
- }
- }
- public void PrepareMethod()
- {
- Delegate = (ArmSubroutine)Method.CreateDelegate(typeof(ArmSubroutine));
- }
- public long Execute(CpuThreadState threadState, MemoryManager memory)
- {
- return Delegate(threadState, memory);
- }
- public bool IsWorthOptimizing()
- {
- if (!_isWorthOptimizing)
- {
- return false;
- }
- if (_callCount++ < MinCallCountForOpt)
- {
- return false;
- }
- //Only return true once, so that it is
- //added to the queue only once.
- _isWorthOptimizing = false;
- return true;
- }
- }
- }
|