
David Turner
Ben, Eric, thanks for your help. A whole new world of low-level statistics opens up before me...
No worries!
You're not wrong.
I've trawled through the STG as best as I can for a newbie. The function with a large number in the 'Alloc' column looks pretty much to be the heart of the `step` function. There's a lot of nesting but it looks largely to be just checking the bounds on array indices, which I don't think allocates anything.
Something that I should have mentioned earlier is that STG has the nice property that all allocation is syntactically obvious: allocated closures manifest as `let`s. This makes it fairly easy to pick out possible allocation sites, even in large dumps.
However I see this this little snippet at the very bottom of the nesting:
case indexArray# [ds1_sl1b y2_sl5H] of _ [Occ=Dead] { (##) ipv8_sl60 [Occ=Once!] -> case ipv8_sl60 of _ [Occ=Dead] { GHC.Word.W8# dt6_sl62 [Occ=Once] -> case ss_sl5v of dt7_sl63 { __DEFAULT -> (#,,#) [__word 1 dt6_sl62 dt7_sl63]; }; }; };
I'm guessing that the `indexArray` call is the line that reads `nextState = aTransitionsTable makeAutomaton AU.! (currentState, nextByte)`, and to me it looks like it might be unboxing the thing it's getting out of the array. Not sure that counts as an allocation, but I'm surprised anyway.
The unboxing should just involve looking at the value field of the W8# closure (e.g. a memory dereference) and putting the value in a machine register. There is no allocation here as far as I can see.
I'll keep digging anyway, but it'd be good to hear of any progress at your end too. Hope it didn't spoil your lunch!
Far from it! It was nice to have a puzzle to ponder. Cheers, - Ben