1.
In the Chakra's JIT compilation process, it stores variables' type information by basic block.
```
function opt(b) {
let o;
if (b) {
// BASIC BLOCK (a)
o = {};
} else {
// BASIC BLOCK (b)
o = 1.1;
}
// BASIC BLOCK (c)
return o;
}
```
For example, let's think the above code gets optimized. At the basic block (a), the type of "o" is always "Object". At the basic block (b), the type of "o" is always "CanBeTaggedValue_Float". At the basic block (c), it combines the two types, and marks the type of "o" as "CanBeTaggedValue_Mixed"(Object + CanBeTaggedValue_Float).
Explanation of TaggedValue in Chakra: http://abchatra.github.io/TaggedFloat/
But unlike variables, the type information of constants like numbers, strings is managed globally. This means, once a constant is marked as some type in a certain block. All blocks will treat it as that type regardless of the control flow.
2.
Chakra uses a BailOutOnTaggedValue bailout to ensure a variable's type is "Object". The bailouts can be generated when inlining JavaScript functions.
```
function opt(inlinee) {
inlinee();
}
Generated IR code for the above code:
StatementBoundary #0 #0000
s6.var = StartCall 1 (0x1).i32 #0000
BailOnNotObject s3[LikelyCanBeTaggedValue_Object].var #0006 Bailout: #0006 (BailOutOnInlineFunction)
s10.var = Ld_A [s3[LikelyObject].var+8].u64 #0006
BailOnNotEqual [s10.var!].i32, 26 (0x1A).i32 # Bailout: #0006 (BailOutOnInlineFunction)
BailOnNotEqual [s3[LikelyObject].var+40].u64, 0xXXXXXXXX (FunctionBody [Anonymous function (#1.3), #4]).u64 # Bailout: #0006 (BailOutOnInlineFunction)
```
As you can see after the "BailOnNotObject" opcode which generates "BailOutOnTaggedValue" bailouts, the type of "s3" becomes "LikelyObject" from "LikelyCanBeTaggedValue_Object". This means there's no case where "s3" is not an object after the opcode which ensures its type, so it's safe to use it as an object without checks after the opcode.
But the problem is that this can be applied to constants.
暂无评论