Index

Show enters and exits. Hide enters and exits.

00:00:01boyscoutCleanup GC specs, remove useless tests. - dafae6c - Evan Phoenix
00:00:01boyscoutStub out GC methods, pass all specs. - abee1a2 - Evan Phoenix
00:00:01boyscoutUse mock_numeric rather than NumericSub - 3b13360 - Evan Phoenix
00:00:01boyscoutClarify edge case in Numeric#coerce specs - e688abf - Evan Phoenix
00:00:01boyscoutFix Numeric#ceil and Numeric#floor - 4f211f3 - Evan Phoenix
00:00:02boyscoutAdd Numeric#coerce class checking - c2fef06 - Evan Phoenix
00:00:04boyscoutGet the numeric tower more compatible with MRI. - e315ca0 - Evan Phoenix
00:04:04boyscoutCI: rubinius: e315ca0 successful: 3024 files, 11768 examples, 36003 expectations, 0 failures, 0 errors
00:53:39rueFFS
01:27:06boyscoutFix UnboundMethod#name to return a String, not a Symbol - a01c37d - Evan Phoenix
01:27:06boyscoutFix some Enumerable edge cases - e871a59 - Evan Phoenix
01:27:06boyscoutClean up Comparable - 5dcfdb1 - Evan Phoenix
01:41:36boyscoutCI: rubinius: 5dcfdb1 successful: 3024 files, 11770 examples, 36007 expectations, 0 failures, 0 errors
03:27:29boyscoutENV.index: implementation - 9957f99 - Marc-Andre Lafortune
03:31:28boyscoutCI: rubinius: 9957f99 successful: 3024 files, 11770 examples, 36007 expectations, 0 failures, 0 errors
19:20:27kstephenscan anybody point me to documentation/examples on how to interface a write-barrier GC into rubininus?
19:20:46evanthere is none of those things
19:20:57evanthere is really just the code for the existing one
19:21:04rueThough the GC already uses a write barrier
19:21:12kstephensI have a real-time GC i've written that i'd like to try out.
19:21:42kstephenshttp://kurtstephens.com/pub/tredmill/current/doc/html/index.html
19:22:51evanwell
19:22:58evancheck in ObjectMemory
19:23:00kstephensit requires no separate GC thread, and is guaranteed to have bounded time during allocation.
19:23:04evanObjectMemory::write_barirer
19:23:23evanyou'd put a write barrier in there.
19:24:03kstephensdoes that generate LLVM code? or is it just called from LLVM compiled code?
19:24:17evanneither.
19:24:23evanwell, LLVM calls that if it needs to.
19:24:34evanbut thats pretty rare.
19:24:34kstephenshow does LLVM decide?
19:24:53evanthere isn't a lot of JIT generated code that directly manipulates references
19:25:08kstephensso it doesn't hit the write barrier before all object mutations?
19:25:11evanbecause CallFrame accessible references are always checked.
19:25:20evanso we don't run the write barrier for them.
19:25:46kstephensCallFrame is essentially the stack?
19:26:20evanyeah
19:26:54kstephensmy GC may not require stack or global root write-barrier, if you configure it to make the root mark phase to be atomic.
19:27:25evani thought treadmill required a read barrier
19:27:30evanto keep the object color correct.
19:27:31kstephensso what I'm looking for is a hook, where any mutations to objects allocated from the GC, will hit the write barrier first.
19:27:47kstephensmy implementation uses a write barrier.
19:27:48evanoh
19:27:49evanfirst?
19:27:55evanit's always run after.
19:27:56evanatm.
19:28:01kstephenssorry, i meant "after"
19:28:18evanhuh?
19:28:22evansay what you mean again.
19:28:23kstephensmaybe this is more of an LLVM question.
19:28:50kstephensso what I'm looking for is a hook, where any mutations to objects allocated from the GC, will hit the write barrier after the mutation.
19:29:23kstephensbut I must be able to guarantee that no allocations will occur between the mutation and calling the write barrier.
19:29:42evanok, thats true.
19:30:54kstephensif stack frames are not allocated through the GC, i dont need a write barrier for those mutations.
19:31:41kstephensDoes LLVM ever allocate objects on the stack?
19:31:54evanof course not.
19:32:09evanyou can never do that in a GC.
19:32:26evanit allocates some data structures on the C stack, like the CallFrame
19:32:40evanbut GC objects are only ever allocated by the GC.
19:32:41kstephenswell, some system do use alloca() as a hemispace pointer: see chicken scheme.
19:32:54evanfuck no.
19:33:01evanthat sounds like a lot of pain.
19:33:28kstephenswell, not really. makes continuations a piece of cake.
19:33:49evanwell
19:33:51kstephensin fact ordinary C code cant tell the difference.
19:33:58evanthat sounsd like something else
19:33:59kstephens... that is linked in.
19:33:59evananyway.
19:34:18evanwhat do you want to know
19:34:28evanputting code in ObjectMemory::write_barrier is probably what you want
19:34:57kstephensand where would I interface calls to GC allocation?
19:36:09evanObjectMemory::allocate_object
19:36:18evanis where all allocations go through
19:36:34kstephensgreat, thanks!
19:36:43evanwell, ObjectMemory::allocate_object_mature too.
19:37:04evanyou'll need to read BakerGC::collect though
19:37:12kstephenshmm, what's that for?
19:37:16evanfor how to find the roots.
19:38:05evanBakerGC is semispace collector.
19:38:10evanused for the young generation.
19:38:16kstephensTM keeps a list of root spaces, but I should probably add a root scan callback.
19:38:29evanroot spaces?
19:38:50kstephensregions of memory that contain roots.
19:39:00kstephens(or potential pointers) rather.
19:39:09kstephensTM is conservative.
19:39:37evanwell
19:39:52evanyou'll need to directly mark the roots rubinius gives you
19:40:01evanbecause the roots can spread out.
19:40:02kstephensI can add a callback for that.
19:41:06kstephensis the BakerGC compacting?
19:41:12kstephens... just curious.
19:41:26evanoh yeah
19:41:28evanbigtime.
19:41:30evanso
19:41:42evani guess you haven't work with rubinius before?
19:41:47kstephensnope
19:42:06kstephensat some point you weren't using LLVM, right?
19:42:21evanyeah, we introduce LLVM
19:42:25evanas the JIT
19:42:29evanbut you can run rubinius without it.
19:42:33evanif you need.
19:42:41kstephensbytecode?
19:42:53kstephensor AST traversal?
19:43:14kstephensor native code gen?
19:43:26evanbytecode
19:43:30kstephensI guess if it was AST it wouldn't be faster than MRI 1.8.x
19:43:31evanhow did you hear about rubinius?
19:43:44evanfeels like this is the first day you're looking at it :)
19:44:22kstephensmostly watching how you guys in ruby-core list are trying to nail down how MRI really behaves :)
19:45:01kstephenslanguage lawyers prevent confusion.
19:45:47evanah, so this is the first time you're looking at rubinius, and thusly the insides.
19:45:59kstephensmy interest in rubinius because MRI is kinda dead from the optimization and GC architecture angle.
19:46:27kstephensI've peeked around a bit and built it, but now its time to get my hands dirty.
19:46:55evanok
19:47:05evanso, rubinius has always had an accurate GC
19:47:16evanso it's possible that there are things that depend on it
19:47:24evanthat i can't think of right now
19:47:58kstephensconservative < accurate: as far as assumptions go.
19:48:14evanyeah
19:48:25evanyou're more than welcome to play around, of course
19:48:30kstephensI have an write barrier that can take accurate pointers or not-so accurate pointers.
19:48:31evanbut why would you want a conservative GC?
19:48:38rueI am glad my "subtle" hints at avoiding trying to fix MRI GC were heard :P
19:48:54kstephensThe conservative part is not what I'm after, its the bounded allocation time.
19:49:11kstephensthe real-time aspect of TM is where I think it applies here.
19:49:25evanwell
19:49:33evanrubinius GC allocation time is bounded atm.
19:49:35kstephensThe conservative part is mostly due to how I think it might work with non-GC aware libraries.
19:49:45evanit never GCs on allocation
19:49:52evanthe allocator sets a hint
19:50:00evanthat is seen later on and the GC is run
19:51:02kstephensdoes rubinous ever call malloc() directly (i.e. via C++ new operator, for example?)
19:51:31evansure
19:51:36kstephensok
19:51:42kstephensthat's what I figured.
19:51:43evanwhy?
19:52:01evanall the VM internal data uses either malloc() or now
19:52:01kstephensI'll need to disable my malloc() hook.
19:52:02evaner. new.
19:52:11evanah ok.
19:53:46kstephensi'm not sure my work will improve rubinius, but MRI is not a good research platform.
19:54:04evansurely
19:54:15evani've tried to keep interfaces clean inside the VM
19:54:21kstephensi can tell
19:54:31evanso you should only have to touch a few points to change it
19:54:57kstephensfrankly I like that its written in C++.
19:55:06kstephensC++ is the new assembler.
19:55:17evan:) i live that it is too
19:55:24evanit's made it easier to develop that doing it in C
19:55:45kstephensyup
19:56:29kstephensThanks for answering my questions.
19:56:34evanno problem!
19:56:36kstephensGood info.
19:56:40evani'm happy to help
19:56:43evanlet me know what i can do
19:57:10kstephenstnx
19:59:54kstephensoh, one last question: how difficult would it be to generate in-line LLVM code for the write barrier, instead of calling a function?
20:00:20evanpretty easy
20:00:42evanyou'd just detect when to emit it
20:00:46evanand emit it as LLVM IR
20:00:49kstephensis that something you have planned?
20:00:56evansure.
20:00:58evan:)
20:01:40kstephensdo you ignore mutations that store immediates? (Fixnums, etc?)
20:02:07evanwhen I can
20:02:12kstephenscool.
20:02:19evanthe write_barrier has code to ignore immediates later on
20:02:26evanso they never get to the real meat
20:03:36kstephensreference & 1 => Fixnum?
20:03:39kstephenslike MIR?
20:03:42evanyeah
20:03:45evancheck out oop.hpp
20:03:46kstephenss/MIR/MRI/
20:03:57evanall the rules are in there
20:04:03kstephensgreat, great!
20:16:59evanoop
20:17:01evanwoop!
20:17:07evanall tags removed for Numeric.
20:17:22brixensweet!
20:21:14boyscoutRemove Range tags - 86fe1ee - Evan Phoenix
20:21:14boyscoutFix Method#name to return a String - d309394 - Evan Phoenix
20:21:14boyscoutFix coercion of the argument to Kernel.exit - d423726 - Evan Phoenix
20:21:14boyscoutRemove some Numeric tags - cf92226 - Evan Phoenix
20:21:14boyscoutMore Numeric tower revisement - cdbd761 - Evan Phoenix
20:21:15boyscoutFinish cleaning up Numeric failures - ad7a5eb - Evan Phoenix
20:23:49evanwtf
20:24:00evanwhy is there a random StringIO spec in io/print_spec.rb
20:24:17brixenwho knows
20:24:29evanok, i'm deleteting it.
20:24:49evani'm double checking the blame
20:25:02brixenwhich spec?
20:25:34brixenthis whole file is all kinds of what the fuck why do I try?!
20:25:36brixengoddamn
20:26:02evan:/
20:26:03evanhttp://github.com/rubyspec/rubyspec/commit/71bcaf058c7ddaf3cdb3452e950e8a286df13dde
20:26:30evanhe completely changed WHAT was being spec'd.
20:26:33evan:/
20:26:57brixenyeah
20:27:36rueValid reason for the change, probably, but a...sub-optimal implementation :P
20:27:48evanwell
20:27:52evanbut it's a spec for IO#print
20:27:57evanand the spec doesn't call IO#print...
20:28:05brixenright
20:28:23rueYes, it would be wrong even if StringIO < IO, which it is not :)
20:28:34evanexactly.
20:28:51evani'm checking the behavior on MRI now
20:28:56evanand i'll rewrite this test.
20:29:00brixenthis spec should use ruby_exe instead of any mock
20:30:46boyscoutCI: rubinius: ad7a5eb successful: 3024 files, 11791 examples, 36079 expectations, 0 failures, 0 errors
20:31:10evanso, it appears that IO#print calls IO#write, which should call #to_s and if the result is not a String, then uses rb_any_to_s
20:31:22evanwhich is the "#<0x... class>" thing
20:32:07evanbrixen: should I use the output matcher?
20:32:50rueThe output matcher is just for actual output, unless it was changed
20:33:54evan o = mock('o')
20:33:54evan o.should_not_receive(:to_str)
20:33:56evan o.should_receive(:to_s).and_return("hello")
20:33:58evan lambda { $stdout.print(o) }.should output("hello#{$\}")
20:34:00evanthat passes
20:34:13brixenok
20:34:19evanthat ok?
20:34:41brixenI think it should use ruby_exe, but I'm looking at output matcher now
20:34:59brixenI'd rather it not have anything in the path of IO#print
20:35:36brixenthe output matcher uses IOStub
20:35:39evanwell, this is IO#print, so i can print to a tempfile or something
20:35:48evanno need to use $stdout
20:36:05evanin fact, this jumps through hoops to use $stdout
20:36:31brixenyou can just use ruby_exe and compare on the output
20:36:47brixenwhich will more naturally use $stdout
20:36:47evando you have an example i can look at?
20:37:06brixenruby_exe("some code").should something
20:37:12brixenack ruby_exe ;)
20:37:24evanis that better than the output matcher?
20:37:36brixenwell, output matcher uses IOStub
20:37:40evanseems like launching another process is less elegant than using output matcher
20:37:46evanI don't know what IOStub is.
20:37:57brixenit's an object that fakes an IO
20:38:04brixenbut we are testing an IO method
20:38:07evanoh
20:38:10evaneeeeww
20:38:13evanok
20:38:14brixenseems silly to say we are testing it while using a fake
20:38:19evanwhy not a tempfile?
20:38:31brixenhence, ruby_exe("print something").should == "something"
20:38:31evanyeah, we clearly can't use the output matcher
20:38:34brixenor a tmp file
20:38:38evanit's completely changing what we're specing
20:38:42brixenright
20:38:46brixenthat was my point
20:38:53brixenyou can use a tmp file
20:38:57evanwhat about this output_to_fd() matcher
20:39:07evandoes that use IOStub too?
20:39:19brixenit writes to a tmp file
20:40:08evanok, it uses a reopen trick.
20:40:18evanis there an easy way to use a temp file?
20:40:21brixenit already does
20:40:35brixenlook at mspec/lib/mspec/matchers/output_to_fd.rb
20:40:38evanall the reopen tricks aren't needed
20:40:41brixenI think that's all you'd want to do
20:40:44evancan i just use tmp() ?
20:40:47brixenyes
20:40:54evanand they'll get cleaned up automatically?
20:40:58brixenno
20:41:20evanok
20:41:28evanwell do they atleast go in the right directory?
20:41:45brixenlet me write the spec
20:41:53evanno let me!
20:41:55evanyou write too many!
20:42:01brixenthis is "does not call obj.to_str" ?
20:42:14evanyeah
20:42:16brixenk
20:42:24evanok, i'll get it right
20:42:28evani see what to do
20:42:34brixenso you need a file name: name = tmp("io_print")
20:42:46evanyou know what would be awesome?
20:42:49brixenbut you need to delete it
20:43:01evanif tmp took a block and did File.unlink on it in an ensure
20:43:25brixenhm
20:44:01brixenoften one name is used multiple times though
20:44:13evanok, no prob.
20:45:28brixenhttp://gist.github.com/288138
20:45:45brixentmp() just returns a filename
20:45:59brixenyou can open it or do whatever you want
20:46:22brixentouch(name, mode="w") takes an optional block
20:46:45evanhttps://gist.github.com/cfce939506c25ba8c225
20:47:08brixenno begins and ensures in specs
20:47:14evanok..
20:47:15brixenthat's what before/after actions are for
20:47:36evank
20:47:42brixenall that extra stuff to tmp() is unnecessary
20:47:50brixenjust tmp("io_print")
20:49:57evanhttps://gist.github.com/e8570700096db43f5548
20:50:01brixenyou could do touch(@name) { |f| f.print o }
20:50:55brixenthis seems more complicated that it needs to be
20:51:07evanok
20:51:09evanreally?
20:51:10brixenhmm
20:51:11evannot to me.
20:51:23evanput the data in the temp file
20:51:25brixennot just this one spec, the process
20:51:28evanread it back out and check that it's what you expect.
20:51:35brixenright
20:51:40brixenwell, that's what output_to_fd does
20:51:57evanbut you need an IO to do that already
20:52:05evanand using $stdout is needless
20:52:14evanoutput_to_fd depends no IO#reopen
20:52:22evanand it's trivial to avoid having that dependency
20:52:39evans/depends no/depends on/
20:52:54brixenone sec
20:55:30brixenevan: I just pushed to your gist
20:56:03evanok, so just use IO.read
20:56:12brixentouch and rm_r, yes
20:56:42evanok, cool
20:56:44evani'll commit this
20:56:48brixenk
20:57:16DefilerThere's not a File method that means 'this process could create a file in the given directory', right?
20:57:39evanaccess is the method in C
20:57:45brixenevan: I think the block form of tmp() would be good for these type of IO specs
20:57:54evanbrixen: yep.
20:58:02evanDefiler: i'm not sure access() is exposed
20:58:05brixenevan: maybe even redoing output matcher to use that
20:58:12evancool
20:58:46brixengrabbing some lunch, I'll look at that after
21:00:05evanditto.
21:10:14boyscoutFix IO#print spec to actually test IO#print - 86fb947 - Evan Phoenix
21:10:14boyscoutRemove IO#print tags - d0f1971 - Evan Phoenix
21:10:14boyscoutCleanup the IO#print specs - 4f2bc22 - Evan Phoenix
21:10:58rueOh, I thought #output was #output_to_fd
21:12:30rueGoing through File is not necessarily a good idea if trying to test IO
21:13:13evanmuch better than depending on IO#reopen
21:13:14evanimho.
21:13:47rueI disagree, provided #reopen can be specified. Only circular dependencies are bad
21:14:10boyscoutCI: rubinius: 4f2bc22 successful: 3024 files, 11791 examples, 36082 expectations, 0 failures, 0 errors
21:15:11rueThen again File and IO have virtually no proper separation so it is somewhat academic.
21:16:36evananyway, lunch.
21:26:28dbussinkevan: are you ok with some helper method on a string that basicly cuts x bytes off by decreasing @num_bytes and @characters?
21:59:56evandbussink: why does that need to be a method?
22:00:06evanjust do @num_bytes -= total
22:00:11evani should just remove @characters.
22:00:14evanwe've never use dit.
22:13:46evanman
22:14:03evanpeople really need to take more than 1 second in naming and grouping their it blocks
22:14:06evangeez.
22:22:18brixenindeed
22:27:44Zoxcwants a function to get the real name of a file on a case insensitive filesystem :(
22:28:14evanuse ls.
22:28:19evanor just read the dir
22:28:49Zoxcdoesn't know how to read the file stations on Windows
22:28:55evanDir["#{path}/*"].find { |i| i.downcase == orig.downcase }
22:34:39ZoxcI wrote this thing: http://pastie.org/797847
22:34:50Zoxcwhich only works for relative paths
22:38:48evanfun
22:40:25Zoxcand I cleaned it up ^^ http://pastie.org/797858
22:40:54evanyou probably just need File.expand_path
22:40:56evanrather than using Pathname
22:41:05evanFile.expand_path cleans up the path pretty darn well.
22:41:25Zoxcyeah, that will probably be faster
22:41:35Zoxcthen I only got to convert into a relative path again :D
22:41:46evanoh
22:41:50evanFile.expand_path does that too
22:41:59evanFile.expand_path(dir, Dir.getwd)
22:42:50Zoxcno, it just use that other parameter as the current directory
22:43:13evanm, yes.
22:43:15evanmy mistake.
22:43:41kronos_vanohttp://isitruby19.com/ may be clone it for rubinius? "isitrubinius.com" :D
22:44:07evanif you want, sure.
23:20:39yakischlobathey should be a single site :/
23:21:15evani wouldn't argue with that either.
23:22:31yakischlobai duno why there should be 3 identical sites instead of just listing compatibility and sorting comments per ruby implementation
23:35:12evanok, finally implemented IO#ungetc
23:35:22evanthere is one failing spec that i'm going to leave failing
23:35:28evanit's stupid.
23:37:11lopexisitruby186p342.com ?
23:37:48brixenevan: which?
23:38:06evannot the spec, the behavior.
23:38:18brixenyeah, curious which it is
23:38:21evanit's a bug in 1.8
23:38:24evanthat is fixed in 1.9
23:38:28evanit "raises IOError when invoked on stream that was not yet read"
23:38:29brixenah
23:38:47evanin 1.8, you can't call #ungetc until you've called #read at least once.
23:38:52evanwhich is dumb.
23:38:53brixenshould be probably be a ruby_bug then
23:38:56brixenfixed in 1.9
23:39:03evank
23:39:04evanok
23:39:33brixenhmm yeah
23:39:44brixenI would have made this a ruby_bug instead of ruby_version_is
23:39:56brixenbut then, probably pointless to file a bug ticket on 1.8
23:39:57brixen:/
23:40:10evanso given that it's changed in 1.9
23:40:21evando i need to find down a ruby-core bug number or anything?
23:40:37brixenwell, that's what I mean, they probably will just ignore it
23:40:38brixenlike http://redmine.ruby-lang.org/issues/show/2578
23:40:41brixenso dunno
23:40:51brixenmight as well file a ticket
23:41:03brixenthere's no reason that should be not considered a bug, would you say?
23:41:19evanwell, lets see.
23:42:46brixenhm, I wonder...
23:42:46evanso
23:42:54evani'm betting this was not a "bug"
23:42:59evanso much as they fixed the behavior in 1.9
23:43:04evanbecause 1.9 has it's own buffer code
23:43:15evanit's not just using FILE's stdio functions
23:43:31brixenthat's just what I was wondering
23:43:49brixenlooking at man ungetc, i don't see whether it fails if *stream had not been read
23:44:11evansurprise!
23:44:13brixenit says it allows as much pushback as there is sufficient memory
23:45:00evanyeah
23:45:09evanwell, it doesn't. :)
23:45:15evanit's an edge case.
23:45:21evanwhere there is no back buffer allocated yet
23:45:22evani think.
23:46:54brixenhmm
23:47:11brixen"The file-position indicator is decremented by each successful call to ungetc(); if its value was 0 before a call, its value is unspecified after the call."
23:47:43evan*shrug*
23:48:01evanMRI's IO#ungetc in 1.8 is a very thin wrapper around ungetc
23:48:25brixenyeah, I get EOF doing ungetc on a stream I haven't read from
23:48:37evanoh actually.. i wonder if it's this first condition in 1.8
23:48:43evan if (!(fptr->mode & FMODE_RBUF))
23:48:55evani'll bet it is
23:49:17evanyeah, that this code just sucks
23:49:26evanbecause RBUF mode is set by a bunch of random things
23:49:31evanincluding by a bunch of read methods
23:49:37evanso it's a bad edge case.
23:50:02brixenhm, I was wrong
23:50:06brixenI was using an empty file
23:50:19brixenI just opened a non-empty file and did ungetc without reading
23:50:45brixenthe next read get the char I ungetc'd
23:51:07evanit blocks named like
23:51:09evan it "can handle any numerical argument without breaking" do
23:51:11brixenso this is just a wonky 1.8 behavior resulting from its weird way of implementing IO
23:51:14evannot very useful.
23:51:22brixenyeah, love those specs
23:51:27brixenit "works" do
23:51:30brixenmmkay
23:52:01brixenhm, I hate cases like this...
23:52:28brixenon the one hand, it's a totally useless spec because is any app code going to depend on *failing* in this particular way?
23:52:44brixenon the other hand, it's a difference between 1.8 and 1.9
23:52:59brixenI'd say rm the 1.8 spec and leave the 1.9 one
23:53:16evank
23:53:24brixenwhat do you think?
23:53:47evanseems logical to me
23:54:08evanwait
23:54:09brixenalternatively, we could file a bug on 1.8
23:54:13evanaren't IO#seek and IO#pos= the same?
23:54:33brixeni thought so
23:54:44evanhah
23:54:47evanso in MRI
23:54:53evanthey're 2 different functions
23:54:57evanwith pretty much the same code in them.
23:55:03brixenwell, #seek can take a WHENCE
23:55:05brixenarg
23:55:33brixen#pos= is like #seek(off, SEEK_SET)
23:55:35brixenI think
23:55:37evanyep.
23:58:53evanIO#pos= and IO#seek almost need a shared spec
23:59:01evanbecause the same person seems to have written them
23:59:09evanbut they got better as they went on
23:59:17evanso the pos= ones are slightly better.
23:59:23evanbut they're basically the same
23:59:27evani'm going to at least fix them box
23:59:29evanboth