01:17 unicodable6 joined, quotable6 joined 02:58 ilbot3 joined 03:57 bloatable6 joined 07:52 buggable joined, huggable joined, ZofBot joined 09:31 lizmat joined 09:42 lizmat joined 10:13 lizmat joined 11:00 lizmat joined 11:26 Ven`` joined 11:32 lizmat joined 11:41 Ven`` joined 11:44 Ven` joined 11:46 committable6 joined 13:53 Ven`` joined 14:14 bisectable6 joined 14:28 Ven`` joined 14:47 squashable6 joined
nine Why does the MAST compiler define its own constants for MVM_EX_ACTION_*? 15:04
Another interesting bit: _disabling_ the JIT and removing the goto at the end of the inline causes segfaults - with a completely screwed up stack. 15:29
And when the non-JITed version doesn't segfault, it throws the infamous "const_iX NYI" error. So something really must corrupt some memory. 15:30
timotimo i wonder if it's worth the hassle to introduce read-only sections to put the bytecode into? 15:36
nine Still not really closer to answering the question of what frame handlers have to do with INLINE_START and INLINE_END annotations. 15:42
timotimo well, that changes where we look, right?
nine What do you mean? 15:43
timotimo well, we sometimes want to throw something "from" an outer frame
nine It breaks when the handler's GOTO annotation is outside [INLINE_START..INLINE_END]. 15:45
What really confuses me is that there's almost nothing that even uses INLINE_END information. 15:47
timotimo but it changes the ranges in the handler table
and those probably impact lots of places? 15:48
nine But that's why it makes no sense: the ranges in the handler table are defined by the FH_START and FH_END annotations, not INLINE_START, INLINE_END
timotimo huh, but we're supposed to store the inline start and end, too? 15:50
nine But maybe the whole INLINE_END thing is just a red herring. Moving INLINE_END "fixes" things only when the JIT is enabled. The weird segfault when the JIT is disabled is unaffected. 15:53
timotimo hmm 15:54
i'm sufficiently distracted such that i can't think about this 16:05
nine The only thing that would make some sense would be that it's some deopt issue. But I can't find any indication that the optimized cuid is deoptimized somewhere 16:10
Can find neither the inliner, nor the inlinee's cuid in the deopt log 16:16
timotimo hm, OK :\
jnthn INLINE_END is used to src/spesh/codegen.c and a couple of places under src/jit/. It's used at code-gen time to build the table of deopt extents 16:18
Bytecode extents for when we interpret spesh'd code, and machine code extents for JIT
It's used to figure out "are we in an inline" during deopt, but also when resolving $*FOO 16:19
16:25 zakharyas joined
nine jnthn: order in the deopt table does not matter, does it? 16:31
jnthn: also can you confirm that the comment in src/spesh/deopt.c:118 just does not make sense? We get that offset from the inlines and deopt tables, not from any instruction. 16:33
17:23 coverable6 joined, benchable6 joined 17:33 domidumont joined 17:38 domidumont joined 17:43 zakharyas joined
jnthn iirc, order does matter in so far as innermost inlines should come first 17:52
nine: And yeah, that comment seems out of date 17:54
nine jnthn: the way it works now (in master and my branch) the innermost inlines will always be last. The inlinee's deopt table is appended to the inliner's 18:19
18:40 releasable6 joined 18:41 greppable6 joined, reportable6 joined, statisfiable6 joined, nativecallable6 joined
jnthn nine: Hm, I wonder if we scan it in reverse order then...can't remember 18:42
Ohh...
Maybe we don't scan it at all in deopt
'cus we pass in the deopt index
Or some such
I forget
(Sorry, mostly afk today)
Somewhere, we must be figuring out the "chain" of inlines, however, so we can reassemble the call stack
nine jnthn: uninline in deopt.c just iterates over cand->inlines and creates the frames. And there I'm quite sure we want to work from outer to innermost frame. 18:47
jnthn Oh, I guess I coulda done it that way too 18:49
nine So no smoking gun there...
jnthn Either way there's inter-loop fixups
Could always try turning on the deopt logging flag and comparing wiht master 18:50
iirc it outputs what frames it recreated
dinner, bbl 18:52
nine jnthn: I have 2 test cases where I used MVM_SPESH_LIMIT to find the optimization that breaks the code. In one case there is no deoptimization at all of the affected frame and in the other case there are no recreated frames (which I take as we weren't in inlined code at the time) 18:58
Ok, now it gets really interesting. 19:02
I compared the deopt log of both test cases with that on master. In both cases the log is identical (modulo offset/target differences of course) _except_ for one extra "Recreated frame" message on master. 19:04
The message is about the inlinee of the breaking optimization but NOT the same inliner. 19:05
timotimo that sounds fun, but maybe we're just(?) doing better at inlining in your branch for some reason?
nine And in both cases it's a deopt all that causes the frame to be created on master but not on inline_in_place 19:10
19:37 Kaiepi joined 20:50 evalable6 joined 21:12 dogbert2 joined
nine Correction: the missing "Recreated frame" message is exactly about the inlinee in the inliner of the breaking optimization 21:15
I just misread the deopt log before
samcv github.com/MoarVM/moarvm.org/pull/10 21:18
this looks fine i think?
lizmat yeah, looks ok to me 21:26
nine jnthn: github.com/MoarVM/MoarVM/blob/mast...eopt.c#L32 are you sure it's supposed to be offset < cand->inlines[i].end? Shouldn't that be <=? 21:28
lizmat
.oO( those pesky off-by-ones )
21:48
nine In fact, I'm pretty sure it should be <= as .end is the offset of the last instruction in the inlined code. And the spectest shows that it can at least not be much wronger ;) 21:51
Geth MoarVM: 7ea08024ed | (Stefan Seifert)++ | src/spesh/deopt.c
Fix off-by-one error in uninline

The INLINE_END annotation sits on the last instruction of a chain of inlined basic blocks, so it's this instruction's offset in the bytecode we record as the end of the inlined code (mirroring the start offset). This means that if we are exactly at cand->inlines[i].end, we are still in inlined code and have to re-create the frame on uninlining.
This probably didn't cause issues before because inlined code always ends with a goto.