Show enters and exits. Hide enters and exits.
| 00:22:29 | ice799 | brixen: INT2FIX(RHASH(obj)->tbl->num_entries) is painful, but it can be dealt with. depending on how much suffering you can handle, i suppose. |
| 00:28:36 | brixen | ice799: it can be dealt with by removing the totally unnecessary static from rb_hash_size |
| 00:28:46 | ice799 | well, sure. |
| 00:28:54 | brixen | unless someone can point out a good reason for it being there |
| 00:28:59 | brixen | which no one has |
| 00:29:03 | evan | nope! |
| 00:29:11 | ice799 | there is probably no good reason for it, but you can be backward compatible with that usage |
| 00:29:16 | ice799 | if you want to be. |
| 00:29:27 | brixen | I don't follow |
| 00:29:38 | brixen | what if your hash in not based on st? |
| 00:29:51 | brixen | there is no tbl->num_entries to return |
| 00:30:02 | ice799 | Heh. How much pain do you want? |
| 00:30:05 | brixen | without going through gymnastics |
| 00:30:09 | brixen | exactly ;) |
| 00:30:15 | ice799 | ok, well withough gymnastics, you are fucked. |
| 00:36:14 | ice799 | Ah, so you guys do the GIL, thing, too, huh? |
| 00:36:28 | brixen | for now, yes |
| 00:36:29 | ice799 | Where was I when that became the new hotness? |
| 00:36:35 | brixen | it will go away eventually |
| 00:36:45 | brixen | not the new hotness, just the GIL :) |
| 00:37:08 | brixen | it was a couple months back |
| 00:37:23 | ice799 | Eh, I don't like the whole GIL thing very much. Why even use native threads? |
| 00:37:45 | ice799 | I don't like it mostly because you don't have fine-grained control on the OS scheduler, do when you decide to start the race for the GIL |
| 00:38:02 | ice799 | you can't really do very much to ensure that a specific person doesn't get starved to shit. |
| 00:38:32 | ice799 | Presumably one could solve this with a condition var, or some other locking primitive. But it seems that not building your own locking primitives is -also- the new hotness, sadly. |
| 00:39:27 | brixen | crosses fingers hoping for an abort |
| 00:40:05 | evan | ice799: i don't really like the GIL either |
| 00:40:10 | evan | but it's a stepping stone |
| 00:40:32 | ice799 | IMHO, I personally like green threads over the pthread+GIL thing that everyone is doing. |
| 00:41:01 | evan | i like green threads too |
| 00:41:22 | evan | but their correct implementation when using the C stack is non-trivial. |
| 00:41:36 | ice799 | It's not all that hard, imho. |
| 00:41:48 | slava | native threads are a better bet |
| 00:41:59 | ice799 | i pushed some patches to MRI that fixed a lot of the problems MRI had with their green thread implementation |
| 00:42:03 | evan | we want to eliminate the GIL eventually anyway, like I said. |
| 00:42:12 | ice799 | Word. |
| 00:42:32 | evan | and i'm open to MxN threads as well. |
| 00:42:42 | ice799 | Word. |
| 00:43:03 | evan | I need to implement stack saving soon, for continuations |
| 00:43:15 | evan | using that same mechanism, we could play with green threads |
| 00:43:27 | ice799 | Well, I'd like to say that I'd implement it, because it seems that mri will not accept my patches unless they are ported to 1.8 head first. |
| 00:43:33 | evan | it's trickier than on MRI |
| 00:43:33 | ice799 | er |
| 00:43:37 | evan | because our GC is accurate |
| 00:43:38 | ice799 | but, rather. |
| 00:43:54 | ice799 | tricky = fun, though. |
| 00:43:59 | evan | are your patches for 1.8.6? |
| 00:44:02 | evan | yes, quite fun! |
| 00:44:11 | ice799 | evan: 1.8.6 and 1.8.7 |
| 00:44:19 | ice799 | Essentially, I moved the thread stacks to the heap |
| 00:44:25 | ice799 | to allow constant time thread switching in MRI |
| 00:44:28 | evan | ah yes! |
| 00:44:30 | evan | i saw those patches. |
| 00:44:31 | ice799 | instead of the brain dead memcpy'ing. |
| 00:44:33 | evan | very nice. |
| 00:44:36 | ice799 | thanks. |
| 00:44:46 | evan | yes, rather than doing the stack_extend() + memcpy over the stack memory |
| 00:44:52 | evan | which always seemed ultra evil to me |
| 00:44:58 | evan | but i guess necessary |
| 00:45:06 | evan | slava tells the story about having to do that on windows |
| 00:45:18 | evan | that true slava? |
| 00:45:20 | slava | its only a problem if you have C frames mixed in |
| 00:45:29 | ice799 | there was no reason for mri to do that, honestly. |
| 00:45:29 | evan | assume you do |
| 00:45:31 | slava | because of how windows does seh |
| 00:45:39 | slava | but why would you? |
| 00:45:51 | slava | does ruby code ever call C which calls ruby? |
| 00:45:55 | evan | HAH |
| 00:45:56 | yakischloba | yes. |
| 00:46:00 | evan | thats the whole way MRI is implemented. |
| 00:46:21 | slava | what about rubinius? |
| 00:46:30 | evan | much much much less |
| 00:46:35 | evan | but we've got the interpreter |
| 00:46:38 | evan | which would be a C frame. |
| 00:46:55 | evan | so unless we compile everything upfront, there would be C frames due to mixed mode |
| 00:47:03 | ice799 | word. |
| 00:47:24 | slava | that's a problem since you can't control the C frame's stack layout, to know where it ends, so it might make thread switching harder |
| 00:47:39 | ice799 | what do you mean you can't control it? |
| 00:47:43 | slava | you can use llvm to generate an interpeter on startup though, instead of writing it in C |
| 00:47:49 | ice799 | you can write whatever you want to the stack, so you can forge stack frames if you wish. |
| 00:47:57 | slava | ice799: not with portable C++ |
| 00:48:19 | ice799 | Meh. |
| 00:49:14 | ice799 | when/if I merge my junk to 1.8, i'll probably write it so that the x86 path is fast |
| 00:49:20 | ice799 | and everyone else uses the shitty slow memcpy path. |
| 00:49:32 | ice799 | and then if non-x86 people come forward to fix their paths, good for them. |
| 00:49:48 | slava | its compiler specific really |
| 00:49:55 | ice799 | Huh? |
| 00:50:01 | ice799 | As long as you conform to the x86 ABI, who cares? |
| 00:50:01 | slava | if you have an accurate gc, you need to know what offsets in the stack frame hold pointers into the heap |
| 00:50:16 | slava | and you can't assume the compiler puts locals in the same place |
| 00:50:34 | evan | we force the compiler to use certain sections of memory for managed pointers |
| 00:50:38 | evan | using a shadow stack |
| 00:51:00 | ice799 | Ah, I see. |
| 00:51:06 | evan | so it's a matter of walking the shadow stack and reconstructing it when it's been copied to another region of memory |
| 00:51:06 | ice799 | well, with gymnastics it could be solved, I bet. |
| 00:51:13 | ice799 | yeah what i'm saying is |
| 00:51:14 | slava | evan: that works |
| 00:51:15 | ice799 | don't do any copying. |
| 00:51:26 | ice799 | just point the initial thread stack at a chunk of memory on the heap. |
| 00:51:27 | slava | how big do you make your per-thread stacks though? |
| 00:51:28 | ice799 | and then never copy. |
| 00:51:41 | ice799 | Use the same default that pthread uses, 1meg. |
| 00:51:49 | ice799 | pthreads don't grow, and no one seems to care. |
| 00:52:17 | ice799 | Of course, you could include a Thread.stack_size= to let people tune if they like. |
| 00:52:27 | ice799 | slava: you can also grow if you want to do gymnastics. |
| 00:52:49 | ice799 | you could just create a guard page under the thread stack, when it faults |
| 00:52:53 | ice799 | you know the guy has overflown |
| 00:52:57 | ice799 | so then just try a mremap |
| 00:53:02 | ice799 | tell it not to move the mapping. |
| 00:53:05 | slava | i'd like to see you get that working reliably with MRI :) |
| 00:53:12 | ice799 | slava: it is working reliably. |
| 00:53:20 | slava | actually, because MRI is so buggy, something like this is made easier. a few more crashes now and then won't be noticable |
| 00:53:26 | ice799 | Hah. |
| 00:53:30 | slava | since a typical setup runs multiple web servers which restart evey few hours |
| 00:53:32 | ice799 | It is reliable, my friend. |
| 00:53:34 | slava | or so I've heard anyway |
| 00:54:19 | ice799 | slava: all of that is already written. I haven't done the mremap because no one cares about their thread stacks growing, it seems. |
| 00:54:32 | ice799 | slava: And it all seems to work pretty well. ::shrug:: |
| 00:54:39 | slava | you can't guarantee that mremap doesn't move your data |
| 00:54:44 | ice799 | yes you can. |
| 00:54:46 | ice799 | there is a flag. |
| 00:54:49 | ice799 | man mremap |
| 00:55:00 | slava | in that case it won't always be able to grow the stack |
| 00:55:03 | ice799 | If it can't do the mapping, it'll just fail and you'll just raise a stackoverflow |
| 00:55:09 | slava | your trick with the guard page will only work if you don't move the stack from the fault handler |
| 00:55:21 | ice799 | Huh ? |
| 00:55:34 | ice799 | Faults get handled on a separate signal stack. |
| 00:55:43 | slava | that's not what I was talkinga bout |
| 00:55:59 | slava | if you compute an address relative to the stack pointer, then do something which grows the stack, your address might not be valid anymore, if the stack moved |
| 00:56:09 | ice799 | Correct, which is why you don't move them. |
| 00:56:26 | ice799 | you call mremap and tell it not to move the mapping. If that fails, and you STILL want to grow it |
| 00:56:32 | ice799 | you can do more gymnastics to make it happen. |
| 00:56:33 | ice799 | But again. |
| 00:56:37 | ice799 | Pthreads don't grow. |
| 00:56:39 | ice799 | No one cares. |
| 00:57:14 | ice799 | Anyway, if you'd like to still grow after all that failure, you can allocate more stack space somewhere else in memory, and then just forge a frame. |
| 00:57:37 | ice799 | but, really, why even bother? |
| 00:57:45 | ice799 | just set it a meg, if it faults, too bad. |
| 01:06:19 | brixen | evan: sanity check, should a Handle ever get deleted when references_ > 0 ? |
| 01:06:39 | evan | hm |
| 01:06:43 | evan | i'd think no |
| 01:06:53 | brixen | well then houston, we have a problem |
| 01:07:15 | brixen | let's see if I can figure it out |
| 01:07:37 | evan | k |
| 01:12:03 | evan | arg |
| 01:12:09 | evan | i'm flummuxed on a debugging problem |
| 01:12:10 | evan | bbiab. |
| 02:27:08 | evan | brixen: any luck? |
| 02:40:25 | brixen | evan: well, it's not collecting any handles with positive references, that I can see |
| 02:41:03 | brixen | but http://gist.github.com/134308 |
| 02:41:21 | brixen | should it ever call get_object() on a handle that has <= 0 references? |
| 02:41:39 | brixen | I would think not |
| 02:41:54 | brixen | because if the GC got there first, that object would no longer be valid |
| 02:41:55 | brixen | right? |
| 02:42:22 | brixen | cooking dinner, brb.. |
| 02:43:43 | evan | yeah |
| 02:43:45 | evan | thats true |
| 02:43:57 | evan | the checksum basically validates that |
| 02:44:06 | evan | and it's a bit stronger by testing a full 32bits |
| 02:44:43 | brixen | the problem I see is this (if I've got this right)... |
| 02:45:00 | brixen | a C ext allocs some memory that has a VALUE element |
| 02:45:10 | brixen | it does mem->obj = rb_something |
| 02:45:28 | brixen | NMF is destroyed and it does handle->deref() |
| 02:45:41 | brixen | and now mem->obj is a handle with 0 references |
| 02:45:55 | brixen | right? |
| 02:46:11 | brixen | I don't see how to keep mem->obj alive |
| 02:46:23 | evan | it can be kept alive via ANY reference |
| 02:46:30 | evan | so if it's not seen via rb_gc_mark |
| 02:46:36 | evan | it just have to be reference by anything else |
| 02:46:41 | evan | to keep the ref count above 0, and alive |
| 02:46:47 | brixen | right |
| 02:46:48 | evan | some way MRIs GC works |
| 02:46:53 | brixen | well, wait |
| 02:47:00 | evan | s/some/same/ |
| 02:47:12 | brixen | referenced by what exactly, to keep it alive |
| 02:47:28 | brixen | it can't just be a value in an alloc'd bit of memory, can it? |
| 02:47:43 | evan | thats not strong enough to keep it alive, no. |
| 02:47:48 | evan | because we can't see that. |
| 02:47:50 | brixen | I think that is the issue here |
| 02:47:54 | brixen | right |
| 02:48:34 | brixen | because the bonus memory is hanging off of the parser or emitter struct, which are themeselves put in a Data_Wrap_Struct |
| 02:48:44 | brixen | but no the bonus pointer |
| 02:48:49 | brixen | s/no/not/ |
| 02:48:54 | brixen | unless I'm missing something |
| 02:48:58 | evan | ok |
| 02:49:03 | evan | i had to check the handle code |
| 02:49:22 | evan | if what you said happens happens |
| 02:49:31 | evan | and references_ drops to 0 |
| 02:49:34 | evan | it's put into weak mode |
| 02:49:45 | evan | which means the handle stays alive if the object the handle points to stays alive |
| 02:50:10 | evan | so if there is any way the object the handle points to is alive, the handle should be alive |
| 02:50:15 | brixen | right |
| 02:50:18 | evan | if the object is GC'd, the handle is GC'd |
| 02:50:22 | brixen | ok, I was tracking that right then |
| 02:51:04 | brixen | so, a call to get_object() when the handle references == 0 is valid |
| 02:51:26 | evan | yes |
| 02:51:44 | evan | references_ is strong_handle_references |
| 02:51:57 | evan | meaning, that something in capi has said "this handle needs to stay alive for me" |
| 02:52:02 | brixen | but, when the gc runs, if references == 0 and the CApiHandle is not seen, the GC collects it |
| 02:52:05 | brixen | right? |
| 02:52:14 | evan | well, no. |
| 02:52:19 | evan | it shouldn't. |
| 02:52:37 | evan | if references is 0 AND the object the handle points to is being GCd |
| 02:52:39 | evan | the handle is GCd |
| 02:52:50 | brixen | right |
| 02:52:52 | evan | so, for example |
| 02:52:54 | brixen | that's what I meant |
| 02:52:55 | evan | rb_cObject |
| 02:52:57 | evan | returns a handle |
| 02:53:00 | evan | that never dies |
| 02:53:06 | evan | because Object is never out of scope |
| 02:53:21 | brixen | gotcha |
| 02:53:22 | evan | ok, just wanted to be clear |
| 02:53:26 | brixen | yeah |
| 02:53:32 | evan | this is tricky |
| 02:53:44 | evan | because i've built a garbage collection system on a garbage collection system |
| 02:54:13 | brixen | so, if nothing references the CApiHandle object AND references == 0, GC collects (just to be sure I can state this in words) |
| 02:54:16 | brixen | right? |
| 02:54:17 | evan | this is both awesome and crazy at the same time |
| 02:54:25 | evan | s/this/which/ |
| 02:54:54 | seydar | hypothetically speaking if I wanted to eavesdrop on the conversation, what is the background I'd need to know? |
| 02:54:56 | evan | wait. |
| 02:55:02 | evan | why do you say CApiHandle there |
| 02:55:24 | brixen | vm/builtin/capi_handle.hpp |
| 02:55:31 | evan | no. |
| 02:55:35 | evan | then |
| 02:55:38 | evan | ok. |
| 02:55:48 | brixen | NativeMethodFrame::get_handle |
| 02:55:50 | evan | here's how it goes. |
| 02:56:01 | evan | capi::Handle.object_ |
| 02:56:09 | evan | points to a managed object |
| 02:56:29 | evan | if references_ > 0, the GC keeps Handle.object_ alive |
| 02:56:43 | evan | if references_ == 0, the GC checks if Handle.object_ is still alive |
| 02:56:47 | evan | if it is, nothing happens |
| 02:57:08 | evan | if it's becoming garbage, the capi::Handle is deallocated |
| 02:57:24 | evan | CApiHandle is simply a wrapper for capi::Handle.object_ |
| 02:57:59 | evan | capy::Handle.object_->get_ivar("capi_handle") == CApiHandle that wraps capi::Handle |
| 02:58:52 | brixen | and "the GC checks if Handle.object_ is still alive" means finding the object when the GC does the transitive closure walk, yes? |
| 02:59:02 | evan | correct. |
| 02:59:05 | brixen | k |
| 02:59:34 | brixen | I still think these assumptions are breaking down, but I need to trace this through the syck code |
| 02:59:46 | evan | could very well be |
| 03:00:07 | evan | answer the question: how is ->bonus seen by the GC |
| 03:00:14 | brixen | yes |
| 03:00:19 | evan | via rb_gc_mark? rb_global_variable? |
| 03:00:38 | brixen | I need to figure it out, but yes, that's the question I have too |
| 03:00:42 | evan | is it simply shoved into an array or somewhere else the GC sees |
| 03:00:47 | brixen | so I'm on the path :) |
| 03:00:51 | evan | that 3rd one leverages the fact that MRI is non-moving |
| 03:00:55 | evan | and ANY reference keeps an object alive |
| 03:00:56 | brixen | right |
| 03:01:07 | evan | so you toss a ref somewhere the GC can see |
| 03:01:23 | evan | then you can have a zillion places that VALUE is stored in unmanaged memory |
| 03:02:04 | evan | (this, for those playing along at home, is why no one has ever fit a generational GC to MRI successfully) |
| 03:02:09 | brixen | got it |
| 03:02:14 | evan | ok, need to run to the store. |
| 03:02:15 | evan | i'll be back later. |
| 03:02:17 | brixen | ok |
| 03:04:08 | seydar | brixen: if it's safe to interrupt, _why_ are there a zillion places that VALUE is stored? |
| 03:05:40 | brixen | seydar: in MRI a VALUE is a pointer to an object |
| 03:06:56 | seydar | and the pointers are located in unmanaged memory? |
| 03:07:56 | brixen | well, generally a pointer to unmanaged memory is associated with an MRI object using Data_Wrap_Struct |
| 03:08:16 | brixen | which creates a managed object that contains the pointer |
| 03:08:47 | brixen | ok, eating dinner, bbiab.. |
| 03:08:53 | seydar | so i learned recently, but what exactly causes the pointer to be duplicated? |
| 03:09:02 | seydar | lame. dinner should be eaten according to EST |
| 03:09:46 | brixen | sorry :P |
| 03:10:02 | brixen | the issue here isn't pointer duplication |
| 03:10:11 | brixen | not sure what the problem with that would be exactly |
| 03:10:26 | brixen | anyway, bb20m EST ;) |
| 03:10:27 | seydar | I'm trying to decipher "<@evan> then you can have a zillion places that VALUE is stored in unmanaged memory" |
| 03:10:36 | seydar | i'll be waiting |
| 03:10:46 | seydar | rue_XIV: ping! |
| 04:23:08 | seydar | pax, children |
| 07:44:47 | brixen | evan: see vm/builtin/data.cpp |
| 07:45:18 | brixen | evan: but, trying to implement ::mark, I'm running into vm.cpp : 58 current_mark(NULL) |
| 07:45:50 | brixen | which, when rb_gc_mark executes, segfaults of course |
| 07:46:00 | brixen | because gc is NULL |
| 07:49:24 | brixen | hmm |
| 07:52:39 | evan | hm. |
| 07:53:04 | evan | brixen: ah ah! |
| 07:53:05 | evan | of course! |
| 07:53:08 | evan | all my fault! |
| 07:54:50 | brixen | evan: well, I'm a little further |
| 07:54:59 | evan | did you get the current_mark passed down? |
| 07:55:01 | evan | thats all that needed to do |
| 07:55:08 | brixen | yeah, one sec |
| 07:55:10 | brixen | I'll diff ya |
| 07:55:13 | evan | k |
| 07:55:21 | brixen | I was totally chasing my tail on the damn handle |
| 07:55:26 | brixen | facepalms |
| 07:55:29 | evan | i was going to say, just throw it into a thread local |
| 07:55:32 | evan | yeah |
| 07:55:34 | brixen | handles* |
| 07:55:39 | evan | when it was all my fault! |
| 07:55:41 | evan | sorry :/ |
| 07:55:44 | brixen | which seem to be working fine |
| 07:55:48 | brixen | nah, my fault |
| 07:55:56 | brixen | I have a totally simple repro too! |
| 07:55:58 | brixen | sec.. |
| 07:58:12 | brixen | http://gist.github.com/134406 |
| 07:58:25 | brixen | I just followed the existing code for ::mark |
| 07:58:36 | brixen | I wasn't reading the commented code at first |
| 07:58:47 | brixen | but why does it only call for one Data object? |
| 07:58:56 | brixen | it misses all the rest |
| 07:59:08 | brixen | and they get collected |
| 07:59:45 | brixen | oh, wait, 0x1b228c0 gets deleted too |
| 08:00:17 | evan | ::mark should be called on all live Data objects |
| 08:01:16 | brixen | well, every one of those dates is in an array, and the date obj should have a data_wrap_struct from Date#to_yaml |
| 08:01:35 | brixen | and that struct has a function to mark the bonus fields |
| 08:02:09 | evan | so is this not working? |
| 08:02:34 | brixen | it appears that ::mark is not called on those data objects, yes |
| 08:03:03 | evan | Date (not Data) uses Data_Wrap_Struct? |
| 08:03:06 | evan | is that what i'm seeing? |
| 08:03:19 | brixen | well |
| 08:04:00 | brixen | hm, do you have the mri code handy? |
| 08:04:05 | evan | yeah |
| 08:04:12 | brixen | I can take you through the yaml code |
| 08:04:23 | evan | fffun! |
| 08:04:26 | evan | 0xfffun! |
| 08:04:28 | brixen | see lib/yaml/rubytypes.rb |
| 08:04:29 | brixen | heh |
| 08:04:33 | brixen | class Date |
| 08:04:54 | evan | ok, i see it. |
| 08:04:54 | brixen | then lib/yaml.rb : def YAML.quick_emit |
| 08:05:10 | evan | ok |
| 08:05:23 | brixen | then syck/rubyext.c syck_emitter_s_alloc |
| 08:05:34 | brixen | and syck_emitter_reset |
| 08:05:46 | brixen | quick_emit will create the emitter obj |
| 08:05:53 | evan | ok |
| 08:05:57 | brixen | which will call syck_emitter_s_alloc |
| 08:06:02 | brixen | and syck_emitter_reset |
| 08:06:10 | brixen | which is Emitter#initialize |
| 08:06:31 | brixen | syck_emitter_s_alloc call Data_Wrap_Struct |
| 08:06:31 | evan | ok |
| 08:07:02 | evan | yep |
| 08:07:10 | evan | and i see bonus-> fields set in _reset() |
| 08:07:15 | brixen | right |
| 08:07:22 | evan | and I see syck_mark_parser |
| 08:07:27 | evan | marking bonus fields |
| 08:07:48 | brixen | in the bottom part of that gist, line 288 |
| 08:08:07 | brixen | there is only one call to Data::Info::mark before all those deletes |
| 08:08:13 | brixen | that's what I don't understand |
| 08:08:33 | evan | oh |
| 08:08:35 | evan | thats easy. |
| 08:08:43 | evan | there is only one Data_Wrap_Struct in use |
| 08:08:55 | evan | the syck parser/emitter object itself |
| 08:09:21 | evan | parser_s_alloc is the only thing here that creates Data objects |
| 08:09:34 | evan | ok, there are a few more |
| 08:09:38 | evan | but thats the main one for this |
| 08:09:54 | evan | you call it, and it calls rb_gc_mark |
| 08:09:57 | evan | on all the bonus fields, etc. |
| 08:10:22 | evan | err., i meant syck_emitter_s_alloc |
| 08:10:24 | evan | but same diff really. |
| 08:10:27 | evan | it's the same pattern. |
| 08:10:46 | brixen | hmm, I was thinking quick_emit was creating an emitter for each obj |
| 08:11:06 | evan | i don't think so |
| 08:11:11 | evan | I think it calls reset on the same one |
| 08:11:17 | brixen | yeah, checking now |
| 08:11:21 | evan | yeah, that emitter.reset |
| 08:11:47 | brixen | I didn't think of that, since opts = {} in both quick_emit and in Date#to_yaml call to quick_emit |
| 08:11:48 | evan | hm, it does call Emitter.new.set_resolver() |
| 08:11:49 | evan | though... |
| 08:12:20 | brixen | def YAML.emitter; Emitter.new.set_resolver( YAML.resolver ); end |
| 08:12:27 | evan | hm. |
| 08:12:33 | brixen | emitter in emitter.reset has to be that method |
| 08:12:34 | evan | oh! |
| 08:12:35 | evan | der. |
| 08:12:42 | evan | all the other ones are dead already! |
| 08:12:48 | brixen | :C |
| 08:12:48 | evan | they're already garbage |
| 08:12:59 | evan | so of course ::mark is called on them |
| 08:13:27 | brixen | you mean delete? |
| 08:13:30 | evan | no |
| 08:13:36 | evan | i mean that the emitters live a very short time |
| 08:13:49 | evan | so they are created, do their business, and become garbage |
| 08:13:56 | evan | before the GC runs even once |
| 08:14:08 | evan | the case you're seeing |
| 08:14:20 | evan | you managed to catch one live, during a GC |
| 08:14:30 | brixen | ok |
| 08:14:40 | evan | if you want to validate this |
| 08:14:54 | evan | you could add a counter to find_lost_souls in baker.cpp |
| 08:15:00 | evan | to count the number of Data objects seen as dead. |
| 08:15:06 | brixen | ok |
| 08:15:09 | evan | or register that Data needs cleanup |
| 08:15:17 | evan | and you could print out all the dead Data objects |
| 08:15:37 | brixen | so, why are we trying to access a deleted object then |
| 08:15:42 | brixen | what am I missing |
| 08:16:16 | evan | ok, lets go back to your problem. |
| 08:16:29 | brixen | very bottom of the gist |
| 08:16:47 | evan | yes, i see us marking bonus->port |
| 08:16:51 | evan | but then, right below |
| 08:16:53 | evan | we delete it |
| 08:17:19 | evan | it would seem THATS the issue. |
| 08:17:37 | evan | so, what is rb_gc_mark doing |
| 08:17:47 | evan | because it's not saying "HEY ASSHOLE, I NEED THIS TO STAY ALIVE" properly |
| 08:18:01 | brixen | well, that and we never mark 0x1b22910 |
| 08:18:07 | brixen | and that's the one we try to access |
| 08:18:10 | brixen | not the one we marked |
| 08:18:23 | evan | well |
| 08:18:23 | evan | ok |
| 08:18:33 | evan | print out all handles passed to rb_gc_mark |
| 08:18:36 | evan | and validate that |
| 08:18:40 | brixen | k |
| 08:18:50 | evan | my hunch is you'll see it marked. |
| 08:19:08 | evan | because, here's what i'm guessing is happening. |
| 08:19:12 | evan | references_ is at 0 |
| 08:19:25 | evan | well, hm. |
| 08:19:29 | evan | let me think about this... |
| 08:20:13 | evan | brixen: where did you put that "deleteing <addr>" line? |
| 08:20:19 | evan | what file/line |
| 08:21:04 | brixen | in ~Handle() |
| 08:21:23 | brixen | vm/capi/handle.cpp |
| 08:21:29 | evan | ok |
| 08:21:37 | evan | so do 2 things |
| 08:21:41 | evan | in rb_gc_mark |
| 08:21:59 | evan | on line 22, print out handle and handle->object() |
| 08:22:18 | evan | and in ~Handle(), print out object() as well |
| 08:22:29 | evan | we need to match things up |
| 08:22:33 | brixen | k |
| 08:22:41 | brixen | there are only 3 calls to rb_gc_mark |
| 08:22:56 | evan | thats fine |
| 08:23:00 | evan | thats EXACTLY what I expect |
| 08:23:03 | brixen | k |
| 08:23:08 | evan | the 3 that emitter_mark calls |
| 08:23:12 | evan | for the 3 fields in bonus |
| 08:23:17 | brixen | yeah |
| 08:23:46 | brixen | in rb_gc_mark do you want the original object() or res? |
| 08:24:12 | evan | well, i want object() after the conditional code has run |
| 08:24:20 | evan | so we need to know what is handle now pointing to |
| 08:24:24 | brixen | k |
| 08:24:27 | evan | res might be NULL, we don't need to know that |
| 08:24:37 | evan | we need to know handle->object() |
| 08:24:48 | brixen | got it |
| 08:27:47 | brixen | http://gist.github.com/134413 |
| 08:28:34 | evan | ah ha! |
| 08:28:43 | evan | we did mark the handle we tried to access |
| 08:28:55 | evan | and we then delete it! |
| 08:28:56 | evan | OOPS |
| 08:28:57 | evan | :D |
| 08:29:23 | brixen | I see |
| 08:29:47 | evan | so why did we delete a handle we just marked? |
| 08:30:02 | brixen | someone erased the chalk mark? |
| 08:30:26 | evan | well, lets... |
| 08:30:41 | evan | we're in a young gen sweep, yes? |
| 08:30:55 | brixen | yes |
| 08:31:13 | brixen | I was looking at ObjectMemory::prune_handles earlier |
| 08:31:39 | brixen | and baker.cpp : 130 |
| 08:31:45 | evan | k. |
| 08:31:52 | brixen | nothing was standing out such as to poke me in the eye or anything |
| 08:31:53 | evan | i was trying to find prune_handles |
| 08:32:00 | evan | ah ah! |
| 08:32:28 | evan | ok! |
| 08:32:33 | evan | so, baker.cpp:130 |
| 08:32:43 | evan | that code doesn't run for our handle in question |
| 08:32:47 | evan | because it's weak! |
| 08:32:55 | brixen | ahh indeed |
| 08:33:01 | evan | we instead allow the GC to find it |
| 08:33:27 | evan | ok |
| 08:33:44 | evan | so the code at 157 must be wrong |
| 08:34:38 | brixen | 157? |
| 08:34:52 | evan | objectmemory.cpp:157 |
| 08:34:57 | brixen | ah |
| 08:35:16 | evan | if we marked 0x132dd20 |
| 08:35:29 | evan | then the code on 157 should come up false |
| 08:35:38 | evan | because it is young and it should be forwarded |
| 08:36:20 | evan | or it's not young |
| 08:36:34 | evan | so this code should blow by |
| 08:37:37 | evan | agardiner: hey there! |
| 08:37:40 | brixen | agardiner! |
| 08:38:03 | agardiner | howdy! |
| 08:38:11 | agardiner | how are you both? |
| 08:38:20 | evan | brixen: on line 158, print out if obj is young and if obj is forwarded |
| 08:38:40 | evan | oh good |
| 08:38:42 | evan | we're debugging |
| 08:38:43 | evan | :D |
| 08:38:56 | agardiner | whatcha debugging? |
| 08:39:00 | evan | brixen: and print out obj's address |
| 08:39:02 | evan | brixen: the GC |
| 08:39:06 | evan | er. |
| 08:39:09 | evan | agardiner: the GC! |
| 08:39:13 | agardiner | fun! |
| 08:39:51 | agardiner | still using immix? |
| 08:39:59 | evan | yep |
| 08:40:06 | evan | we're debugging the funnest part |
| 08:40:12 | evan | the capi Handle system |
| 08:40:30 | agardiner | ah... |
| 08:40:46 | agardiner | does that use pinning? |
| 08:41:03 | evan | nope |
| 08:41:15 | evan | would be neat to use it though |
| 08:41:20 | evan | but we'd have to be able to pin young objects |
| 08:41:26 | evan | something i haven't implemented |
| 08:42:35 | agardiner | have you come across anyone else using immix for real? |
| 08:42:45 | evan | not yet |
| 08:42:48 | evan | it works great |
| 08:42:53 | evan | i'm sure someone will. |
| 08:42:57 | agardiner | cutting edge! |
| 08:42:59 | agardiner | :-) |
| 08:43:37 | evan | daring even! |
| 08:44:11 | agardiner | so how goes progress? |
| 08:44:18 | evan | going well |
| 08:44:21 | agardiner | seems like things are stabilising somewhat? |
| 08:44:23 | evan | been working on performance for a while |
| 08:44:26 | evan | yeah |
| 08:44:26 | brixen | evan: prune: 0x1b22930, 0x132dd20, weak: 1, young: 1, forwarded: 0 |
| 08:44:38 | evan | wtf. |
| 08:44:43 | evan | why is it not forwarded? |
| 08:44:43 | brixen | I don't get it |
| 08:44:55 | evan | send me your diff again |
| 08:45:03 | evan | something smells. |
| 08:46:12 | brixen | well, this has the Data::Info::mark diff http://gist.github.com/134406 |
| 08:46:36 | evan | no |
| 08:46:38 | evan | i need the whole diff |
| 08:46:42 | evan | give me the whole thing |
| 08:46:43 | evan | all your changes. |
| 08:47:08 | brixen | including the syck/yaml import? |
| 08:47:17 | evan | ok, minus that. |
| 08:47:22 | evan | at least everything in vm |
| 08:47:27 | brixen | sec.. |
| 08:48:10 | evan | FUCk. |
| 08:48:26 | evan | damnit. |
| 08:48:32 | evan | i really wonder if this is going to be it. |
| 08:48:35 | evan | go into vm.hpp |
| 08:48:39 | evan | change current_mark to be |
| 08:48:45 | evan | ObjectMark* current_mark; |
| 08:49:17 | brixen | http://gist.github.com/134418 |
| 08:49:28 | brixen | k |
| 08:50:13 | evan | then change your ::mark to do |
| 08:50:30 | evan | ObjectMark* cur = ->current_mark; |
| 08:50:35 | evan | ->current_mark = &mark; |
| 08:50:42 | evan | (*data...)(); |
| 08:50:46 | evan | ->current_mark = cur; |
| 08:51:48 | evan | and change rb_gc_mark to do |
| 08:51:53 | evan | ->current_mark->call(..) |
| 08:52:24 | evan | are you testing this running the full specs? |
| 08:52:34 | brixen | yeah |
| 08:52:48 | evan | ok |
| 08:52:52 | evan | try that |
| 08:52:54 | evan | tell me what happens |
| 08:53:02 | brixen | running the code at the top of this is my repro http://gist.github.com/134406 |
| 08:53:06 | brixen | but I can run the full specs |
| 08:53:21 | evan | no no |
| 08:53:22 | evan | thats fine |
| 08:53:29 | evan | stick with what you've been using |
| 08:53:36 | brixen | k |
| 09:00:30 | brixen | same result |
| 09:00:44 | evan | k |
| 09:00:53 | evan | set a breakpoint in rb_gc_mark |
| 09:00:59 | evan | on the call to ->call() |
| 09:01:05 | evan | you're going to step into that |
| 09:01:10 | evan | and figure out wtf is going on |
| 09:01:16 | brixen | k |
| 09:06:55 | evan | if it's a young object |
| 09:06:57 | evan | and it is |
| 09:07:02 | evan | then it should be forwarded |
| 09:07:07 | evan | and the bit set to indicate as such |
| 09:07:15 | evan | if it's not, we need to figure out why |
| 09:08:00 | brixen | k |
| 09:27:37 | brixen | wth http://gist.github.com/134432 |
| 09:30:57 | brixen | hm, well the copy should not be forwarded |
| 09:31:14 | evan | oh. |
| 09:31:15 | brixen | the original object->forwarded_p() is true |
| 09:31:15 | evan | geez. |
| 09:31:20 | evan | i'm fucking stupid. |
| 09:31:28 | evan | yep. |
| 09:31:35 | evan | i've got the logic all backwards. |
| 09:32:44 | evan | ok, so do |
| 09:34:00 | evan | check_forwards ? (obj->young_object_p() && young.validate(obj) != cValid) : !obj->marked_p() |
| 09:34:07 | evan | should do the trick |
| 09:34:21 | brixen | ahh ok |
| 09:34:36 | brixen | I couldn't figure out the logic with forwarded_p() :P |
| 09:34:59 | evan | i got confused because most code is looking at refs and asking "was the object seen?" |
| 09:35:26 | evan | rarely is code expecting to find the forwarded copy somewher |
| 09:35:29 | evan | thats why |
| 09:35:34 | brixen | makes sense |
| 09:36:21 | evan | ooh yeah |
| 09:36:23 | evan | check this out: http://gist.github.com/134435 |
| 09:36:41 | evan | the IC stats |
| 09:37:28 | brixen | whoa |
| 09:37:39 | evan | 97.16% of ICs had one class ever seen |
| 09:37:47 | agardiner | how do you get 0 class? is that an IC that hasn't been called at all? |
| 09:37:51 | evan | yeah |
| 09:37:58 | evan | those are ICs that haven't been used |
| 09:38:01 | evan | for whatever reason |
| 09:38:10 | brixen | interesting jump from 3 to 3+ |
| 09:38:11 | evan | methods not executed, branches not taken, etc. |
| 09:38:27 | evan | yeah, thats actually consistent with the research |
| 09:38:49 | brixen | so 3+ is basically megamorphic |
| 09:38:50 | evan | there is a rise in the graph toward the mega-morphic end |
| 09:39:06 | evan | because there is a bunch of utility code that ends up being megamorphic |
| 09:39:16 | brixen | can you print those out? ie code location? |
| 09:39:26 | evan | great example: Module#attr_accessor |
| 09:39:39 | evan | because it calls attr_reader and attr_writer internally |
| 09:40:05 | evan | and the receiver is pretty much always seen as a metaclass |
| 09:40:11 | evan | thus, different. |
| 09:40:23 | agardiner | does this mean have you implemented PICs now? |
| 09:40:25 | evan | brixen: which do you want printed out? |
| 09:40:34 | evan | agardiner: i could implement them in a jiff |
| 09:40:36 | evan | was going to tomorrow |
| 09:41:28 | brixen | evan: the code location of the megamorphic calls |
| 09:41:33 | agardiner | cool... wonder if it will help much. If you recall, I implemented something simple in shotgun, but didn't commit it because it made no difference to perf |
| 09:41:42 | evan | yeah |
| 09:41:47 | evan | i doubt it will make much perf difference |
| 09:42:20 | evan | brixen: i could probably figure out a way to, yes. |
| 09:42:56 | agardiner | geez, i can't believe that was like a year ago... |
| 09:43:01 | evan | i know |
| 09:43:03 | evan | time flies |
| 09:43:13 | agardiner | doesn't it... |
| 09:48:38 | brixen | evan: I think we should re-convene further into the AM |
| 09:48:39 | brixen | http://gist.github.com/134438 |
| 09:48:56 | evan | yeah |
| 09:48:57 | brixen | see line 16 |
| 09:48:59 | evan | i think so too |
| 09:49:31 | evan | see ya in the morning. |
| 09:49:35 | brixen | k |
| 09:49:38 | brixen | nite! |
| 09:49:57 | agardiner | night |
| 09:50:07 | brixen | morning agardiner! heh |
| 09:50:16 | agardiner | :-D |
| 09:50:21 | brixen | I can't believe how much earlier it is in the UK |
| 09:50:28 | evan | seriously. |
| 09:50:29 | evan | oh btw |
| 09:50:38 | evan | bin/mspec ci -T -Xic.stats |
| 09:50:47 | evan | 1 class: 97.12% |
| 09:51:02 | evan | 1 class: 110288 97.1255% |
| 09:51:02 | evan | 2 classes: 1728 1.52177% |
| 09:51:03 | agardiner | ah... its later. coming up for 10am Tues |
| 09:51:12 | brixen | interesting |
| 09:51:21 | brixen | evan: you should try that with rails -h right quick |
| 09:51:29 | evan | umm |
| 09:51:41 | evan | lets see how quickly the gem installs |
| 09:51:46 | brixen | heh |
| 09:51:50 | brixen | I thought you had it already |
| 09:52:00 | agardiner | this is a striaght count of ICs by classes, right - not based on usage? |
| 09:52:00 | brixen | run ic.stats on gem install! |
| 09:52:03 | evan | I did at one point |
| 09:52:12 | evan | agardiner: no, thats ALL usage |
| 09:52:43 | evan | thats saying, 97.12% of ICs only ever seen one receiver class |
| 09:52:50 | evan | only ever see |
| 09:53:05 | evan | brixen: ok, running... |
| 09:53:18 | evan | wow, this is awesome |
| 09:53:20 | agardiner | right, but the 1% that see more than 1 class might be called many more (or less times), no? |
| 09:53:25 | evan | 1 class: 26018 97.1836% |
| 09:53:25 | evan | 2 classes: 333 1.24384% |
| 09:53:30 | evan | thats for rails -h |
| 09:54:00 | brixen | agardiner: ah interesting point |
| 09:54:09 | evan | agardiner: i've got hit counters on all the entries |
| 09:54:10 | brixen | evan: do you have a call count in the ICs? |
| 09:54:13 | evan | yes. |
| 09:54:17 | evan | call counters per class |
| 09:54:24 | brixen | nice |
| 09:54:26 | agardiner | that would be interesting |
| 09:54:34 | evan | tell ya what |
| 09:54:36 | evan | i'll find out |
| 09:54:38 | evan | IN THE MORNING! |
| 09:54:41 | brixen | heh |
| 09:54:42 | agardiner | :-D |
| 09:54:43 | brixen | OK |
| 09:54:52 | evan | nite / morning boys |
| 09:54:56 | agardiner | get some sleep then, you slacker! :-P |
| 09:55:06 | evan | i'm off to sleeps! |
| 09:55:08 | agardiner | nite |
| 09:55:17 | brixen | will have nightmares about handles and forwarded objects |
| 09:55:34 | evan | hehe |
| 09:55:35 | agardiner | hah, my nightmare last night was workflow |
| 09:55:39 | evan | sleeps |
| 17:24:50 | evan | morning |
| 17:25:00 | evan | brixen: i realized last night as I was brushing my teeth whats going on |
| 17:26:33 | sbryant_work | morning |
| 17:26:42 | evan | mornig |
| 17:26:44 | evan | morning |
| 17:29:13 | agardiner | morning |
| 17:29:13 | sbryant_work | Crazy weekend? |
| 17:33:26 | evan | sbryant_work: no, not too crazy |
| 17:33:27 | evan | you? |
| 17:34:08 | sbryant_work | Decently crazy. |
| 17:34:40 | sbryant_work | Went out drinking with a friend. We end up in a "fancy" bar and he goes to pay. |
| 17:34:50 | sbryant_work | We get up to leave and he takes off. |
| 17:34:57 | sbryant_work | Like bolts down the street. |
| 17:35:13 | sbryant_work | he was already drunk and thought everyone was bailing on the check. |
| 17:35:22 | sbryant_work | Some people do not hold their booze! |
| 17:36:38 | brixen | evan: morning |
| 17:36:45 | brixen | what's going on? :) |
| 17:36:45 | evan | brixen: morning |
| 17:36:48 | evan | ok |
| 17:37:03 | evan | there are actually 2 cases for objects seen on line 157 |
| 17:37:25 | evan | 1) objects marked which have been marked via rb_gc_mark |
| 17:37:37 | evan | 2) objects which have been marked, but not via rb_gc_mark |
| 17:37:45 | brixen | ok |
| 17:38:23 | evan | by changing it like we did, we made one case work, and one case break |
| 17:38:45 | evan | easiest fix is to rearrange the code a little |
| 17:38:49 | brixen | k |
| 17:38:49 | evan | so that if check_forwards is set |
| 17:38:52 | evan | and the object is young |
| 17:39:10 | evan | if it's cValid, don't do anything with it, keep going |
| 17:39:33 | evan | if it's forwarded, do the code on 172 |
| 17:39:44 | evan | if it's neither, do the code on 160 |
| 17:40:44 | brixen | k |
| 17:41:13 | agardiner | right, i'm off... |
| 17:41:18 | agardiner | catch you later |
| 17:41:20 | brixen | see ya agardiner! |
| 18:11:29 | brixen | woot |
| 18:11:47 | brixen | oh dr phoenix, your Rx appears to work, confirm I read your handwriting |
| 18:11:48 | brixen | http://gist.github.com/134686 |
| 18:12:06 | brixen | tracking down an issue with Qnil passed to rb_gc_mark now |
| 18:12:16 | evan | ah |
| 18:12:17 | evan | thats easy |
| 18:12:24 | brixen | but it ran for a long time, through many collections |
| 18:12:28 | evan | you probably just need to check for references |
| 18:12:31 | evan | yay! |
| 18:12:31 | brixen | yeah |
| 18:12:36 | brixen | yay indeed! |
| 18:12:39 | evan | oh btw, interesting numbers: http://gist.github.com/134687 |
| 18:12:42 | evan | just ran those |
| 18:13:01 | brixen | wow, that is a long tail |
| 18:13:17 | evan | yep |
| 18:13:28 | sbryant_work | What do those numbers mean? |
| 18:13:46 | brixen | and it would be interesting to see the proportion of calls in that 2.88% |
| 18:13:53 | evan | sbryant_work: thats enumerating all the InlineCaches in the system |
| 18:13:57 | evan | ie, every sendsite |
| 18:13:58 | brixen | ie the tail |
| 18:14:27 | evan | and this says that 97.12% of sends always had the same receiver class |
| 18:14:29 | brixen | evan: you might just have gotten us to the point where PIC shows results! |
| 18:14:40 | sbryant_work | Thanks! |
| 18:14:46 | evan | perhaps! |
| 18:15:17 | evan | i'm going to generate some stats that take the number of hits into account |
| 18:15:25 | brixen | coool |
| 18:24:38 | brixen | wooot! |
| 18:24:41 | brixen | it finished |
| 18:24:59 | evan | WOO |
| 18:25:00 | brixen | had to check that handle itself was a reference in rb_gc_mark |
| 18:25:07 | evan | yep. |
| 18:25:09 | evan | make sense |
| 18:25:14 | brixen | excelente |
| 18:25:19 | evan | yay! |
| 18:25:25 | brixen | fucking crazy how cool these handles are |
| 18:25:30 | evan | yeah |
| 18:25:31 | brixen | take that syck! |
| 18:25:38 | evan | i'm really happy with how they turned out |
| 18:25:51 | brixen | me too |
| 18:28:12 | sbryant_work | neat-o |
| 18:28:23 | sbryant_work | I wish this damn project would end so I could work on more interesting things :-\ |
| 18:28:39 | evan | sbryant_work: what you work on? |
| 18:28:55 | sbryant_work | A rails app this legal company bought. |
| 18:29:08 | sbryant_work | They want to do things that aren't very rails "friendly" |
| 18:29:24 | sbryant_work | So it's a lot of extra code, doing ugly things and waiting on red tape |
| 18:29:31 | evan | fun. :/ |
| 18:29:44 | sbryant_work | But after it's done they told me I could work on whatever I'd like |
| 18:30:22 | sbryant_work | Imagine having 7 different database (with all the same structure) and you have to pull data from each of them on a single request. |
| 18:31:06 | evan | hehe |
| 18:31:09 | sbryant_work | Oh and you have another database for the "core" of the application |
| 18:31:12 | evan | I just called a variable |
| 18:31:14 | evan | these_hits |
| 18:31:22 | evan | because i've got 3 other variables named varations of hits |
| 18:31:24 | sbryant_work | So the 7 different databases aren't directly related to your site. |
| 18:31:57 | sbryant_work | I'm wrapping things in modules based on the database they talk to |
| 18:31:57 | enebo | evan: Are your stats generated via a rubyspec run? |
| 18:32:07 | evan | the last gist was |
| 18:32:08 | evan | yes |
| 18:32:11 | enebo | ok |
| 18:32:16 | sbryant_work | so they do things like set_table_name and establish_connect :db |
| 18:32:26 | evan | i'm generating another one now |
| 18:32:32 | evan | that takes into account the usage of the IC |
| 18:32:46 | enebo | I have always been interested in gather these stats too |
| 18:32:47 | sbryant_work | is this for bench.rubini.us? |
| 18:32:48 | evan | sbryant_work: ug. yes, i've done that too. |
| 18:32:54 | evan | sbryant_work: partly |
| 18:32:56 | enebo | for various site caches |
| 18:33:07 | sbryant_work | evan: I tried to dynamically generate all the code |
| 18:33:28 | sbryant_work | but that didn't work out as planned because I couldn't get that call to establish_connect be lazily evaluated |
| 18:33:50 | evan | ok: http://gist.github.com/134687 |
| 18:33:52 | evan | check out the bottom |
| 18:34:27 | evan | that bottom one is how many hits an IC containing that number of tracked classes |
| 18:34:53 | evan | so, interestingly, there are very few megamorphic Ics |
| 18:34:57 | evan | but they're hit A LOT. |
| 18:35:10 | evan | actually |
| 18:35:16 | evan | I might be skewing this... |
| 18:35:23 | evan | let me check. |
| 18:37:46 | evan | hm, so for the megamorphic counters |
| 18:38:16 | evan | there is a counter thats incremented everytime there is no more room for any more tracked classes |
| 18:38:30 | evan | which would be run everytime the IC is wrong |
| 18:38:39 | brixen | well, looks like ~20% in 2-10 |
| 18:38:49 | brixen | so a PIC should make a big diff |
| 18:39:07 | evan | perhaps up 4 |
| 18:39:13 | evan | after that, it's not as useful |
| 18:39:44 | brixen | yeah, 2-4 is > 15% |
| 18:39:57 | evan | let me try something... |
| 18:40:19 | brixen | man, I'd love to know where these are |
| 18:40:23 | brixen | like the 6 one |
| 18:40:29 | enebo | evan: I am wonder which sites are in 10+.... |
| 18:40:35 | evan | yeah |
| 18:40:40 | brixen | enebo: heh, me too |
| 18:40:41 | evan | everyone wants to know where they are! |
| 18:40:47 | enebo | find them!!!! :) |
| 18:40:49 | brixen | publish a zine! |
| 18:40:54 | evan | gets out his cartographers hat |
| 18:41:00 | brixen | inquiring minds want to know |
| 18:41:09 | brixen | use your 3gs compass! |
| 18:41:16 | evan | hah |
| 18:41:57 | sbryant_work | Are you going IC hit hunting? |
| 18:42:32 | evan | interesting |
| 18:42:40 | evan | my change didn't change the stats, thats good |
| 18:43:41 | evan | ok, lets see |
| 18:43:57 | evan | if i can print out the file:line of all megamorphic sends |
| 18:46:26 | enebo | some hash call in map :) |
| 18:46:39 | evan | probably something like that |
| 18:46:48 | evan | we'll see shortly! |
| 18:49:04 | sbryant_work | This channel is pretty exciting today. |
| 18:49:45 | boyscout | Better explanation of the benchmark graphs. - 34443d5 - Brian Ford |
| 18:49:45 | boyscout | Added rb_io_write and specs. - a3c74cb - Brian Ford |
| 18:49:45 | boyscout | Added rb_gc_mark_maybe. - 26c1844 - Brian Ford |
| 18:49:45 | boyscout | Rake task to compile syck extension. - 7cf24f4 - Brian Ford |
| 18:49:45 | boyscout | Added Syck extension. - 8776651 - Brian Ford |
| 18:49:46 | boyscout | Always compile extensions with debug symbols. - 3ffd142 - Brian Ford |
| 18:49:48 | boyscout | Don't bus error if rb_global_variable gets invalid address. - 13bb5be - Brian Ford |
| 18:49:50 | boyscout | Added rb_hash_size. - 869ec1d - Brian Ford |
| 18:49:50 | evan | WOO |
| 18:49:52 | boyscout | Added OBJ_TAINT, OBJ_TAINTED. - e823303 - Brian Ford |
| 18:49:54 | boyscout | Fixes for Syck extension integrated in rbx. - e4ee79b - Brian Ford |
| 18:49:55 | evan | KEEP COMIN' |
| 18:49:56 | boyscout | Removed failing tags for YAML. - 7b3e2ad - Brian Ford |
| 18:49:57 | evan | GO GO GO |
| 18:49:58 | boyscout | Removed RbYAML. - 7f63316 - Brian Ford |
| 18:50:00 | boyscout | Fixed sprintf format warning on gcc 4.3. - fbbcf02 - Brian Ford |
| 18:50:01 | evan | CHUG |
| 18:50:02 | boyscout | Fixed rb_gc_mark to check handles are references. - 835263c - Brian Ford |
| 18:50:03 | evan | CHUG |
| 18:50:04 | boyscout | Dr Phoenix's Rx for the treatment of weak and strong handles. - ee676d8 - Brian Ford |
| 18:50:04 | evan | CHUG |
| 18:50:08 | brixen | haha |
| 18:50:11 | evan | HAHAH |
| 18:50:13 | evan | i love that last one |
| 18:50:24 | brixen | I think I get point for best commit msg in a while :) |
| 18:50:29 | brixen | points* |
| 18:50:30 | evan | you do |
| 18:50:34 | evan | brixen += 5 |
| 18:50:40 | brixen | rock |
| 18:51:25 | brixen | scouts breakfast while boyscout chugs |
| 18:52:04 | sbryant_work | That was awesome. |
| 18:54:17 | evan | woo |
| 18:54:22 | evan | i think i've got IC locations |
| 18:54:33 | brixen | schweet |
| 18:57:50 | boyscout | CI: ee676d8 success. 2709 files, 10776 examples, 33796 expectations, 0 failures, 0 errors |
| 18:57:57 | evan | woo |
| 18:59:46 | brixen | yay |
| 19:01:52 | evan | ok |
| 19:01:54 | evan | check out http://gist.github.com/134687 |
| 19:02:03 | evan | i've printed out the file:line of the megamorphic sites |
| 19:02:15 | evan | and run them through a script that shows the code at that location |
| 19:02:24 | evan | i'll run this on the specs now. |
| 19:03:40 | evan | a lot a lot of these are class/module related |
| 19:03:43 | evan | which makes sense |
| 19:06:42 | enebo | and may or may not be hot on a more conhesive set of code (e.g. something which runs the same code a lot versus something which spans the entire runtime+libraries) |
| 19:06:45 | brixen | interesting! |
| 19:06:47 | evan | specs! |
| 19:06:48 | evan | http://gist.github.com/134720 |
| 19:07:35 | brixen | line #s might be a bit off |
| 19:07:49 | brixen | eg kernel/common/marshal.rb 273 |
| 19:08:47 | evan | if they're off |
| 19:08:54 | evan | they're usually one line too far down |
| 19:09:01 | brixen | yeah |
| 19:09:08 | evan | yeah, like that one |
| 19:09:15 | evan | it's object_id there probably |
| 19:09:28 | evan | hey |
| 19:09:29 | evan | you know |
| 19:09:33 | evan | i should be printing out the name of the IC |
| 19:09:41 | brixen | so, am I reading right, #object_id, #send, #kind_of? |
| 19:09:43 | evan | and all the classes recorded there |
| 19:09:47 | brixen | yeah, I was thinking that |
| 19:45:10 | evan | ok, print out the names and classes helps |
| 19:45:16 | evan | the line numbers are definitely off |
| 19:45:19 | evan | need to fix that. |
| 19:46:07 | evan | let me gist this... |
| 19:46:49 | evan | http://gist.github.com/134687 |
| 19:47:09 | evan | ok, you can see how the mega's are basically not even using the cache |
| 19:47:20 | evan | when it's called on classe |
| 19:47:30 | evan | it ends up just cycling through |
| 19:47:43 | evan | making little to no use of the cache |
| 19:47:47 | brixen | interesting |
| 19:49:35 | evan | i could adjust the caching |
| 19:49:46 | evan | so that when it adds a new class |
| 19:49:52 | evan | it kicks out any class that had 0 hits |
| 19:50:02 | evan | rather than letting it fill up with classes with 0 hits |
| 19:50:21 | brixen | sounds reasonable |
| 19:50:28 | evan | lets see what that does... |
| 19:50:42 | evan | this is some fun research |
| 19:50:49 | brixen | indeed |
| 19:51:18 | sbryant_work | sounds like a plan |
| 19:53:12 | evan | wow |
| 19:53:22 | evan | doing that means there are 3 times fewer mega-morphic sites |
| 19:54:04 | evan | because megamorphic now means at 10+ receiver class that had at least one cache hit |
| 19:55:05 | evan | http://gist.github.com/134687 |
| 19:55:17 | evan | bottom one is the new logic, reusing any tracking spot with 0 hits |
| 19:55:38 | sbryant_work | wow. |
| 19:55:53 | sbryant_work | Orders of magnitude difference. |
| 19:56:10 | evan | yeah |
| 19:56:15 | evan | i'll run the specs now. |
| 20:04:29 | evan | hehe |
| 20:04:30 | evan | rock |
| 20:04:39 | sbryant_work | what's the results? |
| 20:04:43 | evan | __metaclass_init__ is megamorphic |
| 20:04:48 | evan | and all the results are |
| 20:04:53 | evan | MetaClas:<metaclass> |
| 20:04:57 | evan | ie, a metaclass of a metaclass |
| 20:05:06 | evan | sbryant_work: it's crashing on the specs |
| 20:05:08 | evan | i need to figure out why |
| 20:06:53 | sbryant_work | good luck! |
| 20:07:37 | evan | I find it interesting how badly ICs deal with Metaclasses |
| 20:08:29 | brixen | Metaclass, the IC repellant |
| 20:09:56 | evan | i wonder if i can find any info on how smalltalk dealt with this |
| 20:10:03 | evan | they've got the same problem here |
| 20:10:11 | evan | since their classes have metaclasses in the same way |
| 20:11:59 | brixen | evan: this is interesting http://www.jot.fm/issues/issue_2009_01/article4/ |
| 20:12:08 | brixen | search for metaclass |
| 20:13:05 | brixen | Obj-C 2.0 is sounding kinda hip |
| 20:16:32 | brixen | evan: do you have this paper http://portal.acm.org/citation.cfm?id=141936.141947 |
| 20:17:48 | evan | my acm membership expired, maybe I should renew it |
| 20:17:56 | evan | yeah, i've read that one |
| 20:18:05 | evan | it's all about these crazy techniques for organizing method tables |
| 20:18:08 | evan | as I recall |
| 20:18:56 | evan | ok, time to push this. |
| 20:25:16 | evan | that paper uses lazy, versioned IC clearing |
| 20:25:19 | evan | interesting |
| 20:25:45 | brixen | can you email it to me? |
| 20:25:56 | evan | the first one |
| 20:26:00 | evan | the jot.fm one |
| 20:26:13 | brixen | ahh |
| 20:26:28 | brixen | haven't finished reading it |
| 20:27:36 | evan | i'm skimming |
| 20:40:58 | boyscout | Fix mis-cache of methods called via #send - 3b291e0 - Evan Phoenix |
| 20:40:58 | boyscout | Add klass tracking in ICs, add ability to disable the IC - 362c395 - Evan Phoenix |
| 20:40:58 | boyscout | Fix up IC profiling, add -Xic.stats - 66c60d8 - Evan Phoenix |
| 20:45:37 | boyscout | CI: 66c60d8 success. .................................................................................................... .................................................................................................... .................................................................................................... ............................................................................... |
| 20:47:04 | brixen | hm |
| 20:47:40 | evan | :/ |
| 20:48:17 | evan | i'm having it manually build again |
| 20:50:28 | boyscout | CI: 66c60d8 success. 2709 files, 10776 examples, 33796 expectations, 0 failures, 0 errors |
| 20:51:08 | evan | hm, ok |
| 20:51:11 | evan | well |
| 20:51:15 | evan | that means it's lunch time. |
| 20:51:57 | brixen | yah, moi aussi |