我们从前一阵子 Maui 几个被离职的Mono 工具链相关的微软员工来说起,通过现象看本质,这意味着.NET 10 将完成对Mono的完全替代。.NET 10 特性中有一个 @dotnet/runtime/issues/112158 CoreCLR Interpreter, 将 Mono 的解释器(interpreter)移植到 CoreCLR 的工作进展和目标。Mono 是 .NET 项目的一个实现,历史上以其解释器模式和嵌入式支持而闻名。将其解释器移植到 CoreCLR 的目标是为 CoreCLR 提供完整的解释器支持,包括运行测试套件和支持无 JIT/AOT(Just-In-Time 编译/提前编译)模式的全解释器模式。

我们来综合回顾一下Mono Interpreter,结合其历史背景、工作原理、应用场景:

一、Mono 解释器的历史与演进

  1. 起源与早期阶段:Mono 项目始于 2001 年,最初为实现跨平台 .NET 环境,开发团队为 .NET 指令集编写了一个解释器(mint),用于在 Linux 上引导自托管的 .NET 开发环境。此时解释器被视为构建 JIT 编译器的临时工具。随着泛型功能的加入,同时维护解释器和 JIT 引擎的成本剧增,最终解释器被移除。

  2. 重新引入与现代化:2017 年,Mono 团队重新引入解释器,并升级其对 .NET 的支持,包括泛型和最新 .NET 版本。这一版本的解释器通过混合模式执行(结合静态编译和解释执行)解决了全静态编译(AOT)的局限性。

二、Mono 解释器的工作原理

  1. 核心机制

    • 解释执行 CIL 代码:Mono 解释器直接解释 .NET 中间语言(CIL),无需预编译或即时编译(JIT),逐行解析并执行代码。
    • 混合模式执行:允许解释代码与静态编译(AOT)或 JIT 编译的代码协同工作。例如,核心库可静态编译优化,动态代码则通过解释器执行。
  2. 动态能力增强

    • 支持反射与动态代码生成:通过解释器实现 System.Reflection.Emit,使得在静态编译环境中也能动态生成代码(如 Entity Framework 的表达式树解析)。
    • 轻量级执行:解释器对性能不敏感的代码(如静态构造函数)执行效率更高,减少内存占用和代码生成开销。

三、应用场景与优势

  1. 跨平台与受限环境

    • iOS、游戏主机等平台:这些平台禁止动态代码生成(如 JIT),解释器通过混合模式支持动态加载代码,无需重新编译整个应用。
    • WebAssembly 支持:解释器是 Mono 在 WebAssembly 上运行的两种方式之一(另一种为 LLVM 静态编译)。
  2. 开发效率提升

    • 热加载与快速迭代:游戏开发者可实时调整代码逻辑,无需触发全量编译,显著缩短调试周期。
    • 教学与原型设计:解释器支持动态执行,适合快速验证算法或教学演示。
  3. 兼容性与扩展性

    • 脚本语言支持:IronPython、IronRuby 等脚本语言可在静态编译环境中运行,扩展 .NET 的脚本化能力

四、与其他执行模式的对比

执行模式 特点 适合场景
JIT编译 运行时动态编译为机器码,执行效率高,但占用内存较多。 高性能计算、常规应用开发
NativeAOT 预编译为机器码,启动快,但缺乏动态性,需全量重新编译。 iOS、游戏主机等受限平台
Mono Interpreter 逐行解释执行,灵活性高,支持动态代码,但运行时效率较低。 动态调试、热加载、教学场景
混合模式 结合 AOT 与解释器,核心代码静态优化,动态部分解释执行。 需要平衡性能与灵活性的复杂应用

五、CoreCLR Interpreter 与 Mono Interpreter

Mono Interpreter 通过灵活的执行模式弥补了 JIT 和 AOT 的不足,特别适用于动态代码需求强烈的场景(如游戏开发、教学工具)。其混合模式执行和跨平台能力使其成为 .NET 生态中不可或缺的组件。在.NET的统一运行时计划旨在合并不同运行时(比如Mono和CoreCLR),以提供更一致的开发体验和更高效的运行时性能。CoreCLR Interpreter是基于Mono Interpreter的实现,为了在CoreCLR中提供支持解释执行的能力。其目标包括:

  • 在不使用JIT或AOT的情况下运行代码。
  • 支持动态场景,例如运行时生成的代码。
  • 提供跨平台支持,包括桌面和嵌入式平台。

CoreCLR Interpreter 与Mono Interpreter的区别

1. 架构差异:

◦ Mono Interpreter是为嵌入式设备和低资源环境设计的,强调轻量级和灵活性。

◦ CoreCLR Interpreter更关注与CoreCLR其他组件(如GC和JIT编译器)的集成。

2. 功能覆盖:

◦ CoreCLR Interpreter已经移植了Mono Interpreter的大部分功能,并针对CoreCLR进行了优化。

◦ Mono特有的一些功能(如特定平台优化)可能未完全移植。

3. 性能改进:

◦ CoreCLR Interpreter专注于与CoreCLR的深度集成,在性能上可能优于Mono Interpreter。

六、CoreCLR Interpreter 最新进展

虽然CoreCLR Interpreter在目标和功能上已经能够替代Mono Interpreter,但在某些特定场景下,Mono Interpreter可能仍然使用(例如,为了支持遗留的Mono项目或特定的嵌入式环境)。CoreCLR Interpreter在功能和性能上已经覆盖了Mono Interpreter的绝大部分使用场景,但在某些遗留或特定需求下,Mono Interpreter可能仍然有其作用。

CoreCLR Interpreter的进展与任务拆解

@dotnet/runtime/issues/112158 CoreCLR Interpreter 任务被分成多个阶段(M1-M6),每个阶段完成了一系列具体的功能,以下是对关键任务的拆解和分析:

M1:基础功能

  • 完成情况: 基础解释器编译和简单方法执行已经实现。
  • 关键功能:
    • 解释器集成(Interp wire-in)。
    • libcoreclr 中实现解释器执行器。
    • 基础的解释器运行时测试。
  • 意义: 奠定了解释器框架的基础,使开发者能够在 CoreCLR 上运行基本的解释器代码。

M2:对象操作的压力测试

  • 已完成的功能:
    • 常量加载和算术操作。
    • 局部变量和参数加载。
    • 静态方法调用、变量偏移量分配器和分支操作码。
    • newobj 创建、字段访问、间接加载/存储操作码。
    • 精确 GC 扫描和 safepoint。
    • 值类型(ValueType)支持,包括字段、构造函数及局部变量支持。
  • 待完成:
    • 基础泛型支持。
  • 意义: 确保了解释器可以处理复杂的对象操作和垃圾回收场景。

M3:异常处理和解释器调用

  • 已完成的功能:
    • 支持虚方法和接口方法调用。
    • 可直接调用非解释器代码。
  • 待完成:
    • 异常路径支持(try/finally/leave)。
    • 异常抛出和恢复至正确处理程序。
    • 从异常处理(EH)中调用finallyfilter子句。
    • 空检查和算术溢出操作码。
  • 意义: 使解释器能够处理异常和调用场景,这对于运行复杂测试套件至关重要。

M4:与编译代码混合

  • 待完成的功能:
    • 区分解释器/JIT/R2R(Ready-to-Run)代码以便于测试。
    • 支持 callildftn,目标方法可能是解释器或 JIT。
    • 委托创建和调用,包括混合解释器和 JIT 的场景。
  • 意义: 支持解释器代码与 JIT 编译代码之间的无缝协作。

M5:P/Invoke 支持和完整解释器支持

  • 待完成的功能:
    • 实现 P/Invoke 支持和反向 P/Invoke 支持。
    • 支持 Console.WriteLine("Hello World") 在全解释器模式中运行。
  • 意义: 通过支持 P/Invoke 以及其他系统调用,进一步增强解释器的功能,使其能够运行更复杂的程序。

M6:CoreCLR 启动所需的 IL 操作码

  • 已完成的功能:
    • ldtokenbox/unboxsizeofldobj/stobjlocalloc
  • 待完成的功能:
    • 数组操作(ldlennewarrstelem 等)。
    • 类型转换(isinstcastclass)。
    • 其他操作码(如 cpblkinitblktailcall 等)。
  • 意义: 支持 CoreCLR 启动所需的关键 IL 操作码,最终目标是通过解释器运行完整的 .NET 程序。

Nice-to-Have 改进

虽然不在当前项目范围内,但一些改进建议可以提升解释器性能和可维护性,例如:

  • 移除 StackType 使用,仅依赖 InterpType
  • 优化重导入逻辑,使用类似于 RyuJIT 的图结构方法。

七、CoreCLR Interpreter 与 NativeAOT 协作

CoreCLR Interpreter 和 NativeAOT 的目标场景有所区别,但在以下场景中存在潜在的协作可能性:

  1. 调试与诊断:在 NativeAOT 环境中,可以使用解释器模式调试代码,无需重新生成本机代码。
  2. 功能补充:NativeAOT 本质上是静态编译模式,而解释器模式可以作为动态场景下的补充,处理无法静态编译的动态代码。
  3. 混合运行:如果 CoreCLR Interpreter 和 NativeAOT 都支持调用边界的混合运行,则可以结合两者的优点,在性能和灵活性之间找到平衡。

总结

.NET统一运行时从Mono到CoreCLR的迁移是一个渐进过程,目标是通过整合运行时技术(如AOT和解释器)来提升性能和一致性。CoreCLR Interpreter 的开发是 .NET 平台的重要里程碑,旨在通过完整的解释器支持扩展 CoreCLR 的应用场景,包括资源受限的环境和动态代码运行需求。

.NET 10 进展之 CoreCLR Interpreter的更多相关文章

  1. PHPSTORM 10.0.3 --PHP Interpreter is not configured

    PHP Interpreter is not configured Please configure PHP Interpreter to use built-in weberver

  2. Mac OS 10.12 - 解决“bad interpreter: No such file or directory”问题!

    在Mac OS10.12里面执行shell脚本时候,无法执行,错误提示:“bad interpreter: No such file or directory”,经过上网搜索,最终解决了,解决方法,首 ...

  3. [GeekBand] 面向对象的设计模式(C++)(2)

    本篇笔记紧接上篇,继续学习设计模式. 4. 对象创建类设计模式 通过对象创建模式绕开new,来避免对象创建(new)过程中所导致的紧耦合,从而支持对象创建的稳定.它是接口抽象之后的第一步工作. 4.1 ...

  4. php.exe

    PhpStorm 10.0.2 php  interpreter  填入php.exe 暂且不用填写 Listen 63342

  5. js oc与线程

    分属不同的线程 //定义需要暴露给js的内容,这里我们只暴露personName和queryPersonName接口 @protocol PersonProtocol <JSExport> ...

  6. oc js 调用 函数调用栈

    //定义需要暴露给js的内容,这里我们只暴露personName和queryPersonName接口 @protocol PersonProtocol <JSExport> @proper ...

  7. iOS js 使用与JSContext

    JSContext:js执行环境,包含了js执行时所需要的所有函数和对象: js执行时,会在执行环境搜索需要的函数然后执行,或者保存传入的变量或函数: JSContext *jsContext = [ ...

  8. 推荐:一个适合于Python新手的入门练手项目

    随着人工智能的兴起,国内掀起了一股Python学习热潮,入门级编程语言,大多选择Python,有经验的程序员,也开始学习Python,正所谓是人生苦短,我用Python 有个Python入门练手项目, ...

  9. 记一次 .NET 某物管后台服务 卡死分析

    一:背景 1. 讲故事 这几个月经常被朋友问,为什么不更新这个系列了,哈哈,确实停了好久,主要还是打基础去了,分析 dump 的能力不在于会灵活使用 windbg,而是对底层知识有一个深厚的理解,比如 ...

  10. 记一次 .NET 某智慧物流 WCS系统 CPU 爆高分析

    一:背景 1. 讲故事 哈哈,再次见到物流类软件,上个月有位朋友找到我,说他的程序出现了 CPU 爆高,让我帮忙看下什么原因,由于那段时间在苦心研究 C++,分析和经验分享也就懈怠了,今天就给大家安排 ...

随机推荐

  1. Week09_day05(Hbase的安装搭建)

    搭建完全分布式集群 HBase集群建立在hadoop集群基础之上,所以在搭建HBase集群之前需要把Hadoop集群搭建起来,并且要考虑二者的兼容性.现在就以5台机器为例,搭建一个简单的集群. 软件版 ...

  2. Windows上安装MySQL详细教程

    1.MySQL简介 MySQL是最流行的关系型数据库管理系统,在WEB应用方面MySQL是最好的RDBMS(Relational Database Management System:关系数据库管理系 ...

  3. SpringBoot三种获取Request和Response的方法

    通过静态方法获取,你也可以封装一个静态方法出来 @GetMapping(value = "") public String center() { ServletRequestAtt ...

  4. burpsuite激活

    激活burpsuite--教程 点击Start 文件,把三个框都选上 点击RUN,会自动启动,复制一下那个证书 粘贴刚刚复制的密钥,点击下一个即可 这里点击手动激活,复制请求,粘贴到刚刚那个激活程序的 ...

  5. 深入理解C++ 空类大小

    在C++中,规定空类(即类中没有任何数据成员.成员函数.虚函数等成员的类)的大小为1字节,这背后主要有以下几方面的原因: 保证对象的唯一性和可区分性 在C++的面向对象编程模型中,对象是类的实例化结果 ...

  6. Windows编程----进程的当前目录

    进程的当前目录 Windows  Api中有大量的函数在调用的时候,需要传递路径.比如创建文件,创建目录,删除目录,删除文件等等.创建文件的APICreateFile做比喻,如果我们要创建的文件路径不 ...

  7. 设备管理笔记1-oee

    什么是oee 类似于一种设备管理模型,如软件行业的质量模型.cmmi模型等 指标包括什么? 正常指标应该是多少,目前我们的指标为多少? 制造行业存在的6大问题分别是什么 指标包括什么? 包括 可用性性 ...

  8. CNVD挖掘思路

    CNVD挖掘思路 CNVD获取条件 首先,先来了解一下目前cnvd发证资格 1.事件型 事件型漏洞必须是三大运营商(移动.联通.电信)的中高危漏洞,或者党政机关.重要行业单位.科研院所.重要企事业单位 ...

  9. yolov5 train报错:TypeError: expected np.ndarray (got numpy.ndarray)

    前言 mac intel 机器上,使用 yolov5 物体检测训练时报错:TypeError: expected np.ndarray (got numpy.ndarray) 这个错误信息 TypeE ...

  10. 朱朝兵《Web前端开发之HTML5+CSS3快速入门》课程资料在线学习

    <Web前端开发之HTML5+CSS3快速入门> [课程简介]本课程由一直专注前端技术与Discuz模板设计与制作!DZ起点网创始人朱朝兵出品,通过本课程学习,即可掌握html5的基本结构 ...