Show enters and exits. Hide enters and exits.
| 01:37:49 | evan | who's got a working heap dump? |
| 01:37:55 | evan | <== that guy |
| 01:46:28 | BrianRice | cool |
| 02:00:25 | slava | evan: heap dump? |
| 02:00:59 | evan | slava: memory debugging tool |
| 02:01:07 | evan | writes the whole heap out to a file to be analyzed |
| 02:01:27 | slava | oh, makes sense |
| 02:01:37 | slava | does it dump the ivars of each object too? |
| 02:02:18 | evan | yep |
| 02:02:24 | evan | with references |
| 02:03:46 | slava | one cool thing you can do with that is make your inspector tool and other tools that look at objects access all ivars with one extra level of indirection |
| 02:04:00 | slava | so you can make a proxy type that wraps an object stored in such a dump |
| 02:04:17 | slava | and then do offline debugging with the same tools you use in the running image |
| 02:04:22 | evan | thats true. |
| 04:44:18 | BrianRice | hm not a bad idea |
| 05:39:31 | maharg | evan: does it have enough information to rebuild an entire interpreter state (less, obviously, any open external resources or C extension objects)? |
| 05:39:48 | maharg | because you could do a lot more than debug with that |
| 05:46:47 | evan | maharg: you mean... an image? :D |
| 05:47:11 | evan | I could dump all CallFrame state |
| 05:47:23 | evan | then it would be a matter of reconstructing it to be used. |
| 05:53:19 | slava | and then you'd have serializable continuations |
| 05:53:36 | slava | store a fiber in the database and resume execution in another VM |
| 05:53:36 | evan | bada-boom. |
| 05:53:45 | evan | slava: how do you serialize a call stack? |
| 05:54:22 | evan | or, rather, how do you unserialize a call stack |
| 05:59:41 | slava | we don't :) |
| 05:59:48 | evan | that makes it easy! |
| 05:59:55 | slava | in fact I'm going to remove general continuations at some point altogether, so we won't have a 'callstack' as a first-class type anymore |
| 06:00:11 | evan | the image restarts at a fixed position then |
| 06:00:14 | slava | well, how would you serialize a call frame that's executing compiled code? |
| 06:00:14 | evan | that you can't return past |
| 06:00:24 | evan | slava: you can't! |
| 06:00:27 | slava | oh, images can get loaded at an arbitrary base address |
| 06:00:27 | evan | thats why i was wonder! |
| 06:00:30 | evan | you're magic |
| 06:00:31 | evan | so who knows. |
| 06:00:46 | slava | so its a matter of fixing up the return address in each frame |
| 06:01:07 | slava | transporting a callstack between images is much harder though; your code may have compiled slightly differently, etc |
| 06:01:16 | evan | totally. |
| 06:01:23 | slava | if you compile the same word twice in factor, it might end up with a different register allocation the second time because of weird hash effects and such |
| 06:01:35 | slava | so you'd have to juggle spill slots around somehow. too magic |
| 06:01:36 | evan | fun! |
| 06:01:46 | evan | yes, bigger fish to fry. |
| 06:01:52 | evan | let Dan figure that out. |
| 06:01:53 | slava | but yeah, you can reify a continuation, save the image, start it again, and reflect that continuation |
| 06:01:53 | evan | :D |
| 06:02:19 | slava | but that's just a matter of going through and adding (new_address - old_address) to each return address and spilled pointer :) |
| 06:02:46 | slava | sbcl doesn't do image relocation on startup, which means they have to mmap the image at a fixed address, and update their VM for every minor point release of every OS that changes the address space slightly |
| 06:02:55 | evan | yep |
| 06:02:55 | slava | and on openbsd which has address space randomization, they're out of luck |
| 06:03:02 | evan | doesn't emacs do that too? |
| 06:03:05 | slava | yep |
| 06:03:13 | slava | the bookkeeping required for image relocation is similar to what you need for precise GC |
| 06:03:18 | evan | yeah |
| 06:03:25 | slava | sbcl has a conservative GC; every stack location that looks like a pointer is treated like one |
| 06:03:31 | evan | ouch. |
| 06:03:33 | slava | so they have a copying collector, but if something is referenced from the call stack it gets pinned down |
| 06:04:10 | evan | ewww. |
| 06:04:26 | slava | on platforms with lots of registers, like PPC, its precise, because they divide the register file into two -- tagged pointers and untagged integers |
| 06:04:32 | slava | so the GC traces every tagged register as a root |
| 06:04:43 | slava | but on x86, you don't have enough registers to be able to do that, and they don't do GC maps either |
| 06:05:10 | evan | aah. |
| 06:06:05 | slava | moral of the story: design decisions that made sense on early 90's SPARC workstations don't necessarily make sense today, hence whiny RISC trolls who pine for the good old days |
| 06:06:23 | evan | hah |
| 06:06:52 | slava | the main thing I hate about x86 is not the register shortage but the fact that some instructions have fixed register assignments |
| 06:07:26 | slava | some recent research shows how to do graph coloring register allocation in polynomial time, but when you add fixed registers to the mix its still NP-complete. if only intel knew at the time :) |
| 06:08:14 | slava | its totally random too. multiplication can take operands in any register, but shifts must have the shift count in ECX. why are shifts special? why ECX? |
| 06:08:15 | evan | you mean like the ones to push and pop from the stack? |
| 06:08:26 | evan | ah yeah |
| 06:08:27 | evan | that stuff. |
| 06:08:41 | evan | thats "optimization"! |
| 06:08:41 | slava | no, like IDIV storing the result in EAX, shifts with ECX, and some of the atomic compare and swap stuff is hard-wired in weird ways too |
| 06:09:11 | slava | yeah, you save one whole byte every time you divide |
| 06:09:21 | slava | too bad you generate a ton of unnecessary MOVs :) |
| 06:10:13 | slava | I always thought it was odd that Forth had a /MOD word until I learned that on x86, IDIV computes both the div and the mod |
| 06:10:50 | slava | PowerPC doesn't even have mod, instead you compute x-(x/y)*y |
| 06:47:27 | evan | brixen: http://gist.github.com/444643 |
| 06:48:09 | brixen | sweet |
| 06:49:19 | evan | all from the heap dump |
| 06:49:32 | evan | it's got all the references between objects too |
| 06:50:20 | brixen | very cool |
| 06:50:59 | evan | thats a dump from a script that jsut calls dump_heap |
| 06:51:03 | evan | so it's pretty much just the startup. |
| 06:51:29 | brixen | 20k tuples to start up |
| 06:51:30 | brixen | wow |
| 06:51:39 | evan | yeah, seems high doesn't it. |
| 06:51:44 | evan | i need to verify these numbers. |
| 06:51:45 | brixen | a bit |
| 07:51:09 | jarib | brixen: no, on 1.9 configure crashes since `` will raise Errno::ENOENT if the command isn't found |
| 09:08:02 | khaase | just added rbx to the rack ci: http://ci.rkh.im/job/Rack-Rubinius/2/console |
| 09:08:13 | khaase | any idea where this comes from? |
| 09:09:03 | khaase | huh, that spec passes for me locally |
| 10:05:23 | jarib | brixen: created #378 |
| 10:08:25 | jarib | brixen: the build still fails after fixing configure though http://gist.github.com/444768 |
| 17:07:51 | iamstef | apparently im missing something... 1.0.1 has some sort of limited debugger support, but i can seem to figure out how to enable the debugger |
| 17:08:02 | iamstef | anyone got a sec to explain this, little detail im missing? |
| 17:12:47 | cyndis | require 'debugger'; Debugger.start |
| 18:35:20 | boyscout | Add a number of GC stats to the query agent - 5e5679d - Evan Phoenix |
| 18:45:54 | boyscout | CI: rubinius: 5e5679d successful: 3456 files, 13603 examples, 41167 expectations, 0 failures, 0 errors |
| 19:15:36 | dbussink | evan: cool though that it's exactly 20k tuples ;) |
| 19:19:26 | dbussink | jarib: what ruby version are you using? |
| 19:21:02 | evan | dbussink: yeah, thats funny isn't it |
| 19:21:17 | evan | dbussink: i thought it might be wrong, but adding some more objects dumps it up, so it's right |
| 19:21:48 | dbussink | evan: how funny that numbers like this trip people up ;) |
| 19:21:57 | dbussink | any idea where that number is coming from? |
| 19:22:19 | dbussink | evan: btw, would it be easy to do ivar packing for included modules? |
| 19:22:40 | dbussink | evan: i wonder if it would be possible to detect it with datamapper, or perhaps otherwise expose an api for it |
| 19:22:53 | dbussink | would be nice that like loading 100 db records is nicer on memory pressure :) |
| 19:26:21 | evan | dbussink: actually, i can add it for included modules |
| 19:26:39 | evan | the current code includes ivars seen in superclasses |
| 19:26:49 | evan | i can easily have it include ivars found in include modules |
| 19:28:00 | dbussink | evan: dunno if dm is simple enough in it's usage for proper auto detection though, dunno if adding an api for it would be useful? |
| 19:28:22 | dbussink | evan: because dm tries to be pretty lazy in actually setting stuff etc. |
| 19:28:46 | dbussink | but it could likely be very useful to register ivars that are very likely to be filled |
| 19:28:51 | evan | there is an API |
| 19:29:03 | evan | Module#packed!([:@name, ...]) |
| 19:29:35 | dbussink | evan: ah, cool, maybe i'll try playing with it to see how much it helps :) |
| 19:29:53 | dbussink | also saw it didn't only use a lot less memory on that benchmark, but it was also 10x faster for me here |
| 19:30:11 | evan | what was 10x faster? |
| 19:31:27 | dbussink | evan: this one: https://gist.github.com/40f0ec7be1b89ebee06a |
| 19:32:11 | evan | thats 10x faster on rbx with autopacking? or 10x faster than MRI? |
| 19:32:30 | dbussink | evan: 10x faster with autopacking compared to not packing |
| 19:32:42 | dbussink | evan: that was the revision before you made autopacking the default |
| 19:32:43 | evan | ah yep |
| 19:32:45 | evan | yep yep |
| 19:33:10 | dbussink | pretty impressive improvement :) |
| 19:33:33 | evan | yeah! i'm happy it's worked out so well. |
| 19:33:52 | evan | there are still directions to take it |
| 19:33:55 | evan | like included modules |
| 19:34:01 | dbussink | evan: how smart is it? it considers each @var during class loading? |
| 19:34:14 | evan | and the JIT making use of packing |
| 19:34:18 | dbussink | does it work with stuff like class_eval etc.? |
| 19:34:27 | dbussink | ah, would be nice if the jit could trigger it :) |
| 19:34:38 | dbussink | based on history usage of ivars for a class of objects :) |
| 19:34:52 | evan | it considers ivars used in methods when a method is added to a class |
| 19:34:54 | evan | so stuff like |
| 19:34:57 | dbussink | like, ok, the last 1000 objects of this type used all these ivars, let's pack that |
| 19:34:58 | evan | instance_eval { @name = 1 } |
| 19:35:04 | evan | will add @name to the wrong place |
| 19:35:05 | evan | but thats ok |
| 19:35:26 | evan | it does all the work before an instance of the class is created |
| 19:35:26 | dbussink | well, datamapper defines some readers / writers with class_eval |
| 19:35:44 | evan | when a instance is created, it crystalizes the format |
| 19:35:55 | evan | after than, the format is fixed. |
| 19:36:14 | dbussink | evan: http://github.com/datamapper/dm-core/blob/master/lib/dm-core/model/property.rb#L221-237 |
| 19:36:18 | dbussink | does stuff like that |
| 19:36:40 | dbussink | this is called by property :name, String for example that is in a class body |
| 19:36:57 | evan | that should actualy work ok |
| 19:37:05 | evan | because the class_eval will create the method and add it to the class |
| 19:37:16 | evan | at which time that method will be looked at to see what ivars are used |
| 19:37:30 | evan | so long as this is called before there is an instance of that class |
| 19:37:31 | evan | should be fine |
| 19:37:50 | dbussink | can i easily see what exactly is packed for an object? |
| 19:37:55 | evan | yeah |
| 19:38:03 | evan | the @seen_ivars ivar in class |
| 19:38:05 | evan | just add |
| 19:38:09 | evan | attr_reader :seen_ivars |
| 19:38:45 | dbussink | i'll try with a script to see if it works or not :) |
| 19:39:06 | evan | k |
| 19:39:12 | evan | it happens at method addition time |
| 19:39:18 | evan | not parse time |
| 19:39:19 | evan | which helps |
| 19:39:29 | evan | because meta programming shouldn't defeat it. |
| 19:41:11 | dbussink | evan: hmm, should seen_ivars be on the instance or class? |
| 19:41:19 | evan | class |
| 19:41:22 | evan | sorry |
| 19:41:24 | evan | i meant |
| 19:41:26 | evan | class Class |
| 19:41:28 | dbussink | because it's returning nil on both now for me |
| 19:41:30 | evan | attr_reader :seen_ivars |
| 19:41:30 | evan | end |
| 19:42:42 | evan | dbussink: http://gist.github.com/445211 |
| 19:42:44 | evan | line 17 |
| 19:42:46 | evan | outputs |
| 19:42:51 | evan | [:@name, :@thing, :@more, :@stuff, :@lots, :@crap, :@woo, :@mmmm, :@foo] |
| 19:43:39 | dbussink | evan: hmm, this is returning nil for me: https://gist.github.com/b09acf1dec9a186bd383 |
| 19:44:06 | dbussink | that should go through that whole layer of meta programming though, maybe it gets confused somewhere |
| 19:44:17 | evan | could be |
| 19:44:17 | dbussink | evan: or doesn't it work because that property method comes from a module? |
| 19:44:26 | evan | does it just create accessors and call them? |
| 19:44:33 | evan | does it actually use @<name> syntax? |
| 19:44:56 | dbussink | evan: well, the accessors created do use that, if you look at the code i linked to |
| 19:45:04 | dbussink | evan: http://github.com/datamapper/dm-core/blob/master/lib/dm-core/model/property.rb#L221-237 |
| 19:45:28 | dbussink | evan: instance_variable_name there is something like @id, @name and @age in this example |
| 19:45:34 | evan | what is instance_variable_name? |
| 19:45:37 | evan | k |
| 19:46:52 | evan | what does chainable do? |
| 19:46:56 | dbussink | evan: if i output instance_variable_name and self in that code snippet, i get @id and Person |
| 19:47:04 | evan | a class_eval on the block or something? |
| 19:47:16 | dbussink | evan: ah, that might be it, it creates an anonymous module from the block and then includes it |
| 19:47:21 | evan | thats it. |
| 19:47:33 | dbussink | so people can override it later on with their modules and call super() |
| 19:47:38 | evan | yep |
| 19:47:47 | evan | so the class really doesn't have any ivars |
| 19:47:54 | evan | you're putting them in that anonymous module |
| 19:48:08 | dbussink | but also getting ivars from modules would fix this then right? |
| 19:48:51 | dbussink | evan: yep, removed the chainable to test it and then it works :) |
| 19:49:01 | evan | there are 2 things |
| 19:49:08 | evan | 1) i should teach the code about included modules |
| 19:49:18 | evan | 2) seen_ivars is only the ivars in that exact module |
| 19:49:29 | evan | but at crystalize time |
| 19:49:33 | evan | all the seen_ivars are consulted. |
| 19:50:07 | dbussink | evan: ah ok, so would it be useful to add some __ methods perhaps for this so people can look at it? |
| 19:50:22 | dbussink | evan: or other methods that aren't likely to clash name wise :P |
| 19:50:28 | evan | i could add a method to return the definitive list |
| 19:51:26 | dbussink | that could be useful i guess for people who would want to verify that it works for their objects |
| 19:51:29 | evan | dbussink: after an instance is created |
| 19:51:36 | evan | you can look at @packed_ivar_info on the class |
| 19:51:41 | evan | which shows the mapping of ivar => slot |
| 19:51:52 | evan | that will include ivars found in superclasses |
| 19:52:40 | evan | dbussink: i'll go ahead and add Class.memory_info |
| 19:52:45 | evan | ie |
| 19:52:49 | evan | Class.memory_info(Blah) |
| 19:53:03 | evan | which will report the byte size, packed ivars, etc. |
| 19:53:16 | dbussink | evan: cool :) |
| 19:53:47 | dbussink | evan: funny thing was that sam smoot (who started datamapper originally) was musing about exactly this yesterday in #datamapper :) |
| 19:54:02 | dbussink | that he thought something like this would be really awesome |
| 19:54:03 | evan | hehe |
| 19:54:23 | dbussink | but i'm pretty happy that it's smart enough that besides the included module stuff, it already works :) |
| 19:54:34 | evan | yeah |
| 19:54:43 | evan | by delaying the calculations you can't take back |
| 19:54:46 | evan | it can be pretty smart |
| 19:54:46 | dbussink | guess that means that datamapper internals are also pretty reasonable and do too weird things :P |
| 19:54:55 | dbussink | don't do |
| 19:55:18 | evan | :) |
| 19:55:48 | dbussink | another benefit of being declarative :P |
| 19:55:53 | evan | dbussink: there is already Rubinius.memory_size actually |
| 19:56:04 | dbussink | evan: which i can give a class? |
| 19:56:05 | evan | which is just the byte size |
| 19:56:12 | evan | i think just an object |
| 19:56:23 | evan | i need another one that knows about classes |
| 19:56:29 | evan | and will give info about the classes instances |
| 19:59:59 | dbussink | evan: this is also really the stuff that makes rbx awesome, being able to get information like this from the system etc. |
| 20:03:56 | skaar | evan: is the Rubinius Fiber available by default? I see it in the source tree, but rbx (at least in irb mode) doesn't seem to find it |
| 20:04:32 | cyndis | Rubinius::Fiber |
| 20:12:18 | evan | skaar: the API is experimental |
| 20:12:21 | evan | so it's under Rubinius |
| 20:18:32 | skaar | evan: ah, thanks, got it |
| 20:28:53 | dbussink | finally a pretty exiting world cup match :) |
| 20:30:00 | evan | yeah |
| 20:30:03 | evan | that one was entertaining. |
| 20:30:40 | dbussink | and a good result for the dutch too :p |
| 20:30:58 | dbussink | evan: i was actually surprised by how much attention it gets in the usa |
| 20:30:59 | evan | since you guys killed denmark? |
| 20:31:33 | dbussink | we've qualified now, netherlands will be either first or second in the group now |
| 20:32:14 | evan | the US needs to be beat algeria |
| 20:32:15 | dbussink | denmark and japan have to play for the other place, so they can't both get to 6 points |
| 20:32:28 | evan | at least we control our own fate now. |
| 20:32:44 | dbussink | hehe, and no one else to blame if it fails :P |
| 20:32:49 | evan | yep. |
| 20:33:05 | evan | well, we can blame that ref. |
| 20:33:18 | dbussink | that's true yeah, was a perfectly legal goal |
| 20:33:25 | evan | yeah |
| 20:33:28 | dbussink | but on the other hand, you can thank the english :p |
| 20:33:29 | evan | total bullshit. |
| 20:33:34 | evan | there were 3 fouls in the box too |
| 20:33:36 | evan | by slovenia |
| 20:34:55 | dbussink | haven't seen that match actually, only small parts of the summary |
| 20:35:04 | dbussink | but did see that denied third goal |
| 20:38:32 | evan | I only watched the 2nd half. |
| 20:38:40 | evan | since it was on early here. |
| 20:39:34 | dbussink | actually watched the first game from the netherlands in our bed in the hotel in new york early in the morning :p |
| 20:39:43 | evan | ha! |
| 20:39:55 | evan | i'll bet you were happy :) |
| 20:40:06 | tarcieri | =======<() ~ ♪ ~♫ BZZZZZZZZZZZZZZZZZZZZZZZ |
| 20:40:16 | dbussink | good start of the day :) |
| 20:40:22 | evan | tarcieri: :D |
| 20:41:00 | dbussink | tarcieri: http://i.imgur.com/WXNmF.jpg |
| 20:42:29 | tarcieri | heh |
| 21:05:14 | dbussink | evan: did that manual inlining you did here make a big difference? http://github.com/evanphx/rubinius/commit/0f068f5b84ea873392584116ceb34727902aab68 |
| 23:56:31 | jarib | dbussink: using 1.9.1p378 |