You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This issue is a brain-dump of investigations into a repeatable failure of tests/weak-ephe-final/weaklifetime.ml on mingw-w64. This test was repeatably failing with the ephemeron at index 259 changing length in the course of execution from 906 to 257 and so causing Weak.check to fail when asked to access index 358 of that ephemeron! @ctk21, @kayceesrk and I chased this down to the ephemeron not being marked and the page subsequently being freed and eventually nailed it down to the poll instruction inserted immediately after the extcall in Weak.create. Having then welcomed @stedolan to the scratching-our-heads-in-confusion mix, we're fairly sure that this isn't Windows-specific, but rather that this case is easier to hit on Windows because of the different ABI.
Brief conclusion: doing this correctly with the present safe points implementation requires knowledge that a hardware register contains an OCaml value (as opposed to just an integer). This information exists at clambda, but is dropped at CMM (but obviously could be propagated). It would then be possible to record in the frame_descriptor just prior to the poll that %rax (from the extcall) is a live value.
For now, the problem can be papered over on Windows by not allowing polling just prior to Istackoffset and the situation will hopefully be irrelevant if/when the analysis of safepoints moves from mach to lambda. The purpose of this issue is to ensure we don't forget that!
The gory details:
This is Weak.create:
externalcreate : int -> 'at="caml_weak_create"letcreatel=ifnot (0<= l && l <=Obj.Ephemeron.max_ephe_length) then
invalid_arg("Weak.create");
create l
(note that if %rax contained a value, it would be marked with an *, but this is not possible since at present Mach treats %rax as always an integer). Below the poll is the V/32 assignment to a virtual register which is the normal mechanism (and which gets optimised out), but is happening too late.
The text was updated successfully, but these errors were encountered:
This issue is a brain-dump of investigations into a repeatable failure of
tests/weak-ephe-final/weaklifetime.ml
on mingw-w64. This test was repeatably failing with the ephemeron at index 259 changing length in the course of execution from 906 to 257 and so causingWeak.check
to fail when asked to access index 358 of that ephemeron! @ctk21, @kayceesrk and I chased this down to the ephemeron not being marked and the page subsequently being freed and eventually nailed it down to the poll instruction inserted immediately after the extcall inWeak.create
. Having then welcomed @stedolan to the scratching-our-heads-in-confusion mix, we're fairly sure that this isn't Windows-specific, but rather that this case is easier to hit on Windows because of the different ABI.Brief conclusion: doing this correctly with the present safe points implementation requires knowledge that a hardware register contains an OCaml value (as opposed to just an integer). This information exists at clambda, but is dropped at CMM (but obviously could be propagated). It would then be possible to record in the
frame_descriptor
just prior to the poll that%rax
(from the extcall) is a livevalue
.For now, the problem can be papered over on Windows by not allowing polling just prior to
Istackoffset
and the situation will hopefully be irrelevant if/when the analysis of safepoints moves from mach to lambda. The purpose of this issue is to ensure we don't forget that!The gory details:
This is
Weak.create
:which compiles to:
note also the relevant part of the frame table, which contains no entries (but the correct stack):
which is consistent with the liveness info computed just prior to the poll:
(note that if
%rax
contained a value, it would be marked with an*
, but this is not possible since at present Mach treats%rax
as always an integer). Below thepoll
is theV/32
assignment to a virtual register which is the normal mechanism (and which gets optimised out), but is happening too late.The text was updated successfully, but these errors were encountered: