Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(compiler): Use data segments for string data #1330

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
136 changes: 102 additions & 34 deletions compiler/src/codegen/compcore.re
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,17 @@ let gensym_label = s => {
};
let reset_labels = () => gensym_counter := 0;

let data_segments: ref((int, list(Memory.segment))) = ref((0, []));
let push_data_segment = segment => {
let (count, segments) = data_segments^;
data_segments := (count + 1, [segment, ...segments]);
};
let get_data_segment_count = () => {
let (count, _) = data_segments^;
count;
};
let reset_data_segments = () => data_segments := (0, []);

/* Number of swap variables to allocate */
let swap_slots_i32 = [|Type.int32, Type.int32, Type.int32|];
let swap_slots_i64 = [|Type.int64|];
Expand Down Expand Up @@ -121,6 +132,7 @@ let rec resolve_func = (~env, name) => {

let reset = () => {
reset_labels();
reset_data_segments();
};

let get_runtime_heap_start = wasm_mod =>
Expand Down Expand Up @@ -1271,45 +1283,93 @@ let call_lambda =
};

let allocate_byte_like_from_buffer = (wasm_mod, env, buf, tag, label) => {
let ints_to_push: list(int64) = buf_to_ints(buf);
let get_swap = () => get_swap(wasm_mod, env, 0);
let tee_swap = tee_swap(wasm_mod, env, 0);
let preamble = [
store(
~offset=0,
wasm_mod,
tee_swap(
heap_allocate(wasm_mod, env, 2 + 2 * List.length(ints_to_push)),
),
Expression.Const.make(
wasm_mod,
const_int32(tag_val_of_heap_tag_type(tag)),
),
),
store(
~offset=4,
if (Config.bulk_memory^) {
let segment_offset = get_data_segment_count();
let data_size = Buffer.length(buf);
Memory.(
push_data_segment({
data: Buffer.to_bytes(buf),
kind: Passive,
size: data_size,
})
);
Expression.Block.make(
wasm_mod,
get_swap(),
Expression.Const.make(wasm_mod, const_int32 @@ Buffer.length(buf)),
),
];
let elts =
List.mapi(
(idx, i: int64) =>
gensym_label(label),
[
store(
~offset=0,
wasm_mod,
// compute number of words (add 3 to account for floored division)
tee_swap(heap_allocate(wasm_mod, env, 2 + (data_size + 3) / 4)),
Expression.Const.make(
wasm_mod,
const_int32(tag_val_of_heap_tag_type(tag)),
),
),
store(
~ty=Type.int64,
~offset=8 * (idx + 1),
~offset=4,
wasm_mod,
get_swap(),
Expression.Const.make(wasm_mod, wrap_int64(i)),
Expression.Const.make(wasm_mod, const_int32 @@ data_size),
),
Expression.Memory_init.make(
wasm_mod,
segment_offset,
Expression.Binary.make(
wasm_mod,
Op.add_int32,
get_swap(),
Expression.Const.make(wasm_mod, const_int32(8)),
),
Expression.Const.make(wasm_mod, const_int32(0)),
Expression.Const.make(wasm_mod, const_int32(data_size)),
grain_memory,
),
get_swap(),
],
);
} else {
let ints_to_push: list(int64) = buf_to_ints(buf);
let preamble = [
store(
~offset=0,
wasm_mod,
tee_swap(
heap_allocate(wasm_mod, env, 2 + 2 * List.length(ints_to_push)),
),
Expression.Const.make(
wasm_mod,
const_int32(tag_val_of_heap_tag_type(tag)),
),
ints_to_push,
),
store(
~offset=4,
wasm_mod,
get_swap(),
Expression.Const.make(wasm_mod, const_int32 @@ Buffer.length(buf)),
),
];
let elts =
List.mapi(
(idx, i: int64) =>
store(
~ty=Type.int64,
~offset=8 * (idx + 1),
wasm_mod,
get_swap(),
Expression.Const.make(wasm_mod, wrap_int64(i)),
),
ints_to_push,
);
Expression.Block.make(
wasm_mod,
gensym_label(label),
List.concat([preamble, elts, [get_swap()]]),
);
Expression.Block.make(
wasm_mod,
gensym_label(label),
List.concat([preamble, elts, [get_swap()]]),
);
};
};

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

let data_segments =
let segments =
switch (metadata_tbl_data) {
| Some(data) => [
Memory.{
Expand All @@ -3423,6 +3483,14 @@ let compile_type_metadata = (wasm_mod, env, prog) => {
]
| None => []
};
let data_segments =
if (Config.bulk_memory^) {
let (_, data_segments) = data_segments^;
List.rev_append(data_segments, segments);
} else {
segments;
};

Memory.set_memory(
wasm_mod,
initial_memory,
Expand Down Expand Up @@ -3488,8 +3556,6 @@ let compile_wasm_module =
Option.is_none(Grain_utils.Config.memory_base^),
);

compile_type_metadata(wasm_mod, env, prog);

ignore @@
Table.add_table(
wasm_mod,
Expand Down Expand Up @@ -3526,6 +3592,8 @@ let compile_wasm_module =

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

compile_type_metadata(wasm_mod, env, prog);

validate_module(~name?, wasm_mod);

switch (Config.profile^) {
Expand Down
6 changes: 3 additions & 3 deletions compiler/src/utils/wasm_utils.re
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ type wasm_bin_section_type =
| Element
| Code
| Data
| DataCount;
| DataCount(int);

[@deriving sexp]
type wasm_bin_section = {
Expand Down Expand Up @@ -213,7 +213,7 @@ let section_type_of_int = (~pos=?, ~name=?) =>
| 9 => Element
| 10 => Code
| 11 => Data
| 12 => DataCount
| 12 => DataCount(-1)
| n => raise(MalformedSectionType(n, pos));

let int_of_section_type =
Expand All @@ -230,7 +230,7 @@ let int_of_section_type =
| Element => 9
| Code => 10
| Data => 11
| DataCount => 12;
| DataCount(_) => 12;

let get_wasm_sections = (~reset=false, inchan) => {
let orig_pos = pos_in(inchan);
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/utils/wasm_utils.rei
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ type wasm_bin_section_type =
| Element
| Code
| Data
| DataCount;
| DataCount(int);

[@deriving sexp]
type wasm_bin_section = {
Expand Down
2 changes: 1 addition & 1 deletion compiler/test/suites/basic_functionality.re
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,6 @@ describe("basic functionality", ({test, testSkip}) => {
~config_fn=smallestFileConfig,
"smallest_grain_program",
"",
6540,
6281,
);
});
Loading