Skip to content

Commit 2cfda53

Browse files
authored
Improve stub RT reallocation (AssemblyScript#799)
1 parent 471c68c commit 2cfda53

39 files changed

+1215
-1427
lines changed

std/assembly/rt/stub.ts

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { AL_MASK, BLOCK, BLOCK_OVERHEAD, BLOCK_MAXSIZE } from "rt/common";
1+
import { AL_MASK, BLOCK, BLOCK_OVERHEAD, BLOCK_MAXSIZE, AL_SIZE, DEBUG } from "rt/common";
22

33
// @ts-ignore: decorator
44
@lazy
@@ -9,7 +9,7 @@ var startOffset: usize = (__heap_base + AL_MASK) & ~AL_MASK;
99
var offset: usize = startOffset;
1010

1111
function maybeGrowMemory(newOffset: usize): void {
12-
newOffset = (newOffset + AL_MASK) & ~AL_MASK;
12+
// assumes newOffset is aligned
1313
var pagesBefore = memory.size();
1414
var maxOffset = <usize>pagesBefore << 16;
1515
if (newOffset > maxOffset) {
@@ -27,8 +27,11 @@ function maybeGrowMemory(newOffset: usize): void {
2727
export function __alloc(size: usize, id: u32): usize {
2828
if (size > BLOCK_MAXSIZE) unreachable();
2929
var ptr = offset + BLOCK_OVERHEAD;
30-
maybeGrowMemory(ptr + max<usize>(size, 1));
30+
var actualSize = max<usize>((size + AL_MASK) & ~AL_MASK, AL_SIZE);
31+
maybeGrowMemory(ptr + actualSize);
3132
var block = changetype<BLOCK>(ptr - BLOCK_OVERHEAD);
33+
block.mmInfo = actualSize;
34+
if (DEBUG) block.gcInfo = -1;
3235
block.rtId = id;
3336
block.rtSize = size;
3437
return ptr;
@@ -39,27 +42,38 @@ export function __alloc(size: usize, id: u32): usize {
3942
export function __realloc(ptr: usize, size: usize): usize {
4043
assert(ptr != 0 && !(ptr & AL_MASK)); // must exist and be aligned
4144
var block = changetype<BLOCK>(ptr - BLOCK_OVERHEAD);
42-
var actualSize = (<usize>block.rtSize + AL_MASK) & ~AL_MASK;
43-
var isLast = ptr + actualSize == offset;
45+
var actualSize = block.mmInfo;
46+
if (DEBUG) assert(block.gcInfo == -1);
4447
if (size > actualSize) {
45-
if (isLast) { // maybe grow
48+
if (ptr + actualSize == offset) { // last block: grow
4649
if (size > BLOCK_MAXSIZE) unreachable();
47-
maybeGrowMemory(ptr + size);
50+
actualSize = (size + AL_MASK) & ~AL_MASK;
51+
maybeGrowMemory(ptr + actualSize);
52+
block.mmInfo = actualSize;
4853
} else { // copy to new block at least double the size
49-
let newPtr = __alloc(max<usize>(size, actualSize << 1), block.rtId);
50-
memory.copy(newPtr, ptr, actualSize);
54+
actualSize = max<usize>((size + AL_MASK) & ~AL_MASK, actualSize << 1);
55+
let newPtr = __alloc(actualSize, block.rtId);
56+
memory.copy(newPtr, ptr, block.rtSize);
5157
block = changetype<BLOCK>((ptr = newPtr) - BLOCK_OVERHEAD);
5258
}
53-
} else if (isLast) { // shrink
54-
offset = (ptr + size + AL_MASK) & ~AL_MASK;
59+
} else if (ptr + actualSize == offset) { // last block: shrink
60+
actualSize = (size + AL_MASK) & ~AL_MASK;
61+
offset = ptr + actualSize;
62+
block.mmInfo = actualSize;
5563
}
5664
block.rtSize = size;
5765
return ptr;
5866
}
5967

6068
// @ts-ignore: decorator
6169
@unsafe @global
62-
export function __free(ref: usize): void {
70+
export function __free(ptr: usize): void {
71+
assert(ptr != 0 && !(ptr & AL_MASK)); // must exist and be aligned
72+
var block = changetype<BLOCK>(ptr - BLOCK_OVERHEAD);
73+
if (DEBUG) assert(block.gcInfo == -1);
74+
if (ptr + block.mmInfo == offset) { // last block: discard
75+
offset = changetype<usize>(block);
76+
}
6377
}
6478

6579
// @ts-ignore: decorator

tests/compiler/call-super.optimized.wat

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,6 @@
1616
(local $1 i32)
1717
(local $2 i32)
1818
local.get $0
19-
i32.const 15
20-
i32.add
21-
i32.const -16
22-
i32.and
23-
local.tee $0
2419
memory.size
2520
local.tee $2
2621
i32.const 16
@@ -62,6 +57,7 @@
6257
(func $~lib/rt/stub/__alloc (; 2 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32)
6358
(local $2 i32)
6459
(local $3 i32)
60+
(local $4 i32)
6561
local.get $0
6662
i32.const 1073741808
6763
i32.gt_u
@@ -71,25 +67,37 @@
7167
global.get $~lib/rt/stub/offset
7268
i32.const 16
7369
i32.add
74-
local.tee $2
75-
local.get $0
76-
i32.const 1
70+
local.tee $3
7771
local.get $0
78-
i32.const 1
72+
i32.const 15
73+
i32.add
74+
i32.const -16
75+
i32.and
76+
local.tee $2
77+
i32.const 16
78+
local.get $2
79+
i32.const 16
7980
i32.gt_u
8081
select
82+
local.tee $4
8183
i32.add
8284
call $~lib/rt/stub/maybeGrowMemory
83-
local.get $2
85+
local.get $3
8486
i32.const 16
8587
i32.sub
86-
local.tee $3
88+
local.tee $2
89+
local.get $4
90+
i32.store
91+
local.get $2
92+
i32.const -1
93+
i32.store offset=4
94+
local.get $2
8795
local.get $1
8896
i32.store offset=8
89-
local.get $3
97+
local.get $2
9098
local.get $0
9199
i32.store offset=12
92-
local.get $2
100+
local.get $3
93101
)
94102
(func $call-super/A#constructor (; 3 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
95103
local.get $0

tests/compiler/call-super.untouched.wat

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,6 @@
2020
(local $3 i32)
2121
(local $4 i32)
2222
(local $5 i32)
23-
local.get $0
24-
i32.const 15
25-
i32.add
26-
i32.const 15
27-
i32.const -1
28-
i32.xor
29-
i32.and
30-
local.set $0
3123
memory.size
3224
local.set $1
3325
local.get $1
@@ -81,6 +73,7 @@
8173
(local $3 i32)
8274
(local $4 i32)
8375
(local $5 i32)
76+
(local $6 i32)
8477
local.get $0
8578
i32.const 1073741808
8679
i32.gt_u
@@ -91,25 +84,39 @@
9184
i32.const 16
9285
i32.add
9386
local.set $2
94-
local.get $2
9587
local.get $0
88+
i32.const 15
89+
i32.add
90+
i32.const 15
91+
i32.const -1
92+
i32.xor
93+
i32.and
9694
local.tee $3
97-
i32.const 1
95+
i32.const 16
9896
local.tee $4
9997
local.get $3
10098
local.get $4
10199
i32.gt_u
102100
select
101+
local.set $5
102+
local.get $2
103+
local.get $5
103104
i32.add
104105
call $~lib/rt/stub/maybeGrowMemory
105106
local.get $2
106107
i32.const 16
107108
i32.sub
108-
local.set $5
109+
local.set $6
110+
local.get $6
109111
local.get $5
112+
i32.store
113+
local.get $6
114+
i32.const -1
115+
i32.store offset=4
116+
local.get $6
110117
local.get $1
111118
i32.store offset=8
112-
local.get $5
119+
local.get $6
113120
local.get $0
114121
i32.store offset=12
115122
local.get $2

tests/compiler/constructor.optimized.wat

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,6 @@
2222
(local $1 i32)
2323
(local $2 i32)
2424
local.get $0
25-
i32.const 15
26-
i32.add
27-
i32.const -16
28-
i32.and
29-
local.tee $0
3025
memory.size
3126
local.tee $2
3227
i32.const 16
@@ -68,6 +63,7 @@
6863
(func $~lib/rt/stub/__alloc (; 1 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32)
6964
(local $2 i32)
7065
(local $3 i32)
66+
(local $4 i32)
7167
local.get $0
7268
i32.const 1073741808
7369
i32.gt_u
@@ -77,25 +73,37 @@
7773
global.get $~lib/rt/stub/offset
7874
i32.const 16
7975
i32.add
80-
local.tee $2
81-
local.get $0
82-
i32.const 1
76+
local.tee $3
8377
local.get $0
84-
i32.const 1
78+
i32.const 15
79+
i32.add
80+
i32.const -16
81+
i32.and
82+
local.tee $2
83+
i32.const 16
84+
local.get $2
85+
i32.const 16
8586
i32.gt_u
8687
select
88+
local.tee $4
8789
i32.add
8890
call $~lib/rt/stub/maybeGrowMemory
89-
local.get $2
91+
local.get $3
9092
i32.const 16
9193
i32.sub
92-
local.tee $3
94+
local.tee $2
95+
local.get $4
96+
i32.store
97+
local.get $2
98+
i32.const -1
99+
i32.store offset=4
100+
local.get $2
93101
local.get $1
94102
i32.store offset=8
95-
local.get $3
103+
local.get $2
96104
local.get $0
97105
i32.store offset=12
98-
local.get $2
106+
local.get $3
99107
)
100108
(func $start:constructor (; 2 ;) (type $FUNCSIG$v)
101109
(local $0 i32)

tests/compiler/constructor.untouched.wat

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,6 @@
2828
(local $3 i32)
2929
(local $4 i32)
3030
(local $5 i32)
31-
local.get $0
32-
i32.const 15
33-
i32.add
34-
i32.const 15
35-
i32.const -1
36-
i32.xor
37-
i32.and
38-
local.set $0
3931
memory.size
4032
local.set $1
4133
local.get $1
@@ -89,6 +81,7 @@
8981
(local $3 i32)
9082
(local $4 i32)
9183
(local $5 i32)
84+
(local $6 i32)
9285
local.get $0
9386
i32.const 1073741808
9487
i32.gt_u
@@ -99,25 +92,39 @@
9992
i32.const 16
10093
i32.add
10194
local.set $2
102-
local.get $2
10395
local.get $0
96+
i32.const 15
97+
i32.add
98+
i32.const 15
99+
i32.const -1
100+
i32.xor
101+
i32.and
104102
local.tee $3
105-
i32.const 1
103+
i32.const 16
106104
local.tee $4
107105
local.get $3
108106
local.get $4
109107
i32.gt_u
110108
select
109+
local.set $5
110+
local.get $2
111+
local.get $5
111112
i32.add
112113
call $~lib/rt/stub/maybeGrowMemory
113114
local.get $2
114115
i32.const 16
115116
i32.sub
116-
local.set $5
117+
local.set $6
118+
local.get $6
117119
local.get $5
120+
i32.store
121+
local.get $6
122+
i32.const -1
123+
i32.store offset=4
124+
local.get $6
118125
local.get $1
119126
i32.store offset=8
120-
local.get $5
127+
local.get $6
121128
local.get $0
122129
i32.store offset=12
123130
local.get $2

tests/compiler/exports.optimized.wat

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,6 @@
6464
(local $1 i32)
6565
(local $2 i32)
6666
local.get $0
67-
i32.const 15
68-
i32.add
69-
i32.const -16
70-
i32.and
71-
local.tee $0
7267
memory.size
7368
local.tee $2
7469
i32.const 16
@@ -113,20 +108,26 @@
113108
global.get $~lib/rt/stub/offset
114109
i32.const 16
115110
i32.add
116-
local.tee $1
117-
i32.const 4
111+
local.tee $2
112+
i32.const 16
118113
i32.add
119114
call $~lib/rt/stub/maybeGrowMemory
120-
local.get $1
115+
local.get $2
121116
i32.const 16
122117
i32.sub
123-
local.tee $2
118+
local.tee $1
119+
i32.const 16
120+
i32.store
121+
local.get $1
122+
i32.const -1
123+
i32.store offset=4
124+
local.get $1
124125
local.get $0
125126
i32.store offset=8
126-
local.get $2
127+
local.get $1
127128
i32.const 4
128129
i32.store offset=12
129-
local.get $1
130+
local.get $2
130131
)
131132
(func $exports/Car#get:numDoors (; 5 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
132133
local.get $0

0 commit comments

Comments
 (0)