Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(549)

Unified Diff: pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart

Issue 1699033003: dart2js cps: Combine integer type check with bounds check. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Update status Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart
index 7cb92608d54dec77baae5c2238792c9ebb407b5c..156226216205f4d85cdc75c815e95e09ede3e3ed 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart
@@ -781,14 +781,21 @@ class Refinement extends Primitive {
/// Checks that [index] is a valid index on a given indexable [object].
///
-/// Compiles to the following, with a subset of the conditions in the `if`:
+/// In the simplest form, compiles to the following:
///
-/// if (index < 0 || index >= object.length || object.length === 0)
+/// if (index < 0 || index >= object.length)
/// ThrowIndexOutOfRangeException(object, index);
///
-/// [index] must be an integer, and [object] must refer to null or an indexable
-/// object, and [length] must be the length of [object] at the time of the
-/// check.
+/// In the general form, any of the following conditions can be checked:
+///
+/// Lower bound: `index >= 0`
+/// Upper bound: `index < object.length`
+/// Emptiness: `object.length !== 0`
+/// Integerness: `index >>> 0 === index`
+///
+/// [index] must be an integer unless integerness is checked, and [object] must
+/// refer to null or an indexable object, and [length] must be the length of
+/// [object] at the time of the check.
///
/// Returns [object] so the bounds check can be used to restrict code motion.
/// It is possible to have a bounds check node that performs no checks but
@@ -825,6 +832,9 @@ class BoundsCheck extends Primitive {
/// because that corresponds to `object.length - 1` in the error case.
bool get hasEmptinessCheck => checks & EMPTINESS != 0;
+ /// If true, check that `index` is an integer.
+ bool get hasIntegerCheck => checks & INTEGER != 0;
+
/// True if the [length] is needed to perform the check.
bool get lengthUsedInCheck => checks & (UPPER_BOUND | EMPTINESS) != 0;
@@ -833,6 +843,7 @@ class BoundsCheck extends Primitive {
static const int UPPER_BOUND = 1 << 0;
static const int LOWER_BOUND = 1 << 1;
static const int EMPTINESS = 1 << 2; // See [hasEmptinessCheck].
+ static const int INTEGER = 1 << 3; // Check if index is an int.
static const int BOTH_BOUNDS = UPPER_BOUND | LOWER_BOUND;
static const int NONE = 0;
@@ -859,17 +870,13 @@ class BoundsCheck extends Primitive {
}
String get checkString {
- if (hasUpperBoundCheck && hasLowerBoundCheck) {
- return 'upper-lower-checks';
- } else if (hasUpperBoundCheck) {
- return 'upper-check';
- } else if (hasLowerBoundCheck) {
- return 'lower-check';
- } else if (hasEmptinessCheck) {
- return 'emptiness-check';
- } else {
- return 'no-check';
- }
+ if (hasNoChecks) return 'no-check';
+ return [hasUpperBoundCheck ? 'upper' : null,
+ hasLowerBoundCheck ? 'lower' : null,
+ hasEmptinessCheck ? 'emptiness' : null,
+ hasIntegerCheck ? 'integer' : null,
+ 'check']
+ .where((x) => x != null).join('-');
}
bool get isSafeForElimination => checks == NONE;

Powered by Google App Engine
This is Rietveld 408576698