Skip to content

Commit 8c062af

Browse files
committed
feat(compiler): Use data segments for string data
1 parent 7b7acfd commit 8c062af

File tree

4 files changed

+107
-39
lines changed

4 files changed

+107
-39
lines changed

compiler/src/codegen/compcore.re

Lines changed: 102 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,17 @@ let gensym_label = s => {
3737
};
3838
let reset_labels = () => gensym_counter := 0;
3939

40+
let data_segments: ref((int, list(Memory.segment))) = ref((0, []));
41+
let push_data_segment = segment => {
42+
let (count, segments) = data_segments^;
43+
data_segments := (count + 1, [segment, ...segments]);
44+
};
45+
let get_data_segment_count = () => {
46+
let (count, _) = data_segments^;
47+
count;
48+
};
49+
let reset_data_segments = () => data_segments := (0, []);
50+
4051
/* Number of swap variables to allocate */
4152
let swap_slots_i32 = [|Type.int32, Type.int32, Type.int32|];
4253
let swap_slots_i64 = [|Type.int64|];
@@ -121,6 +132,7 @@ let rec resolve_func = (~env, name) => {
121132

122133
let reset = () => {
123134
reset_labels();
135+
reset_data_segments();
124136
};
125137

126138
let get_runtime_heap_start = wasm_mod =>
@@ -1271,45 +1283,93 @@ let call_lambda =
12711283
};
12721284

12731285
let allocate_byte_like_from_buffer = (wasm_mod, env, buf, tag, label) => {
1274-
let ints_to_push: list(int64) = buf_to_ints(buf);
12751286
let get_swap = () => get_swap(wasm_mod, env, 0);
12761287
let tee_swap = tee_swap(wasm_mod, env, 0);
1277-
let preamble = [
1278-
store(
1279-
~offset=0,
1280-
wasm_mod,
1281-
tee_swap(
1282-
heap_allocate(wasm_mod, env, 2 + 2 * List.length(ints_to_push)),
1283-
),
1284-
Expression.Const.make(
1285-
wasm_mod,
1286-
const_int32(tag_val_of_heap_tag_type(tag)),
1287-
),
1288-
),
1289-
store(
1290-
~offset=4,
1288+
if (Config.bulk_memory^) {
1289+
let segment_offset = get_data_segment_count();
1290+
let data_size = Buffer.length(buf);
1291+
Memory.(
1292+
push_data_segment({
1293+
data: Buffer.to_bytes(buf),
1294+
kind: Passive,
1295+
size: data_size,
1296+
})
1297+
);
1298+
Expression.Block.make(
12911299
wasm_mod,
1292-
get_swap(),
1293-
Expression.Const.make(wasm_mod, const_int32 @@ Buffer.length(buf)),
1294-
),
1295-
];
1296-
let elts =
1297-
List.mapi(
1298-
(idx, i: int64) =>
1300+
gensym_label(label),
1301+
[
1302+
store(
1303+
~offset=0,
1304+
wasm_mod,
1305+
// compute number of words (add 3 to account for floored division)
1306+
tee_swap(heap_allocate(wasm_mod, env, 2 + (data_size + 3) / 4)),
1307+
Expression.Const.make(
1308+
wasm_mod,
1309+
const_int32(tag_val_of_heap_tag_type(tag)),
1310+
),
1311+
),
12991312
store(
1300-
~ty=Type.int64,
1301-
~offset=8 * (idx + 1),
1313+
~offset=4,
13021314
wasm_mod,
13031315
get_swap(),
1304-
Expression.Const.make(wasm_mod, wrap_int64(i)),
1316+
Expression.Const.make(wasm_mod, const_int32 @@ data_size),
1317+
),
1318+
Expression.Memory_init.make(
1319+
wasm_mod,
1320+
segment_offset,
1321+
Expression.Binary.make(
1322+
wasm_mod,
1323+
Op.add_int32,
1324+
get_swap(),
1325+
Expression.Const.make(wasm_mod, const_int32(8)),
1326+
),
1327+
Expression.Const.make(wasm_mod, const_int32(0)),
1328+
Expression.Const.make(wasm_mod, const_int32(data_size)),
1329+
grain_memory,
1330+
),
1331+
get_swap(),
1332+
],
1333+
);
1334+
} else {
1335+
let ints_to_push: list(int64) = buf_to_ints(buf);
1336+
let preamble = [
1337+
store(
1338+
~offset=0,
1339+
wasm_mod,
1340+
tee_swap(
1341+
heap_allocate(wasm_mod, env, 2 + 2 * List.length(ints_to_push)),
1342+
),
1343+
Expression.Const.make(
1344+
wasm_mod,
1345+
const_int32(tag_val_of_heap_tag_type(tag)),
13051346
),
1306-
ints_to_push,
1347+
),
1348+
store(
1349+
~offset=4,
1350+
wasm_mod,
1351+
get_swap(),
1352+
Expression.Const.make(wasm_mod, const_int32 @@ Buffer.length(buf)),
1353+
),
1354+
];
1355+
let elts =
1356+
List.mapi(
1357+
(idx, i: int64) =>
1358+
store(
1359+
~ty=Type.int64,
1360+
~offset=8 * (idx + 1),
1361+
wasm_mod,
1362+
get_swap(),
1363+
Expression.Const.make(wasm_mod, wrap_int64(i)),
1364+
),
1365+
ints_to_push,
1366+
);
1367+
Expression.Block.make(
1368+
wasm_mod,
1369+
gensym_label(label),
1370+
List.concat([preamble, elts, [get_swap()]]),
13071371
);
1308-
Expression.Block.make(
1309-
wasm_mod,
1310-
gensym_label(label),
1311-
List.concat([preamble, elts, [get_swap()]]),
1312-
);
1372+
};
13131373
};
13141374

13151375
let allocate_byte_like_uninitialized = (wasm_mod, env, size, tag, label) => {
@@ -3405,7 +3465,7 @@ let compile_type_metadata = (wasm_mod, env, prog) => {
34053465
| (initial_memory, None) => (initial_memory, Memory.unlimited)
34063466
};
34073467

3408-
let data_segments =
3468+
let segments =
34093469
switch (metadata_tbl_data) {
34103470
| Some(data) => [
34113471
Memory.{
@@ -3423,6 +3483,14 @@ let compile_type_metadata = (wasm_mod, env, prog) => {
34233483
]
34243484
| None => []
34253485
};
3486+
let data_segments =
3487+
if (Config.bulk_memory^) {
3488+
let (_, data_segments) = data_segments^;
3489+
List.rev_append(data_segments, segments);
3490+
} else {
3491+
segments;
3492+
};
3493+
34263494
Memory.set_memory(
34273495
wasm_mod,
34283496
initial_memory,
@@ -3488,8 +3556,6 @@ let compile_wasm_module =
34883556
Option.is_none(Grain_utils.Config.memory_base^),
34893557
);
34903558

3491-
compile_type_metadata(wasm_mod, env, prog);
3492-
34933559
ignore @@
34943560
Table.add_table(
34953561
wasm_mod,
@@ -3526,6 +3592,8 @@ let compile_wasm_module =
35263592

35273593
ignore @@ compile_main(wasm_mod, env, prog);
35283594

3595+
compile_type_metadata(wasm_mod, env, prog);
3596+
35293597
validate_module(~name?, wasm_mod);
35303598

35313599
switch (Config.profile^) {

compiler/src/utils/wasm_utils.re

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ type wasm_bin_section_type =
2222
| Element
2323
| Code
2424
| Data
25-
| DataCount;
25+
| DataCount(int);
2626

2727
[@deriving sexp]
2828
type wasm_bin_section = {
@@ -213,7 +213,7 @@ let section_type_of_int = (~pos=?, ~name=?) =>
213213
| 9 => Element
214214
| 10 => Code
215215
| 11 => Data
216-
| 12 => DataCount
216+
| 12 => DataCount(-1)
217217
| n => raise(MalformedSectionType(n, pos));
218218

219219
let int_of_section_type =
@@ -230,7 +230,7 @@ let int_of_section_type =
230230
| Element => 9
231231
| Code => 10
232232
| Data => 11
233-
| DataCount => 12;
233+
| DataCount(_) => 12;
234234

235235
let get_wasm_sections = (~reset=false, inchan) => {
236236
let orig_pos = pos_in(inchan);

compiler/src/utils/wasm_utils.rei

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ type wasm_bin_section_type =
2121
| Element
2222
| Code
2323
| Data
24-
| DataCount;
24+
| DataCount(int);
2525

2626
[@deriving sexp]
2727
type wasm_bin_section = {

compiler/test/suites/basic_functionality.re

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,6 @@ describe("basic functionality", ({test, testSkip}) => {
377377
~config_fn=smallestFileConfig,
378378
"smallest_grain_program",
379379
"",
380-
6540,
380+
6281,
381381
);
382382
});

0 commit comments

Comments
 (0)