00:03:15  * floodyquit (Ping timeout: 250 seconds)
00:35:38  * [[zzz]]joined
00:38:13  * [[zz]]quit (Read error: Operation timed out)
01:02:56  * c4milojoined
01:03:15  * mraleph1quit (Ping timeout: 260 seconds)
01:46:27  * mralephjoined
02:20:17  * c4miloquit (Remote host closed the connection)
03:21:39  * c4milojoined
03:25:35  * c4miloquit (Remote host closed the connection)
04:29:02  * asrailquit (Ping timeout: 256 seconds)
05:16:41  * Vbitzquit (Quit: Computer has gone to sleep.)
05:41:13  * M28quit (Read error: Connection reset by peer)
05:42:23  * M28joined
06:02:11  * asrailjoined
06:44:19  * xan_joined
06:48:25  * asrailquit (Ping timeout: 276 seconds)
06:57:55  * C-Manjoined
07:28:16  * juanjosanchezjoined
07:37:09  * guorquit (Read error: No route to host)
07:56:37  * mraleph1joined
07:57:09  * mralephquit (Read error: Connection reset by peer)
07:57:31  * C-Manquit (Quit: Connection reset by beer)
08:13:09  * jonaslundjoined
08:25:11  * C-Manjoined
09:27:11  * Net147joined
10:27:44  * floodyjoined
10:27:48  <floody>helllo
10:37:49  <floody>could someone please help me? i trying to write an extension to nodejs and i'm little confused in that part how can i easily expose deeply nested cpp objects to the js world, could someone show me a good example?
11:08:55  * juanjosanchezquit (Ping timeout: 252 seconds)
13:00:36  * C-Manquit (Quit: Connection reset by beer)
13:58:28  * juanjosanchezjoined
14:07:32  * asrailjoined
14:16:43  * decoder_joined
14:18:06  * decoderquit (Ping timeout: 249 seconds)
14:19:02  * c4milojoined
15:06:00  * bnoordhuisjoined
15:31:43  * RT|Chatzillaquit (Quit: ChatZilla [Firefox])
15:52:32  * Net147quit (Quit: HydraIRC -> http://www.hydrairc.com <- Nine out of ten l33t h4x0rz prefer it)
16:08:11  * sanjoydquit (Remote host closed the connection)
16:08:15  * Alex_Gaynorquit (Read error: Connection reset by peer)
16:26:28  * C-Manjoined
16:56:14  * bnoordhuisquit (Ping timeout: 256 seconds)
17:20:28  * Alex_Gaynorjoined
17:35:00  * floodyquit (Quit: Page closed)
18:02:33  * bnoordhuisjoined
18:07:11  * bnoordhuisquit (Ping timeout: 252 seconds)
18:08:29  * sanjoydjoined
18:10:09  * bnoordhuisjoined
18:14:19  * juanjosanchezquit (Ping timeout: 264 seconds)
18:27:11  * juanjosanchezjoined
18:34:51  * carifjoined
18:47:33  * floodyjoined
18:47:39  <floody>hello
18:57:10  <bnoordhuis>what's up floody?
18:58:44  <Alex_Gaynor>mraleph1: ping
19:32:08  <mraleph1>pong Alex_Gaynor
20:19:15  * carifquit (Read error: No route to host)
20:20:15  * carifjoined
20:22:22  * Vbitzjoined
20:25:36  <Alex_Gaynor>mraleph1: Does v8 or dart do any loop unrolling? (Particular in cases where stuff is not syntactically constant, such as over the elements of a variadic function)
20:30:17  <mraleph1>we don't unroll any loops
20:30:21  <mraleph1>no unrolling
20:30:24  <mraleph1>no peeling
20:30:27  <mraleph1>no nothing
20:30:30  <mraleph1>never got to it.
20:30:45  <mraleph1>too much other stuff to care about
20:30:48  <mraleph1>Alex_Gaynor: ^^^^
20:31:16  <Alex_Gaynor>mraleph1: ok, thanks, do you feel like looking over some notes on adding loop unrolling to pypy (feel free to not care at all :))?
20:33:29  <Alex_Gaynor>Also, do you know of any other dynamic (or static, I guess) language JITs which do unrolling?
20:34:14  <mraleph1>lua? :-)
20:34:21  <mraleph1>he does everything
20:34:31  <Alex_Gaynor>That's what I figured :D I wonder if he's on IRC
20:34:44  <bnoordhuis>Alex_Gaynor: fwiw, loop unrolling has been a subject of some debate on the gcc mailing lists
20:34:57  <bnoordhuis>apparently it's harmful as often as it's beneficial
20:34:57  <mraleph1>JVM does unrolling.
20:35:11  <mraleph1>especially if you work with arrays.
20:35:30  <mraleph1>like do four things at a time.
20:35:37  <mraleph1>for tight loops.
20:35:46  <Alex_Gaynor>bnoordhuis: Sure, there are codesize concerns (depending on your architecture and other fun); but I have cases that can do better codegen, stuff like (python): `for attr in ["a", "c"]: getattr(obj, attr)()`
20:35:54  <Alex_Gaynor>(yes, people do metaprogramming like this)
20:36:01  <mraleph1>Alex_Gaynor: I would be very interested to look at your notes. I am always very curious about PyPy.
20:36:11  <Alex_Gaynor>mraleph1: https://gist.github.com/alex/5664808 (feel free to ask about stuff that makes no sense)
20:36:59  <bnoordhuis>Alex_Gaynor: right. that makes sense
20:37:32  <mraleph1>oh metaprogramming. this is pretty cool.
20:37:43  <mraleph1>ah this is why you asked about for (var x in foo)
20:38:00  <Alex_Gaynor>Yes, somehow I'm supposed to make: https://bitbucket.org/zzzeek/sqlalchemy/src/master/lib/sqlalchemy/engine/base.py#cl-597 fast :)
20:38:51  * fijaljoined
20:38:54  <fijal>mraleph1: hi
20:39:03  <mraleph1>hi!
20:39:54  <mraleph1>I suppose you inline execute into call site where object is known?
20:40:08  <mraleph1>where is the loop that you are tracing?
20:41:45  <Alex_Gaynor>http://bpaste.net/show/102625/ is an example
20:43:13  <Alex_Gaynor>Right now, we inline into execute and then immediately emit a call to the execute() loop
20:43:21  <Alex_Gaynor>ideally that whole loop would be unrolled (assumign the type of object is constant)
20:45:22  * ls3joined
20:49:16  <mraleph1>interesting.
20:49:50  <mraleph1>though I skipped almost all details related to IR or innards of the pipeline :-)
20:49:57  <Alex_Gaynor>:)
20:50:56  <mraleph1>for JavaScript main retardiness in optimizing for (var k in o) is that k will iterate over names and you have to manually access o[k] and then you need to link this two things together in the IR and blargh
20:51:33  <mraleph1>and then be carefull to guard in the right places against the shape changes.
20:51:42  <mraleph1>but you are kinda free from all this.
20:52:35  <mraleph1>which actually makes me wonder if LuaJIT actually unrolls something like this.
20:52:56  <Alex_Gaynor>I'm not sure, I don't think Mike hangs out on IRC unfortunately.
20:53:06  <Alex_Gaynor>I don't think .*?Monkey does either.
20:53:25  <bnoordhuis>you mean the spidermonkey guys?
20:53:39  <Alex_Gaynor>spider/ion/whatever else they're up to
20:53:48  <bnoordhuis>they hang in some of the irc.mozilla.org channels
20:53:58  <bnoordhuis>hang, hang out.
20:54:22  <bnoordhuis>PST office hours, mostly
20:56:55  <mraleph1>which reminds me about one thing
20:58:03  <mraleph1>in node.js MySQL driver author got a big boost by manually unrolling for (var i = 0; i < cols.length; i++) a[cols[i]] = row[i]; using code generation.
20:58:36  <mraleph1>though it's pretty hairy to do this optimization automatically.
20:59:20  <mraleph1>I am just sitting here and trying to understand if I ever saw a case where it would help without any implementation complications
21:01:04  <fijal>mraleph1: I think we don't have such issues
21:01:08  <fijal>but not because pthon
21:01:09  <fijal>python
21:01:14  <fijal>but because meta-tracing
21:01:52  <mraleph1>which issues in particular? building IR for for (var k in o) { …. o[k] … }?
21:02:00  <Alex_Gaynor>yes
21:02:41  <mraleph1>well, still to see that this loop is actually loop over property values, you need some pass over IR.
21:02:57  <mraleph1>metatracing does not give it you for free.
21:03:15  <fijal>mraleph1: no, but you structure the interpreter in a way that you get this shit for free
21:03:21  <fijal>the same way we have for free **kwargs
21:03:34  <fijal>if you actually have stuff that's escapeable
21:03:56  <fijal>mraleph1: you don't get it for free, but it's easier
21:04:05  <fijal>since you can tell the compiler "this is constant, this is not"
21:04:13  <fijal>does not always work like that, but you can structure it that way
21:04:19  <fijal>e.g. our jit does not know about maps at all
21:04:27  <fijal>(or hidden classes how you call them)
21:04:30  <mraleph1>mhm
21:04:48  <mraleph1>how do you track dependencies then?
21:05:10  <mraleph1>do you assume that everything that is not inside the trace can affect any slot?
21:05:29  <mraleph1>where one slot essentially contains map, or something like that.
21:05:39  <mraleph1>(and by slot I mean part of the object)
21:05:49  <fijal>you guard on the map shape
21:05:54  <fijal>anything can affect the shape
21:06:16  <fijal>but it's just one check
21:06:22  <fijal>and then you know the shape is what you're expecting
21:06:28  <fijal>we also have version numbers on type dictionaries
21:06:29  <fijal>that helps
21:06:32  <fijal>version tags actually
21:06:37  <fijal>mraleph1: python is complicated
21:07:33  * qenghoquit (Remote host closed the connection)
21:08:08  <mraleph1>yeah, I see.
21:08:38  <mraleph1>I need to look at PyPy again.
21:09:09  <fijal>no, we all suck
21:09:15  <Alex_Gaynor>haha
21:09:24  * qenghojoined
21:09:25  <fijal>that's what I was told when I visited you guys ;-)
21:09:47  <mraleph1>how do you get from lookup in the interpreter to guard on shape and load?
21:09:48  <Alex_Gaynor>mraleph1: I just found a mail from you on this very subject! http://lua-users.org/lists/lua-l/2009-11/msg00968.html
21:09:49  <fijal>not exactly ;-)
21:10:05  <fijal>mraleph1: let me dig the code
21:10:13  <fijal>mraleph1: I think it's something like
21:10:21  <fijal>jit.hint(type.shape, promote=True)
21:10:27  <fijal>which does emit guard_value
21:10:31  <mraleph1>Alex_Gaynor: lol
21:10:55  <mraleph1>Alex_Gaynor: it's not exactly the same though and I was utterly confused back then :-)
21:11:30  <fijal>mraleph1: to be honest we wrote a paper on exaclty that subject
21:11:36  <fijal>you should read it, it's quite readable
21:11:43  <mraleph1>Alex_Gaynor: ah no, that thread is not where I was confused :-)
21:11:58  <fijal>https://bitbucket.org/pypy/pypy/src/a8943ada15ee4e7111b75237d3b7340b7453c9d0/pypy/objspace/std/typeobject.py?at=default#cl-362
21:12:00  <mraleph1>fijal: yes, I should. I actually read it, I think but I forgot details already.
21:12:12  <mraleph1>fijal: it was quite a bit of time ago.
21:12:26  <mraleph1>maybe three years, or was it the wrong paper?
21:12:47  <fijal>http://scholar.google.com/citations?view_op=view_citation&hl=en&user=S0rpYpkAAAAJ&citation_for_view=S0rpYpkAAAAJ:kNdYIx-mwKoC
21:12:48  <fijal>this one
21:13:02  <fijal>2011
21:13:09  <fijal>so not even 2 years ago
21:13:47  * fijalgoes back to "pypy, the bad parts"
21:13:55  <mraleph1>I don't think I read this one.
21:14:11  <fijal>I think it's quite readable
21:14:12  <mraleph1>I read only this one
21:14:13  <mraleph1>http://dl.acm.org/citation.cfm?id=1565824.1565827&coll=DL&dl=GUIDE&CFID=333227241&CFTOKEN=84213604
21:14:30  <mraleph1>I'll read the one you pointed to, thanks.
21:14:39  <fijal>that's the basic one
21:14:43  <mraleph1>yep.
21:14:53  <mraleph1>that is why I don't recall any details.
21:14:54  <fijal>the newer one covers specifically maps and methods and types
21:14:55  <fijal>I think
21:14:58  <mraleph1>maybe there were none :-)
21:15:04  <fijal>the basic ones cover meta-tracing in general
21:15:09  <fijal>there is also one about escape analysis
21:15:23  <fijal>and there is one that has not been written yet, which we should write about frames
21:17:57  <mraleph1>ah-ha, I see.
21:18:08  <mraleph1>so you still tell it which one is actually constant.
21:18:14  <mraleph1>or likely to be constant
21:18:19  <mraleph1>so can serve as a guard.
21:18:21  <fijal>I tell it
21:18:28  <mraleph1>promote thingy
21:18:30  <fijal>"make a version of assembler per value"
21:18:38  <fijal>this is how promote works - "assume this is constant"
21:18:40  <mraleph1>yep, yep.
21:18:45  <fijal>if it's not a new path has to be compiled
21:19:04  <fijal>so if you say write a program that stores stuff in type's __dict__ only
21:19:08  <fijal>you could do that in python
21:19:12  <fijal>performance will be horrible
21:20:42  <mraleph1>yep, this is quite similar to what I considering to do at the method JIT level to produce specialize stubs: tell compiler to fully constant fold lookup routines given the fixed hidden class.
21:21:14  <mraleph1>or given any number of fixed constant (or quasi constant arguments).
21:21:49  <mraleph1>where by quasi constant is meant that certain slots in object are assumed to constant.
21:22:05  <mraleph1>and guarded against.
21:22:05  <fijal>we have quasi constant stuff and it means something else ;-)
21:22:20  <fijal>it means out of line guards
21:22:24  <fijal>we can probably do that too
21:22:29  <mraleph1>well this is side effect of inventing terminology independently.
21:22:30  <fijal>it results in no assembler
21:22:42  <Alex_Gaynor>out-of-line guards are cool
21:22:50  <Alex_Gaynor>So luajit2 defintiely does some loop unrolling, but I completely fail to understand the heuristic
21:23:04  <mraleph1>yes it does.
21:23:14  <mraleph1>I saw the code but it is indeed confusing.
21:23:37  <mraleph1>I think one of the things that triggers unrolling is when he fails to connect phies on the backedge to achieve type stability.
21:24:09  <fijal>that's indeed odd
21:24:55  <mraleph1>http://repo.or.cz/w/luajit-2.0.git/blob/HEAD:/src/lj_opt_loop.c#l418
21:24:59  <mraleph1>it is all here.
21:25:16  <Alex_Gaynor>mraleph1: Oh really? I'm looking at lj_record.c and it appears to be there :)
21:25:22  <mraleph1>hm.
21:25:30  <mraleph1>MYSTERY
21:25:35  <mraleph1>what are you looking at?
21:25:36  <fijal>what's LJ_UNLiKELY?
21:25:50  <mraleph1>hint for a compiler I think to rearrange branches
21:25:59  <mraleph1>condition is unlikely to happen
21:25:59  <Alex_Gaynor>rec_loop_interp
21:26:10  <fijal>mraleph1: do you know how on modern architecture tell the processor "this is the likely branch"?
21:26:23  <Alex_Gaynor>you put it first I think?
21:26:25  <mraleph1>I think he is helping GCC to layout code
21:26:31  <Alex_Gaynor>pentium had an instruction for it
21:26:35  <Alex_Gaynor>but it's a noop now, as far as I know
21:27:02  <mraleph1>unlikely code can at least be moved to the bottom to utilize icache better
21:27:16  <mraleph1>I am not sure whether it is witchcraft or snake oil though
21:27:26  <Alex_Gaynor>A little of both?
21:28:25  <mraleph1>ah that one is also doing unrolling.
21:30:42  <Alex_Gaynor>I think what I'm interested is loopunroll (and not instunroll)
21:33:17  <mraleph1>so there are two unrollings: one unrolls inner loops by simply recording them as part of the trace and the other unrolls already recorded trace as whole.
21:33:31  <Alex_Gaynor>The first one is what I want (I believe)
21:33:38  <mraleph1>yep, seems so.
21:36:36  <mraleph1>though his way of deciding to unroll is indeed pretty convoluted.
21:36:50  <Alex_Gaynor>Do you understand the heuristic?
21:36:57  <mraleph1>weeeell.
21:37:23  <mraleph1>not entirely.
21:37:39  * c4miloquit (Remote host closed the connection)
21:38:15  <mraleph1>first of all I don't understand why would outer loop become hotter than inner one, this does not seem to hit even simplest case like your execute.
21:38:33  <Alex_Gaynor>Indeed, I would expect the inner loop to be compiled (badly)
21:38:43  <Alex_Gaynor>then the outer loop would decide to ignore the inner loop and re-trace it
21:38:50  <Alex_Gaynor>(and eventually throw away the inner one)
21:39:14  <mraleph1>and I don't think we will ever come to this place if we have successfully traces inner one.
21:39:19  <mraleph1>*traced
21:40:10  <mraleph1>because successfully jited inner loops will go into rec_loop_jit
21:41:08  <mraleph1>though there is some magic there in rec_loop_jit as well.
21:42:48  <Alex_Gaynor>it looks like an inner loop will always stop if it hits there
21:42:54  <mraleph1>it really seems like this whole heuristic is to catch loops that are not loops
21:42:55  <mraleph1>yep
21:43:02  <mraleph1>no wait
21:43:07  <Alex_Gaynor>(unless there's some value for ev besides LEAVE and ENTER)
21:43:22  <mraleph1>also if J->parent != 0
21:43:41  <Alex_Gaynor>but I don't think it would be a root trace there ever?
21:43:54  <Alex_Gaynor>err, sorry rather it would always be root trace
21:44:06  <mraleph1>what about two nested loops?
21:44:23  <Alex_Gaynor>If you leave a non-root trace, something besides err/stop ahppens
21:44:24  <mraleph1>like root and then one and then another.
21:44:37  <Alex_Gaynor>so then you have J->parent == 1 (I assume)?
21:44:46  <mraleph1>I guess so
21:45:08  <Alex_Gaynor>so when you LEAVE that loop, something happens?
21:48:26  <mraleph1>which one?
21:48:31  <mraleph1>the innermost?
21:48:36  <Alex_Gaynor>one with J->parent != 0
21:49:26  <mraleph1>so it seems that if he started unrolling the first inner loop he will indiscriminately unroll all inner loops as well.
21:49:35  <mraleph1>as he goes deeper.
21:50:03  <Alex_Gaynor>hmmm
21:52:34  <mraleph1>at least that is how I read this code
21:52:58  <mraleph1>or rather wait
21:53:08  <mraleph1>I said bullshit
21:53:21  <mraleph1>he indiscriminately unrolls loops in side traces.
21:54:10  <Alex_Gaynor>Sounds right, I'm not sure it's so useful for me though
21:54:40  <mraleph1>I guess not.
21:55:30  <mraleph1>anyway. have to go now :-)
21:55:40  <mraleph1>was fun digging into LJ2 sourced :-)
21:55:49  <Alex_Gaynor>Indeed, was fun :)
21:55:56  <Alex_Gaynor>I guess I'll write a prototype with explicit declaration of unrolling and then invent some hueristics.
21:56:04  <mraleph1>:-)
21:57:58  * piscisaureus_joined
22:16:27  * RT|Chatzillajoined
22:17:55  * floodyquit (Ping timeout: 250 seconds)
22:27:16  * juanjosanchezquit (Quit: Leaving)
22:44:41  * asrailquit (Read error: Operation timed out)
23:15:04  * mraleph1quit (Read error: Connection reset by peer)
23:15:06  * piscisaureus_quit (Quit: ~ Trillian Astra - www.trillian.im ~)
23:15:16  * mralephjoined
23:28:17  * hackygoluckyjoined