Skip to content

Commit e90cc27

Browse files
committed
feat(compiler): Use data segments for string data
1 parent 13ac7fa commit e90cc27

File tree

4 files changed

+108
-39
lines changed

4 files changed

+108
-39
lines changed

compiler/src/codegen/compcore.re

Lines changed: 103 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,17 @@ let gensym_label = s => {
3434
};
3535
let reset_labels = () => gensym_counter := 0;
3636

37+
let data_segments: ref((int, list(Memory.segment))) = ref((0, []));
38+
let push_data_segment = segment => {
39+
let (count, segments) = data_segments^;
40+
data_segments := (count + 1, [segment, ...segments]);
41+
};
42+
let get_data_segment_count = () => {
43+
let (count, _) = data_segments^;
44+
count;
45+
};
46+
let reset_data_segments = () => data_segments := (0, []);
47+
3748
/* Number of swap variables to allocate */
3849
let swap_slots_i32 = [|Type.int32, Type.int32, Type.int32|];
3950
let swap_slots_i64 = [|Type.int64|];
@@ -117,6 +128,7 @@ let rec resolve_func = (~env, name) => {
117128

118129
let reset = () => {
119130
reset_labels();
131+
reset_data_segments();
120132
};
121133

122134
let get_runtime_heap_start = wasm_mod =>
@@ -1267,45 +1279,93 @@ let call_lambda =
12671279
};
12681280

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

13111371
let allocate_byte_like_uninitialized = (wasm_mod, env, size, tag, label) => {
@@ -3378,7 +3438,7 @@ let compile_type_metadata = (wasm_mod, env, prog) => {
33783438
| (initial_memory, None) => (initial_memory, Memory.unlimited)
33793439
};
33803440

3381-
let data_segments =
3441+
let segments =
33823442
switch (metadata_tbl_data) {
33833443
| Some(data) => [
33843444
Memory.{
@@ -3396,6 +3456,14 @@ let compile_type_metadata = (wasm_mod, env, prog) => {
33963456
]
33973457
| None => []
33983458
};
3459+
let data_segments =
3460+
if (Config.bulk_memory^) {
3461+
let (_, data_segments) = data_segments^;
3462+
List.rev_append(data_segments, segments);
3463+
} else {
3464+
segments;
3465+
};
3466+
33993467
Memory.set_memory(
34003468
wasm_mod,
34013469
initial_memory,
@@ -3461,8 +3529,6 @@ let compile_wasm_module =
34613529
Option.is_none(Grain_utils.Config.memory_base^),
34623530
);
34633531

3464-
compile_type_metadata(wasm_mod, env, prog);
3465-
34663532
ignore @@
34673533
Table.add_table(
34683534
wasm_mod,
@@ -3497,12 +3563,15 @@ let compile_wasm_module =
34973563

34983564
ignore @@ compile_main(wasm_mod, env, prog);
34993565

3566+
compile_type_metadata(wasm_mod, env, prog);
3567+
35003568
validate_module(~name?, wasm_mod);
35013569

35023570
switch (Config.profile^) {
35033571
| Some(Release) => Optimize_mod.optimize(wasm_mod)
35043572
| None => ()
35053573
};
3574+
35063575
wasm_mod;
35073576
};
35083577

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-
6507,
380+
6281,
381381
);
382382
});

0 commit comments

Comments
 (0)