Due to array type inference we may find ourselves entering a loop with a different array mode (and hence structure) than what we leave with. Typically the loop will have an idempotent effect on both array type and structure: whenever it runs it transitions, either directly or indirectly, the array to exactly one structure. This can be optimized using an effectful structure check: if an object doesn't have the structure we wanted, we attempt to convert to that structure and only OSR exit if we cannot do so. If such an effectful structure check is hoisted, it ought to allow for rapid up-casting from bottom arrays to int arrays, int arrays to double arrays, and so on.
It would also be great if an effectful structure check could speculate must-not-alias. Ordinarily an effectful structure check would have to be assumed by the CFA to clobber all structures, since it may change the structure of some object and all other objects we have references to may be aliased to that object.
But we could speculate against this by having the effectful slow path of an effectful structure check check all variables that have been proven to have some structure, and verify that they are not equal to the object being effectfully checked.
*** Bug 99269 has been marked as a duplicate of this bug. ***
Created attachment 171146 [details]
Attachment 171146 [details] did not pass style-queue:
Total errors found: 1 in 20 files
If any of these errors are false positives, please file a bug against check-webkit-style.
(In reply to comment #4)
> Attachment 171146 [details] did not pass style-queue:
> Total errors found: 1 in 20 files
> If any of these errors are false positives, please file a bug against check-webkit-style.
I should note that I changed the bug title to reflect that I'm only introducing the notion of effectful structure checks, and not hoisting them yet. This is because with the current implementation of https://bugs.webkit.org/show_bug.cgi?id=98606, it's unlikely that a loop that accesses an array directly will see multiple array types unless there are additional indirections. This is because in the programs I've seen, it's unlikely that you'll have a loop that operates directly over an array without mutating it - and if it mutates it, the baseline JIT will already LUB the array to a single type and the array allocation profile will henceforth only allocate arrays at the LUBed type. So, what we worry about is loops of the form:
for (things) ... = array[i]
where the array can have multiple types. It turns out that this kind of loop is considerably less likely in real code than:
for (things) ... = o.array[i]
for (things) ... = o[i][j]
in which case hoisting doesn't buy you much. Hence, I'm not going to implement hoisting, yet.
However, for such loops, having the effectful array check be a structure check instead of an indexing type check is profitable - it saves on some arithmetic, a register, and a load. Also, the one remaining load is dead except for a branch, which tends to be quite fast in most architectures.
Landed in http://trac.webkit.org/changeset/132759