WebKit Web Inspector 增加覆盖率分析和类型推断功能

阅读数:955 2015 年 9 月 7 日

话题:JavaScript语言 & 开发架构

WebKit 中的 Web Inspector(Web 检查器)主要用于查看页面源代码、实时 DOM 层次结构、脚本调试、数据收集等,日前增加了两个十分有用的新功能:覆盖率分析和类型推断。覆盖率分析工具能够可视化地精确显示 JavaScript 程序执行的部分。类型推断工具则可以直观地给重要变量加上类型信息的注释。这两项功能使得在 Web Inspector 中理解和调试 JavaScript 程序变得更加简便,编程体验得到了极大的提升。

覆盖率分析功能

理解程序如何工作是一件复杂而繁琐的过程,需要知道在特定的输入情况下程序执行了哪些部分。在网页应用中,通常需要关心用户与网页交互时程序执行的部分。Web Inspector 现在就可以准确地显示程序正在运行的部分以及没有运行的部分。

同样地,在理解程序的控制流程时,必须知道哪些函数正在执行,甚至需要深入到函数内部的 if-then 条件分支中。查找 bug 时一般会监测某段程序有没有执行,这也是协调整个程序工程各个功能模块的必由之路。覆盖率分析工具可以帮助编程者找出程序中的细节问题。

类型推断功能

JavaScript 类型推断是 Web Inspector 中另一个振奋人心的新功能。JavaScript 中的所有变量都有类型,但是在阅读 JavaScript 代码或函数时,很难一下子知道某个变量属于什么类型。现在,类型推动工具就可以解决浏览 JavaScript 程序时,难以确定重要变量类型的问题。

JavaScript 属于动态类型语言,相比于静态类型语言(比如SwiftHaskell等)而言,编写 JavaScript 程序时并不需要进行类型声明。因此,JavaScript 程序中的任意一个变量或表达式都可以是任意一种类型,函数也可以返回任意类型的值。静态类型语言能够避免混淆不匹配的类型,当类型检查器发现类型匹配错误时,编译器不会通过编译。而 JavaScript 就没有这样的限制,只要 JavaScript 程序没有语法错误,就可以通过编译。再比方说,在静态类型语言中,不能把一个数赋值给一个数组变量,但是在 JavaScript 中就可以。像这样类型错配的小例子看起来好像很容易避免,然而当 JavaScript 程序变得庞大复杂、拥有越来越多的类时,就很难记录所有可能的类型,也不可避免地会出现错配的情况。虽然 JavaScript 不是静态类型语言,但它的变量通常只会有一种特定的类型(单态性极大地促进了 JIT 编译器成功优化 JavaScript 程序),JavaScript 程序经常因为难以预料的类型泄漏而产生错误。有很多例子可以说明这种缺少强制类型保护的弊端,在这里就不一一列举了。

Web Inspector 的类型推断功能使得查找和解决这类问题更加快捷方便。类型相关的错误有时很容易定位,类型不匹配时会报出运行类型错误。但在大多数情况下,类型不匹配问题并不会报错,而且会很难定位,甚至难以复现。类型推断工具这时就可以辅助有效地查找这类微小的错误。在 Web Inspector 中开启类型推断功能后,JavaScript 程序会在重要的变量和函数旁显示类型提示。编程者可以直接浏览 JavaScript 程序,不需要加载 console.log 文件或在调试时分步暂停。类型推断工具十分适合反向查找类型相关的错误。正如类型推断功能自身的名称所说的那样,它仅仅是依据程序中曾经出现过的数据类型进行推断。它既不能有百分之百的把握显示变量正确的类型,也不能基于已有的信息进行类型预测。另外,类型推断工具会实时进行更新。当新的信息加入程序时,它就会更新注释。使用类型推断工具可以帮助编程者更好地把握程序脉络,也有助于更好地熟悉新代码。

关于编译的补充说明

类型推断功能与JavaScriptCore's JIT编译架构高度集成在一起,下图显示了 JSC 编译器的工作流程图。

JSC 首先将 JavaScript 代码解析为抽象语法树(AST,Abstract Syntax Tree),而后生成字节码。接下来 JSC 会翻译字节码,并在 LLInt(Low Level Interpreter)中收集分析信息。如果一个函数已经执行了足够的时间,JSC 会在 Baseline 中直接将这部分字节码编译为机器码;如果这个函数继续执行多次,JSC 会用DFG 和 FTL JIT进行优化。由于类型推断信息被编译进了 JSC 的字节码,JSC 之后可以调用它的多层编译器对类型推断进行优化。如果不进行优化,使用类型推断工具进行调试会变得异常缓慢。具体的优化过程细节可以参考官方说明


感谢徐川对本文的审校。

给 InfoQ 中文站投稿或者参与内容翻译工作,请邮件至editors@cn.infoq.com。也欢迎大家通过新浪微博(@InfoQ@丁晓昀),微信(微信号:InfoQChina)关注我们,并与我们的编辑和其他读者朋友交流(欢迎加入 InfoQ 读者交流群)。