XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFESystem

【Rust】XFE系统,基于Rust和汇编

公开
关注 0 Fork 0 Star 0
UTF-8
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// Exercises the Microsoft NativeAOT runtime contracts that the bare-metal PAL
// must support. Compilation alone is never a guest runtime verification.
internal static class Program
{
    [DllImport("xfe_pal", EntryPoint = "xfe_runtime_probe_report")]
    private static extern void Report(int stage, long value);

    private sealed class Root(int value) { internal int Value = value; }
    private sealed class DependentValue(object owner)
    {
        internal object Owner = owner;
        ~DependentValue() => Interlocked.Increment(ref finalized);
    }
    [ThreadStatic] private static int threadToken;
    private static readonly object Gate = new();
    private static int finalized, stopWorker, iterations, workerResult, zeroDivisor;
    private static bool workerReady;

    private static int Main()
    {
        var table = new ConditionalWeakTable<object, Root>();
        var key = new object();
        table.Add(key, new Root(42));
        byte[] bytes = new byte[32768]; bytes[^1] = 211;
        threadToken = 7;
        GC.Collect();
        if (table.GetValue(key, _ => new Root(-1)).Value != 42 || bytes[^1] != 211 || threadToken != 7)
            return 1;
        Report(1, GC.GetTotalMemory(false));
        int exceptionMask = 0;
        try
        {
            try { Throw(); }
            catch (InvalidOperationException) { exceptionMask |= 1; }
            try { _ = ReadNull(null); }
            catch (NullReferenceException) { exceptionMask |= 2; }
            try { _ = Divide(70, Volatile.Read(ref zeroDivisor)); }
            catch (DivideByZeroException) { exceptionMask |= 4; }
            try { _ = Divide(int.MinValue, Volatile.Read(ref zeroDivisor) - 1); }
            catch (OverflowException) { exceptionMask |= 8; }
            try { _ = DivideLong(long.MinValue, Volatile.Read(ref zeroDivisor) - 1); }
            catch (OverflowException) { exceptionMask |= 16; }
        }
        finally { Report(2, exceptionMask == 31 ? 1 : 0); }
        if (exceptionMask != 31) return 2;

        var cycleTable = new ConditionalWeakTable<object, DependentValue>();
        CreateUnrootedCycle(cycleTable, out WeakReference weakKey, out WeakReference weakValue);
        for (int i = 0; i < 4; i++) { GC.Collect(); GC.WaitForPendingFinalizers(); }
        if (weakKey.IsAlive || weakValue.IsAlive || Volatile.Read(ref finalized) != 1) return 3;
        GC.KeepAlive(cycleTable);
        Report(3, 1);

        var worker = new Thread(Worker);
        worker.Start();
        lock (Gate)
            while (!workerReady)
                if (!Monitor.Wait(Gate, 5000)) return 4;
        if (Volatile.Read(ref workerResult) != 0) return 4;
        Report(4, 1);
        for (int i = 0; i < 8; i++)
        {
            _ = new byte[64 * 1024];
            GC.Collect(2, GCCollectionMode.Forced, blocking: true, compacting: true);
            if (Volatile.Read(ref workerResult) != 0 || bytes[^1] != 211 || table.GetValue(key, _ => new Root(-1)).Value != 42)
                return 5;
            Thread.Yield();
        }
        if (Volatile.Read(ref iterations) < 8 || threadToken != 7) return 5;
        Report(5, 1);
        Volatile.Write(ref stopWorker, 1);
        if (!worker.Join(5000) || Volatile.Read(ref workerResult) != 1 || threadToken != 7) return 6;
        Report(6, 1);
        GC.KeepAlive(key);
        GC.KeepAlive(bytes);
        return 0;
    }

    [MethodImpl(MethodImplOptions.NoInlining)]
    private static void Throw() => throw new InvalidOperationException("NativeAOT EH probe");
    [MethodImpl(MethodImplOptions.NoInlining)]
    private static int ReadNull(Root? value) => value!.Value;
    [MethodImpl(MethodImplOptions.NoInlining)]
    private static int Divide(int numerator, int denominator) => numerator / denominator;
    [MethodImpl(MethodImplOptions.NoInlining)]
    private static long DivideLong(long numerator, long denominator) => numerator / denominator;
    [MethodImpl(MethodImplOptions.NoInlining)]
    private static void CreateUnrootedCycle(ConditionalWeakTable<object, DependentValue> table, out WeakReference keyReference, out WeakReference valueReference)
    {
        var key = new object(); var value = new DependentValue(key);
        table.Add(key, value); keyReference = new WeakReference(key); valueReference = new WeakReference(value);
    }
    [MethodImpl(MethodImplOptions.NoInlining)]
    private static void Worker()
    {
        try
        {
            threadToken = 91;
            var root = new Root(91);
            var retained = new byte[65536]; retained[0] = 17; retained[^1] = 193;
            lock (Gate) { workerReady = true; Monitor.PulseAll(Gate); }
            while (Volatile.Read(ref stopWorker) == 0)
            {
                var allocation = new byte[4096]; allocation[^1] = 113;
                if (root.Value != 91 || retained[0] != 17 || retained[^1] != 193 || allocation[^1] != 113 || threadToken != 91)
                { Volatile.Write(ref workerResult, -1); return; }
                Interlocked.Increment(ref iterations);
                Thread.SpinWait(64);
            }
            try { Throw(); }
            catch (InvalidOperationException) { Volatile.Write(ref workerResult, 1); }
            GC.KeepAlive(root); GC.KeepAlive(retained);
        }
        catch (Exception) { Volatile.Write(ref workerResult, -2); }
        finally { if (threadToken != 91) Volatile.Write(ref workerResult, -3); }
    }
}