Skip to content

Fix MPR 7301 (Flambda versus lazy)#713

Merged
mshinwell merged 6 commits intoocaml:trunkfrom
mshinwell:lazy_immutable
Jul 26, 2016
Merged

Fix MPR 7301 (Flambda versus lazy)#713
mshinwell merged 6 commits intoocaml:trunkfrom
mshinwell:lazy_immutable

Conversation

@mshinwell
Copy link
Copy Markdown
Contributor

Currently, Forward_tag values are marked as Immutable in Translcore, which means that Flambda deduces approximations for them and may use such approximations during simplification. Unfortunately this loses the information that the value may be replaced during GC by the value pointed to by the forwarding pointer, which can cause wrong code (MPR 7301).

This patch marks Forward_tag blocks as Mutable in all cases where they may be updated by the GC. As noted in the comment, this isn't entirely satisfactory, since in fact these blocks may be replaced by immediates or updated in other ways that are not just simple field mutation. We should fix this in the future, but there should not be any correctness issue at the moment, since Flambda doesn't try to do anything with mutable values.

Application of lazy to some kinds of values (e.g. a manifest closure) can translate to a no-op, which as shown by MPR 7292, can cause warning messages complaining about writes to immutable values when functions such as Lazy.force are inlined. The specific example in MPR 7292 arises partially because there is a deficiency in the simplification of "switch" statements in Flambda (see OCamlPro/flambda-task-force#159), but that aside, I think we should include the changes to Camlinternallazy given here in case the same problem arises in some other context. We may need to consider a better approach to suppressing warning 59 in future.

@mshinwell mshinwell added this to the 4.04 milestone Jul 25, 2016
@alainfrisch
Copy link
Copy Markdown
Contributor

I was concerned that only setting the Immutable property would not capture the fact that the tag itself could change. But it seems the tag of lazy values is never read directly, always through the caml_obj_tag primitive (in Lazy.from_val/is_val, or in the code generated by matching.ml), and thus flambda cannot be "too clever" and illegally simplify away the tag extraction.

What about generating a call to the opaque identity around the creation of the forward block? This should be a bit safer than the current solution (Immutable) for future optimizations (e.g. shortcutting the call to caml_obj_tag when the tag seems to be known), no?

(I was also concerned that there might be other cases of blocks whose tag change, but this does not seem to be the case for now: Obj.set_tag is also called in camlinternalMod, but this should be covered -- perhaps adding the opaque identity there could be cleaner, though.)

@chambart
Copy link
Copy Markdown
Contributor

I was going to say the same thing as @alainfrisch, Popaque is the only way to prevent the tag information from being used.

@chambart
Copy link
Copy Markdown
Contributor

Also we might not want to hide the setfield argument inside an opaque to be able to see other potential missing cases

@alainfrisch
Copy link
Copy Markdown
Contributor

I confirm that the patch avoids the segfault in our failing tests.

@mshinwell
Copy link
Copy Markdown
Contributor Author

@alainfrisch You mean setting the Mutable property, not Immutable, right? Anyway, yes, maybe it is in fact better to generate Popaque around this (and aim to have a new primitive in the future, as per the comment).

@chambart Maybe in fact that is a better idea, at least for the moment. I'll revert that part.

@alainfrisch
Copy link
Copy Markdown
Contributor

You mean setting the Mutable property, not Immutable, right?

Yes, sorry.

@chambart
Copy link
Copy Markdown
Contributor

I'm not sure what should be the semantics of such a lazy makeblock to fit well with the Pforce code. Maybe that suggest that Plazyforce lowering should apply later in native code to handle that well.

@mshinwell
Copy link
Copy Markdown
Contributor Author

@alainfrisch @chambart Can one of you please approve this if you are certain of the fix?

@alainfrisch
Copy link
Copy Markdown
Contributor

Yes, I'm rather confident this patch addresses the root cause of the problem. (Don't forget to add an entry to Changes!)

@mshinwell mshinwell changed the title Fix MPR 7292 and 7301 (Flambda versus lazy) Fix MPR 7301 (Flambda versus lazy) Jul 26, 2016
@mshinwell mshinwell merged commit 333a516 into ocaml:trunk Jul 26, 2016
shindere pushed a commit to shindere/ocaml that referenced this pull request Aug 11, 2016
camlspotter pushed a commit to camlspotter/ocaml that referenced this pull request Oct 17, 2017
EduardoRFS pushed a commit to esy-ocaml/ocaml that referenced this pull request Dec 17, 2021
stedolan pushed a commit to stedolan/ocaml that referenced this pull request Sep 21, 2022
EmileTrotignon pushed a commit to EmileTrotignon/ocaml that referenced this pull request Jan 12, 2024
* Repair build broken by mirage-kv 6.0.0

In mirage-kv 5.0.0 the function last_modified returned a result of
type:

  (int * int64, error) result Lwt.t

This was changed in 6.0.0, where it returns a result of type:

  (Ptime.t, error) result Lwt.t

This caused a typing error. Removing the call to function

  Ptime.v : int * int64 -> Ptime.t

solved the issue.

* Formatting

Co-authored-by: Cuihtlauac ALVARADO <cuihtmlauac@tarides.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants