安卓反编译无法得到源码-华为的方舟编译器诞生了,这次它彻底明白底层是如何打败Android的。知识

商店:旨在塑造轻知识点,每次不断更新更少的知识点,不厌其烦地阅读。不要占用太多时间,不断唤起记忆深处的知识点。

一、编译

简单地说:编译器将中级语言(开发人员友好的语言)“翻译”为低级语言(机器友好的语言)。

编译过程:源代码→预处理器→编译器→目标代码→链接器→可执行文件

编译器类型:

本机编译器

生成在与编译器相同的环境中运行的可执行对象代码。

交叉编译器,用于生成跨平台运行的目标代码。

二、方舟编译器的架构

8 月 31 日安卓反编译无法得到源码,方舟编译器开源。

架构设计:

三、安卓四大杀手锏:

3.1 Java的“虚拟机”

Java在任何地方编译和执行,利用虚拟机来平滑所有硬件平台资源。Java首先被编译成Java字节码,运行时,虚拟机被用来将Java字节码(即中间代码)解释为机器可以运行的机器码。

Android 体验过的虚拟机:3.1.1

安卓 1.0Dalvik 虚拟机,边解释边执行。

3.1.2 安卓 2.2Dalvik 虚拟机安卓反编译无法得到源码,JIT 即时编译。每次启动应用程序时,代码都会首先转换为机器代码。这就是当时该计划启动缓慢的原因。不需要逐字汇编。

3.1.3 安卓5.0ART虚拟机,AOT编译器。在安装过程中将代码转换为两个补码并保留。在5.0时代,这经历了安装时间过长的激励。

3.1.4 安卓7.0ART虚拟机,混合编译。混合编译 = AOT+JIT + 类库。AOT 在闲暇时执行,当 AOT 为时已晚时,使用 JIT 和协程。

3.1.5 摘要:编译器和类库都扔在虚拟机上。这些虚拟机+编译器+类库占用了大量的硬件资源,很难实现软件运行性能的最大化。这是安卓竞争硬件的原罪,不停地增加视频内存和存储空间,咱们跑个点。

3.2 Java跨语言JNI费用

JNI 继续使硬件资源不堪重负,通过简单的笨重虚拟机增加了这一额外费用。

3.3 优化空间有限

编译器由三部分组成

后端:负责源码转换字节码

编译器优化:负责代码优化

喷洒,闭源值得怀疑:方舟编译器怎么这么难?

作者丨赵玉英

是不是闭源的时候就被指责了这样的编译器,开源后被喷了之后,方舟编译器怎么会这么难?在本文中,Harmony 开源总监和 Ark 编译器的架构师首次以完整、公开的方式分享了 Ark 编译器的基本架构。

1. 方舟编译器怎么这么难?

自 8 月 31 日即将开源以来,方舟编译器的讨论

已经达到了高潮,2019年8月31日话题“如何对待方舟编译器的开源?被浏览量超过500万次,网友发表评论800多条。因为这个开源发布的代码较少,很多网友都抛出了疑问,比如运行时计划、开源的原因、开发后的应用是否只能在华为手机上运行以及未来如何做生态等等,方舟编译器在开源后六年磨砺出来的,是如何面临如此艰难的困境的?事实上,与

过去六年的发展相比,目前的情况可能不是最困难的。

2009年,华为成立第一个编译团队,最初针对无线基站领域的DSP性能问题。

2014年,Open64的鼻祖Fred Chow加入,这对华为后来的编译器开发产生了重要影响,包括现在的方舟编译器。

2017年,华为手机销量非常高,大量新问题开始出现。当时,在整个混合执行模式下,解释执行的比例特别高,执行性能相对较低,在后台生成JIT代码的过程会消耗大量的CPU资源,编译一个函数需要很长时间。据悉,由于优化不当,虚拟机的暂停时间特别长,尤其是在内存不足的情况下,会造成很多卡顿。

基于以上原因,整个团队讨论了两种可能的解决方案:一种是更换现有的虚拟机;第二种是启动一个新的炉子,并制作一套可以执行Java的新操作环境和编译器。第一条路径相对简单无故障,但只能解决部分问题,华为最终选择了第二条路线,这导致了当前方舟编译器的诞生。

在 Ark 编译器的设计中,FredChow 的一篇论文提供了一个很好的思路:基于统一的 IR,它既支持多种编程语言表示,又支持指定生成的前端多芯片代码。这构成了方舟编译器的理论基础。在此理论基础上,ARK编译器团队基于MAPLEIRE进行了更复杂的优化和更通用的控制流分析。

2019年4月,华为发布方舟编译器,8月底开源其编译框架代码,并计划跟进完整方舟编译器的全部代码。然而,开源的方舟编译器受到了来自世界各地的开发者的高度关注,面对现在开源的少量代码,很难相信这是一个多语言、跨平台、高效的编程环境。

于是,整个团队首次公开了方舟编译器的基本架构和源代码分析。

2. 分析

方舟编译器的源代码

8月31日,华为方舟编译器开源了编译器框架的部分源代码,包括编译器中间表示(IR)和语言编译实现,并结合编译器的其他二进制补码组件,实现了Java程序编译过程到aarch64汇编指令。

在华为的描述中,开发者可以基于开源代码和双补码代码编译构建编译器工具链,尝试编译Java程序。社区参与者可以通过框架源代码学习方舟编译器的中级表示(IR)和基本的中端编译框架,熟悉方舟编译器的架构思想,并参与编译器中端优化的贡献。Ark编译器是一个统一的编程平台,旨在支持多种编程语言和多种芯片平台的联合编译和操作,包括编译器、工具链和运行时等关键组件。

就范围可见,整个方舟编译器代码的开源部分由C、C++头文件、源码和汇编代码组成,C语言头文件占绝大多数,目前提供的代码超过7万行,注释约1万行,还有许多空白行, 加上大约 100,000 行代码,注释很少。每个文件作为一个整体的大小不是很大,有的超过2000行,大多数小于1000行。

从代码内容来看,它主要与中间代码有关,实际上,它

还包括相位和IPA,但实际上主要是阶段管理的辅助代码,真正相关的代码还没有呈现。 huawei_secure_c文件包含许多关键代码,例如内存副本和其他关键功能。根据所选的测试用例,目前 Java 1.6 及以上版本支持没有问题,从 Java 到 IR 的转换还是比较流畅的,但在第三个库版本支持中可能存在问题。

至于上面提到的中间代码,根据 MAPLE 文档,主要有以下几个特点:

尽可能保留源代码信息;高级树层次结构;低级与指令一一对应;可扩展 – 支持新的语言和控制结构。

方舟基地在中间用 IR 表示

目前开源方舟基础设施的一部分是关于Java/Kotlin编程语言实现的,因为这两类语言严重依赖虚拟机,方舟编译器去掉了虚拟机,在上面完成了部分功能;另一部分是对后续优化和分析的基本支持,例如开源 SSA 的表示。

Ark编译器的架构师在最近的一次分享中说,MapleIR的设计考虑了三件事:

1. IR 以三种不同的格式存在:

2、分层设计,枫的整个观点是从Open64的鼻祖Fred Chow开始的,当时Open64的设计是五层结构。Ark编译器总结并借鉴了Open64的经验,产生了分层设计,并根据需要选择不同的层。这允许高级语言快速返回原始代码,这是大多数编译器都支持的,并且可以在许多应用场景中使用。据悉,顶部中间表示实现接近原始语言的优化会更方便。例如,Ark 编译器保留了更高级别的类类型,这对于 TBAA 和 Devirtual 来说相对容易做到。

3.高级结构更接近原始语言。原始语言中的代码是最精简的,Ark编译器希望中间结构也能更加精简,比如更小的分发格式。同时,希望编译优化可以重用,当引入新语言时,可以最大限度地减少更改。分层后,引入新语言时安卓反编译无法得到源码,只能更改高级,而高级扩展后,底层的所有优化保持不变。

在中间语言部分,方舟编译器架构师说它可以分为两部分:类型和运算符。

在类型上,Maple 编译器中有一个 Globaltab 的表示形式,其中保存了所有全局符号。第一项是类型表,它的实现是 MirType 的一个向量。MirType 的定义基本上只有这些项目,首先要看的是类型是什么类型。其次,PrimitiveType 类型是什么样子的,例如,Int 或更复杂的结构。

基于最基本的MirType,可以扩展结构结构。将来,信息会变得更加丰富,例如,将出现父类的某些字段,以及VTab,ITa等。基于 MirStructType,可以扩展高级结构,Ark 编译器会保留类信息,这对目前为止的分析优化很有帮助。在算子

上,方舟编译器支持内存的操作,也有结构化的算子。它不仅支持传统调用,还支持许多特定于 Java 的调用。

在内存管理方面,Ark编译器目前基于RC,辅以GC。开发人员可能熟悉 GC,这里有一些对 RC 的支持。RC是比较容易理解的东西,多加一个引号,少的话减去一个,思路也比较简单。在实际应用中,Ark 编译器基本上有四种情况加一个:

减一的场景也比较简单,比如局部变量 LastUse 之后,因为局部变量已经跑掉了,所以指向的原始对象应该是负一;如果对变量重新参数化,则它最初指向的堆对象也会减去 1。

在这些形式中,一个非常简单的函数可能要执行一系列的加减法运算,每个运算可能都要被锁定,基本程序很难运行起来。因此,整个团队开始从三个角度进行优化:

首先,减少插入,许多变量之间的 LiveRange 可能会重叠,重叠后添加一个,并且无法完成从前面减去一个的操作;如果实在没办法防止插入,就看如何降低每个操作的成本,方舟编译器有一个转义分析,主要结果是看变量是否会被多个线程访问。如果变量的值被子线程访问,则无需添加锁,只需加一个或减一个,然后确保它不会提前释放。

其次,RC操作是比较麻烦的事情,方舟编译器现在提供了注解的方式,注解的功效应该是最好的,但是对程序员的要求更高,如果程序员加错了,内存可能会泄露。此外,方舟编译器还提供了一种自我学习的方法。

第三,方舟编译器以RC为主,GC为辅。如果 RC 没有释放某些环,则可以从 GC 释放的环中学习一些规则,将这些规则写入文件或放入视频内存中,以指导下次运行时释放内存。

如上图所示,红色部分已经完成,红色部分仍在下方开发中,

红色部分仍在规划中,华为希望与社区一起建设。

接下来,方舟编译器团队将开放跨语言全程序优化能力。对于Android来说,从Java到C或C到Java的调用次数会特别大,每次调用的成本会比较大。如果你能把这部分做好,你可以把性能提高大约10%到20%。

另外,整个团队也做了一些安全编译,比如把运行时错误移到编译时,因为在运行时状态很难发现bug,如果在编译时上报问题,对开发者比较友好。

3.生态是绕不开的困境

目前,代码的

方舟编译器托管在华为云和代码云平台(gitee.com)上,开源合约是中国首个开源合约《木兰自耕许可证》,也是为了规避其他合约中潜在的开源风险。未来走向开放整流后,方舟编译器将按照附属机构的模式进行托管。开发人员可以通过代码托管平台参与社区贡献,包括文档和代码贡献,也可以在此平台上反馈相关问题和需求。

在生态建立方面,很多开发者觉得这是方舟编译器需要跨越的一大关。虽然生态不一定只有开源安卓反编译无法得到源码, 苹果不开源 但仍有大量开发者愿意为其平台开发应用, Harmony OS开源总监表示,华为之所以选择开源方舟编译器,是因为它真的希望得到广大开发者的帮助,与该领域的众多优秀学者和从业者一起进步。编译器数量;二是获得广大开发者的信任。

然而,今天,许多开发人员认为他们不能参与,而且开源代码很少,因为没有运行时。华为方舟编译器架构师表示,虽然方舟编译器有一个运行时来实现各种运行时相关信息,比如Java反射、JNI调用、内存管理、内存回收机制等,但现在只有6万行代码,是一个非常轻量级的运行时,只提供必要的内容。

目前开发者可以先在华为手机上运行,华为也希望社区能够通过开源做一个简单的运行时。以后会按照计划尽快开放所有的源码,因为代码开源需要清理整顿,希望你们开发者在时间方面少一些耐心。如果开发者想参与社区建设,可以考虑以下几个角度:

4. 结束语

Ark编译器的愿景是构建一个多语言,跨平台和高效的编程环境。面向未来,华为在全场景智能化方面做了很多尝试,如何在全场景下进行高效编程,如何在全红外层面进行优化等等都是极具挑战性的任务,方舟编译器也希望未来能更好地与硬件集成,而这需要更多的开发者参与。

方舟编译器主页:

官方主库:

吉蒂镜像仓库: