Bug 1145442 - Update JIT Optimization docs patch. r=shu

This commit is contained in:
Kannan Vijayan 2015-09-04 11:28:22 -04:00
parent 916718880d
commit 37ccdfa6f6
2 changed files with 148 additions and 112 deletions

View File

@ -21,6 +21,8 @@ Optimization succeeded.
### Disabled
The optimization has been explicitly disallowed.
### NoTypeInfo
Optimization failed because there was no type information associated with
@ -28,9 +30,16 @@ object containing the property. This failure mode is unlikely, and occurs
if the target object is obtained in some roundabout way.
### NoAnalysisInfo
TODO
### NoShapeInfo
The baseline compiler recorded no usable shape information for this operation.
### UnknownObject
### UnknownProperties
The type of the object is not known. This can happen if the operation sees many different types of objects, and so the type of the input to the operation cannot be resolved to a single type.
### UnknownProperties
@ -40,7 +49,8 @@ defined on the object, or if `delete` is used to remove one of the object's
properties.
### Singleton
### NotSingleton
One of the types present in the typeset was a singleton type, preventing the optimization from being enabled.
### NotSingleton
@ -50,8 +60,13 @@ have a 'singleton' type. Singleton types are assigned to objects that are
global scope, and top-level function objects.
### NotFixedSlot
The property being accessed is not stored at a known location in the object. This can occur if one of the expected types of objects to be used in this operation has unknown properties, or if different instances of the object store the property at different locations (for example, some instances have the property assigned in a different order than others).
### InconsistentFixedSlot
The property being accessed is not stored at a known location in the object. This can occur if the operation is polymorphic on different object types and one or more of the object types contain the property at a different slot than the others.
### NotObject
Optimization failed because the stored in the property could potentially
@ -63,16 +78,28 @@ optimization strategy fails in this case.
The object holding the property is not a typed struct object.
### NotUnboxed
The object whose property is being accessed is not formatted as an
unboxed object.
### UnboxedConvertedToNative
The object whose property is being accessed was previously unboxed,
but was deoptimized and converted to a native object.
### StructNoField
The property being accessed does not correspond to a field on typed
The unboxed property being accessed does not correspond to a field on typed
object.
### InconsistentFieldType
The type of an unboxed field is not consistent across all the different types of objects it could be accessed from.
### InconsistentFieldOffset
The offset of an unboxed field is not consistent across all the different types of objects it could be accessed from.
### NeedsTypeBarrier
Optimization failed because somehow the property was accessed in a way
@ -80,16 +107,49 @@ that returned a different type than the expected constant. This is an
unlikely failure mode, and should not occur.
### InDictionaryMode
The object whose property is being accessed is in dictionary mode. Objects which are used in ways that suggest they are hashtables, are turned into dictionary objects and their types marked as such.
### NoProtoFound
A prototype object was not found for all the object used by this operation.
### MultiProtoPaths
Objects used in this operation had differing prototypes.
### NonWritableProperty
The property being assigned to is not writable for some types of objects which are used in this operation.
### ProtoIndexedProps
The object being accessed has indexed properties that are exotic (for example, defined as a property on a prototype object and left as a hole in the underlying object).
### ArrayBadFlags
The array being accessed may have flags that the optimization strategy cannot handle. For example, if the array has sparse indexes, or has indexes that overflow the array's length, the optimization strategy may fail.
### ArrayDoubleConversion
The type-system indicates that some arrays at this site should be converted to packed arrays of doubles, while others should not. The optimization strategy fails for this condition.
### ArrayRange
Could not accurately calculate the range attributes of an inline array creation.
### ArraySeenNegativeIndex
Arrays at this element access location have seen negative indexes.
### TypedObjectNeutered
The typed object being accessed at this location may have been neutered (a neutered typed object is one where the underlying byte buffer has been removed or transferred to a worker).
### TypedObjectArrayRange
Failed to do range check of element access on a typed object.
### AccessNotDense
### AccessNotSimdObject

View File

@ -7,11 +7,11 @@ and function calls.
Optimization information is currently collected for the following operations:
- [GetProperty][getprop] (`obj.prop`)
- [SetProperty][setprop] (`obj.prop = val`)
- [GetElement][getelem] (`obj[elemName]`)
- [SetElement][setelem] (`obj[elemName] = val`)
- [Call][call] (`func(...)`)
- [GetProperty](#getprop) (`obj.prop`)
- [SetProperty](#setprop) (`obj.prop = val`)
- [GetElement](#getelem) (`obj[elemName]`)
- [SetElement](#setelem) (`obj[elemName] = val`)
- [Call](#call) (`func(...)`)
At each operation site, IonMonkey tries a battery of <i>strategies</i>, from
the most optimized but most restrictive to the least optimized but least
@ -24,7 +24,7 @@ speed-up they provide, what kind of program characteristics can prevent them
from being used, and common ways to enable the engine to utilize that
optimization.
## GetProperty
## <a name="getprop"></a>GetProperty
### GetProperty_ArgumentsLength
@ -78,27 +78,23 @@ after it was first assigned, is likely a constant property. It then directly
inlines the value of the property into hot code that accesses it. For
example, in the following code:
```language-js
var Constants = {};
Constants.N = 100;
var Constants = {};
Constants.N = 100;
function testArray(array) {
for (var i = 0; i < array.length; i++) {
if (array[i] > Constants.N)
return true;
}
return false;
}
```
function testArray(array) {
for (var i = 0; i < array.length; i++) {
if (array[i] > Constants.N)
return true;
}
return false;
}
Will have the loop compiled into the following when `testArray` gets hot.
```language-js
for (var i = 0; i < array.length; i++) {
if (array[i] > 100)
return true;
}
```
for (var i = 0; i < array.length; i++) {
if (array[i] > 100)
return true;
}
When this optimization is successful, property access is eliminated entirely
and replaced with an inline constant.
@ -145,14 +141,12 @@ This is the best case for a regular "field" type property that is not
turned into a constant. It compiles down to a single CPU-level load
instruction.
```language-js
function SomeConstructor() {
this.x = 10; // x is a definite slot property
this.y = 10; // y is a definite slot property
someComplicatedFunctionCall();
this.z = 20; // z is not a definite slot property.
}
```
function SomeConstructor() {
this.x = 10; // x is a definite slot property
this.y = 10; // y is a definite slot property
someComplicatedFunctionCall();
this.z = 20; // z is not a definite slot property.
}
In the above example, the properties `x` and `y` can be determined to always
exist on any instance of `SomeConstructor` at definite locations, allowing
@ -173,12 +167,10 @@ additionally have been observed to only store values of one kind of value.
Consider the following constructor:
```language-js
function Point(x, y) {
this.x = x;
this.y = y;
}
```
function Point(x, y) {
this.x = x;
this.y = y;
}
If only integers are ever stored in the `x` and `y` properties,
then the instances of `Point` will be represented in an "unboxed" mode -
@ -197,18 +189,16 @@ base class, where the property access refers to a getter on the base
class.
Consider the following example:
```language-js
function Base() {}
Base.prototype = {
get x() { return 3; }
};
function Base() {}
Base.prototype = {
get x() { return 3; }
};
function Derived1() {}
Derived1.prototype = Object.create(Base.prototype);
function Derived1() {}
Derived1.prototype = Object.create(Base.prototype);
function Derived2() {}
Derived1.prototype = Object.create(Base.prototype);
```
function Derived2() {}
Derived1.prototype = Object.create(Base.prototype);
If a property access for `d.x` sees only instances of both `Derived1` and
`Derived2` for `d`, it can optimize the access to `x` to a call to the
@ -234,16 +224,14 @@ This optimization compiles down to one-or more shape-guarded direct loads
from the object. The following pseudocode describes the kind of machine
code generated by this optimization:
```
if obj.shape == Shape1 then
obj.slots[0]
elif obj.shape == Shape2 then
obj.slots[5]
elif obj.shape == Shape3 then
obj.slots[2]
...
end
```
if obj.shape == Shape1 then
obj.slots[0]
elif obj.shape == Shape2 then
obj.slots[5]
elif obj.shape == Shape3 then
obj.slots[2]
...
end
### GetProp_Innerize
@ -275,7 +263,7 @@ Inline caches are an order of magnitude slower than the other optimization
strategies, and are an indication that the type inference engine has
failed to collect enough information to guide the optimization process.
## SetProperty
## <a name="setprop"></a>SetProperty
### SetProp_CommonSetter
@ -288,18 +276,16 @@ base class, where the property access refers to a setter on the base
class.
Consider the following example:
```language-js
function Base() {}
Base.prototype = {
set x(val) { ... }
};
function Base() {}
Base.prototype = {
set x(val) { ... }
};
function Derived1() {}
Derived1.prototype = Object.create(Base.prototype);
function Derived1() {}
Derived1.prototype = Object.create(Base.prototype);
function Derived2() {}
Derived1.prototype = Object.create(Base.prototype);
```
function Derived2() {}
Derived1.prototype = Object.create(Base.prototype);
If a property write for `d.x = val` sees only instances of both `Derived1` and
`Derived2` for `d`, it can optimize the write to `x` to a call to the
@ -324,14 +310,12 @@ This is the best case for a regular "field" type property that is not
turned into a constant. It compiles down to a single CPU-level load
instruction.
```language-js
function SomeConstructor() {
this.x = 10; // x is a definite slot property
this.y = 10; // y is a definite slot property
someComplicatedFunctionCall();
this.z = 20; // z is not a definite slot property.
}
```
function SomeConstructor() {
this.x = 10; // x is a definite slot property
this.y = 10; // y is a definite slot property
someComplicatedFunctionCall();
this.z = 20; // z is not a definite slot property.
}
In the above example, the properties `x` and `y` can be determined to always
exist on any instance of `SomeConstructor` at definite locations, allowing
@ -352,12 +336,10 @@ additionally have been observed to only store values of one kind of value.
Consider the following constructor:
```language-js
function Point(x, y) {
this.x = x;
this.y = y;
}
```
function Point(x, y) {
this.x = x;
this.y = y;
}
If only integers are ever stored in the `x` and `y` properties,
then the instances of `Point` will be represented in an "unboxed" mode -
@ -382,16 +364,14 @@ This optimization compiles down to one-or more shape-guarded direct stores
to the object. The following pseudocode describes the kind of machine
code generated by this optimization:
```
if obj.shape == Shape1 then
obj.slots[0] = val
elif obj.shape == Shape2 then
obj.slots[5] = val
elif obj.shape == Shape3 then
obj.slots[2] = val
...
end
```
if obj.shape == Shape1 then
obj.slots[0] = val
elif obj.shape == Shape2 then
obj.slots[5] = val
elif obj.shape == Shape3 then
obj.slots[2] = val
...
end
### SetProp_InlineCache
@ -411,7 +391,7 @@ Inline caches are an order of magnitude slower than the other optimization
strategies, and are an indication that the type inference engine has
failed to collect enough information to guide the optimization process.
## GetElement
## <a name="getelem"></a>GetElement
### GetElem_TypedObject
@ -467,25 +447,21 @@ access of the form `arguments[i]` can be directly translated into a
direct reference to the corresponding argument value in the inlined call.
Consider the following:
```language-js
function foo(arg) {
return bar(arg, 3);
}
function bar() {
return arguments[0] + arguments[1];
}
```
function foo(arg) {
return bar(arg, 3);
}
function bar() {
return arguments[0] + arguments[1];
}
In the above case, if `foo` is compiled with Ion, and the call to `bar`
is inlined, then this optimization can transform the entire procedure to
the following pseudo-code:
```
compiled foo(arg):
// inlined call to bar(arg, 3) {
return arg + 3;
// }
```
compiled foo(arg):
// inlined call to bar(arg, 3) {
return arg + 3;
// }
### GetElem_InlineCache
@ -505,7 +481,7 @@ Inline caches are an order of magnitude slower than the other optimization
strategies, and are an indication that the type inference engine has
failed to collect enough information to guide the optimization process.
## SetElement
## <a name="setelem"></a>SetElement
### SetElem_TypedObject
@ -567,7 +543,7 @@ Inline caches are an order of magnitude slower than the other optimization
strategies, and are an indication that the type inference engine has
failed to collect enough information to guide the optimization process.
## Call
## <a name="call"></a>Call
### Call_Inline