[js_runtime] Use Math.clz32

Change-Id: Ibe6598587151d7c5e0595cffde4b35d024f63c15
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/244861
Reviewed-by: Nicholas Shahan <nshahan@google.com>
Commit-Queue: Stephen Adams <sra@google.com>
diff --git a/sdk/lib/_internal/js_dev_runtime/private/js_number.dart b/sdk/lib/_internal/js_dev_runtime/private/js_number.dart
index b90d786..864aac7 100644
--- a/sdk/lib/_internal/js_dev_runtime/private/js_number.dart
+++ b/sdk/lib/_internal/js_dev_runtime/private/js_number.dart
@@ -435,8 +435,7 @@
 
   @notNull
   static int _clz32(@notNull int uint32) {
-    // TODO(sra): Use `Math.clz32(uint32)` (not available on IE11).
-    return 32 - _bitCount(_spread(uint32));
+    return JS('!', 'Math.clz32(#)', uint32);
   }
 
   // Returns pow(this, e) % m.
@@ -581,54 +580,6 @@
     return _binaryGcd(x, y, false);
   }
 
-  // Assumes i is <= 32-bit and unsigned.
-  @notNull
-  static int _bitCount(@notNull int i) {
-    // See "Hacker's Delight", section 5-1, "Counting 1-Bits".
-
-    // The basic strategy is to use "divide and conquer" to
-    // add pairs (then quads, etc.) of bits together to obtain
-    // sub-counts.
-    //
-    // A straightforward approach would look like:
-    //
-    // i = (i & 0x55555555) + ((i >>  1) & 0x55555555);
-    // i = (i & 0x33333333) + ((i >>  2) & 0x33333333);
-    // i = (i & 0x0F0F0F0F) + ((i >>  4) & 0x0F0F0F0F);
-    // i = (i & 0x00FF00FF) + ((i >>  8) & 0x00FF00FF);
-    // i = (i & 0x0000FFFF) + ((i >> 16) & 0x0000FFFF);
-    //
-    // The code below removes unnecessary &'s and uses a
-    // trick to remove one instruction in the first line.
-
-    i = _shru(i, 0) - (_shru(i, 1) & 0x55555555);
-    i = (i & 0x33333333) + (_shru(i, 2) & 0x33333333);
-    i = 0x0F0F0F0F & (i + _shru(i, 4));
-    i += _shru(i, 8);
-    i += _shru(i, 16);
-    return (i & 0x0000003F);
-  }
-
-  @notNull
-  static int _shru(int value, int shift) =>
-      JS<int>('!', '# >>> #', value, shift);
-  @notNull
-  static int _shrs(int value, int shift) =>
-      JS<int>('!', '# >> #', value, shift);
-  @notNull
-  static int _ors(int a, int b) => JS<int>('!', '# | #', a, b);
-
-  // Assumes i is <= 32-bit
-  @notNull
-  static int _spread(@notNull int i) {
-    i = _ors(i, _shrs(i, 1));
-    i = _ors(i, _shrs(i, 2));
-    i = _ors(i, _shrs(i, 4));
-    i = _ors(i, _shrs(i, 8));
-    i = _shru(_ors(i, _shrs(i, 16)), 0);
-    return i;
-  }
-
   @notNull
   int operator ~() => JS<int>('!', r'(~#) >>> 0', this);
 }
diff --git a/sdk/lib/_internal/js_runtime/lib/js_number.dart b/sdk/lib/_internal/js_runtime/lib/js_number.dart
index f217b53..356a4c0 100644
--- a/sdk/lib/_internal/js_runtime/lib/js_number.dart
+++ b/sdk/lib/_internal/js_runtime/lib/js_number.dart
@@ -531,8 +531,7 @@
   }
 
   static int _clz32(int uint32) {
-    // TODO(sra): Use `Math.clz32(uint32)` (not available on IE11).
-    return 32 - _bitCount(_spread(uint32));
+    return JS('JSUInt31', 'Math.clz32(#)', uint32);
   }
 
   // Returns pow(this, e) % m.
@@ -684,47 +683,6 @@
     return _binaryGcd(x, y, false);
   }
 
-  // Assumes i is <= 32-bit and unsigned.
-  static int _bitCount(int i) {
-    // See "Hacker's Delight", section 5-1, "Counting 1-Bits".
-
-    // The basic strategy is to use "divide and conquer" to
-    // add pairs (then quads, etc.) of bits together to obtain
-    // sub-counts.
-    //
-    // A straightforward approach would look like:
-    //
-    // i = (i & 0x55555555) + ((i >>  1) & 0x55555555);
-    // i = (i & 0x33333333) + ((i >>  2) & 0x33333333);
-    // i = (i & 0x0F0F0F0F) + ((i >>  4) & 0x0F0F0F0F);
-    // i = (i & 0x00FF00FF) + ((i >>  8) & 0x00FF00FF);
-    // i = (i & 0x0000FFFF) + ((i >> 16) & 0x0000FFFF);
-    //
-    // The code below removes unnecessary &'s and uses a
-    // trick to remove one instruction in the first line.
-
-    i = _shru(i, 0) - (_shru(i, 1) & 0x55555555);
-    i = (i & 0x33333333) + (_shru(i, 2) & 0x33333333);
-    i = 0x0F0F0F0F & (i + _shru(i, 4));
-    i += _shru(i, 8);
-    i += _shru(i, 16);
-    return (i & 0x0000003F);
-  }
-
-  static int _shru(int value, int shift) => JS('int', '# >>> #', value, shift);
-  static int _shrs(int value, int shift) => JS('int', '# >> #', value, shift);
-  static int _ors(int a, int b) => JS('int', '# | #', a, b);
-
-  // Assumes i is <= 32-bit
-  static int _spread(int i) {
-    i = _ors(i, _shrs(i, 1));
-    i = _ors(i, _shrs(i, 2));
-    i = _ors(i, _shrs(i, 4));
-    i = _ors(i, _shrs(i, 8));
-    i = _shru(_ors(i, _shrs(i, 16)), 0);
-    return i;
-  }
-
   Type get runtimeType => int;
 
   int operator ~() => JS('JSUInt32', r'(~#) >>> 0', this);