Skip to content

Commit

Permalink
[js_runtime] Use Math.clz32
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
rakudrama authored and Commit Bot committed May 16, 2022
1 parent 8a978ff commit 7ff9b2f
Show file tree
Hide file tree
Showing 2 changed files with 2 additions and 93 deletions.
51 changes: 1 addition & 50 deletions sdk/lib/_internal/js_dev_runtime/private/js_number.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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);
}
44 changes: 1 addition & 43 deletions sdk/lib/_internal/js_runtime/lib/js_number.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 7ff9b2f

Please sign in to comment.