[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>
This commit is contained in:
Stephen Adams 2022-05-16 19:13:15 +00:00 committed by Commit Bot
parent 8a978ffc7f
commit 7ff9b2fb5e
2 changed files with 2 additions and 93 deletions

View file

@ -435,8 +435,7 @@ class JSNumber extends Interceptor implements int, double {
@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 @@ class JSNumber extends Interceptor implements int, double {
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);
}

View file

@ -531,8 +531,7 @@ class JSInt extends JSNumber implements int {
}
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 @@ class JSInt extends JSNumber implements int {
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);