Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
Brian Shirai
@brixen
the header bits structure is pretty nice
Brian Shirai
@brixen
pinned is out, no obvious errors
Brian Shirai
@brixen
that was quite a laborious change to pass the address of the object into the collector trace method
but now the stage is set for Immix evacuation, and that's very exciting
probably will clean up Immix a bit more first and implement the thread local allocator using Immix holes first
oh, before any of that, I'll make the collector partially recursive, which will reduce the work to maintain the mark stack
Brian Shirai
@brixen
oh @chuckremes do I have a little treat for you
May 28 22:56:01 [43265] <Warn> Therad id: 3 updating an instance of CompiledCode created by Thread id: 1
and
rubinius 4.1.c1 (2.3.1 9bef0d76 2019-05-28 8.0.0) [x86_64-darwin18.6.0]
Ruby Exception hit toplevel:
Thread id: 3 updating an instance of CompiledCode created by Thread id: 1 (RuntimeError)
it is very very blunt right now (all or nothing), but there are two options, log or raise (or both)
I'll figure out how to make it more subtle, but to start, logging should give a lot of info
the raising option would need so rescue case probably high up
so a combination of compile-time raise option and run-time rescue option could make this quite workable
   --log-concurrent-update    Log when T2 updates an object created by T1
   --raise-concurrent-update  Raise a RuntimeError when T2 updates an object created by T1
Brian Shirai
@brixen
@chuckremes just pushed that code
I'll add some niceties probably tomorrow
since I have the MemoryVisitor now, I need to implement become as well, which will make programming proxies really nice :grinning:
another thing we can do with MemoryVisitor is search a subgraph of the object graph, say from an explicit set of 1+ "roots" instead of the graph roots
I should expose some nice methods for that in Rubinius::Memory
Chuck Remes
@chuckremes
those are treats!
will play with them soon
Brian Shirai
@brixen
gotta figure out what's happening with the rubinius log file lock deadlock
Brian Shirai
@brixen
@chuckremes I’ve made it through my list above pretty quickly, and while I’ve got more to do on the GC (including tracking down nokogiri issue), I’m curious what would be the next most useful thing for you?
Brian Shirai
@brixen
thinking about the JIT, here are some things that are important:
  1. I want to respect "do a little, get a little; do a lot, get a lot";
  2. by using functions as the interface between nanopasses, we can leverage f: A -> B, g: B -> C for composition of passes;
  3. we need an explicit mechanism for describing dependencies independent of the function composition;
  4. then 2 and 3 give us the ability to parallelize compilation where dependencies for pass B(i) are met by an B(i-n), n >= 1
I wish it was easy to do subscript
Brian Shirai
@brixen
the "do a little, get a little" is really important because the old JIT was "do a lot, get a little" and deterred people from contributing
Brian Shirai
@brixen
@chuckremes ok, you need to configure with --{log, raise}-concurrent-update and then you can run rbx with -Xmachine.concurrent.update.{log, raise}=true
I need to make one more change to set the thread_id of the Thread and not Fiber into the object header
since all Fibers attached to a Thread should be able to update an object created by anything on that Thread
Chuck Remes
@chuckremes
@brixen let me just recap what i think i’ve got now in rbx
  1. a logging facility that will tell me when there is cross-thread access (or just mutation?)
  1. the ability for the aforementioned logging facility to raise on cross-thread access (mutation?)
  1. better GC
question: are the isolated heaps implemented yet or just this logging mechanism? if implemented, are they exposed to Ruby-land so I can say Thread.new(heap: :isolated) or Thread.new(heap: :shared) or something?
back to your question… i have a long wish-list but i think i need to subordinate my desires now for something that this community needs which is a taste of the JIT
we want to entice some folks back into the fold but pretty much everyone runs for the hills when they see the current performance levels; if you could spike out a few nanopasses and get some inlining or peephole optimization or onstack replacement or whatever working to boost regular perf then that would be great
Chuck Remes
@chuckremes
so that’s number 1 on my list now :)
Brian Shirai
@brixen
@chuckremes the log or raise on concurrent update is only mutation across threads, and I don't have a mechanism yet to transfer ownership, but that isn't much work, I'll add it
there are a lot of improvements to the GC, more to do
isolated heaps are not yet in, I'll add back thread-local allocation first, and then the ability to create isolated heaps
the isolated heaps need something like "main()", which will be a function, and they won't be able to use Ruby classes unless I come up with a reasonable method to inject those references
the "closed" heaps, which all pointers out of the heap, but not into the heap, can use Ruby classes
I hear you on the JIT, I'm on the same page, so I'll get some basic functions in, and then spike some JIT functionality
Chuck Remes
@chuckremes
great!
Brian Shirai
@brixen
so, this hang is really nasty because the lock being waited on is ultimately in the clib :sob:
a call to localtime_r is calling tzsetwall_basic and that's trying to aquire a lock that is not held in this process
the only thing I can think of is that the lock is held in the parent before fork()
which means that we're racing the logger when forking, but I can't figure out how