• .net7的 nativeaot基本原理


    以helloworld为例,核心代码:

    Console.WriteLine("hello world");

    通过被csc编译过后,得到可执行文件或者dll,比如名为app.exe,ilc将app.exe和托管System核心库作为输入,调用JIT编译器

    将ILcode变为机器码,比如ILcode:

    helloworld字符串入栈;

    调用 System库下Method方法中下标是0x11223344的函数;

    被转换成机器码:

    push "hell world"

    Call System::Console

    就完事了。

    然后形成.o文件,通过LINK可以直接和其他.o链接成exe/ELF/DLL.


     

    还有个特殊点,在BCL库中,只用了C# 的基本语法,相当于只用了C#子集,可以这么理解,把C#当作C语言用了。

    BCL里面用了new 这个关键字,我们知道在CPP里面,是可以重定位new 函数的,比如

    void *operator new(size_t size)

    {

        void *p = pvPortMalloc(size);//你自己的内存分配函数接口,这里用的是FreeRTOS的函数接口

        memset(p, 0, size);

        return p;

    }

    这样就完成了new的重定位。因此我想这可能有类似的写法:

    [MethodImpl(MethodImplOptions.InternalCall)]

    [RuntimeImport(RuntimeLibrary, "RhpNew")]

    private static extern IntPtr RhpNew(函数参数);

    unsafe  Intptr operator new(函数参数)

    {

        巴拉巴拉;

        return RhpNew(........);

    }

    但是我翻遍了runtime和BCL库都没有这个函数的重定位,百思不得其解:如果不是在runtime/BCL里,那就是在编译时

    用了函数替换,把new IL code替换成相应的函数了,果不其然,在ILC编译器源码里,有如下代码:

     if (opcode == ILOpcode.newobj)

     {

        巴拉巴拉;

        _dependencies.Add(GetHelperEntrypoint(ReadyToRunHelper.NewObject), reason);

     }

     ....

     巴拉巴拉;

     case ReadyToRunHelper.NewObject:

    mangledName = "RhNewObject";

    break;

    然后在BCL库里就找到了RhNewObject:

    [RuntimeExport("RhNewObject")]

    public static unsafe object RhNewObject(MethodTable* pEEType)

    {

        巴拉巴拉;

        return InternalCalls.RhpNewFast(pEEType);

    }

    这个RhpNewFast函数Runtime CPP文件里面实现的

    从此完成了new的操作。

    总结一下,调用new,相当于调用RhNewObject/RhNewArray函数(不同场景下的new有不同的函数替换)

    就是函数替换魔法!读取il,然后完成函数替换.


     

    PS:

    我觉得MichalStrehovsky他这个人很牛逼,他的zerosharp C#写的8KB程序可以运行在DOS下

    有没有发现BCL库都是用C#写的,包括非常底层的new和反射,都是C#写的

    在编译器做了魔法处理,所以我觉得他的目标远不止这些,我认为后期,极有可能在C#层面完成一个VM+JIT+GC,

    也就是说使用C#的子集开发一个VM+JIT+GC,

    最底层CPP只提供最基本的函数接口,比如:CreateThread Open Write这就是一个完整的CLR.

    那到时候coreCLR就可以退出历史舞台了

  • 相关阅读:
    025: vue父子组件中传递方法控制:$emit,$refs,$parent,$children
    【网站架构】cpu、内存、带宽是否足够?负载分析,linux内核调优】
    数据库基础篇一
    ensp配置浏览器访问USG6000V1防火墙
    JVM学习-JMM
    完美解决Android adb install 安装提示 INSTALL_FAILED_TEST_ONLY
    粉丝推荐的 GitHub 项目 yyds
    【js】单文件上传和大文件分片上传功能实现
    grpc、https、oauth2等认证专栏实战10:oauth2认证方式介绍
    Java常量池
  • 原文地址:https://blog.csdn.net/snikeguo/article/details/126461313