[dart2js][js_runtime] Use Array.isArray more consistently
The main reason is to do this change is to avoid inconsistencies in what is considered to be a `JSArray`. Using `Array.isArray` allows js-interop where the JavaScript code subclasses `Array`. dart2js-production results: ArrayLoop.pseudopoly.hoisted1-indexing -50.20% ArrayLoop.pseudopoly.indexing -35.18% Iteration.concat.manual 11.69% ListCopy.List.int.unmodifiable.2 12.03% ListCopy.for.int.2 12.58% ListCopy.spread.int.2 13.57% ListCopy.toList.fixed.100 16.06% ListCopy.List.of.fixed.100 16.96% ListCopy.toList.100 17.28% ListCopy.spread.int.cast.2 18.45% ObjectHash.hash.5 19.62% TypedDataPoly.A_UVx5.view.2 21.12% ObjectHash.manual.5 21.70% ListCopy.spread.int.map.2 21.96% ListCopy.spread.int.cast.100 22.12% TypedDataPoly.A_UVx5.view.100 23.04% ListCopy.spread.int.map.100 25.26% ListCopy.List.of.100 27.88% ImagingGaussianBlurOnce 29.67% MegaEquality 37.90% An investigation of the two regressions shows that they benefit from a micro-benchmarking effect. The previous code was monomorphic at the property access in `receiver.constructor == Array`. If this is forced to be polymorphic, the baseline is quite a bit worse, leading to an improvement in line with some of the other benchmarks. Change-Id: I5c265b1d7408fbd41da9c6fa17472bf648000c8d Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/287140 Reviewed-by: Nate Biggs <natebiggs@google.com> Commit-Queue: Stephen Adams <sra@google.com>
This commit is contained in:
committed by
Commit Queue
parent
000655e4d3
commit
62a67ba5bc
@@ -69,7 +69,7 @@ class InterceptorStubGenerator {
|
||||
cls == _commonElements.jsMutableArrayClass ||
|
||||
cls == _commonElements.jsFixedArrayClass ||
|
||||
cls == _commonElements.jsExtendableArrayClass) {
|
||||
condition = js('receiver.constructor == Array');
|
||||
condition = js('Array.isArray(receiver)');
|
||||
} else if (cls == _commonElements.jsStringClass) {
|
||||
condition = js('(typeof receiver) == "string"');
|
||||
} else if (cls == _commonElements.jsNullClass) {
|
||||
@@ -303,8 +303,7 @@ class InterceptorStubGenerator {
|
||||
// For an index operation, this code generates:
|
||||
//
|
||||
// if (typeof a0 === "number") {
|
||||
// if (receiver.constructor == Array ||
|
||||
// typeof receiver == "string") {
|
||||
// if (Array.isArray(receiver) || typeof receiver == "string") {
|
||||
// if (a0 >>> 0 === a0 && a0 < receiver.length) {
|
||||
// return receiver[a0];
|
||||
// }
|
||||
@@ -314,7 +313,7 @@ class InterceptorStubGenerator {
|
||||
// For an index set operation, this code generates:
|
||||
//
|
||||
// if (typeof a0 === "number") {
|
||||
// if (receiver.constructor == Array && !receiver.immutable$list) {
|
||||
// if (Array.isArray(receiver) && !receiver.immutable$list) {
|
||||
// if (a0 >>> 0 === a0 && a0 < receiver.length) {
|
||||
// return receiver[a0] = a1;
|
||||
// }
|
||||
@@ -343,7 +342,7 @@ class InterceptorStubGenerator {
|
||||
if (!containsArray && !containsString) {
|
||||
return null;
|
||||
}
|
||||
jsAst.Expression arrayCheck = js('receiver.constructor == Array');
|
||||
jsAst.Expression arrayCheck = js('Array.isArray(receiver)');
|
||||
|
||||
// Lazy generation of the indexable check. If indexable behavior isn't
|
||||
// used, the isJsIndexable function isn't part of the closed world.
|
||||
|
||||
@@ -385,7 +385,7 @@ void initHooks() {
|
||||
if (JS('bool', 'typeof # == "function"', transformers)) {
|
||||
transformers = [transformers];
|
||||
}
|
||||
if (JS('bool', '#.constructor == Array', transformers)) {
|
||||
if (JS('bool', 'Array.isArray(#)', transformers)) {
|
||||
for (int i = 0; i < JS('int', '#.length', transformers); i++) {
|
||||
var transformer = JS('', '#[#]', transformers, i);
|
||||
if (JS('bool', 'typeof # == "function"', transformer)) {
|
||||
|
||||
Reference in New Issue
Block a user