Show enters and exits. Hide enters and exits.
| 01:09:32 | boyscout | Fixing rb_yield in capi and adding specs. - 7bd4f48 - Cezar Sa Espinola |
| 01:17:25 | boyscout | CI: 7bd4f48 success. 2684 files, 10338 examples, 32883 expectations, 0 failures, 0 errors |
| 01:34:20 | evan | cezarsa: you around? |
| 01:34:36 | cezarsa | evan: yep |
| 01:34:43 | evan | your last fix has a nasty bug |
| 01:34:44 | cezarsa | evan: did i screw anything up? |
| 01:34:52 | evan | current_block_ is hidden from the GC |
| 01:35:29 | evan | easiest fix is to make it a TypedRoot<Object*> |
| 01:35:30 | cezarsa | but it's just holding a reference, i don't instanciate anything |
| 01:35:41 | evan | that doesn't matter |
| 01:35:54 | evan | because if the GC runs while there is an objcet referenced there |
| 01:36:00 | evan | the GC won't see it, and thus can't update it |
| 01:36:04 | evan | if/when the object moves |
| 01:36:25 | cezarsa | hm, ok |
| 01:36:46 | cezarsa | so just change from Object* to TypedRoot<Object*> is enough? |
| 01:36:55 | evan | you have to initialize the TypedRoot |
| 01:37:09 | evan | and you'll need to use .set and .get on it |
| 01:37:15 | evan | to retrieve the true Object* |
| 01:37:42 | evan | TypedRoot can be initialized by passing state to it |
| 01:38:03 | evan | which you'd do in the NativeMethodEnvironment constructor |
| 01:39:18 | cezarsa | k, i'll do it right now |
| 01:39:22 | evan | k |
| 01:39:39 | evan | you really have to be careful when with declaring Object*s |
| 01:40:06 | cezarsa | thx for pointing out, i'm just starting to dig into the new VM, i'll be more careful |
| 01:40:11 | evan | rule of thumb: either they're a // slot or a TypedRoot |
| 01:40:23 | evan | and if you're unsure |
| 01:40:27 | evan | make it a TypedRoot |
| 01:40:31 | evan | it's better to have too many roots |
| 01:40:37 | evan | and fix that later |
| 01:40:50 | evan | than crash because the GC missed an object |
| 01:41:50 | evan | the next level is using OnStack<> |
| 01:43:02 | cezarsa | OnStack objects won't be visited by the GC? |
| 01:43:59 | evan | they are |
| 01:44:00 | evan | thats the point |
| 01:44:27 | evan | it's a way of advising the GC there are Object*s elsewhere |
| 01:44:40 | evan | it's a little more efficient than TypedRoot for a bunch of objects |
| 01:44:48 | evan | and is designed to be used like |
| 01:44:56 | evan | OnStack<1> os(state, obj); |
| 01:45:00 | evan | blah blah, use obj; |
| 01:45:05 | evan | return whatever; |
| 01:45:13 | evan | OnStack's destructor unregisters it |
| 02:05:42 | cezarsa | evan: just to be sure, is this the right way: http://pastie.org/480445 |
| 02:06:30 | evan | yep |
| 02:06:32 | evan | thats exactly it. |
| 02:06:37 | slava | yo |
| 02:07:06 | cezarsa | thx |
| 02:07:09 | evan | yo |
| 02:07:22 | evan | slava: i'm looking at the Handle code in v8 |
| 02:08:35 | slava | is it any good? |
| 02:08:41 | evan | it's interesting |
| 02:09:00 | slava | is it better than what you and I do for gc roots? |
| 02:09:03 | evan | i'm thinknig of perhaps using something a little similar rather than OnStack<> |
| 02:09:09 | evan | it's pretty much the same |
| 02:09:12 | slava | can you explain the genera idea? |
| 02:09:15 | evan | sure |
| 02:09:27 | evan | they've got a single tracking structure |
| 02:09:34 | evan | that the GC is aware of |
| 02:09:46 | evan | it handles out pointers to internal slots |
| 02:10:04 | evan | and the slot is a pointer to the real GC'd object |
| 02:10:15 | evan | so to get the real object, they then just do |
| 02:10:18 | evan | *location_; |
| 02:10:45 | evan | the reason they do that is that makes their Handle class simple and trivially copable |
| 02:10:50 | evan | copyable |
| 02:11:04 | evan | since you can then have multiple Handle's that reference the same location_ |
| 02:11:16 | evan | and they then can pass around Handle's as values |
| 02:11:25 | slava | so the handle has a ctor/dtor that registers it with a global list? |
| 02:11:26 | evan | combine that with a implicit constructor |
| 02:11:53 | evan | and a proper copy constructor |
| 02:12:03 | boyscout | Fixing bug in NativeMethodEnvironment, making the GC happy. (Thanks Evan) - b68ab89 - Cezar Sa Espinola |
| 02:12:05 | evan | yeah, so what they do to unregister handles is that they're scoped |
| 02:12:27 | slava | sure |
| 02:12:28 | evan | so, at some highlevel, before entering a bunch of code that needs handles, they'll do |
| 02:12:32 | evan | HandleScope::Enter |
| 02:12:36 | slava | hmm |
| 02:12:40 | evan | run the code |
| 02:12:40 | evan | then |
| 02:12:47 | evan | HandeScope::Leave |
| 02:12:50 | evan | basicly |
| 02:12:56 | slava | how do the actual handles get used? |
| 02:13:08 | evan | as normal objects |
| 02:13:09 | slava | I guess I'll look at the code at some point |
| 02:13:12 | evan | via operator overloading |
| 02:13:23 | evan | so like |
| 02:13:33 | evan | Handle<Object> obj = blah(); |
| 02:13:37 | evan | where blah returns Object* |
| 02:13:58 | evan | well, they actually wrap it with a macro to create the handle |
| 02:14:01 | evan | but it's the same diff |
| 02:14:07 | evan | then they do |
| 02:14:10 | evan | obj->whatever(); |
| 02:14:26 | evan | Handle<>::operator->() does the deref from the stored location |
| 02:15:01 | evan | one nice thing about using the implicit constructor is that you can add usage incrementally |
| 02:15:59 | slava | sounds good |
| 02:16:06 | boyscout | CI: Build b68ab89 failed. http://ci.rubini.us/rubinius/builds/b68ab89ca48f2e9398f9bc0ee3515459da351188 |
| 02:16:09 | evan | :/ |
| 02:16:30 | evan | cezarsa: did you run that code? |
| 02:16:43 | evan | you didn't run the tests |
| 02:16:44 | cezarsa | i did, and specs also |
| 02:17:01 | evan | you didn't run the VM tests |
| 02:17:18 | cezarsa | ouch |
| 02:17:26 | evan | are you running jsut "rake" |
| 02:17:30 | evan | that runs the VM tests by default |
| 02:18:04 | evan | slava: so it comes down to 2 questions: |
| 02:18:08 | cezarsa | i just did rake build and then bin/mspec ci |
| 02:18:10 | evan | 1) where to put scope enter/leave |
| 02:18:17 | evan | 2) whats the cost of creating a new scope |
| 02:18:21 | evan | cezarsa: thats why |
| 02:18:25 | evan | use |
| 02:18:26 | evan | rake |
| 02:18:26 | cezarsa | sorry, will fix the vm tests now |
| 02:18:33 | evan | that runs the vm tests |
| 02:23:39 | brixen | evan: I've *finally* got some data processing stuff in place |
| 02:23:42 | brixen | check this out http://gist.github.com/112880 |
| 02:23:51 | brixen | that's just starting up irb precompiled |
| 02:24:01 | brixen | 1500 hash instances created |
| 02:24:15 | brixen | the distribution running specs is super flat |
| 02:24:25 | brixen | which is why I added the quartiles for Q3 |
| 02:24:36 | brixen | waiting for spec run to finish right now |
| 02:25:34 | brixen | I added the max object inspect too because the max # for eg :[] was so large compared to even Q3's Q3 |
| 02:25:39 | evan | i'm not smart enough to follow what Q1, Q2, and Q3 mean |
| 02:25:49 | brixen | read that comment at the top |
| 02:25:52 | evan | i did |
| 02:25:53 | evan | :/ |
| 02:26:01 | boyscout | Fixing NativeMethod VM tests. - 59f25b0 - Cezar Sa Espinola |
| 02:26:14 | brixen | basically the value under Q1 means that 25% of the values are <= that value |
| 02:26:23 | brixen | under Q2 it's 50% of the values |
| 02:26:31 | brixen | Q3 is 75% |
| 02:26:40 | brixen | so... |
| 02:26:54 | brixen | 75% of hashs had <= 6 calls to :[] |
| 02:26:59 | evan | that value == ? |
| 02:27:17 | brixen | the number listed in the Qx column |
| 02:27:27 | brixen | it's a little confusing at first |
| 02:27:33 | brixen | I've been staring at it for 2 days |
| 02:27:35 | brixen | heh |
| 02:27:43 | evan | i still don't get it |
| 02:28:01 | evan | 25% of Hash's had a size of 2.0? |
| 02:28:06 | brixen | yes |
| 02:28:09 | evan | er 2 |
| 02:28:15 | brixen | less than or equal to 2 |
| 02:28:25 | brixen | 75% <= 5 elts |
| 02:28:49 | evan | ok, so for [], 75% of Hash,s used 6 as a key? |
| 02:28:53 | evan | i don't get what the numbers actually mean |
| 02:28:58 | brixen | the # of calls |
| 02:29:01 | boyscout | CI: 59f25b0 success. 2684 files, 10338 examples, 32883 expectations, 0 failures, 0 errors |
| 02:29:06 | evan | wait |
| 02:29:11 | evan | so are they all the number of calls? |
| 02:29:17 | brixen | except for size |
| 02:29:24 | evan | i need units |
| 02:29:25 | brixen | that's probably confusing |
| 02:29:30 | evan | yeah, ya think? :D |
| 02:29:36 | brixen | I'll add units to size |
| 02:29:40 | brixen | the rest are calls |
| 02:29:43 | evan | add units to them all |
| 02:29:56 | brixen | um, they're calls |
| 02:30:05 | brixen | that's the main data point |
| 02:30:19 | evan | ok |
| 02:30:21 | evan | so say that somewhere |
| 02:30:32 | evan | the word call appears nowhere |
| 02:30:50 | evan | except in "Emperically" |
| 02:30:58 | brixen | yeah |
| 02:31:00 | brixen | got it |
| 02:31:07 | evan | i'm slow on the math. |
| 02:31:15 | evan | i'm an arty CS guy |
| 02:31:50 | evan | probably better would be to describe myself as a CS cartographer |
| 02:32:02 | brixen | well, the point of the data is to have usage characteristics to link to benchmarks |
| 02:32:10 | slava | a web 2.0 CS personality |
| 02:32:20 | brixen | if no hash is called 50 million times, a benchmark for that is of dubious value |
| 02:32:37 | brixen | if no hash is ever bigger than 1k elements, hash perf for 1M is irrelevant |
| 02:32:43 | brixen | except as an academic exercise |
| 02:32:53 | brixen | in whose number is bigger ;) |
| 02:33:13 | evan | oh totally |
| 02:33:18 | evan | you did all this work |
| 02:33:21 | evan | i want to enjoy it! |
| 02:33:35 | evan | which means i gotta be in the right head space |
| 02:34:29 | brixen | yeah |
| 02:34:52 | brixen | the spec run overfilled my term buffer so I have to rerun it |
| 02:35:01 | evan | hah |
| 02:35:04 | evan | silly iterm |
| 02:35:09 | evan | that never happens to Terminal.app |
| 02:35:28 | brixen | but check this out http://gist.github.com/112883 |
| 02:35:43 | brixen | most calls to :[] |
| 02:35:51 | evan | woo class variables in rbyaml! :/ |
| 02:36:09 | brixen | most calls to :each and :keys was on an empty hash |
| 02:36:19 | evan | weird. |
| 02:37:02 | evan | i guess that means a quick empty check at the top would pay off |
| 02:37:43 | evan | esp. since we construct a block, pass it to each_item, which makes an iterator |
| 02:37:50 | evan | only to find that entry is nil the first time |
| 02:38:33 | brixen | yeah |
| 02:39:01 | brixen | I'm going to run this with rdoc on kernel/ and lib/ |
| 02:39:14 | evan | nice |
| 02:39:15 | evan | yeah |
| 02:39:40 | brixen | and make the max object inspect optional |
| 02:40:30 | evan | good plan |
| 02:40:51 | brixen | I'm trying to find that max :[] hash |
| 02:41:13 | brixen | yup, figured |
| 02:41:20 | brixen | kernel/common/regexp.rb |
| 02:41:29 | brixen | escape table |
| 02:41:52 | brixen | that thing is accessed like 130,000 times |
| 02:42:45 | evan | this is really interesting |
| 02:42:47 | evan | even as a profiler |
| 02:42:56 | evan | ah |
| 02:42:57 | evan | yeah |
| 02:42:58 | evan | that thing. |
| 02:42:59 | evan | you know |
| 02:43:02 | evan | that should be an Array |
| 02:43:06 | evan | since the keys are numbers. |
| 02:43:16 | evan | and there is only table. |
| 02:43:26 | evan | oh hell, a Tuple |
| 02:44:05 | brixen | a sparse 125 entry tuple |
| 02:44:51 | evan | sparsely populated, yeah. |
| 02:45:03 | evan | don't forget, coming soon to a method near you |
| 02:45:08 | evan | Tuple#at is almost free |
| 02:45:24 | brixen | heh, yes |
| 02:45:29 | brixen | I'm excited |
| 02:45:52 | brixen | fib move over, Tuple#at is the new sheriff in town |
| 02:46:54 | evan | for comedic effect, lets say Tuple#at is the black sheriff from blazing saddles |
| 02:47:25 | brixen | heh |
| 02:47:39 | brixen | so, did you see this part: 99513 Hash instances (274 with mixed keys) |
| 02:47:54 | brixen | not sure what else we could tease out of the mixed keys |
| 02:48:10 | evan | no no |
| 02:48:11 | evan | thats fine |
| 02:48:17 | evan | the ratio is the best part |
| 02:48:37 | brixen | yeah, so not very common in this case |
| 02:49:02 | evan | 99.7% are homogenous |
| 02:49:27 | evan | so opts based on Hash's being homogenous would have a big pay off |
| 02:49:35 | evan | brixen: ok, how about this for data |
| 02:49:41 | evan | for the homo key hashs |
| 02:49:54 | evan | how many of those are Symbol, how many are String, how many are Fixnum |
| 02:50:49 | brixen | so, for the mixed keys or total? |
| 02:50:58 | brixen | ie, how would it be different than http://gist.github.com/112880 |
| 02:51:04 | brixen | Key classes |
| 02:51:27 | evan | ah ah |
| 02:51:28 | evan | it's not |
| 02:51:31 | brixen | ok |
| 02:51:33 | evan | i just can't read! |
| 02:51:45 | brixen | I'm going to change Qx to the actual percentage |
| 02:51:48 | brixen | 25% etc |
| 02:51:51 | evan | k |
| 02:53:17 | brixen | this is a previous run with incorrect median, so ignore that http://gist.github.com/112386 |
| 02:53:22 | brixen | but you can see the key counts |
| 02:53:55 | brixen | seems weird to have 1700 Array instance keys |
| 02:54:03 | evan | yeah |
| 02:54:10 | evan | *shrug* |
| 02:54:14 | brixen | but symbol and string are the vast majority |
| 02:54:18 | evan | right |
| 02:54:19 | brixen | symbol the top |
| 02:54:31 | evan | so making Hash fast for symbol is high on the list |
| 02:54:38 | brixen | yeah |
| 02:54:41 | evan | even if it slows down the other key types |
| 02:55:32 | brixen | and since :[] is used the vast majority of these calls, that means making this test fast: key.equal?(@key) or (@key_hash == key_hash and key.eql? @key) |
| 02:56:02 | brixen | for symbol, it should shortcut with key.equal? |
| 02:56:25 | evan | absolutely it should |
| 02:56:35 | brixen | can we jit #equal? yet? :) |
| 02:56:42 | evan | i can add that RIGHT NOW. |
| 02:56:45 | evan | if you'd like |
| 02:56:45 | brixen | heh |
| 02:56:45 | evan | :D |
| 02:56:55 | brixen | andale pronto |
| 02:57:04 | evan | ariba! |
| 02:57:11 | brixen | :D |
| 02:57:57 | evan | i'm reading the vmkit code atm. |
| 02:58:12 | evan | i love that i've actually got other places to look at to find out how people use LLVM |
| 02:58:19 | brixen | nice |
| 03:00:25 | brixen | vmkit could probably be a good resource for enhancing rbx to be an alternative jvm :) |
| 03:00:32 | evan | heheh |
| 03:00:33 | brixen | I'll have to look at this |
| 03:00:49 | evan | i guess vmkit runs eclipse now |
| 03:00:57 | brixen | wow, sweet |
| 03:01:19 | brixen | plots his 2010 oscon talk :D |
| 03:01:59 | evan | we could run eclipse on a rbx based jvm and call it "obscure" |
| 03:02:08 | brixen | heh |
| 03:02:44 | brixen | armageddon |
| 03:02:46 | evan | heh |
| 03:02:58 | brixen | what primitive people think when an eclipse happens |
| 03:03:06 | evan | interestingly |
| 03:03:16 | evan | vmkit passes arguments to methods as a struct |
| 03:03:40 | brixen | any idea why? |
| 03:03:47 | evan | well |
| 03:04:03 | evan | i'm pretty sure it's because then what they do is alloca that same struct type on the caller stack |
| 03:04:11 | evan | and pass that pointer down to the callee |
| 03:04:30 | evan | when all that is reduced to machine code |
| 03:04:37 | evan | it looks almost exactly like the normal C convention |
| 03:04:42 | evan | but they've got full control over it |
| 03:04:50 | brixen | interesting |
| 03:04:50 | evan | which gives them a bit more flexibility |
| 03:04:59 | evan | i'm basically doing the same |
| 03:05:37 | evan | all arguments are passed out of the a JIT'd method by passing the address in the callers operand stack of the receiver and the number of args |
| 03:05:44 | evan | so the signature is always |
| 03:05:55 | evan | (STATE, CallFrame* prev, int argc, Object** args) |
| 03:05:59 | evan | outgoing |
| 03:06:06 | evan | incoming it's |
| 03:06:14 | evan | (STATE, CallFrame* prev, Arguments& args) |
| 03:06:17 | evan | because of splat |
| 03:06:23 | brixen | ahh |
| 03:06:39 | evan | i could construct an Arguments object on the callee stack |
| 03:06:48 | evan | perhaps i'll do that eventually |
| 03:06:58 | evan | the Arguments object on the stack is almost nothing |
| 03:07:03 | evan | so its probably a wash |
| 04:01:33 | brixen | man, my poor CPU |
| 04:01:35 | brixen | http://gist.github.com/112901 |
| 04:01:45 | brixen | took like 25 min to do the compiling run |
| 04:03:43 | evan | wow. |
| 04:04:34 | evan | ack, dinner. |
| 04:05:51 | evan | brixen: awesome data. |
| 04:06:01 | brixen | cool |
| 04:06:17 | brixen | I'm gonna generalize this a bit to run on String and Array |
| 04:06:25 | brixen | ruby is such a sweet language |
| 05:23:13 | evan | MUHAHA |
| 05:23:32 | evan | http://gist.github.com/112919 |
| 05:23:35 | evan | note line 13 |
| 05:23:46 | evan | oh ack, it's one off. |
| 05:25:23 | evan | there we go! |
| 05:25:24 | evan | :D |
| 05:26:02 | brixen | sweet |
| 05:26:23 | brixen | that is so nice |
| 05:26:56 | evan | reload |
| 05:27:05 | evan | the bottom one is when rec is JIT compiled |
| 05:27:21 | evan | 6x more stack space available :D |
| 05:28:26 | brixen | hah, sweet |
| 06:35:15 | boyscout | Collapse recursive calls into one line with the recursion count - 0e084aa - Evan Phoenix |
| 06:35:15 | boyscout | Do the stack depth check for the JIT - b8945bf - Evan Phoenix |
| 06:40:54 | boyscout | CI: b8945bf success. 2684 files, 10338 examples, 32883 expectations, 0 failures, 0 errors |
| 07:55:10 | ddub | weee |
| 07:55:15 | ddub | flight of the conchords was fun |
| 10:08:04 | boyscout | Short round of refactoring - 248fa7e - Evan Phoenix |
| 10:08:04 | boyscout | Begin refactoring Signatures to be created once - cf370fd - Evan Phoenix |
| 10:08:04 | boyscout | Bit more refactoring - e33c35d - Evan Phoenix |
| 10:15:22 | boyscout | CI: e33c35d success. 2684 files, 10338 examples, 32883 expectations, 0 failures, 0 errors |
| 15:13:54 | rue | headius: Um, it seems that those benchmarks are just all-around bad if optimisations can effectively nullify them (and assuming that it is not a valid result for the benchmark) |
| 16:20:56 | scoopr | so, who here likes and knows about parsers? ;) |
| 16:28:31 | malumalu | scoopr: i would like to know :P |
| 16:30:02 | scoopr | I have dangling-else problem .. |
| 16:30:08 | scoopr | and I'm not sure how to go around it with lemon |
| 16:51:45 | headius | rue: probably |
| 16:51:47 | headius | but benchmarking is hard on any optimizing runtime |
| 19:30:20 | rue | Well, I just do not understand how it can be that optimising away code that you try to benchmark is somehow invalid, but simultaneously the benchmark is valid if no optimisation -- or /some limited degree/ -- occurs |
| 19:32:21 | rue | Either you should just delete the benchmark, or accept that optimising it away is a valid result |
| 23:21:18 | boyscout | 1.8.7: Kernel#__method__, __callee__ (created new methods) - 68c566a - Marc-Andre Lafortune |
| 23:21:18 | boyscout | Hash== won't call to_hash anymore (as per rubyspecs) - ad3727f - Marc-Andre Lafortune |
| 23:21:18 | boyscout | Array == and Hash == now handle recursion correctly - 067e28f - Marc-Andre Lafortune |
| 23:21:18 | boyscout | Missing bang in private method names qsort!, qsort_block!, etc... - 01dea76 - Marc-Andre Lafortune |
| 23:21:18 | boyscout | Nuked unused private method Array#remove_outer_arrays - b52e481 - Marc-Andre Lafortune |
| 23:25:00 | boyscout | CI: b52e481 success. 2683 files, 10323 examples, 32868 expectations, 0 failures, 0 errors |