Show enters and exits. Hide enters and exits.
| 02:23:10 | slava | evan: ping |
| 02:31:16 | boyscout | Added libssl-dev to Debian/Ubuntu dependencies - bc7320e - Daniel Luz |
| 02:33:23 | boyscout | CI: bc7320e success. 2723 files, 10829 examples, 33841 expectations, 0 failures, 0 errors |
| 03:00:24 | benschwarz | lstoll!!!!!!!!! |
| 10:55:36 | khaase | against which version of llvm do you usually compile? trunk? |
| 10:59:06 | dbussink | khaase: trunk yeah, 2.5 doesn't have all the needed stuff yet |
| 10:59:19 | dbussink | khaase: i tried trunk two days ago and then it worked fine |
| 10:59:55 | khaase | thanks, i'll give it a try |
| 12:13:43 | cremes | khaase: evan uses revision 73074 of llvm for all of his testing so he doesn't have chase changes in trunk |
| 12:14:11 | cremes | i'd recommend that over the current HEAD if you want to minimize potential problems |
| 12:14:33 | khaase | you know if that plays well with clang? |
| 12:14:48 | cremes | no, i don't know |
| 12:16:25 | khaase | cremes: thanks |
| 12:16:35 | cremes | you're welcome |
| 16:48:31 | devinus | wait |
| 16:49:01 | devinus | so according to the rubinius benchmarks on bench.rubini.us, rubinius is only 10-15% as fast as baseline MRI? |
| 17:39:00 | evan | morning. |
| 17:47:44 | mernen | sup evan |
| 17:50:02 | evan | hey |
| 17:52:06 | evan | brixen: poke |
| 17:52:14 | brixen | yo |
| 17:52:17 | mernen | I was checking the LLVM crash on 64-bit |
| 17:52:27 | evan | mernen: ok |
| 17:52:31 | mernen | I'm really lost on LLVM, so I can't help much |
| 17:52:40 | evan | mernen: where is it crashing |
| 17:52:47 | mernen | but all of my crashes were always on vm/llvm/jit.cpp, line 362 |
| 17:52:50 | mernen | engine_ is null |
| 17:52:55 | evan | oh |
| 17:52:56 | evan | thats easy. |
| 17:53:01 | evan | you're using a newer version of llvm |
| 17:53:07 | mernen | …oh. |
| 17:53:30 | evan | use revision 73074 |
| 17:53:48 | evan | i'll take a little time today and get us working with LLVM head |
| 17:53:55 | mernen | ok, let's see now |
| 17:53:57 | evan | there were some changes to the JIT infrastructure |
| 17:54:00 | evan | thats why it's breaking |
| 17:54:05 | evan | brixen: so, 1 things |
| 17:54:37 | evan | 1) sliming down VariableScope even more, so that the write barrier doesn't have to be called to set locals, and it's easy to create |
| 17:54:49 | brixen | sweeet |
| 17:55:00 | evan | 2) investigating how to handle uncommon branches |
| 17:55:07 | evan | #2 is interesting |
| 17:55:26 | evan | thats where, normally if the guard failed, you'd execute code that just performed the send |
| 17:55:51 | evan | but instead, what you do is execute code equiv to |
| 17:56:06 | evan | return rbx_uncommon(state, call_frame, ...) |
| 17:56:30 | evan | ie, when things go wrong, you just go back and start running the method in the interpreter |
| 17:56:54 | evan | the ammount of code generated is smaller |
| 17:57:15 | evan | and it allows LLVM to optimize more |
| 17:57:18 | brixen | interesting |
| 17:57:50 | evan | imagine you inline an accessor, which returned just a number |
| 17:57:57 | evan | or rather |
| 17:58:03 | evan | i method that returns just a number |
| 17:58:05 | evan | def foo; 12; end |
| 17:58:36 | evan | if you use the uncommon way, here's what happens for code: 1 + foo |
| 17:59:05 | evan | if self.class.class_id == seen_class_id |
| 17:59:08 | evan | val = 12 |
| 17:59:10 | evan | else |
| 17:59:15 | evan | return uncommon() |
| 17:59:16 | evan | end |
| 17:59:22 | evan | return 13 |
| 17:59:33 | evan | if, instead of the return uncommon, we had |
| 17:59:38 | evan | val = send(:foo) |
| 17:59:51 | evan | LLVM couldn't constant prop the 12 and do the addition at compile time |
| 18:00:00 | brixen | I see |
| 18:00:59 | evan | so using uncommon "traps" (tahts what self calls them) |
| 18:01:01 | evan | gives you 2 things |
| 18:01:13 | evan | better value inference (and all the optz that fall out of that) |
| 18:01:22 | evan | and decreased compiled method size |
| 18:01:37 | brixen | very nice |
| 18:02:06 | evan | i think it should be pretty easy to implement too |
| 18:02:18 | evan | since i've been making the JIT use the same datastructures as the interpreter |
| 18:02:22 | evan | CallFrame, VariableScope, etc. |
| 18:03:01 | evan | one wrinkle i haven't worked out yet is how to handle exception handlers well |
| 18:03:11 | evan | since the compiled code doesn't use the UnwindInfo stuctures |
| 18:03:34 | evan | I think i can synthesis them later on in the code, if i need them |
| 18:03:42 | brixen | hmm |
| 18:03:55 | evan | but for now, i'm only going to emit calls to uncommon() if the code isn't inside an exception handler |
| 18:04:01 | evan | we'll play with that. |
| 18:04:09 | brixen | yeah, sounds interesting |
| 18:04:28 | brixen | so, check out #load and #store in this http://gist.github.com/137701 |
| 18:04:51 | brixen | do you think it's possible to inline #store and do only one ivar read for @table? |
| 18:04:59 | brixen | pulling it into a local |
| 18:05:15 | brixen | in generaly, you can't know @table isn't changed when you call a method |
| 18:05:31 | brixen | but I know it's not |
| 18:05:59 | brixen | I wonder if you can get the jit to see that |
| 18:06:42 | evan | i'd think #store could be inlined, sure |
| 18:06:57 | evan | i read what self uses to determine which methods can be inlined |
| 18:07:09 | evan | and for testing i'm going to have to add explicit inlining |
| 18:07:14 | evan | ie, |
| 18:07:22 | evan | Foo.instance_method(:foo).compiled_method.inline! |
| 18:07:34 | evan | I could just leave that in |
| 18:07:36 | evan | and we could use it |
| 18:07:56 | brixen | so, it inlines methods :foo calls or :fooL |
| 18:07:58 | brixen | ? |
| 18:08:06 | evan | whenever Foo#foo is called |
| 18:08:08 | evan | it's inlined. |
| 18:08:12 | brixen | ok |
| 18:08:22 | evan | regardless of method size changes |
| 18:08:29 | evan | or the size of Foo#foo |
| 18:08:39 | brixen | sure, that'd be useful to have to test stuff |
| 18:44:56 | mernen | rbx: Instructions.cpp:1627: static llvm::BinaryOperator* llvm::BinaryOperator::Create(llvm::Instruction::BinaryOps, llvm::Value*, llvm::Value*, const std::string&, llvm::Instruction*): |
| 18:44:57 | mernen | Assertion `S1->getType() == S2->getType() && "Cannot create binary operator with two operands of differing type!"' failed. |
| 18:45:00 | mernen | Aborted (core dumped) |
| 18:45:51 | mernen | tracing back to: rubinius::JITVisit::visit_goto_if_false at vm/llvm/jit_visit.hpp:1538 |
| 18:48:08 | evan | hm |
| 18:48:24 | evan | k |
| 18:50:46 | evan | ah. |
| 18:51:08 | evan | the ConstantInt in added and cmp need to use IntPtrTy |
| 18:51:10 | evan | rather than Int32Ty |
| 19:05:09 | dbussink | evan: i saw a lot of places where Int32Ty was used that i thought were probably wrong |
| 19:05:31 | dbussink | evan: when also investigating that failure on 64 bit, but i don't know enough about it to fix it |
| 19:05:55 | evan | yeah |
| 19:06:10 | evan | likely just need to switch those to IntPtrTy |
| 19:15:32 | evan | rad, that was easy |
| 19:15:38 | evan | uncommon traps seem to be working |
| 19:34:31 | itrekkie | Hi everyone- I'm reading the "getting stated" doc, and there's a reference to a dynamic interpreter, but I can't seem to find any more information, and I'm curious. Can anyone point me to more information? |
| 19:38:03 | evan | itrekkie: ah. the dynamic interpreter is currently gone |
| 19:38:05 | evan | sorry :/ |
| 19:38:12 | evan | we may revive it at some point |
| 19:38:18 | evan | but we're working mainly on the JIT atm |
| 19:38:46 | itrekkie | Ah, that's cool. So -Xrbx.dyni does nothing? |
| 19:38:53 | evan | nope |
| 19:38:56 | evan | sorry |
| 19:39:03 | itrekkie | gotcha, thanks |
| 19:46:29 | dbussink | evan: could you tell me what ConstantInt::get(Type::Int32Ty, (uint64_t)-1) means for llvm? |
| 19:46:42 | dbussink | i don't get the explicit type mismatch |
| 19:48:16 | evan | um. |
| 19:48:29 | evan | ::get takes a Type* and a uint64_t |
| 19:48:40 | evan | it make look like a type mismatch |
| 19:48:44 | evan | but it's not. |
| 19:49:45 | dbussink | evan: i've got that first issue fixed, i now have a very clear "method 'kind_of?': given 1, expected 1 (ArgumentError)" message :P |
| 19:50:02 | mernen | dbussink: same here |
| 19:50:09 | evan | hm. |
| 19:50:20 | mernen | I can't find a simple/easy testcase |
| 19:50:39 | mernen | it fails with irb and rubygems, but I can't get a single simple script that raises anything like that |
| 19:51:19 | dbussink | mernen: it fails compiling readline for me with that message |
| 19:51:37 | mernen | yeah, that too |
| 19:51:49 | mernen | basically, anything nontrivial |
| 19:56:04 | evan | hm. ok |
| 20:03:08 | dbussink | evan: does this like a sensible change: http://pastie.org/528331 ? |
| 20:03:49 | evan | yes |
| 20:06:11 | dbussink | hmm, github web seems to be down for me, but i could push stuff though |
| 20:07:03 | mernen | "@github: Rebooting the environment to reset stuck GFS locks, we'll be back up in a few minutes." |
| 20:07:30 | boyscout | Use IntPtrTy for comparisons, not Int32Ty since that breaks on 64 bit - 095764b - Dirkjan Bussink |
| 20:09:41 | boyscout | CI: 095764b success. 2723 files, 10829 examples, 33841 expectations, 0 failures, 0 errors |
| 20:11:24 | itrekkie | Is the jit built automatically, or must it be enabled at build/runtime? |
| 20:11:35 | evan | itrekkie: you have to enable it at build and runtime |
| 20:11:39 | evan | do |
| 20:11:43 | evan | RBX_LLVM=1 rake build |
| 20:11:45 | evan | to enable it at build time |
| 20:11:46 | evan | then |
| 20:11:53 | evan | bin/rbx -Xjit.enabled .... |
| 20:11:57 | evan | to enable it at runtime |
| 20:15:02 | itrekkie | Is there a way to specify where llvm is installed? or should I install a new copy in vm/external_libs? Also, is there a specific revision of llvm you're using right now? |
| 20:15:36 | itrekkie | Sorry for all these questions, by the way, I'm having a hard time getting at the documentation |
| 20:17:09 | evan | itrekkie: you need llvm from svn, preferable rev 73074 |
| 20:17:22 | evan | and it needs to be available at vm/external_libs/llvm |
| 20:17:44 | evan | i link svn/llvm to git/rbx/vm/external_libs/llvm |
| 20:18:30 | itrekkie | Great, I'll pull that revision and give it a whirl, thanks |
| 20:18:58 | evan | no prob |
| 20:19:08 | evan | rad |
| 20:19:15 | evan | this uncommon trap is helping me debug the JIT nicely |
| 20:19:25 | evan | because i can now easily see all the code thats failing guards |
| 20:48:27 | dgtized | Is there a way to change the threshold for number of calls before a method is jitted? |
| 20:48:31 | dgtized | at runtime? |
| 20:48:47 | evan | -Xconfig.print |
| 20:48:52 | evan | there is an option in there to do just that. |
| 20:50:08 | dgtized | aweomse, thanks |
| 20:51:11 | dgtized | whoops, bin/mspec ci -T-Xjit.enabled -T-Xjit.call_til_compile=50 seems to deterministically segfault |
| 20:52:03 | dbussink | dgtized: getting some errors too yeah |
| 20:52:14 | dbussink | nog aligned pointer being freed |
| 20:54:10 | brixen | what about eggnog aligned pointers? |
| 20:56:38 | evan | dgtized: so, i ran some tests a while ago |
| 20:56:47 | evan | 4000 is actually the sweet spot |
| 20:56:51 | evan | i need to change our default |
| 20:57:11 | evan | ok, brb. |
| 20:57:24 | dgtized | that's fine, but dropping from 75 to 50 definitely causes it to deterministically segfault |
| 20:58:16 | dgtized | I'm guessing that 50 is the threshold that causes it to need to free up a bunch of methods in the cache of functions that are jitted? That's entirely a guess though |
| 21:05:15 | evan | yeah |
| 21:05:17 | evan | it's just a bug |
| 21:05:20 | evan | needs to be fixed |
| 21:07:39 | mernen | vmm->required_args = 1, args.total() = 140733193388033 |
| 21:08:07 | mernen | (that's 2**32+1) |
| 21:10:54 | evan | odd. |
| 21:15:38 | devinus | evan: i've been looking at the rubinius benchmarks on bench.rubini.us and was wondering if i was reading these right. rubinius is about 10-15% as fast as baseline MRI? |
| 21:17:07 | evan | yeah, thats what you're seeing |
| 21:24:28 | dbussink | mernen: probably something that is cast back and forward a few times |
| 21:24:36 | mernen | evan: I see three unknown frames between BlockEnvironment::call and InlineCache::check_cache |
| 21:24:46 | mernen | on BE::call, args.total() = 1 |
| 21:24:55 | mernen | on IC::check_cache(), args.total() = 2**32+1 |
| 21:25:40 | evan | unknown frames? |
| 21:25:48 | mernen | yeah, gdb couldn't identify them |
| 21:26:06 | dbussink | mernen: you can try building it with DEV=1 |
| 21:26:09 | mernen | jit code, I guess? |
| 21:26:16 | evan | oh |
| 21:26:16 | evan | yeah |
| 21:26:40 | evan | oh |
| 21:26:42 | evan | crap. |
| 21:26:46 | evan | size_t on 64bit is 64bits |
| 21:26:47 | evan | yes? |
| 21:26:54 | mernen | right |
| 21:26:57 | evan | thats it. |
| 21:27:07 | mernen | so my build line goes to: rake build:debug RBX_LLVM=1 LLVM_DEBUG=1 DEV=1 |
| 21:27:11 | evan | unsigned int is 32 |
| 21:27:12 | evan | yes? |
| 21:27:19 | evan | whats LLVM_DEBUG? |
| 21:27:42 | mernen | makes rubinius link with vm/external_libs/llvm/Debug |
| 21:27:43 | dbussink | evan: what is size_t? |
| 21:27:51 | evan | mernen: oh |
| 21:27:54 | evan | don't bother with that |
| 21:27:57 | evan | it's entirely unrelated. |
| 21:28:05 | mernen | thought it could help |
| 21:28:09 | evan | mernen: it won't |
| 21:28:16 | evan | none of the errors will be at that level. |
| 21:28:17 | mernen | k |
| 21:28:48 | evan | size_t is the common type to be used for sizes |
| 21:29:00 | dbussink | evan: i mean what structure :) |
| 21:29:05 | evan | Arguments |
| 21:29:08 | evan | in vm/arguments.hpp |
| 21:29:11 | evan | if you change that though |
| 21:29:13 | mernen | so that's more for LLVM-library debugging? |
| 21:29:13 | evan | you need to run |
| 21:29:18 | evan | rake jit:generate_header |
| 21:29:19 | evan | mernen: yep |
| 21:29:25 | mernen | got it |
| 21:29:57 | dbussink | evan: do you want to switch that to unsigned int or fix other stuff for size_t |
| 21:30:40 | mernen | about unsigned int, I believe it should be 64 |
| 21:30:55 | mernen | but I'm far from a reliable source for that |
| 21:30:55 | dbussink | mernen: unsigned int is 32 bits on 64 bit platforms |
| 21:31:04 | dbussink | long == 64 bit |
| 21:31:11 | evan | dbussink: switch to unsigned int |
| 21:31:13 | evan | or uint32_t |
| 21:31:15 | evan | specificly |
| 21:31:23 | evan | unless you plan on having more than 4billion arguments |
| 21:31:26 | evan | i don't. |
| 21:31:33 | dbussink | hehe :) |
| 21:31:40 | evan | "my program state is represented entirely in on call" |
| 21:31:47 | evan | one call |
| 21:31:47 | dbussink | i'll use splat in that case then ;) |
| 21:31:52 | evan | heh |
| 21:31:59 | evan | funny you say |
| 21:32:03 | evan | that was an old bug in shotgun |
| 21:32:25 | evan | a stack overflow because of code like this |
| 21:32:36 | evan | ary = [1] * 8000 |
| 21:32:40 | evan | other.push *ary |
| 21:32:42 | evan | BAM |
| 21:32:45 | evan | 8000 arguments. |
| 21:33:08 | evan | thats why we handle splat specially now. |
| 21:35:05 | dbussink | evan: that also explains the mismatch between all kinds of count stuff in the llvm jit |
| 21:35:17 | dbussink | evan: size_t / unsigned int thingy that is |
| 21:35:24 | evan | gotcha |
| 21:36:35 | slava | hi evan |
| 21:36:52 | evan | hi slava! |
| 21:37:01 | slava | how do you map from machine code locations to source file locations? |
| 21:37:24 | evan | my CallFrame struct has an ip field on it |
| 21:37:29 | evan | thats the bytecode ip |
| 21:37:38 | evan | and simply set it in the compiled code |
| 21:37:42 | slava | so the jitted code updates a slot in the call frame as its going along? |
| 21:37:50 | evan | yep |
| 21:37:55 | slava | ouch :) ok |
| 21:38:02 | evan | LLVM removes the used ones |
| 21:38:05 | evan | it's not really much at all |
| 21:38:15 | evan | all the ones that are unreadable disappear |
| 21:38:16 | slava | how does it know that the ip might be read or not? |
| 21:38:20 | evan | so only ip is set before sends, etc. |
| 21:38:36 | slava | ah, so between subroutine calls you don't need to keep it in sync? |
| 21:38:44 | evan | yep |
| 21:38:53 | slava | fair enough |
| 21:39:17 | evan | the old assembler did pc to virtual-pc mapping |
| 21:39:43 | evan | thats more complicated with LLVM because I don't control the machine code emittion directly |
| 21:39:45 | slava | will llvm's jit allow you to save machine code to disk too? |
| 21:39:47 | evan | i can control it and advise it |
| 21:39:54 | evan | no, not right now |
| 21:40:02 | evan | but thats on the roadmap for LLVM |
| 21:40:28 | slava | I'm still glad I wrote my own code gen, but its a lot of work :) |
| 21:40:32 | evan | i'd have to make my machine code portable if I did |
| 21:40:52 | evan | LLVM now has an interface to parts of the code gen |
| 21:40:52 | slava | another cool idea is to serialize jit profiling data somehow |
| 21:40:56 | evan | JITMemoryManager |
| 21:41:02 | slava | so that very short running scripts can still benefit from type feedback |
| 21:41:13 | evan | and we're going to get to expose the relocation info eventually |
| 21:41:16 | evan | then i can do whatever with it |
| 21:41:21 | slava | ah |
| 21:41:29 | slava | yeah, relocation is the tricky part about saving code to disk |
| 21:41:34 | slava | I've rewritten that code a bunch of times |
| 21:42:57 | evan | slava: i'm working on optimizing uncommon predicted branches atm |
| 21:43:06 | slava | how are you doing that? |
| 21:43:20 | evan | changing it so that the code looks like |
| 21:43:31 | evan | if recv.class.class_id == last_class_id |
| 21:43:38 | evan | <inline code for callee> |
| 21:43:38 | evan | else |
| 21:43:50 | evan | return call_interpreter(current_call_frame) |
| 21:43:51 | evan | end |
| 21:44:04 | slava | cool |
| 21:44:06 | evan | you bail back to the interpreter if the assumptions don't hold |
| 21:44:14 | evan | that improves alias analysis |
| 21:44:27 | slava | why not replace 'return call_interpreter' with a message send? |
| 21:44:30 | evan | and reduced the ammount of machine code |
| 21:44:38 | evan | thats what I do in some cases |
| 21:44:44 | slava | how do you decide? |
| 21:44:52 | evan | right now, if i can use uncommon, i do |
| 21:45:00 | evan | uncommon doesn't handle being called inside an exception handler |
| 21:45:04 | evan | so i emit a send in that case |
| 21:45:12 | evan | the self thesis talks about the trade offs in the 2 |
| 21:45:17 | evan | if you do |
| 21:45:25 | evan | val = <inline code for callee> |
| 21:45:26 | evan | else |
| 21:45:31 | evan | val = send(:blah) |
| 21:45:32 | evan | end |
| 21:45:41 | evan | then you can't optimize anything for val |
| 21:45:47 | evan | because send might do anything |
| 21:45:55 | evan | so the rest of the method is slower |
| 21:46:13 | slava | yeah |
| 21:46:13 | evan | and since thats the uncommon case |
| 21:46:22 | evan | you don't care if it's slower |
| 21:46:29 | slava | do you propagate type information from guards? |
| 21:46:30 | evan | by doing a send, you're slowing down the fast case |
| 21:46:36 | evan | not yet, soon |
| 21:46:44 | evan | i'm adding uncommon support as legwork for generic method inlining |
| 21:47:13 | slava | in factor, if you do something like dup array? [ "Oops" throw ] unless then the rest of the word is compiled assuming the value is an array |
| 21:47:26 | slava | but its a static optimization on source |
| 21:47:37 | evan | yep |
| 21:47:47 | evan | i'm going to likely add explicit inlining for testing too |
| 21:47:53 | evan | so we'll be able to lean on that. |
| 21:48:15 | slava | you can annotate kernel methods with explicit inlining annotations |
| 21:48:41 | slava | also you can compile certain selector sends to have a static fast case, if there's no runtime type info yet |
| 21:48:42 | evan | yep |
| 21:48:48 | slava | eg, if something is calling + there's a good chance its on fixnums |
| 21:48:52 | evan | right |
| 21:48:54 | evan | i do that now |
| 21:49:02 | evan | because the bytecode does |
| 21:49:06 | evan | and actually, i've got extra info there |
| 21:49:16 | evan | because meta_send_op_plus now has an IC too |
| 21:49:25 | evan | so i can actually see "was it actually a fixnum most of the time?" |
| 21:49:28 | slava | yeah |
| 21:49:37 | evan | and if it was, say, a float |
| 21:49:46 | evan | and can emit inline code for float addition |
| 21:50:08 | slava | if you add 'is float' goards and the uncommon case traps, then the rest of the method can ssume the values are floats, and unbox them |
| 21:50:26 | slava | llvm probably won't do this automatically |
| 21:50:31 | dbussink | evan: cool, got passed building readline extension with llvm enabled :) |
| 21:50:35 | evan | dbussink: yay! |
| 21:50:39 | slava | but you can add unboxed float opcodes to your bytecode format perhaps |
| 21:50:39 | evan | slava: no, it won't |
| 21:50:45 | evan | slava: but I can add some LLVM passes |
| 21:50:56 | evan | to help it along |
| 21:55:32 | slava | evan: do you think any of the jit code you've written could be contributed back to llvm-jit, or another separate project? is everything rubinius-specific/ |
| 21:56:04 | evan | there are generic parts |
| 21:56:21 | evan | one thing I do want to write is a generic compiletime/runtime type check system |
| 21:56:30 | slava | that sounds very broad |
| 21:56:56 | evan | well, mainly i want to have a simple API and some passes |
| 21:57:04 | evan | for doing type checks |
| 21:57:15 | evan | that would end up being simple integer comparisons |
| 21:57:29 | slava | ah |
| 21:57:31 | evan | and using some LLVM passes to allow for guard elimination |
| 21:57:53 | evan | i'm not going to get into type theory, thats up to the user |
| 21:57:59 | evan | but they'd have to boil their type down to an int. |
| 21:58:03 | evan | which should be easy. |
| 21:58:46 | evan | the unladen swallow guys are starting to do some type analysis stuff |
| 21:58:58 | evan | i'm going to follow their lead and see if i can't do similar things |
| 21:59:02 | evan | though, from everything i've been reading |
| 21:59:14 | evan | i'm better of ignoring type analysis |
| 21:59:20 | evan | and leaning 100% on type feedback |
| 21:59:24 | boyscout | Use uint32_t for Arguments total - 10c90c8 - Dirkjan Bussink |
| 21:59:30 | dbussink | mernen: i've been able to complete a spec run now, some minor failures though |
| 21:59:54 | slava | evan: with a langauge like ruby that's your best bet |
| 21:59:55 | evan | dbussink: did you do "rake jit:generate_header" ? |
| 22:00:16 | mernen | dbussink: I'm running spec right now |
| 22:00:20 | dbussink | evan: no, but i think it was the correct size already since it was probably made in a 32 bit system with a 32 bit size_t |
| 22:00:23 | mernen | looking good so far |
| 22:00:41 | dbussink | evan: it worked without doing it, i don't llvm-g++ on that machine atm either |
| 22:00:44 | evan | dbussink: ah |
| 22:00:47 | evan | yes |
| 22:00:47 | dbussink | so i just tried and it worked |
| 22:00:50 | evan | actually thats was the issue |
| 22:00:58 | evan | LLVM has total as |
| 22:01:06 | evan | IntegerType::get(32) |
| 22:01:15 | evan | so you just fixed it so that assumption holds true :D |
| 22:01:45 | dbussink | evan: yeah, but i thought that was ok in llvm, since i could imagine having enough with 32 bit sized counts :) |
| 22:01:53 | evan | yeah |
| 22:01:54 | evan | thats fine |
| 22:01:57 | evan | it did the right thing |
| 22:02:01 | evan | and so did you! |
| 22:03:40 | boyscout | CI: 10c90c8 success. 2723 files, 10829 examples, 33841 expectations, 0 failures, 0 errors |
| 22:04:00 | evan | slava: btw, the other reason setting ip in call_frame is no biggy is that call_frame is stack allocated |
| 22:04:13 | evan | so i'm never really worried about it going out to main memory |
| 22:04:24 | dbussink | evan: bin/mspec ci -B full.mspec -t ruby segfaults on 64 bit machine, so we can claim rubinius works better there :p |
| 22:04:35 | evan | hah |
| 22:04:37 | evan | OUCH |
| 22:04:54 | dbussink | default debian lenny ruby |
| 22:07:19 | dbussink | mernen: how does it look? |
| 22:08:03 | mernen | indeed a couple new failures |
| 22:13:20 | dbussink | mernen: hmm, i see some spec failures but they don't fail if i run the spec file directly through mspec :S |
| 22:16:03 | mernen | agh, I cleared the failures terminal |
| 22:20:59 | mernen | I can still reproduce the ipaddr failures here |
| 22:25:11 | mernen | it won't fail with call_til_compile=0 or 500 |
| 22:26:06 | dbussink | mernen: did you add the -Xenable.jit too? |
| 22:26:59 | mernen | no, is that really necessary? |
| 22:27:04 | mernen | doesn't seem to change the results, anyway |
| 22:27:32 | dbussink | mernen: yeah, because otherwise the jit isn't enable |
| 22:27:50 | dbussink | so call_til_compile doesn't do anything without the jit enabled |
| 22:27:55 | dbussink | but that also crashes it with 32 bit |
| 22:28:00 | mernen | you sure? since the beginning I've been running without jit.enabled |
| 22:28:11 | mernen | and it seemed to work fine |
| 22:28:37 | dbussink | it works fine, but it doesn't jit :) |
| 22:28:52 | mernen | I mean, all those jit crashes I've looked at |
| 22:29:03 | mernen | at most, I was playing with jit.call_til_compile |
| 22:29:06 | dbussink | well, those are some llvm parts that are used |
| 22:29:10 | dbussink | hmm, strange |
| 22:29:20 | dbussink | since dgtized reported something else i guess then |
| 22:29:23 | mernen | the jit always seemed to be there |
| 22:29:51 | dbussink | well, i know that isn't enabled unless you provide that option |
| 22:30:02 | dbussink | you can see it with ./bin/rbx -Xconfig.print |
| 22:31:21 | mernen | evan: is it necessary to pass in -Xjit.enabled for the jit to work? |
| 22:31:36 | mernen | I've been running it all day without that switch, even playing with jit.call_til_compile |
| 22:31:56 | mernen | and judging by all the crashes, the jit did seem to be there |
| 22:32:22 | evan | mernen: you must be setting -Xjit.enabled |
| 22:32:30 | evan | jit.call_til_compile does nothing otherwise |
| 22:32:52 | boyscout | Add uncommon branch support - 10d2362 - Evan Phoenix |
| 22:33:10 | mernen | weird |
| 22:34:03 | evan | it had to be something else |
| 22:34:05 | mernen | how did I manage to get the crashes, the failures, the jit frames and all then? |
| 22:34:56 | evan | i don't know |
| 22:34:58 | evan | how were you running it? |
| 22:35:41 | mernen | no special flags, just bin/rbx and possibly some usual arguments like script paths |
| 22:35:58 | evan | you weren't running in the JIT |
| 22:36:09 | mernen | plus mspec ci -T-Xjit.call_til_compile does affect the number of failures I get |
| 22:36:09 | evan | i can't believe you were. |
| 22:36:16 | mernen | seriously |
| 22:36:34 | evan | um. |
| 22:36:35 | evan | do |
| 22:36:36 | mernen | bin/mspec ci -T-Xjit.call_til_compile=0 library/ipaddr => no failures |
| 22:36:40 | evan | bin/rbx -Xconfig.print |
| 22:36:41 | mernen | bin/mspec ci -T-Xjit.call_til_compile=50 library/ipaddr => many failures |
| 22:36:53 | evan | does it say the jit is on? |
| 22:36:55 | mernen | config.print and everything I can think of just tells me jit is off |
| 22:37:02 | evan | it's not on then. |
| 22:37:08 | evan | why that causes failures, I don't know |
| 22:37:11 | evan | do |
| 22:37:13 | evan | -Xjit.show |
| 22:37:19 | evan | and you can actually see if it's on |
| 22:37:26 | mernen | yes, lots of jit info |
| 22:37:28 | boyscout | CI: 10d2362 success. 2723 files, 10829 examples, 33841 expectations, 0 failures, 0 errors |
| 22:37:31 | evan | WHAT?! |
| 22:37:33 | evan | no |
| 22:37:35 | evan | can't be. |
| 22:37:36 | mernen | yes! |
| 22:37:40 | evan | bullshit. |
| 22:37:43 | mernen | the jit has become sentient! |
| 22:37:48 | evan | no really |
| 22:37:50 | evan | that can't be. |
| 22:38:29 | dbussink | evan: freaky stuff, i'm seeing it on 64 bit too :) |
| 22:38:35 | evan | oh come on |
| 22:38:38 | mernen | I'd try it on the mac, but I don't have LLVM compiled here |
| 22:38:39 | evan | stop pulling my leg. |
| 22:38:46 | mernen | means it'd take a while |
| 22:38:52 | dbussink | evan: http://gist.github.com/137833 |
| 22:39:08 | dbussink | doesn't show anything in my mac |
| 22:39:11 | evan | what |
| 22:39:11 | evan | the |
| 22:39:12 | evan | fuck |
| 22:39:17 | dbussink | just gives me the terminal there |
| 22:39:27 | evan | how the fuck can that be!?! |
| 22:39:55 | evan | hm. |
| 22:39:57 | mernen | you've neglected the 64-bit builds for too long |
| 22:39:59 | dbussink | maybe the config variable suffers from some sort of 32 / 64 bit issue that checks some random bit? |
| 22:40:04 | mernen | now they are working on their own |
| 22:40:10 | evan | dbussink: if that were true |
| 22:40:14 | evan | then -Xconfig.print |
| 22:40:16 | evan | would say true |
| 22:40:21 | evan | because that tests that flag. |
| 22:40:23 | mernen | Rubinius::JIT also says false |
| 22:40:31 | evan | huh? |
| 22:41:06 | evan | who added Rubinius::JIT... |
| 22:41:07 | evan | anyawy. |
| 22:41:13 | mernen | well, it always seems to return false anyway |
| 22:41:23 | mernen | guess I don't know what it's for exactly |
| 22:41:26 | evan | what about with -Xjit.enabled |
| 22:41:33 | evan | what does it say |
| 22:41:44 | mernen | jit.enabled config.print does say true |
| 22:41:51 | evan | the code on vmmethod.cpp:501 and 502 |
| 22:41:56 | evan | must be wrong for 64bit |
| 22:42:06 | evan | if the JIT isn't enabled |
| 22:42:09 | evan | call_count should be -1 |
| 22:42:13 | evan | and that branch never entered |
| 22:42:17 | mernen | I'll check that |
| 22:42:34 | evan | call_count is a native_int |
| 22:42:39 | evan | which is 64bit |
| 22:43:25 | dbussink | evan: and jit_call_til_compile is an int... |
| 22:43:46 | dbussink | looks like another classic 32 / 64 bit comparison gone wacky :) |
| 22:44:06 | evan | why the fuck doesn't gcc warn you!? |
| 22:44:10 | evan | fuck you gcc. |
| 22:44:20 | evan | but anyway |
| 22:44:24 | evan | that shouldn't even be entered! |
| 22:44:34 | evan | unless "0" is 32bits!? |
| 22:45:12 | dbussink | the comment says // A negative call_count means we've disabled usage based JIT |
| 22:45:29 | dbussink | so it's probably assigned some negative value that is wrapped around at some point |
| 22:46:00 | evan | wrapped around from what though? |
| 22:46:02 | evan | if it's negative |
| 22:46:05 | evan | it should never be touched |
| 22:47:46 | dbussink | dunno, but something is fishy there at least |
| 22:47:58 | dbussink | but i should really get some sleep, early morning tomorrow |
| 22:48:07 | mernen | evan: call_count = 1 |
| 22:48:09 | mernen | erm |
| 22:48:09 | mernen | 0 |
| 22:48:21 | dbussink | nite ppl |
| 22:48:37 | mernen | cya dbussink |
| 22:49:25 | evan | mernen: where is that? |
| 22:50:29 | mernen | just set a breakpoint on line 501 before running, and the very first time it's reached vmm->call_count is 0 |
| 22:50:49 | evan | but but but |
| 22:50:51 | evan | that can't be. |
| 22:51:22 | evan | mernen: walk through what happens on line 123 of vmmethod.cpp |
| 22:51:31 | mernen | k |
| 22:51:37 | evan | without -Xjit.enabled |
| 22:51:41 | evan | that should always be false |
| 22:51:44 | evan | so that call_count is set to -1 |
| 22:54:28 | mernen | bad news, the condition is true |
| 22:54:37 | evan | wait wait. |
| 22:54:48 | evan | how the hell can that be. |
| 22:54:52 | mernen | oh |
| 22:54:55 | mernen | wait, there's something wrong here |
| 22:54:59 | evan | well |
| 22:55:01 | evan | thats an object |
| 22:55:07 | evan | with a operation bool() |
| 22:55:14 | evan | er, operator bool() |
| 22:55:17 | evan | so print it |
| 22:55:20 | mernen | gdb actually threw me into line 131 |
| 22:55:33 | evan | wtf. |
| 22:55:40 | mernen | anyway |
| 22:55:42 | evan | do this with DEV=1 compiled. |
| 22:55:56 | mernen | I just made a clean build, DEV=1 |
| 22:56:04 | evan | come on gcc. |
| 22:56:08 | evan | wtf are you doing. |
| 22:56:21 | evan | ok |
| 22:56:26 | evan | on line 124 |
| 22:56:32 | evan | change jit_enabled |
| 22:56:37 | evan | to jit_enabled.value |
| 22:56:44 | evan | see what happens |
| 22:56:50 | mernen | evan: http://gist.github.com/137841 |
| 22:57:06 | mernen | I'm still confused by the line number anyway |
| 22:57:19 | evan | no |
| 22:57:21 | evan | you can't do that in gdb |
| 22:57:44 | evan | gdb won't run the operator method |
| 22:57:51 | mernen | oh |
| 22:57:54 | evan | so casting to bool doesn't do what you think it does. |
| 22:57:56 | mernen | anyway, value = false |
| 22:58:02 | evan | sure |
| 22:58:05 | evan | but actually change the condition |
| 22:58:07 | mernen | so I guess it is indeed running line 131 |
| 22:58:09 | evan | and see if it still does |
| 22:58:14 | evan | ie, remove calling the operator bool() |
| 22:58:30 | evan | wtf |
| 22:58:36 | evan | is USAGE_JIT not defined? |
| 22:59:02 | evan | DOH |
| 22:59:05 | evan | slaps himself. |
| 22:59:24 | evan | remove the #ifdef USE_USAGE_JIT |
| 22:59:30 | evan | in all places in that file. |
| 23:00:03 | evan | actually, i'll do |
| 23:00:06 | evan | there are a few places. |
| 23:00:45 | evan | ok, one sec. |
| 23:00:52 | evan | this was a legacy configuration fuckup. |
| 23:00:54 | evan | on my part. |
| 23:00:59 | mernen | in this specific file I only found two places, that test we were before and this conditional |
| 23:01:27 | evan | yeah |
| 23:01:27 | evan | one sec |
| 23:01:31 | evan | i'm about to push a removal |
| 23:02:24 | boyscout | Remove USE_USAGE_JIT flag - a2debe2 - Evan Phoenix |
| 23:02:25 | evan | ok, try that.. |
| 23:05:23 | mernen | btw, is DEV=1 enough to ensure a debug build? I'm using build:debug right now |
| 23:05:44 | boyscout | CI: a2debe2 success. 2723 files, 10829 examples, 33841 expectations, 0 failures, 0 errors |
| 23:05:44 | evan | yes |
| 23:05:47 | evan | they're the same |
| 23:06:19 | mernen | bin/rbx no longer has jit |
| 23:06:35 | evan | huh? |
| 23:06:46 | mernen | I mean, it's no longer magically on |
| 23:06:50 | mernen | but -Xjit.enabled crashes very quickly |
| 23:06:53 | mernen | terminate called after throwing an instance of 'rubinius::Assertion' |
| 23:06:58 | evan | :/ |
| 23:07:33 | mernen | vm/exception.cpp:30, "Only supported on x86" |
| 23:07:56 | evan | i need the full backtrace |
| 23:07:57 | evan | do |
| 23:07:58 | evan | catch throw |
| 23:08:01 | evan | then get the backtrace |
| 23:08:07 | evan | thats a bunk exceptoin being thrown |
| 23:08:52 | evan | ok |
| 23:08:53 | evan | i see it. |
| 23:09:34 | evan | DER. |
| 23:09:40 | evan | need |
| 23:09:52 | evan | actually |
| 23:09:52 | evan | one sec. |
| 23:11:02 | evan | did you set MM_DEBUG? |
| 23:11:18 | evan | oh oh |
| 23:11:19 | evan | no |
| 23:11:19 | evan | nm. |
| 23:11:49 | evan | incoming! |
| 23:11:54 | boyscout | Remove crufty platform check - 0c8637a - Evan Phoenix |
| 23:12:03 | evan | try that. |
| 23:12:10 | ddub | less cruft! |
| 23:13:15 | mernen | will try it in a sec |
| 23:15:04 | boyscout | CI: 0c8637a success. 2723 files, 10829 examples, 33841 expectations, 0 failures, 0 errors |
| 23:15:08 | mernen | "Unknown VM exception detected." |
| 23:15:11 | mernen | http://gist.github.com/137849 |
| 23:16:00 | evan | ok... |
| 23:16:01 | evan | um. |
| 23:16:09 | evan | can you debug that? |
| 23:16:14 | evan | or do you need to me try? |
| 23:17:23 | mernen | I can try |
| 23:24:33 | mernen | …or maybe I can't, seems beyond my knowledge |
| 23:26:02 | mernen | anyway, it won't crash for very small or large values of jit.call_til_compile |
| 23:26:54 | mernen | bbiaw |
| 23:27:16 | evan | what about with the default value? |
| 23:27:34 | evan | using uncommon branches seems to save about 59 bytes of machine code per callsite |
| 23:27:38 | evan | not bad. |
| 23:28:24 | mernen | that's roughly <30 for small values, >2800 for large values |
| 23:29:11 | mernen | so my deductive powers say something's going wrong during the transition |
| 23:29:15 | mernen | anyway, gtg |
| 23:30:02 | evan | ok |
| 23:30:12 | evan | i'm not going to look at it until i have a real 64bit machine to test on |