diff options
author | Xavier Leroy <xavierleroy@users.noreply.github.com> | 2020-06-17 16:03:51 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-06-17 16:03:51 +0200 |
commit | d4dea7afea89f3e6719b7148d5a659fbd62c529d (patch) | |
tree | 0d98709d116eac7ca8c326de1604ee78b3b9b8a8 /runtime | |
parent | 0d1f7b208ea9e6c6e43da9b2f74f8530346811c6 (diff) | |
download | ocaml-d4dea7afea89f3e6719b7148d5a659fbd62c529d.tar.gz |
Adapt caml_alloc_dummy_infix to new closure representation (#9690)
The first closure info field must be valid.
Also document two other places where no change is needed because of
the new closure representation, but for nonobvious reasons.
Diffstat (limited to 'runtime')
-rw-r--r-- | runtime/alloc.c | 12 | ||||
-rw-r--r-- | runtime/obj.c | 5 |
2 files changed, 16 insertions, 1 deletions
diff --git a/runtime/alloc.c b/runtime/alloc.c index d21f0886c9..73a8f01b13 100644 --- a/runtime/alloc.c +++ b/runtime/alloc.c @@ -227,6 +227,12 @@ CAMLprim value caml_alloc_dummy_infix(value vsize, value voffset) { mlsize_t wosize = Long_val(vsize), offset = Long_val(voffset); value v = caml_alloc(wosize, Closure_tag); + /* The following choice of closure info causes the GC to skip + the whole block contents. This is correct since the dummy + block contains no pointers into the heap. However, the block + cannot be marshaled or hashed, because not all closinfo fields + and infix header fields are correctly initialized. */ + Closinfo_val(v) = Make_closinfo(0, wosize); if (offset > 0) { v += Bsize_wsize(offset); Hd_val(v) = Make_header(offset, Infix_tag, Caml_white); @@ -257,6 +263,10 @@ CAMLprim value caml_update_dummy(value dummy, value newval) dummy = dummy - Infix_offset_val(dummy); size = Wosize_val(clos); CAMLassert (size == Wosize_val(dummy)); + /* It is safe to use [caml_modify] to copy code pointers + from [clos] to [dummy], because the value being overwritten is + an integer, and the new "value" is a pointer outside the minor + heap. */ for (i = 0; i < size; i++) { caml_modify (&Field(dummy, i), Field(clos, i)); } @@ -266,6 +276,8 @@ CAMLprim value caml_update_dummy(value dummy, value newval) Tag_val(dummy) = tag; size = Wosize_val(newval); CAMLassert (size == Wosize_val(dummy)); + /* See comment above why this is safe even if [tag == Closure_tag] + and some of the "values" being copied are actually code pointers. */ for (i = 0; i < size; i++){ caml_modify (&Field(dummy, i), Field(newval, i)); } diff --git a/runtime/obj.c b/runtime/obj.c index 63a2a60ebe..f4324ea99f 100644 --- a/runtime/obj.c +++ b/runtime/obj.c @@ -138,8 +138,11 @@ CAMLprim value caml_obj_with_tag(value new_tag_v, value arg) for (i = 0; i < sz; i++) Field(res, i) = Field(arg, i); } else { res = caml_alloc_shr(sz, tg); + /* It is safe to use [caml_initialize] even if [tag == Closure_tag] + and some of the "values" being copied are actually code pointers. + That's because the new "value" does not point to the minor heap. */ for (i = 0; i < sz; i++) caml_initialize(&Field(res, i), Field(arg, i)); - // Give gc a chance to run, and run memprof callbacks + /* Give gc a chance to run, and run memprof callbacks */ caml_process_pending_actions(); } CAMLreturn (res); |