最简单的方法还是用 GCC/GCOV/LCOV 系列. 以下是方法:
|
# 编译 SpiderMonkey CFLAGS="-fprofile-arcs --coverage" CXXFLAGS="-fprofile-arcs --coverage" ~/gecko-dev/js/src/configure --enable-debug && make -j 8 # 跑回归测试集 cd ~/gecko-dev/js/src/tests/ ./jstests.py ~/gcov-mozjs/obj/dist/bin/js cd ../jit-test/ ./jit_test.py ~/gcov-mozjs/obj/dist/bin/js # 生成HTML lcov --capture --directory mozjs-obj/ --output-file mozjs-coverage.info genhtml mozjs-coverage.info --output-directory lcov-output/ |
获取之后就可以直接用浏览器打开看了.

需要注意的是这个只能看到函数覆盖率和代码行覆盖. 更细致的覆盖度, 例如路径覆盖, 可能需要别的工具了(not sure).
从代码覆盖度上看, 还是有一些代码是没有测试到的. 看了一下原因可以分成几类:
- 我编译 SpiderMonkey 的时候使用了’–enable-debug’编译, 有一些调试代码没有执行到;
- 测试使用的是Mozilla自带的回归测试脚本, 用于交互式执行的部分, 例如 editline, 都没有执行到;
- 硬件配置相关的部分, 由于我使用的机器是 X86_64 SSE4.2, 所以有一些特定的代码也是覆盖不到的;
- 最后, 就是测试集可以覆盖但是没有覆盖到的代码部分.
完整的覆盖信息可以看 http://hellocompiler.com/spidermonkey/lcov/index.html
转发,我一直期待(但是自己没有做)的工具之一:
Nicolas B. Pierron via lists.mozilla.org
Hello everybody,
I am please to do an early announce a new tool named Jit DevTools.
This new tool is an addon which mostly target Jit developers. It uses the recently added Debugger.onIonCompilation hook to display the latest MIR [1] and LIR graphs within the dev tools.
To use this tool, go to a web page, and open the Jit DevTools panel, then wait until a function got compiled.
Once a function is compiled, you can select a compiled script, which will display the MIR graph of the compilation. If you need to, you can also have a look at the LIR graph. The output is similar to the one rendered with iongraph [5].
By selecting any inlined script, the background of the block titles will change color, if the block correspond to the inlined instance. This feature is quite useful to identify how a function plays in a compiled script.
You might find this tool quite handy to use for the following use cases:
– Investigating DOM optimization.
– Investigating jsperf issues.
– Comparing function implementations, and impacts on the generated code.
This addon works on optimized builds, and even with parallel compilation enabled.
You can download [2] this early version from http://people.mozilla.org/~npierron/jit-dev-tools/ , or build it your-self by using the sources [3] with jpm tool [4].
Have fun, and enjoy.
[1] http://people.mozilla.org/~npierron/jit-dev-tools/jit-dev-tools-0.0.1.png
[2] http://people.mozilla.org/~npierron/jit-dev-tools/jit-dev-tools-0.0.1.xpi
[3] https://github.com/nbp/jit-dev-tools/
[4] https://developer.mozilla.org/en-US/Add-ons/SDK/Tools/jpm
[5] https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Hacking_Tips#Using_IonMonkey_spew_%28JS_shell%29
Firefox 浏览器内部的内存管理是基于”Compartment”的.
提出这个概念的背景, 是 Firefox 既是一个单进程多线程的架构, 又支持多 Tab 页面浏览. 这就导致了不同的网页的内容出现在同一个虚拟地址空间中. Firefox 3.5 之前的内存组织方式是一视同仁的散布在堆中. 这样如果 Firefox 有内存方面的漏洞, 导致恶意页面可以访问到敏感页面(例如银行支付页面)的内存信息, 就悲剧了. 性能上使得页面浏览的时候无法利用缓存访问的局部性, Cache Miss 高一点点对于软件的速度影响是很可观的(1).
于是 Mozilla 把单个进程的堆, 以网页为单位分成了子堆, 在浏览器的内部实现了一套隔离和通信机制. 你可以认为 Mozilla 把操作系统对于进程所做的工作, 在线程的层次上做了一层实现. 具体的实现原理和示意图可以参考文后的相关文献.
相关文献:
[1]: Andreas Gal 的博客
[2]: MDN上的介绍
[3]: 论文: Compartmental memory management in a modern web browser. 里面的配图很好, 看起来很直观. ACM链接. PDF下载的地址
尾注:
(1) 这里有一个研究问题: 在单核的架构中, 编译器优化的主要目标之一就是减少 CPU Cache Miss, 但是在多核中, CPU Cache 还是编译器优化的主要目标么? 我并不知道答案.
Ehsan Akhgari 在自己的一篇博客[1]中介绍了如何通过 git 的 log 日志统计得到了各个开发人员的提交统计. 并给出了Mozilla SpiderMonkey 引擎开发人员2012年上半年的提交统计, 这是一部分结果:
|
$ git log --format='%an <%ae>' \ --since=2012-01-01 --until=2012-07-01 \ --all --no-merges -- js/ | sed 's/@/--at--/' | \ grep -v ^commit | sort | uniq -c | sort -rn | head 199 David Anderson <danderson--at--mozilla.com> 155 Jan de Mooij <jdemooij--at--mozilla.com> 133 Jeff Walden <jwalden--at--mit.edu> 115 Luke Wagner <luke--at--mozilla.com> 114 Bill McCloskey <wmccloskey--at--mozilla.com> 108 Nicholas Nethercote <nnethercote--at--mozilla.com> 105 Marty Rosenberg <mrosenberg--at--mozilla.com> 104 Bobby Holley <bobbyholley--at--gmail.com> 103 Nicolas Pierron <nicolas.b.pierron--at--mozilla.com> 78 Terrence Cole <terrence--at--mozilla.com> |
Ehsan 在博客中同时提供了生成数据的(一行)命令脚本, 并对各个参数进行了详细的解释. 只要是 git 仓库就可以使用这种脚本进行统计(需要改一下起始时间和结束时间). 如果你有兴趣, 可以看看自己的仓库中谁最努力. 🙂
[1]: Data about people’s contribution to the Mozilla code base
如果你看过 SpiderMonkey 的代码目录,你就发现经常会有名为“ABC-inl.h”的文件与头文件“ABC.h”成对出现。这是 SpiderMonkey 内部组织的一个风格(不知道算不算规范),其目的是为了改善和提高系统内部的模块性。感兴趣的同学可以看看这个 Mozilla 维基页面[1]或者这个 Bugzilla 链接[2]。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
|
$find ./mozilla-central/js/ -iname '*-inl.h' ./src/frontend/SharedContext-inl.h ./src/frontend/ParseMaps-inl.h ./src/frontend/Parser-inl.h ./src/frontend/ParseNode-inl.h ./src/ion/BaselineFrame-inl.h ./src/ion/PcScriptCache-inl.h ./src/ion/IonFrameIterator-inl.h ./src/ion/CompileInfo-inl.h ./src/ion/IonFrames-inl.h ./src/ion/shared/Lowering-shared-inl.h ./src/ion/shared/CodeGenerator-shared-inl.h ./src/ion/LIR-inl.h ./src/builtin/Iterator-inl.h ./src/vm/ArgumentsObject-inl.h ./src/vm/RegExpStatics-inl.h ./src/vm/GlobalObject-inl.h ./src/vm/RegExpObject-inl.h ./src/vm/Shape-inl.h ./src/vm/Stack-inl.h ./src/vm/StringObject-inl.h ./src/vm/BooleanObject-inl.h ./src/vm/String-inl.h ./src/vm/ScopeObject-inl.h ./src/vm/ObjectImpl-inl.h ./src/vm/NumberObject-inl.h ./src/gc/Barrier-inl.h ./src/gc/FindSCCs-inl.h ./src/gc/Nursery-inl.h |
[1]: https://wiki.mozilla.org/JS_engine_modularization
[2]: https://bugzilla.mozilla.org/show_bug.cgi?id=653057
Recent Comments