技术探讨之请教方舟编译器的十个问题

方舟编译器迈出开源第一步,引发技术社区热烈讨论。本书作者针对方舟编译器提出八大技术疑问,涉及语言特性支持、编译器架构、性能优化、调试兼容性等方面,期待方舟编译器团队解答。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

缘起

华为的方舟编译器终于走出开源的第一步,官方地址为https://www.openarkcompiler.cn/home 。我个人于今年4月在机械工业出版社出版了“深入理解Android”系列书籍的最后一本书——《深入理解Android Java虚拟机ART》一书。

640?wx_fmt=jpeg

这本书围绕Android系统中Java虚拟机ART做了详尽的源码分析。其中,第六章更是以全书最多的篇幅从字节码到机器码的编译过程进行了详细介绍。

640?wx_fmt=jpeg

写书时,我一直耿耿于怀国内在计算机基础核心技术上缺乏领军公司的投入之时,没想到今年华为先送出方舟编译器,紧接其后是鸿蒙OS。未来不敢说结局怎样,但现时真切让我和我周围的小伙伴看到了希望。就算激起无论是正面还是负面的全民大讨论,我觉得相比无人问津也算是大大的进步。

言归正传,结合方舟的官网,我其实有几个技术问题想请教。当然,随着方舟进一步扩大和深度开源,这些问题可能也就不言自明。到时候感兴趣的读者不妨以这里提到的问题来看看方舟是如何巧妙解决它们的。

问题一

https://www.openarkcompiler.cn/document/FAQ Q2说“当前部分Java语言特性和JVM虚拟机特性的支持未包括在本次开源代码中,包括:annotation、lambda表达式、泛型等”。想了解下,这部分功能是否已经在方舟编译器上实现但目前还未开源出来?还是什么别的情况?出于什么考虑,lambda表达式和泛型未能在此时开源?

640?wx_fmt=jpeg

问题二

编译器领域现在业界都使用三段式编译器。架构如下:

640?wx_fmt=jpeg

编译器框架LLVM和核心就是LLVM IR,而方舟编译器也有一个Maple IR。请问相比LLVM IR,Maple IR的优势在哪里?它的愿景是什么?

问题三

经过方舟编译器处理后的应用,从公开渠道上的信息上看,在流畅度等几个方面有大幅提升。能否详细介绍下流畅度是怎么衡量的?也就是说,方舟内部是如何评价经过方舟编译器处理后以及没有经过方舟编译器处理后的应用的性能?都选了哪些测试点?

问题四

适配了方舟编译器的有几十个APP,但还有很多APP开发者没有机会第一时间接触方舟(包括我自己)。想了解下使用方舟编译器是否有副作用?比如,如果将字节码全部转成了机器码,这会占据较大的存储空间。请问是否有类似这样的问题,有什么好的解决办法吗?

问题五

方舟编译器说干掉了JVM虚拟机(原话可能不是如此,但我理解是这个意思),请问经过方舟编译器处理的应用是否能按以前的Java程序那样调试?

备注:为什么会问这个问题?java程序debug时必须靠jvm帮忙,比如处理jdwp,更关键是要靠jvm来解释执行字节码。不过,我在ART那本书里并没有详细介绍这个过程,我不保证这个问题问正确了。也请懂行的朋友们指正。

问题六

方舟编译器对java语言的特性支持如何?比如,ART虚拟机中,一个java方法即使以机器码方式运行,在某些时候也必须回退到解释执行。比如下面的ArrayIndexOutOfBounds异常的处理。

640?wx_fmt=jpeg

对于类似这种问题,方舟编译器在技术层面上对于它们大概的解决思路是什么?

问题七

ART虚拟机在诸如synchronized等的实现上做了大量工作(ART一书的第十二章),包括优化(比如一个线程如果已经得到某个锁的情况下,后续再去获取这个锁的话,实际上只是递增了该锁的引用计数)。虽然PTHREAD相关同步处理也有类似的优化,但我想了解下方舟编译器(如果干掉虚拟机的话),有没有针对这方面的处理或者优化?

问题八

引用计数是垃圾回收的一种经典技术。方舟编译器说是用引用计数代替了其它几种GC技术,做到随用随收。但其中有一些需要特别注意的地方(ART一书的第十三章、十四章专门讲解内存分配和GC)。垃圾回收是和内存分配息息相关的。ART虚拟机内部对内存分配有着良好的管理。比如rosalloc分配器,BumpPointerSpace、针对大内存对象的LargeObjectSpace等。请问方舟编译器是怎么应对的?是将java层的new直接对应到比如native层的new/malloc(直接依赖os的内存分配机制),还是也依赖一个小的,轻量级的runtime来协助这方面的工作?

另外,ART在内存管理方面做了一些优化,比如当程序退到后台后,会对内存进行碎片整理。如果方舟编译器是随用随收的话,请问长时间运行后,是否会存在内存碎片?如果有,是如何处理的呢?

问题九

官网上提到了伴随方舟编译器有一个轻量级的运行时,这个运行时主要工作是什么?它和ART JVM有何区别?方舟编译器未来还要支持Javascript,这个运行时是否也能支持JS?还是说需要一个针对js的运行时?最后,这个运行时会开源吗?

问题十

我想方舟编译器的背后是承载了华为甚至很多国人伟大梦想的,但一时领先并不保证长久领先。比如,媒体做了经过方舟编译器处理后APP和苹果手机上APP打开速度的对比测试。方舟编译器的效果比较明显。但ios13据苹果官方数据上看,APP启动速度提升了两倍。这说明我们在努力,对手也在努力。华为是一个有着很强忧患意识的伟大公司。那么,方舟编译器针对ios13是否有优势?我们这个优势会不会很容易被对手颠覆呢?我们该如何努力,朝哪个方向努力呢?

最后

无论怎样,方舟编译器都会在IT历史上留下浓重的笔墨。衷心期望我个人或其它朋友能为我们自己的IT成果——方舟编译器、鸿蒙OS等编写学习资料,贡献自己的微薄力量。

最后的最后

  • 我期望的结果不是朋友们从我的书、文章、博客后学会了什么知识,干成了什么,而应该是说,神农,我可是踩在你的肩膀上的喔。

  • 关于学习方面的问题,我已经讨论完了。后面这个公众号将对一些基础的技术,新技术做一些学习和分享。也欢迎你的投稿。不过,正如我在公众号“联系方式”里说的那样——郑渊洁在童话大王《智齿》里有一句话令我印象深刻,大意是“我有权保持沉默,但你说的每一句话都可能成为我灵感的源泉”。所以,影响不是单向的,很可能我从你那学到的东西更多。

640?wx_fmt=jpeg

神农和朋友们的杂文集

长按识别二维码关注我们

### 方舟字节码文件格式说明 #### 字节码操作码扩展机制 方舟字节码的操作码最初设计为8位宽,这使得可定义的最大操作码数量受限于256个。然而,随着方舟编译器的发展及其支持的功能增多,所需的操作码数目已超出这一限制。为此,方舟字节码采用了一种前缀方案来解决这个问题,允许操作码长度从原来的8位扩充到了16位[^1]。 对于那些经常使用的指令来说,仍然保持原有的单字节形式;而对于较少见或新增加的指令,则通过添加特定的前缀字节形成双字节结构。这种做法不仅解决了操作码不足的问题,同时也优化了程序执行效率——常用指令占用更少的空间并能更快解析。 #### 同名实体处理方式 当在同一作用域内存在多个具有相同名字的对象时,在生成对应的内部表示过程中会给这些对象附加额外的信息以便区分它们。具体而言,首次遇到的名字不会带有任何特殊标记,而后续重复出现的名字会在其后面追加一个由"^"开头紧跟十六进制数构成的重命名序列号[^2]。例如: - `variable` (第一次出现) - `variable^1`(第二次出现) - `variable^2`(第三次出现) 这种方法可以有效防止因变量或其他符号冲突而导致的错误,并简化调试过程中的追踪工作。 #### 函数定义实例分析 下面给出的是一个简单的函数定义片段作为例子展示如何编写遵循上述规则的实际代码[^3]: ```arkm .function any .func_main_0(any a0, any a1, any a2) { getmodulenamespace 0x1 ; 获取模块空间 ldai 0x3 ; 加载立即数值3 stmodulevar 0x0 ; 存储到模块级变量位置0处 ldexternalmodulevar 0x0 ; 读取外部模块变量0的内容存入寄存器a sta v0 ; 将结果保存至局部虚拟机寄存器v0中 throw.undefinedifholewithname a ; 如果a未初始化则抛出异常 ldexternalmodulevar 0x1 ; 类似地加载另一个外部模块变量... sta v1 throw.undefinedifholewithname b ; lda v1 ; 取得之前存储的结果 add2 0x0, v0 ; 执行二元运算并将得到的新值放回原处 sta v0 ... } ``` 此段伪代码展示了几个典型的操作符以及参数传递的方式,其中包含了获取当前上下文环境、访问全局/本地数据区等内容。值得注意的是这里使用了一些特殊的助记符如`getmodulenamespace`, 它们对应着具体的机器级别命令集的一部分实现细节。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值