[02:01] <Voldenet> this itself is not critical, but maybe moar should eventually be able to throw errors properly – for example MVM_file_open_fh can tell you if something is a directory or maybe give you platform-specific error, but it gets flattened into a string

[02:13] <Voldenet> while you can parse strings and they don't change often, it still feels icky to do that

[04:31] *** ShimmerFairy left
[04:40] *** ShimmerFairy joined
[13:08] *** librasteve_ joined
[13:20] <Geth> ¦ MoarVM/moar-gdb-rrdb: 8 commits pushed by (Timo Paulssen)++

[13:20] <Geth> ¦ MoarVM/moar-gdb-rrdb: 19cfcdda55 | WIP on "rrdb", database of stuff that happens during replay

[13:20] <Geth> ¦ MoarVM/moar-gdb-rrdb: e7a4edb073 | WIP on libmoar-gdb plugin stuff

[13:20] <Geth> ¦ MoarVM/moar-gdb-rrdb: 00807a23a6 | cleanup moar rrdb, implement moar bt

[13:20] <Geth> ¦ MoarVM/moar-gdb-rrdb: 39fe4fdf06 | gdb string pretty printer improvement

[13:20] <Geth> ¦ MoarVM/moar-gdb-rrdb: d4c14ae1d3 | show callsite including argument values

[13:20] <Geth> ¦ MoarVM/moar-gdb-rrdb: 5f5333e688 | dump_p6opaque helper: string truncation, pointer output

[13:20] <Geth> ¦ MoarVM/moar-gdb-rrdb: f0aff5fb0c | put the output of gdb command "info inferior" into gdb moar-rrdb

[13:20] <Geth> ¦ MoarVM/moar-gdb-rrdb: 10bb4308cd | gdb plugin: update comments

[13:20] <Geth> ¦ MoarVM/moar-gdb-rrdb: review: https://github.com/MoarVM/MoarVM/compare/6e3a00c903a1...10bb4308cd86

[13:20] <timo> (just a rebase)

[13:34] *** guifa_ joined
[15:53] *** guifa_ left
[15:59] *** guifa_ joined
[16:24] <Geth> ¦ MoarVM/2026.06: 12f1c345f1 | (Will Coleda)++ | 2 files

[16:24] <Geth> ¦ MoarVM/2026.06: Update changelog and version

[16:24] <Geth> ¦ MoarVM/2026.06: review: https://github.com/MoarVM/MoarVM/commit/12f1c345f1

[16:25] <Geth> ¦ MoarVM: coke++ created pull request #2019: Update changelog and version

[16:25] <Geth> ¦ MoarVM: review: https://github.com/MoarVM/MoarVM/pull/2019

[16:28] <Geth> ¦ MoarVM/main: 12f1c345f1 | (Will Coleda)++ | 2 files

[16:28] <Geth> ¦ MoarVM/main: Update changelog and version

[16:28] <Geth> ¦ MoarVM/main: review: https://github.com/MoarVM/MoarVM/commit/12f1c345f1

[16:28] <Geth> ¦ MoarVM/main: cfc173f079 | (Will Coleda)++ (committed using GitHub Web editor) | 2 files

[16:28] <Geth> ¦ MoarVM/main: Merge pull request #2019 from MoarVM/2026.06

[16:28] <Geth> ¦ MoarVM/main: 

[16:28] <Geth> ¦ MoarVM/main: Update changelog and version

[16:28] <Geth> ¦ MoarVM/main: review: https://github.com/MoarVM/MoarVM/commit/cfc173f079

[17:32] *** librasteve_ left
[17:54] <timo> uhhhh do we resolve bytecode annotations purely by the cur_op offset into effective_bytecode and then looking at the static frame's annotation segment? that seems like we would get wrong filename / line number pairs for frames as soon as spesh is involved ... which may or may not include instrumentation such as the one the debugserver uses to add breakpoint instructions (though the breakpoint

[17:54] <timo> instructions would go on correct locations, since they would still be correct when the spesh graph used for instrumentation was created)

[18:16] *** ShimmerFairy left
[18:18] *** ShimmerFairy joined
[18:22] <Geth> ¦ MoarVM/moar-gdb-rrdb: 13 commits pushed by (Timo Paulssen)++

[18:22] <Geth> ¦ MoarVM/moar-gdb-rrdb: review: https://github.com/MoarVM/MoarVM/compare/10bb4308cd86...88037a8879a2

[18:22] <timo> ^- rebase, but also new features and changes

[18:35] *** guifa_ left
[18:36] *** librasteve_ joined
[18:36] *** guifa_ joined
[18:41] *** guifa_ left
[18:46] *** ShimmerFairy left
[18:51] *** ShimmerFairy joined
[19:07] *** MasterDuke joined
[19:10] <MasterDuke> timo: i'm looking through the still-existing iter spesh code. when running my example, `if (in_facts->flags & MVM_SPESH_FACT_KNOWN_TYPE) {` in `iter_facts()` is not true, when called in `case MVM_OP_iter` in `add_bb_facts()`

[19:11] <MasterDuke> the test code is: `nqp -e 'my $l := nqp::list(); my int $p := 0; while $p++ < 10_000 { nqp::push($l, $p) }; my int $j := 10000; while $j-- { my $iter := nqp::iterator($l); nqp::while($iter, my $a := nqp::shift($iter)) }'`

[19:12] <MasterDuke> i know very little about facts. how do i tell why the type isn't known?

[19:12] <timo> you'll definitely want to be looking at the spesh log for this

[19:13] <MasterDuke> there are only two `iter`s in the spesh log

[19:14] <MasterDuke> oh, from the before and after of `<mainline>

[19:14] <MasterDuke> `iter            r11(12),   r1(6)`

[19:15] <MasterDuke> `r1(6): usages=2, flags=0     (merged from 2 regs)`

[19:15] <MasterDuke> `r11(12): usages=0, flags=0`

[19:15] <timo> ok, so we can't prove what is being iterated over there

[19:16] <MasterDuke> oh, which registers should i be looking at, they have different numbers before and after optimization

[19:17] <MasterDuke> oh, but either set are pretty much the same

[19:18] <MasterDuke> (in the facts they have)

[19:18] <MasterDuke> it's essentially the same if i change to iterating over an nqp::list_i

[19:19] <timo> the before-optimization facts are going to have many missing flags and known types and such

[19:19] <timo> at least potentially

[19:23] <MasterDuke> before and after are essentially the same

[19:25] <timo> so, the register equivalent to r1(6), i.e. what we're creating the iter for, comes from a PHI that has two inputs, which is what "merged from 2" means

[19:26] <timo> can you see what these versions of the register are, and where they come from?

[19:26] <timo> i'm assuming the PHI lives where the loop is entered from before or from the jump-back address

[19:27] <MasterDuke> hm, "can you see what these versions of the register are, and where they come from?" how do i get that from the spesh log?

[19:28] <timo> go up to the instructions and find a PHI that has the target as its first argument, the other arguments are the sources

[19:28] <MasterDuke> there are a bunch of PHIs a couple instructions before the iter

[19:28] <MasterDuke> `PHI               r1(6),   r1(0),   r1(5)`?

[19:28] <timo> PHI means "the register r1 has different versions in the different predecessors of this block"

[19:29] <timo> so we can only rely on what we know to be true about all incoming versions, that's what "merged" refers to

[19:29] <MasterDuke> `r1(0): usages=3, flags=0` and `r1(5): usages=1, flags=0     (merged from 2 regs)`

[19:31] <Geth> ¦ MoarVM/moar-gdb-rrdb: ae24fde56a | (Timo Paulssen)++ | tools/libmoar.so-gdb.py

[19:31] <Geth> ¦ MoarVM/moar-gdb-rrdb: gdb plugin: RRDB: Fix sql statements, allow skipping gc tracking

[19:31] <Geth> ¦ MoarVM/moar-gdb-rrdb: 

[19:31] <Geth> ¦ MoarVM/moar-gdb-rrdb: Recording the before and after address of every object when they get

[19:31] <Geth> ¦ MoarVM/moar-gdb-rrdb: moved around by the GC takes a significant chunk of the time when

[19:31] <Geth> ¦ MoarVM/moar-gdb-rrdb: creating the rrdb, and there isn't anything yet that uses any of the

[19:31] <Geth> ¦ MoarVM/moar-gdb-rrdb: information anyway.

[19:31] <Geth> ¦ MoarVM/moar-gdb-rrdb: review: https://github.com/MoarVM/MoarVM/commit/ae24fde56a

[19:31] <timo> so we know literally nothing about these two. r1(5) is also merged from others though

[19:33] <MasterDuke> `PHI               r1(5),   r1(3),   r1(7)` where `r1(3): usages=2, flags=0     (merged from 2 regs)` and `r1(7): usages=6, deopt=20,19, flags=0     (merged from 4 regs)`

[19:34] <timo> well, you can already guess what i'd tell you next :D

[19:34] <MasterDuke> maybe there's too much inlining happening to make this a good test case?

[19:35] <timo> try making the loop that goes over the $l into a sub and passing the $l in, then (unless nqp inlines it itself for some reason) spesh should learn what the type of the incoming argument actually is, and guard on it

[19:36] *** guifa_ joined
[19:40] <MasterDuke> still doesn't know the type in `iter_facts()`

[19:41] <MasterDuke> but i do see `Observed type specialization of 'iter-a-bunch' ... It was planned for the type tuple: Type 0: BOOTIntArray (Conc)`

[19:41] <timo> ok, then the register it puts the $l into from the function arguments is expected to have the known type flag on it

[19:48] <MasterDuke> r0(2)?

[19:51] <timo> might be

[19:51] <MasterDuke> well, i see `r0(2): usages=1, flags=9     KnTyp Concr (type: BOOTIntArray)`

[19:51] <Geth> ¦ MoarVM/moar-gdb-rrdb: 1890e0618a | (Timo Paulssen)++ | tools/libmoar.so-gdb.py

[19:51] <Geth> ¦ MoarVM/moar-gdb-rrdb: gdb plugin: Output bytecode file and cuuid in single-frame view too

[19:51] <Geth> ¦ MoarVM/moar-gdb-rrdb: review: https://github.com/MoarVM/MoarVM/commit/1890e0618a

[19:52] <timo> that's good. so it'll go through some instructions, likely including a PHI or two, before reaching the `iter` opcode

[19:53] <MasterDuke> yeah `iter              r7(4),   r0(4)`, where `r7(4): usages=1, flags=0` and `r0(4): usages=2, flags=0     (merged from 2 regs)`

[19:54] <MasterDuke> `PHI               r0(4),   r0(0),   r0(3)` where `r0(0): usages=2, flags=0` and `r0(3): usages=1, flags=0     (merged from 2 regs)`

[19:55] <MasterDuke> `PHI               r0(3),   r0(2),   r0(5)` where `r0(2): usages=1, flags=9     KnTyp Concr (type: BOOTIntArray)` and `r0(5): usages=6, deopt=10,9, flags=0     (merged from 4 regs)`

[19:55] <timo> so all of versions 0, 3, and 4 don't have the info any more

[19:55] <timo> and r0(0) probably comes from the BB number 0? i.e. has no value set to it at all?

[19:56] <MasterDuke> i believe so, i don't see it as the first arg in any of the PHIs

[20:02] <Geth> ¦ MoarVM/moar-gdb-rrdb: e504417c10 | (Timo Paulssen)++ | tools/libmoar.so-gdb.py

[20:02] <Geth> ¦ MoarVM/moar-gdb-rrdb: gdb plugin: Fix TC sorting, reject cases like "double tc" out-right

[20:02] <Geth> ¦ MoarVM/moar-gdb-rrdb: review: https://github.com/MoarVM/MoarVM/commit/e504417c10

[20:03] <timo> the BB that has the PHI with r0(0) in the middle would have a Predecessor where that's the version of the register that "lives there"

[20:04] <timo> does this frame have any frame handlers? like a handler goto annotation somewhere? I think we currently create a "fake" successor of BB 0 to every BB that has a handler jump point, or maybe every BB that's covered by a handler

[20:04] <MasterDuke> don't see anything like that

[20:05] <MasterDuke> BB 4 and 8 have PHIs with r0(0)

[20:06] <timo> anything interesting in 4 and 8's Preds?

[20:07] <MasterDuke> `0, 3` and `0, 5, 6, 7`. don't know if that's interesting

[20:13] <Geth> ¦ MoarVM/moar-gdb-rrdb: 6e7788d834 | (Timo Paulssen)++ | tools/libmoar.so-gdb.py

[20:13] <Geth> ¦ MoarVM/moar-gdb-rrdb: gdb plugin: Fix TC sorting, reject cases like "double tc" out-right

[20:13] <Geth> ¦ MoarVM/moar-gdb-rrdb: review: https://github.com/MoarVM/MoarVM/commit/6e7788d834

[20:13] <timo> there's the BB 0

[20:14] <timo> we're doing that for some kind of extra safety so we don't mess things up, but it does frustrate optimization like in this case

[20:16] <MasterDuke> should i do some more random work before/after the iteration to "isolate" it?

[20:17] <timo> https://gist.github.com/timo/20b8e7f029b21581997f151be3bdce7f

[20:17] <timo> can you try "upgrading" to rakudo?

[20:17] <MasterDuke> oh, nice

[20:18] <MasterDuke> still calling nqp::iter though?

[20:19] <timo> yeah. may need a nqp::decont or two here and there

[20:19] <timo> or maybe using IterationBuffer

[20:19] <timo> actually, native arrays are repr'd VMArray IIRC?

[20:22] <MasterDuke> i think so. hm, doesn't optimize iter-a-bunch now

[20:24] <MasterDuke> `raku -e 'use nqp; my $l := nqp::list_i(); my int $p = 0; while $p++ < 10_000 { nqp::push_i($l, $p) }; sub iter-a-bunch(Mu $list is raw) { my int $j = 10000; while $j-- { my $iter := nqp::iterator($list); nqp::while($iter, my $a := nqp::shift($iter)) }; }; iter-a-bunch($l)'` is what i ran

[20:26] <MasterDuke> or `raku -e 'use nqp; my int @l; my int $p = 0; while $p++ < 10_000 { @l.push($p) }; sub iter-a-bunch(int @list) { my int $j = 10000; while $j-- { my $iter := nqp::iterator(@list); nqp::while($iter, my $a := nqp::shift($iter)) }; }; iter-a-bunch(@l)'`

[20:27] <timo> it doesn't show up in the spesh log at all?

[20:28] <MasterDuke> not as a before/after

[20:29] <MasterDuke> changed to call it a bunch of times, now it does

[20:29] <MasterDuke> `Type 0: array[int] (Conc)`

[20:33] <MasterDuke> `iter             r10(4),   r1(4)` where `r10(4): usages=1, flags=0` and `r1(4): usages=2, flags=0     (merged from 4 regs)`

[20:34] <MasterDuke> `PHI               r1(4),   r1(0),   r1(3),   r1(5),   r1(5)` where `r1(0): usages=2, flags=0` and `r1(3): usages=1, flags=0     (merged from 4 regs)` and `r1(5): usages=10, deopt=13,12, flags=0     (merged from 4 regs)`

[20:35] <MasterDuke> `PHI               r1(3),   r1(2),   r1(5),   r1(5),   r1(5)` where `r1(2): usages=1, flags=9     KnTyp Concr (type: array[int])`

[20:36] <timo> ugh. still got version 0 in there, which is probably from BB 0 again

[20:40] <MasterDuke> added some fluff beginning and end of the sub. `iter             r17(7),   r1(7)` where `r17(7): usages=1, flags=0` and `r1(7): usages=2, flags=0     (merged from 4 regs)`

[20:41] <MasterDuke> `PHI               r1(7),   r1(0),   r1(6),   r1(8),   r1(8)` still the `(0)`

[20:42] <timo> i mean, facts could always take the type for iterators and say we know that's the type right? but we wouldn't have knowledge about whether it's an array or hash iterator

[20:43] <MasterDuke> right now the code does distinguish those

[20:45] <Geth> ¦ MoarVM/moar-gdb-rrdb: 13b30534e2 | (Timo Paulssen)++ | tools/libmoar.so-gdb.py

[20:45] <Geth> ¦ MoarVM/moar-gdb-rrdb: gdb plugin: throw out some debug noise

[20:45] <Geth> ¦ MoarVM/moar-gdb-rrdb: review: https://github.com/MoarVM/MoarVM/commit/13b30534e2

[20:45] <Geth> ¦ MoarVM/moar-gdb-rrdb: 4b00388fca | (Timo Paulssen)++ | tools/libmoar.so-gdb.py

[20:45] <Geth> ¦ MoarVM/moar-gdb-rrdb: gdb plugin: RRDB: don't store "elapsed time" redundantly

[20:45] <Geth> ¦ MoarVM/moar-gdb-rrdb: 

[20:45] <Geth> ¦ MoarVM/moar-gdb-rrdb: it only changes from one event to the next, so storing an extra table with

[20:45] <Geth> ¦ MoarVM/moar-gdb-rrdb: event to elapsed time values makes a lot more sense.

[20:45] <Geth> ¦ MoarVM/moar-gdb-rrdb: review: https://github.com/MoarVM/MoarVM/commit/4b00388fca

[20:45] <timo> what exactly were you looking to optimize? the boolification of the iterator, right?

[20:48] <MasterDuke> yeah

[20:50] <timo> what does that look like by that point?

[20:51] <MasterDuke> the original thought was optimizing looping via iter+shift, which triggered my reach-into-the-array-body attempt. but then you pointed out the problem with that and said the boolification of the iterator was taking time

[20:52] <MasterDuke> you mean in spesh?

[20:53] <timo> yeah

[20:53] <timo> i assume it's a dispatch to boot-boolify before, and after just a runcfunc

[20:54] <MasterDuke> i see a lot of boot-boolify dispatches, trying to figure out the right one...

[20:56] <MasterDuke> but yeah, i see two boot-boolifys in the before of iter-a-bunch and two sp_runcfunc_i after

[20:57] <timo> right

[20:57] <timo> i hope it doesn't sp_runcfunc_i into box into unbox right away

[20:57] <timo> do you know about the trace spesh optimizer gdb script?

[20:57] <MasterDuke> hm, don't think i've used that

[20:58] <MasterDuke> and i don't see any box/unbox at all in iter-a-bunch

[20:58] <timo> that's good at least

[21:00] <timo> the trace spesh script works by putting a bunch of breakpoints in different spots in spesh's optimize, then at each of these it spits out MVM_spesh_dump (i.e. the same stuff that lands in the spesh log) into a file and tracks the files in a scratch git repository, then at the end you can see a git log with diffs of how the spesh dump changes step by step

[21:00] <MasterDuke> oooo

[21:00] <timo> you load it into gdb with the "source" command I think

[21:00] <timo> it's in moarvm's tools folder

[21:01] <timo> you do have to be in the right spot at the start in order for it to work right, i.e. at the start of the right frame's spesh happening

[21:01] <timo> and uhhh with changes in spesh's code, maybe a few of the break points are no longer valid?

[21:03] <MasterDuke> seems to be doing something

[21:05] <MasterDuke> well, it was. now it looks like it's just sitting

[21:06] <timo> it should throw you into a pager, but you can go to /tmp and look for the folder where the git repo was created to go in and "git log -u" yourself

[21:06] *** guifa_ left
[21:07] <MasterDuke> `fatal: your current branch 'master' does not have any commits yet`

[21:07] <timo> so it wasn't very successful, huh?

[21:08] <MasterDuke> added 13 breakpoints, but doesn't seem to be doing much after that

[21:08] <timo> you got a gdb prompt again? otherwise you can ctrl-c and see what's up

[21:09] <MasterDuke> no prompt

[21:09] <MasterDuke> and ctrl-c didn't do anything

[21:12] *** guifa_ joined
[21:14] <timo> :|

[21:14] <timo> pstree showing anything suspicious? could be a different process has the tty or something

[21:15] <MasterDuke>         │                   ├─bash─┬─gdb─┬─raku───{raku}

[21:15] <MasterDuke>         │                   │      │     └─8*[{gdb}]

[21:21] <MasterDuke> but afk for a while. dinner and then putting kids to bed. should be back later this evening if anybody is still around

[21:22] <timo> all right!

[21:25] *** MasterDuke left
[21:52] *** guifa_ left
[21:57] *** guifa_ joined
[22:13] *** librasteve_ left
[23:47] *** guifa_ left
[23:51] *** guifa_ joined
