On Tue, Sep 28, 2004 at 07:13:20AM +0900, Mauricio Fern?ndez wrote: > On Mon, Sep 27, 2004 at 01:20:44AM +0900, Alexander Kellett wrote: > > Rubydium works by generating optimized platform specific code > > on the fly, as needed, using instance type information gathered > > during the execution itself. > > > > Optimisations are possible as the generated code can be specialized > > for the types in question, therefore allowing heavy inlining of > > speed critical sections. > > How are you going to implement code cache invalidation? Will you just > detect method redefinitions or is there some better way? ouch, good question :P in the case of non-inlined non-type-specialized methods this is trivial as the dispatcher will be called into again, will have been notifed of the modification to the object model, and will be able to adjust the generated method as needed. however, in the case of an inlined/specialized method, in which a method call from within the specialized parent could result in a object model modification, this becomes slightly more difficult. in this case a kind of "cache exception" would be thrown, the inlined method would be jumped out of, and a new updated method generated and control passed on. > > This preview can execute an primitive subset of the > > Ruby language, its slow, buggy, more complex than i'd > > really like, and will probably make you loose a fair > > amount of hair just getting the preview working :) > > How large a subset? have just been working on some stability improvements to the current engine while trying to find out exactly what sort of stuff could be implemented with the current subset. i've got this nice example running in the latest version :) def strlen str return str.get_element(0) end def putstr str size = str.get_element(0) n = 1 # pos 0 is the length while n < (size + 1) putchar str.get_element(n) n += 1 end end def num_to_s num n = num pos = 0 while n > 0 pos += 1 n /= 10 end t = VByteArray.new t.alloc((pos + 1) * 4) size = pos t.set_element(0, size) n = num while n > 0 ch = ?0 + n % 10 t.set_element(pos, ch) n /= 10 pos += -1 end t end def mul_line sx, sy, y max_num_len = strlen(num_to_s(sx * sy)) alignment = max_num_len + 1 x = 1 while x < (sy + 1) num_str = num_to_s(x * y) num_spaces = alignment - strlen(num_str) c = 0 while c < num_spaces putstr " " c += 1 end putstr num_str x += 1 end end def mul_table sx, sy y = 1 while y < (sy + 1) mul_line sx, sy, y putstr "\\n" y += 1 end end mul_table 12, 12 which produces the very pretty (:P) output: 1 2 3 4 5 6 7 8 9 10 11 12 2 4 6 8 10 12 14 16 18 20 22 24 3 6 9 12 15 18 21 24 27 30 33 36 4 8 12 16 20 24 28 32 36 40 44 48 5 10 15 20 25 30 35 40 45 50 55 60 6 12 18 24 30 36 42 48 54 60 66 72 7 14 21 28 35 42 49 56 63 70 77 84 8 16 24 32 40 48 56 64 72 80 88 96 9 18 27 36 45 54 63 72 81 90 99 108 10 20 30 40 50 60 70 80 90 100 110 120 11 22 33 44 55 66 77 88 99 110 121 132 12 24 36 48 60 72 84 96 108 120 132 144 (note the code doesn't reflect ruby's api basically out of pure lazyness on my part, it would be possible to use ruby's object model / naming schemes however i just quickly hacked this together in a half hour :)) > > However, its a proof of concept that does show that > > The Twist is implementable using the libjit library. > > How does libjit interact with low-level things like OS threads? as far as i can tell (and as far as the libjit documentation reports) this should be no problem :), this is principally a question of making sure that the standard library is reentrant. however as 90% of the standard lib will be implemented in ruby itself. i see no reason why not :) > > Any failed tests?, first please check that you actually do have an > > interpreter build of libjit rather than a x86 backend build. If you're > > certain that there are other errors, feel free to email me the failure > > reports :) > > Do you know when it will become possible to use the x86 backend? the libjit x86 backend doesn't implement some of the more esoteric features that i've used. hopefully i'll be able to get this up and running in the near future :) > And how big a speed increase can be expected relative to the interpreted VM? in a quick benchmark 1000 calls to method with an 10000 iteration loop took 22 seconds with ruby. and exactly the same with rubydium :) this is as currently no inlining of the calls is performed thusly an actual ruby method call (to dynamically generate the method) takes place for every call. i've benchmarked libjit quickly, a gcd (greatest common denominator) benchmark takes 15 seconds. this is in comparison to 30 seconds for a non optimised gcc. 12 seconds for -O3 gcc (though the compile takes 3 seconds :P). and... well... lets say a "while" longer for ruby :) (an hour based on a quick sample) i would hope that for that particular benchmark, rubydium will be able to achieve the 15 second time within the coming 6 months of development. hope that helped answer your questions :) cheers, Alex