01:49 ilbot3 joined 03:14 KDr2_ joined 05:38 brrt joined 05:43 TimToady joined 05:58 TimToady joined 06:40 brrt joined
brrt good * #moarvm 06:47
somewhat predictably, using the JIT local types array blows up horribly in the GC 06:48
i haven't quite figured out why just yet
nwc10 start it running under valgrind and go off and make coffee? 06:58
brrt that's a decent idea, but i already know that it's a small number being interpreted as an object 07:03
what i don't know if that is due to a too-small buffer being allocated
nwc10 in which case, valgrind (plus disabling the FSA) should make that obvious? 07:04
or at lesat, give you time for more coffee
brrt can i disable the FSA? 07:11
nwc10 I think it's
src/core/fixedsizealloc.c
-#define FSA_SIZE_DEBUG 0
+#define FSA_SIZE_DEBUG 1
at least, that's what I'm building with locally 07:12
but
I thought that there was another thing you could do to it...
no wait, the other way was just to say that the max sized thing for the FSA was 0, meaning that it call camee from malloc 07:13
brrt well, let's just try it out 07:14
nwc10 but looking at the code in src/core/fixedsizealloc.c I can see that the debug is more sophisticated - it comes from malloc *and* the size is checked too
brrt valgrind doesn't have much more information yet... 07:19
clang y u so slow 07:20
address 0x96f is not malloc'd or stack'd or whatever 07:29
nwc10 and given that was all you typed, there was no backtrace? 07:31
as in, straight out, garbage value used as pointer? 07:32
brrt correct
well, garbage marking as pointer 07:33
it happens in Gc
07:58 zakharyas joined 08:31 zakharyas joined
timotimo with --valgrind the FSA will have redzones next to its allocations 09:20
--valgrind in moar's Configure.pl
brrt hmm, i'll try that out 09:22
timotimo what it doesn't do is to put freed pieces into a long list 09:32
valgrind does that for regular malloc
it keeps freed stuff around long to find use-after-free even if the use comes long after the free
jnthn brrt: What's in the local types array, or what exactly is it doing GC-wise? 09:59
brrt local types is how we determine which of the locals to scan 10:00
jnthn Yes
brrt i've changed the spill memory allocator to mark spilled values (which go into the local values array) as objects
jnthn Where is the spilled stuff stored?
On the stack? 10:01
brrt on the work buffer
frame->work
jnthn A
brrt why
jnthn Ah
brrt because otherwise, suppose we have to trampoline, we're in big problems
jnthn OK, so you extend that with extra space to spill into?
brrt that is the intention yes
but since i've changed that, it might be broken
:-)
jnthn We already have a mechanism for that, iirc 10:02
(Allocating an extra reg)
brrt yeah, so, one of the challenges with that is 10:04
the JIT runs far after the spesh graph building
eh manipulation
so it could well be that the temporary is already released prior my allocation starts
(we should have a new 'high water mark' for that)
which means i'm going to go ahead and do all the wrong things if i'd use that
jnthn Well, the extras are added during optimization, fwiw 10:06
brrt uhuh, still, point kind of stands 10:10
:-)
this is just a case of me doing something silly wrong
10:10 domidumont joined 11:01 brrt joined 11:06 brrt joined 11:33 brrt joined 11:49 AlexDaniel joined 11:54 brrt joined 12:06 brrt joined
Geth MoarVM: 74ad7f7fb8 | (Timo Paulssen)++ | src/core/interp.c
fix error message for decodersetlineseps getting non-decoder
12:12
jnthn In preparation for upcoming spesh improvemnet work, I'm currently working on a list of its shortcomings 12:15
gist.github.com/jnthn/95d0705d225e...faa337624b is so far; I'm still adding things :)
brrt interesting little finding regarding my bug; i'm writing to 0x15e, not to 0x150, or 0x158 12:16
jnthn oops 12:17
timotimo oh, oh, i have one, jnthn 12:19
this pretty much piggybacks on "bad statistics":
when we have a function with multiple loops, OSR will kick in while the code runs in the first loop, and then the optimized version runs forever, even though in the second loop it could likely OSR again and gather new stats 12:20
jnthn You've seen this happen in real world code, I guess? :)
timotimo yup 12:21
i don't have good example code or measurements, though
i ought to be able to come up with an example where a function with two loops is noticably slower than two functions with one loop each and another function calling each ni turn 12:22
jnthn Yeah, I can believe it'd happen 12:23
timotimo i'm trying to find good example code to guide my jit implementation of the different encoder ops 12:24
zef installing itself gave me decoderaddbytes, now i'm also seeing read_fhb, close_fh, open_fh, getcp_s, fc, and chr 12:25
(obviously this is more than just encoder/decoder related)
jnthn Yeah, but all worth having :) 12:26
timotimo fc is very easy to add, yay 12:27
(it also only occured a single time across all processes it spawned to install zef)
brrt notes that having a separate thread for spesh/jit work would open space for much more aggressive optimizations 12:31
jnthn brrt: that also 12:32
dogbert11 jnthn: interesting spesh writeup, looks as if there are a lot of wins to had there although I suspect none of them are LHF 12:36
*to be had
jnthn Added four more things 12:37
Including timotimo++'s one, which I totally hadn't thought of
timotimo how do we feel about jitting lock/unlock and semtryacquire and friends? 12:40
brrt nothing about it
timotimo well, "when should i put it into the jit" :P 12:41
dogbert11 "Since they have are called on a huge range of types..." # nitpick 12:42
12:42 TimToady joined
dogbert11 also, what about bugs in the current implementation, will they be removed at the same time as this work is being done? 12:43
jnthn dogbert11: Yes, those could also do with going into this document to make sure we address them 12:44
dogbert11 I see three RT's with spesh in the headline
jnthn Got links? 12:45
dogbert11 m: sub foo () {$ = 42}; for ^2000000 { $ = foo }; say now - INIT now # RT #130855
camelia Cannot assign to an immutable value
in block <unit> at <tmp> line 1
synopsebot6 Link: rt.perl.org/rt3/Public/Bug/Display...?id=130855
dogbert11 there's one
jnthn wowser 12:46
dogbert11 the other are 131306 and 126364
there's one MoarVM issue which might apply as well: github.com/MoarVM/MoarVM/issues/552 12:47
12:48 TimToady joined
timotimo all the lock ops have the reprid and concreteness checks in the interpreter at the moment 12:57
12:57 TimToady joined
timotimo for the purpose of jitting that'd have to move into the function itself 12:57
(or be done using the exprjit)
jnthn Updated it again to now contain bugs dogbert11++ pointed out and some further points 13:00
timotimo "inforamtion" <3 13:02
jnthn fixed :) 13:07
And added two more things
timotimo running a spectest with my jit additions 13:08
jnthn Gradually running out of things to put on the list :)
oh!
Added one more big one that I forgot 13:11
timotimo oh yeah 13:12
jnthn wonders what else there is 13:13
Though if we nail that lot then we'd be doing really quite well :)
dogbert11 will any kind off tooling have to made in order to make debugging spesh easier? 13:18
timotimo well, if we make the "new" spesh log a bit machine-readable, we'll be able to build something
jnthn already speculated an "optimization report"
dogbert11 I seem to remember that you or jnthn have written that finding spesh bugs is a real chore 13:19
jnthn dogbert11: Yeah, that's part of my "explain what we did" suggestion 13:21
Geth MoarVM: 8eb050f06b | (Timo Paulssen)++ | src/jit/graph.c
jit a bunch more ops

open_fh, close_fh, read_fhb, decoderaddbytes, fc, chr, getcp_s, objectid
taken from bails during zef's self-installation
13:23
dogbert11 I see it :)
jnthn Anyway, I leave that gist for further suggestions/input for now
But I think it or something like it will be my input for a spesh re-design 13:24
My idea being to try and gradually move towards the goal from what we have
Rather than to do it over
Because it's not like what we have is all bad. :)
It could just be improved quite a bit :) 13:25
timotimo has to drive over to his old apartment and get a whole bunch of stuff out of there :| 13:26
so we can clean up fully and paint the walls and such
with temperatures as they are, this is going to be hell 13:27
jnthn :(
Yeah, it's 34C here :S
timotimo same here
jnthn Horrible
timotimo at least my care has A/C
dogbert11 17C
timotimo car*
dogbert11 34C is unbearable 13:28
jnthn dogbert11: Goodness, that's nice.
Is that typical for late June there, or just a one-off? :)
dogbert11 quite typical here in Scandinavia 13:29
a few degrees warmer wouldn't hurt though
jnthn When I lived in Scandinavia it was in the south of Sweden, which I guess is a bit warmer than the average :) 13:30
But still typically a few degrees cooler than it can get here
dogbert11 34C, I hope there's AC available 13:31
jnthn Alas no, 'cus it's relatively unusual for this to happen
And 34C is outside. In is more like 26C. Still too hot, but not quite so bad.
nwc10 but your commute will be breifly unbearable? :-/ 13:32
dogbert11 can't you find a pub lacated in a cellar somewhere :)
*located
jnthn Mmm :) 13:40
jnthn away for a bit
[Coke] No pub found, "lacated". Did you mean "lactated" ? 13:56
14:05 brrt joined
jnthn
.oO( milk stout )
14:13
brrt i have the answer to my bug 14:20
who wants to know... 14:21
it's actually kind of cute
but
i'm allocating 'on top of' the local + the space for the args
but local_types is acting as if my temps get to the end of the local 14:22
which is the more correct thing to do, to be fair
14:34 AlexDani` joined
brrt with GC stress, compiling core.settings takes impossibly long 14:55
but doesn't burn yet
Geth MoarVM/even-moar-jit: 65938869df | (Bart Wiegmans)++ | 5 files
Use jit code local types array for roots

Spilled values are stored, by default, in the frame work array. If they had been on the stack, entering the interpreter would destroy them.
This moves those spilled values into the work array proper (they used to be after the args array) and ensures that the GC will properly trace and update them. This then ensures that the JIT compiled code will always have the proper values regardless of whether we call something that allocates memory.
14:57
16:07 brrt joined
lizmat the max we've seen outside here was 35.9 16:12
it's way cooler now
only 34 :-(
brrt that's insane :-o 16:27
thunderstorms entering here
[Coke] looks like high outside here today is 27C 16:43
weather's been all over the map here this spring/summer
(well, spring, I guess) 16:44
lizmat previous high temp ever for 22nd June was 31.7 16:45
16:54 zakharyas joined 16:59 domidumont joined
ilmari we had 33Ā°C here yesterday, but only 23Ā°C today 17:00
jnthn Urgh, this is decidedly not the kind of weather to think in. 17:59
yoleaux 16:56Z <lizmat> jnthn: looks like nqp::create is actually assigning type objects to vivify attributes, is that correct ?
jnthn .tell lizmat Vivification happens at first access, not at creation time
yoleaux jnthn: I'll pass your message to lizmat.
nwc10 have you thought about the beer fridge? 18:01
lizmat m: use nqp; class A { has Int $.a is default(42) is rw }; my $a := nqp::create(A); dd $a.a; dd nqp::getattr($a,A,q/$!a/).VAR.default # jnthn, then why doesn't this show 42 twice ? 18:11
camelia Int $!a = Int
42
jnthn I'll bet if you stick is rw on the attr you'll get it :) 18:15
When it's not "is ro" then we decontainerize it
And I guess the decontainerization process doesn't care for the default 18:16
nwc10 thinks about the beer in the fridge, and the couple of crates in the L2 cache 18:17
jnthn Or something along those lines
Oh, but you did put `is rw` 18:18
That makes it stranger still
o.O
OK, I've no idea what it's doing :)
Without going on more of a debugging spree than I'm up for right now
Hang on a moment 18:19
m: use nqp; class A { has Int $.a is default(42) is rw }; my $a := nqp::create(A); dd nqp::getattr($a,A,q/$!a/) 18:20
camelia Int $!a = Int
jnthn It's nothing to do with the accessor at all
In this case it's possible that attr container auto-viv just doesn't pay any attention to `is default` 18:21
fwiw, it's also entirely possible attr container auto-viv wants to go away. 18:22
And that we should initialize them explicitly during construction
Because right now we pay for it on every single attribute access 18:23
Turning them all into a branch
It made performance sense on balance back in the day
But not so much when we've a modern VM 18:24
Suspect brrt would like the JIT output much more if we did this. :-)
Though more importantly, I suspect CPUs rather would doo.
*too
Something to think about, anyways 18:25
lizmat well, it could make all object creation a lot simpler
jnthn How so?
lizmat has $.a = 42 vs has $.a is default(42)
the former would need the BUILDALL action, the latter not 18:26
or a simpler one
jnthn You're assuming BUILDALL actions are here for the longhaul :)
If we did end up making the changes I just suggested we'd pretty much have to revisit that lot anyway
lizmat well, it's a bug that "is default" is getting ignored for attributes
jnthn We'd also have to figure out some other kind of solution for attrinitted
lizmat anyways, it feels like a lot could be gained there 18:27
a lot that doesn't show in profiles much, as it's spread out a lot
anyways, dinner calls&
jnthn Happy nomming :) 18:28
And yeah, agree that a good look at object init could win us a lot
18:32 domidumont joined 19:35 TimToady joined 19:47 TimToady joined 19:51 TimToady joined 19:57 TimToady joined
robertle I am failing to understand how register allocation etc works in moar. how/when/where are register frames created? and how is the number of registers in the frame determined? 20:28
jnthn robertle: See allocate_frame in src/core/frame.c, also MVMStaticFrame.h carries the number that are needed 20:30
robertle so do we do that for each lexical scope, roughly? 20:32
that would be surprising 20:33
20:33 zakharyas joined 20:34 brrt joined
jnthn Yes 20:35
Well
Naively :-)
robertle naively is what I am after!
jnthn Reality is more interesting.
In that Perl6::Optimizer flattens away scopes in some cases 20:36
robertle that means a "register" is almost directly associated with a variable?
jnthn NQP::Optimizer does so far more aggressively; we can't go quite all that far with Perl 6
Though we can go further than we do 20:37
We use register and local as synonyms
A frame can have both lexicals and registers
Register = temporary working space
robertle right, and we need these as scratch space e.g. inside an expression 20:38
jnthn And is destroyed immediately when the thing returns
In some cases, lexical variables that aren't closed over are optimized into locals (e.g. registers)
The lexical space lives longer 20:39
There's no distinction at MoarVM level about which registers are scratch space and which are cases of lexical optimized into local
It only differentiates on the lifetime (can go away at return, may have to live beyond return) 20:40
robertle o how do we access registers from an outer frame? we can't just GET_REG?
jnthn You can't
Only lexicals can do that 20:41
In MVMFrame those are ->work and ->env respectively
->work cannot be touched from anything except the bytecode in that call frame.
(This turns out to be a hugely important property for optimization) 20:43
robertle argh, I am missing more fundamental bits as well... 20:46
20:54 MasterDuke joined 21:01 AlexDaniel joined 21:54 MasterDuke joined 22:59 TimToady joined