Dart 代码的组件集合Dart VM3

简介: 这是我参与8月更文挑战的第 8 天,活动详情查看:8月更文挑战。为应掘金的八月更文挑战,通过 JIT 运行源代码本节将介绍当从命令行执行 Dart 时会发生什么:

这是我参与8月更文挑战的第 8 天,活动详情查看:8月更文挑战。为应掘金的八月更文挑战

通过 JIT 运行源代码

本节将介绍当从命令行执行 Dart 时会发生什么:

// hello.dart
main() => print('Hello, World!');
$ dart hello.dart
Hello, World!
复制代码

「Dart 2 VM 开始不再具有从原始代码直接执行 Dart 的能力,相反 VM 希望获得包含序列化内核 AST 的内核二进制文件(也称为 dill 文件)」。将 Dart 源代码翻译成 Kernel AST 的任务是由通用前端 (CFE)处理的,CFE 是用 Dart 编写并在不同 Dart 工具上共享(例如 VM、dart2js、Dart Dev Compiler)。

网络异常,图片无法展示
|

为了保持直接从源代码执行 Dart ,这里托管一个名为 kernel service 的辅助 isolate,它处理将 Dart 源代码编译到内核中,然后 VM 运行生成的内核二进制文件。

网络异常,图片无法展示
|

然而这种设置并不是 CFE 和 VM 运行 Dart 代码的唯一方法,例如 「Flutter 是将编译到 Kernel 的过程和从 Kernel 执行的过程完全分离」,并将它们放在不同的设备上实现:编译发生在开发者机器(主机)上,执行在目标移动设备上处理,目标移动设备接收由 flutter 工具发送给它的内核二进制文件。

网络异常,图片无法展示
|

这里需要注意,该 Flutter 工具不处理 Dart 本身的解析, 相反它会生成另一个持久进程 frontend_server,它本质上是围绕 CFE 和一些 Flutter 特定的 Kernel-to-Kernel 转换的封装。

frontend_server 将 Dart 源代码编译为内核文件, 然后 flutter 将其发送到设备, 当开发人员请求热重载时 frontend_server 开始发挥作用:在这种情况下 frontend_server 可以重用先前编译中的 CFE 状态,并重新编译实际更改的库。

「一旦内核二进制文件加载到 VM 中,它就会被解析以创建代表各种程序实体的对象,然而这个过程是惰性完成的」:首先只加载关于库和类的基本信息,源自内核二进制文件的每个实体都保留一个指向二进制文件的指针,以便以后可以根据需要加载更多信息。

网络异常,图片无法展示
|

每当我们引用 VM 内部分配的对象时,我们都会使用 Untagged 前缀,因为这遵循了 VM 自己的命名约定:内部 VM 对象的布局由 C++ 类定义,名称以 Untagged头文件 runtime/vm/raw_object.h 开头。例如 dart::UntaggedClass 是描述一个 Dart 类 VM 对象, dart::UntaggedField 是一个 VM 对象

「只有在运行时需要它时(例如查找类成员、分配实例等),有关类的信息才会完全反序列化」,在这个阶段,类成员会从内核二进制文件中读取,然而在此阶段不会反序列化完整的函数体,只会反序列化它们的签名。

网络异常,图片无法展示
|

此时 methods 在运行时可以被成功解析和调用,因为已经从内核二进制文件加载了足够的信息,例如它可以解析和调用 main 库中的函数。

package:kernel/ast.dart 定义了描述内核 AST 的类; package:front_end处理解析 Dart 源代码并从中构建内核 AST。dart::kernel::KernelLoader::LoadEntireProgram是 将内核 AST 反序列化为相应 VM 对象的入口点;pkg/vm/bin/kernel_service.dart 实现了内核服务隔离,runtime/vm/kernel_isolate.cc 将 Dart 实现粘合到 VM 的其余部分; package:vm 承载大多数基于内核的 VM 特定功能,例如各种内核到内核的转换;由于历史原因一些特定于 VM 的转换仍然存在于 package:kernel 中。

最初所有的函数都会有一个占位符,而不是它们的主体的实际可执行代码:它们指向 LazyCompileStub,它只是要求运行时系统为当前函数生成可执行代码,然后 tail-calls 这个新生成的代码。

网络异常,图片无法展示
|

第一次编译函数时,是通过未优化编译器完成的。

网络异常,图片无法展示
|



相关文章
|
Java Android开发
提示Eclipse内存
提示Eclipse内存
|
存储 数据库 开发者
现代数据库管理系统中的索引设计与优化
索引是数据库管理系统中的重要组成部分,对于提高查询性能和数据访问效率至关重要。本文将探讨现代数据库管理系统中的索引设计与优化策略,包括索引类型、索引选择原则、索引优化技巧等。通过深入理解索引的内部工作原理和优化策略,开发者可以更好地利用索引提升数据库性能。
282 1
|
JavaScript Java 测试技术
基于Java的校园闲置物品交易平台的设计与实现(源码+lw+部署文档+讲解等)
基于Java的校园闲置物品交易平台的设计与实现(源码+lw+部署文档+讲解等)
224 0
|
安全 Linux 测试技术
肥肠恐布--探索Kali Linux中的Metasploit Framework(MSF听说肾透大佬经常用)
Metasploit Framework(MSF)是一款功能强大的漏洞利用工具,广泛用于网络渗透测试和安全评估。在Kali Linux中,Metasploit是一个集成的框架,为安全研究人员提供了一套丰富的工具和资源,以便于发现和利用系统中的漏洞。本篇博客将带您了解Metasploit的基本原理和使用方法。
881 0
|
存储 移动开发 算法
Java SE基础知识详解第[15]期—File、方法递归、IO流
Java SE基础知识详解第[15]期—File、方法递归、IO流
Java SE基础知识详解第[15]期—File、方法递归、IO流
|
Linux
linux驱动开发 使用设备树编写一个led驱动程序
linux驱动开发 使用设备树编写一个led驱动程序
377 0
|
关系型数据库 MySQL 应用服务中间件
|
4天前
|
云安全 人工智能 算法
以“AI对抗AI”,阿里云验证码进入2.0时代
三层立体防护,用大模型打赢人机攻防战
1313 3