1、测试文件test.js
function log(msg){
console.log(msg)
}
hi = "hello"
log(hi)
2、输出AST语法树
d8 --print-ast test.js
[generating bytecode for function: ]
--- AST ---
FUNC at 0
. KIND 0
. LITERAL ID 0
. SUSPEND COUNT 0
. NAME ""
. INFERRED NAME ""
. DECLS
. . FUNCTION "log" = function log
. EXPRESSION STATEMENT at 47
. . ASSIGN at 50
. . . VAR PROXY unallocated (0000022CC5A21D98) (mode = DYNAMIC_GLOBAL, assigned = true) "hi"
. . . LITERAL "hello"
. EXPRESSION STATEMENT at 61
. . ASSIGN at -1
. . . VAR PROXY local[0] (0000022CC5A21CC8) (mode = TEMPORARY, assigned = true) ".result"
. . . CALL
. . . . VAR PROXY unallocated (0000022CC5A21B10) (mode = VAR, assigned = true) "log"
. . . . VAR PROXY unallocated (0000022CC5A21D98) (mode = DYNAMIC_GLOBAL, assigned = true) "hi"
. RETURN at -1
. . VAR PROXY local[0] (0000022CC5A21CC8) (mode = TEMPORARY, assigned = true) ".result"
[generating bytecode for function: log]
--- AST ---
FUNC at 12
. KIND 0
. LITERAL ID 1
. SUSPEND COUNT 0
. NAME "log"
. PARAMS
. . VAR (0000022CC5A21B68) (mode = VAR, assigned = false) "msg"
. DECLS
. . VARIABLE (0000022CC5A21B68) (mode = VAR, assigned = false) "msg"
. EXPRESSION STATEMENT at 24
. . CALL
. . . PROPERTY at 32
. . . . VAR PROXY unallocated (0000022CC5A21D18) (mode = DYNAMIC_GLOBAL, assigned = false) "console"
. . . . NAME log
. . . VAR PROXY parameter[0] (0000022CC5A21B68) (mode = VAR, assigned = false) "msg"
hello
3、输出作用域
d8 --print-scopes test.js
Inner function scope:
function log () { // (000001E067B50EA8) (12, 43)
// 2 heap slots
// local vars:
VAR msg; // (000001E067B54E18) never assigned
}
Global scope:
global { // (000001E067B50C88) (0, 68)
// will be compiled
// 1 stack slots
// temporary vars:
TEMPORARY .result; // (000001E067B51288) local[0]
// local vars:
VAR log; // (000001E067B510D0)
// dynamic vars:
DYNAMIC_GLOBAL hi; // (000001E067B51358)
function log () { // (000001E067B50EA8) (12, 43)
// lazily parsed
// 2 heap slots
}
}
Global scope:
function log (msg) { // (000001E067B50EA8) (12, 43)
// will be compiled
// local vars:
VAR msg; // (000001E067B51128) parameter[0], never assigned
}
hello
4、输出字节码
d8 --print-bytecode test.js
[generated bytecode for function: (0x03970824fc39 <SharedFunctionInfo>)]
Parameter count 1
Register count 3
Frame size 24
000003970824FCEA @ 0 : 12 00 LdaConstant [0]
000003970824FCEC @ 2 : 26 fa Star r1
000003970824FCEE @ 4 : 27 fe f9 Mov <closure>, r2
000003970824FCF1 @ 7 : 61 37 01 fa 02 CallRuntime [DeclareGlobals], r1-r2
000003970824FCF6 @ 12 : 12 01 LdaConstant [1]
000003970824FCF8 @ 14 : 15 02 00 StaGlobal [2], [0]
000003970824FCFB @ 17 : 13 03 02 LdaGlobal [3], [2]
000003970824FCFE @ 20 : 26 fa Star r1
000003970824FD00 @ 22 : 13 02 04 LdaGlobal [2], [4]
000003970824FD03 @ 25 : 26 f9 Star r2
000003970824FD05 @ 27 : 5d fa f9 06 CallUndefinedReceiver1 r1, r2, [6]
000003970824FD09 @ 31 : 26 fb Star r0
000003970824FD0B @ 33 : aa Return
Constant pool (size = 4)
000003970824FCB1: [FixedArray] in OldSpace
- map: 0x0397080404b1 <Map>
- length: 4
0: 0x03970824fc61 <FixedArray[2]>
1: 0x03970824fc01 <String[#5]: hello>
2: 0x03970824fbf1 <String[#2]: hi>
3: 0x0397081c692d <String[#3]: log>
Handler Table (size = 0)
Source Position Table (size = 0)
[generated bytecode for function: log (0x03970824fc71 <SharedFunctionInfo log>)]
Parameter count 2
Register count 2
Frame size 16
000003970824FE4E @ 0 : 13 00 00 LdaGlobal [0], [0]
000003970824FE51 @ 3 : 26 fa Star r1
000003970824FE53 @ 5 : 28 fa 01 02 LdaNamedProperty r1, [1], [2]
000003970824FE57 @ 9 : 26 fb Star r0
000003970824FE59 @ 11 : 59 fb fa 02 04 CallProperty1 r0, r1, a0, [4]
000003970824FE5E @ 16 : 0d LdaUndefined
000003970824FE5F @ 17 : aa Return
Constant pool (size = 2)
000003970824FE1D: [FixedArray] in OldSpace
- map: 0x0397080404b1 <Map>
- length: 2
0: 0x0397081c68b9 <String[#7]: console>
1: 0x0397081c692d <String[#3]: log>
Handler Table (size = 0)
Source Position Table (size = 0)
hello
5、测试文件test1.js
let a = {x:1}
function bar(obj) {
return obj.x
}
function foo (count) {
let ret = 0
for(let i = 1; i < count; i++) {
ret += bar(a)
}
return ret
}
//foo(7049)
//foo(100000)
6、输出优化信息
//foo(7049)
d8 --trace-opt-verbose test1.js
[not yet optimizing foo, not enough ticks: 0/2 and ICs changed]
//foo(10000)
[not yet optimizing foo, not enough ticks: 0/2 and ICs changed]
[marking 0x01410824fe35 <JSFunction foo (sfi = 000001410824FCD9)> for optimized recompilation, reason: small function]
[compiling method 0x01410824fe35 <JSFunction foo (sfi = 000001410824FCD9)> using TurboFan OSR]
[optimizing 0x01410824fe35 <JSFunction foo (sfi = 000001410824FCD9)> - took 141.370, 62.753, 1.551 ms]
7、输出反优化信息
//没有输出。。。
d8 --trace-deopt test1.js
8、test2.js
function strToArray(str) {
let i = 0
const len = str.length
let arr = new Uint16Array(str.length)
for (; i < len; ++i) {
arr[i] = str.charCodeAt(i)
}
return arr;
}
function foo() {
let i = 0
let str = 'test V8 GC'
while (i++ < 1e5) {
strToArray(str);
}
}
foo()
9、输出反优化信息
d8 --trace-gc test2.js
[4600:0000019D00000000] 490 ms: Scavenge 1.2 (2.4) -> 0.3 (3.4) MB, 14.5 / 0.0 ms (average mu = 1.000, current mu = 1.000) allocation failure
[4600:0000019D00000000] 500 ms: Scavenge 1.2 (3.4) -> 0.3 (3.6) MB, 2.0 / 0.0 ms (average mu = 1.000, current mu = 1.000) allocation failure
[4600:0000019D00000000] 501 ms: Scavenge 1.3 (3.6) -> 0.3 (3.6) MB, 0.1 / 0.0 ms (average mu = 1.000, current mu = 1.000) allocation failure
[4600:0000019D00000000] 503 ms: Scavenge 1.3 (3.6) -> 0.3 (3.6) MB, 0.1 / 0.0 ms (average mu = 1.000, current mu = 1.000) allocation failure
[4600:0000019D00000000] 505 ms: Scavenge 1.3 (3.6) -> 0.3 (3.6) MB, 0.1 / 0.0 ms (average mu = 1.000, current mu = 1.000) allocation failure
[4600:0000019D00000000] 506 ms: Scavenge 1.3 (3.6) -> 0.3 (3.6) MB, 0.1 / 0.0 ms (average mu = 1.000, current mu = 1.000) allocation failure
[4600:0000019D00000000] 508 ms: Scavenge 1.3 (3.6) -> 0.3 (3.6) MB, 0.1 / 0.0 ms (average mu = 1.000, current mu = 1.000) allocation failure
[4600:0000019D00000000] 509 ms: Scavenge 1.3 (3.6) -> 0.3 (3.6) MB, 0.1 / 0.0 ms (average mu = 1.000, current mu = 1.000) allocation failure
[4600:0000019D00000000] 511 ms: Scavenge 1.3 (3.6) -> 0.3 (3.6) MB, 0.1 / 0.0 ms (average mu = 1.000, current mu = 1.000) allocation failure
[4600:0000019D00000000] 513 ms: Scavenge 1.3 (3.6) -> 0.3 (3.6) MB, 0.1 / 0.0 ms (average mu = 1.000, current mu = 1.000) allocation failure
[4600:0000019D00000000] 515 ms: Scavenge 1.3 (3.6) -> 0.3 (3.6) MB, 0.1 / 0.0 ms (average mu = 1.000, current mu = 1.000) allocation failure
[4600:0000019D00000000] 516 ms: Scavenge 1.3 (3.6) -> 0.3 (3.6) MB, 0.1 / 0.0 ms (average mu = 1.000, current mu = 1.000) allocation failure
[4600:0000019D00000000] 518 ms: Scavenge 1.3 (3.6) -> 0.3 (3.6) MB, 0.1 / 0.0 ms (average mu = 1.000, current mu = 1.000) allocation failure
[4600:0000019D00000000] 520 ms: Scavenge 1.3 (3.6) -> 0.3 (3.6) MB, 0.1 / 0.0 ms (average mu = 1.000, current mu = 1.000) allocation failure
10、test3.js
function Foo(property_num,element_num) {
//添加可索引属性
for (let i = 0; i < element_num; i++) {
this[i] = `element${i}`
}
//添加常规属性
for (let i = 0; i < property_num; i++) {
let ppt = `property${i}`
this[ppt] = ppt
}
}
var bar = new Foo(10,10)
console.log(%HasFastProperties(bar));
delete bar.property2
console.log(%HasFastProperties(bar));
11、使用内部方法
//%HasFastProperties测试是否有快属性
d8 --allow-natives-syntax test3.js
true
false