Skip to content

Commit fa42172

Browse files
authored
[std] Optimize reverse method for Arrays (AssemblyScript#2016)
1 parent 91b531c commit fa42172

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+27078
-26041
lines changed

std/assembly/array.ts

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import { BLOCK_MAXSIZE } from "./rt/common";
44
import { COMPARATOR, SORT } from "./util/sort";
5+
import { REVERSE } from "./util/bytes";
56
import { joinBooleanArray, joinIntegerArray, joinFloatArray, joinStringArray, joinReferenceArray } from "./util/string";
67
import { idof, isArray as builtin_isArray } from "./builtins";
78
import { E_INDEXOUTOFRANGE, E_INVALIDLENGTH, E_ILLEGALGENTYPE, E_EMPTYARRAY, E_HOLEYARRAY } from "./util/error";
@@ -431,18 +432,7 @@ export class Array<T> {
431432
}
432433

433434
reverse(): Array<T> {
434-
var len = this.length_;
435-
if (len) {
436-
let front = this.dataStart;
437-
let back = this.dataStart + (<usize>(len - 1) << alignof<T>());
438-
while (front < back) {
439-
let temp = load<T>(front);
440-
store<T>(front, load<T>(back));
441-
store<T>(back, temp);
442-
front += sizeof<T>();
443-
back -= sizeof<T>();
444-
}
445-
}
435+
REVERSE<T>(this.dataStart, this.length_);
446436
return this;
447437
}
448438

std/assembly/typedarray.ts

Lines changed: 23 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { COMPARATOR, SORT } from "./util/sort";
22
import { E_INDEXOUTOFRANGE, E_INVALIDLENGTH, E_NOTIMPLEMENTED } from "./util/error";
33
import { joinIntegerArray, joinFloatArray } from "./util/string";
4+
import { REVERSE } from "./util/bytes";
45
import { idof } from "./builtins";
56
import { ArrayBufferView } from "./arraybuffer";
67

@@ -124,7 +125,8 @@ export class Int8Array extends ArrayBufferView {
124125
}
125126

126127
reverse(): this {
127-
return REVERSE<this, i8>(this);
128+
REVERSE<u8>(this.dataStart, this.length);
129+
return this;
128130
}
129131

130132
join(separator: string = ","): string {
@@ -264,7 +266,8 @@ export class Uint8Array extends ArrayBufferView {
264266
}
265267

266268
reverse(): this {
267-
return REVERSE<this, u8>(this);
269+
REVERSE<u8>(this.dataStart, this.length);
270+
return this;
268271
}
269272

270273
join(separator: string = ","): string {
@@ -404,7 +407,8 @@ export class Uint8ClampedArray extends ArrayBufferView {
404407
}
405408

406409
reverse(): this {
407-
return REVERSE<this, u8>(this);
410+
REVERSE<u8>(this.dataStart, this.length);
411+
return this;
408412
}
409413

410414
join(separator: string = ","): string {
@@ -544,7 +548,8 @@ export class Int16Array extends ArrayBufferView {
544548
}
545549

546550
reverse(): this {
547-
return REVERSE<this, i16>(this);
551+
REVERSE<u16>(this.dataStart, this.length);
552+
return this;
548553
}
549554

550555
join(separator: string = ","): string {
@@ -684,7 +689,8 @@ export class Uint16Array extends ArrayBufferView {
684689
}
685690

686691
reverse(): this {
687-
return REVERSE<this, u16>(this);
692+
REVERSE<u16>(this.dataStart, this.length);
693+
return this;
688694
}
689695

690696
join(separator: string = ","): string {
@@ -824,7 +830,8 @@ export class Int32Array extends ArrayBufferView {
824830
}
825831

826832
reverse(): this {
827-
return REVERSE<this, i32>(this);
833+
REVERSE<u32>(this.dataStart, this.length);
834+
return this;
828835
}
829836

830837
join(separator: string = ","): string {
@@ -964,7 +971,8 @@ export class Uint32Array extends ArrayBufferView {
964971
}
965972

966973
reverse(): this {
967-
return REVERSE<this, u32>(this);
974+
REVERSE<u32>(this.dataStart, this.length);
975+
return this;
968976
}
969977

970978
join(separator: string = ","): string {
@@ -1104,7 +1112,8 @@ export class Int64Array extends ArrayBufferView {
11041112
}
11051113

11061114
reverse(): this {
1107-
return REVERSE<this, i64>(this);
1115+
REVERSE<u64>(this.dataStart, this.length);
1116+
return this;
11081117
}
11091118

11101119
join(separator: string = ","): string {
@@ -1244,7 +1253,8 @@ export class Uint64Array extends ArrayBufferView {
12441253
}
12451254

12461255
reverse(): this {
1247-
return REVERSE<this, u64>(this);
1256+
REVERSE<u64>(this.dataStart, this.length);
1257+
return this;
12481258
}
12491259

12501260
join(separator: string = ","): string {
@@ -1384,7 +1394,8 @@ export class Float32Array extends ArrayBufferView {
13841394
}
13851395

13861396
reverse(): this {
1387-
return REVERSE<this, f32>(this);
1397+
REVERSE<f32>(this.dataStart, this.length);
1398+
return this;
13881399
}
13891400

13901401
join(separator: string = ","): string {
@@ -1524,7 +1535,8 @@ export class Float64Array extends ArrayBufferView {
15241535
}
15251536

15261537
reverse(): this {
1527-
return REVERSE<this, f64>(this);
1538+
REVERSE<f64>(this.dataStart, this.length);
1539+
return this;
15281540
}
15291541

15301542
join(separator: string = ","): string {
@@ -1844,20 +1856,6 @@ function FOREACH<TArray extends ArrayBufferView, T>(
18441856
}
18451857
}
18461858

1847-
// @ts-ignore: decorator
1848-
@inline
1849-
function REVERSE<TArray extends ArrayBufferView, T>(array: TArray): TArray {
1850-
var ptr = array.dataStart;
1851-
for (let front: usize = 0, back: usize = array.length - 1; front < back; ++front, --back) {
1852-
let frontPtr = ptr + (front << alignof<T>());
1853-
let backPtr = ptr + (back << alignof<T>());
1854-
let temp = load<T>(frontPtr);
1855-
store<T>(frontPtr, load<T>(backPtr));
1856-
store<T>(backPtr, temp);
1857-
}
1858-
return array;
1859-
}
1860-
18611859
// @ts-ignore: decorator
18621860
@inline
18631861
function WRAP<TArray extends ArrayBufferView, T>(

std/assembly/util/bytes.ts

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
export function REVERSE<T>(ptr: usize, len: usize): void {
2+
if (len > 1) {
3+
let
4+
i: usize = 0,
5+
tail: usize,
6+
hlen: usize = len >> 1;
7+
8+
if (ASC_SHRINK_LEVEL < 1) {
9+
if (sizeof<T>() == 1) {
10+
// TODO: Decide later: Does we need this fast path cases?
11+
//
12+
// if (len == 4) {
13+
// store<u32>(ptr, bswap(load<u32>(ptr)));
14+
// return;
15+
// }
16+
// if (len == 8) {
17+
// store<u64>(ptr, bswap(load<u64>(ptr)));
18+
// return;
19+
// }
20+
tail = len - 8;
21+
while (i + 7 < hlen) {
22+
let front = ptr + i;
23+
let back = ptr + tail - i;
24+
let temp = bswap(load<u64>(front));
25+
store<u64>(front, bswap(load<u64>(back)));
26+
store<u64>(back, temp);
27+
i += 8;
28+
}
29+
}
30+
31+
if (sizeof<T>() == 2) {
32+
tail = len - 2;
33+
while (i + 1 < hlen) {
34+
let front = ptr + (i << 1);
35+
let back = ptr + (tail - i << 1);
36+
let temp = rotr(load<u32>(back), 16);
37+
store<u32>(back, rotr(load<u32>(front), 16));
38+
store<u32>(front, temp);
39+
i += 2;
40+
}
41+
}
42+
}
43+
44+
tail = len - 1;
45+
while (i < hlen) {
46+
let front = ptr + (i << alignof<T>());
47+
let back = ptr + (tail - i << alignof<T>());
48+
let temp = load<T>(front);
49+
store<T>(front, load<T>(back));
50+
store<T>(back, temp);
51+
i++;
52+
}
53+
}
54+
}

tests/compiler/assert-nonnull.optimized.wat

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@
5555
if
5656
i32.const 1184
5757
i32.const 1248
58-
i32.const 106
58+
i32.const 107
5959
i32.const 42
6060
call $~lib/builtins/abort
6161
unreachable
@@ -261,7 +261,7 @@
261261
if
262262
i32.const 1184
263263
i32.const 1248
264-
i32.const 106
264+
i32.const 107
265265
i32.const 42
266266
call $~lib/builtins/abort
267267
unreachable
@@ -277,7 +277,7 @@
277277
if
278278
i32.const 1296
279279
i32.const 1248
280-
i32.const 110
280+
i32.const 111
281281
i32.const 40
282282
call $~lib/builtins/abort
283283
unreachable

tests/compiler/assert-nonnull.untouched.wat

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,7 @@
310310
if
311311
i32.const 160
312312
i32.const 224
313-
i32.const 106
313+
i32.const 107
314314
i32.const 42
315315
call $~lib/builtins/abort
316316
unreachable
@@ -335,7 +335,7 @@
335335
if
336336
i32.const 272
337337
i32.const 224
338-
i32.const 110
338+
i32.const 111
339339
i32.const 40
340340
call $~lib/builtins/abort
341341
unreachable
@@ -366,7 +366,7 @@
366366
if
367367
i32.const 160
368368
i32.const 224
369-
i32.const 106
369+
i32.const 107
370370
i32.const 42
371371
call $~lib/builtins/abort
372372
unreachable

tests/compiler/class.untouched.wat

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2724,7 +2724,7 @@
27242724
if
27252725
i32.const 432
27262726
i32.const 480
2727-
i32.const 64
2727+
i32.const 65
27282728
i32.const 60
27292729
call $~lib/builtins/abort
27302730
unreachable

tests/compiler/extends-baseaggregate.optimized.wat

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2554,7 +2554,7 @@
25542554
if
25552555
i32.const 1616
25562556
i32.const 1664
2557-
i32.const 17
2557+
i32.const 18
25582558
i32.const 48
25592559
call $~lib/builtins/abort
25602560
unreachable

tests/compiler/extends-baseaggregate.untouched.wat

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3761,7 +3761,7 @@
37613761
if
37623762
i32.const 592
37633763
i32.const 640
3764-
i32.const 17
3764+
i32.const 18
37653765
i32.const 48
37663766
call $~lib/builtins/abort
37673767
unreachable

tests/compiler/infer-array.optimized.wat

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2844,7 +2844,7 @@
28442844
end
28452845
i32.const 1280
28462846
i32.const 1488
2847-
i32.const 106
2847+
i32.const 107
28482848
i32.const 42
28492849
call $~lib/builtins/abort
28502850
unreachable

tests/compiler/infer-array.untouched.wat

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3708,7 +3708,7 @@
37083708
if
37093709
i32.const 256
37103710
i32.const 464
3711-
i32.const 106
3711+
i32.const 107
37123712
i32.const 42
37133713
call $~lib/builtins/abort
37143714
unreachable
@@ -3734,7 +3734,7 @@
37343734
if
37353735
i32.const 256
37363736
i32.const 464
3737-
i32.const 106
3737+
i32.const 107
37383738
i32.const 42
37393739
call $~lib/builtins/abort
37403740
unreachable
@@ -3760,7 +3760,7 @@
37603760
if
37613761
i32.const 256
37623762
i32.const 464
3763-
i32.const 106
3763+
i32.const 107
37643764
i32.const 42
37653765
call $~lib/builtins/abort
37663766
unreachable
@@ -3786,7 +3786,7 @@
37863786
if
37873787
i32.const 256
37883788
i32.const 464
3789-
i32.const 106
3789+
i32.const 107
37903790
i32.const 42
37913791
call $~lib/builtins/abort
37923792
unreachable
@@ -3828,7 +3828,7 @@
38283828
if
38293829
i32.const 256
38303830
i32.const 464
3831-
i32.const 106
3831+
i32.const 107
38323832
i32.const 42
38333833
call $~lib/builtins/abort
38343834
unreachable
@@ -4604,7 +4604,7 @@
46044604
if
46054605
i32.const 256
46064606
i32.const 464
4607-
i32.const 106
4607+
i32.const 107
46084608
i32.const 42
46094609
call $~lib/builtins/abort
46104610
unreachable
@@ -4650,7 +4650,7 @@
46504650
if
46514651
i32.const 256
46524652
i32.const 464
4653-
i32.const 106
4653+
i32.const 107
46544654
i32.const 42
46554655
call $~lib/builtins/abort
46564656
unreachable
@@ -4696,7 +4696,7 @@
46964696
if
46974697
i32.const 256
46984698
i32.const 464
4699-
i32.const 106
4699+
i32.const 107
47004700
i32.const 42
47014701
call $~lib/builtins/abort
47024702
unreachable
@@ -4721,7 +4721,7 @@
47214721
if
47224722
i32.const 976
47234723
i32.const 464
4724-
i32.const 110
4724+
i32.const 111
47254725
i32.const 40
47264726
call $~lib/builtins/abort
47274727
unreachable

0 commit comments

Comments
 (0)