Apparently it still wasn't clear what the issue was, given we still got issues opened on this problem. Make it even more explicit so people hopefully read it all now and know how to solve it.
This allocates a ByteArray without zero'ing all the memory. This is for example useful when used in String::create, where the memory will be overwritten anyway. Other cases are where ByteArray used as backing store for Bignum and Regexp.
This code produces a crash: class Foo def __finalize__ end end foo = Foo.new ObjectSpace.define_finalizer(foo) GC.run(true) When run: --------------------------------------------- CRASH: A fatal error has occurred. Backtrace: ./bin/rbx[0x4a5370] /lib/x86_64-linux-gnu/libc.so.6(+0x364a0)[0x7f5ab242e4a0] ./bin/rbx(_ZN8rubinius7BakerGC15walk_finalizersEv+0x69)[0x619bd9] ./bin/rbx(_ZN8rubinius7BakerGC7collectERNS_6GCDataEPNS_17YoungCollectStatsE+0x3a1)[0x61a031] ./bin/rbx(_ZN8rubinius12ObjectMemory13collect_youngERNS_6GCDataEPNS_17YoungCollectStatsE+0x66)[0x549de6] ./bin/rbx(_ZN8rubinius12ObjectMemory13collect_maybeEPNS_5StateERNS_11GCTokenImplEPNS_9CallFrameE+0x160)[0x54a170] ./bin/rbx(_ZN8rubinius2VM13collect_maybeERNS_11GCTokenImplEPNS_9CallFrameE+0x3f)[0x57f2ff] ./bin/rbx(_ZN8rubinius6System11vm_gc_startEPNS_5StateERNS_11GCTokenImplEPNS_6ObjectEPNS_9CallFrameE+0x31)[0x5e5091] ./bin/rbx(_ZN8rubinius10Primitives11vm_gc_startEPNS_5StateEPNS_9CallFrameEPNS_10ExecutableEPNS_6ModuleERNS_9ArgumentsE+0xcf)[0x50e20f] ... ObjectSpace.define_finalizer stores cTrue as a finalizer placeholder in this case. And when GC runs, it doesn't consider there may be immediates and dereferences that cTrue. Thereby, a crash is waiting for you. :p
The JIT thread itself managed the GC state of LLVMState, so we shouldn't interfere with that logic from the compile_soon logic that actually gets executed by another thread. Fixes #2226
StringIO works like an IO object and basically operates on strings as them being byte arrays without encodings. This fixes a bunch of test failures on Nokogiri as well, which uses a StringIO internally and got results back with the wrong encoding. Also fixes #2163 because the wrong encoding came out, because the encoding aware methods used in StringIO before would change the encoding if a ASCII-8BIT string was written to the StringIO. With this change, they retain the original encoding, so things come out in the right encoding from Nokogiri.
This uses the return value of the insert to determine if the value was already in the set or not, so we only reference it if it was newly added.
When flushing handles, it can happen that new handles are added to the set. This mainly happens for cases where we flush an RArray handle, because that also gets handles for all elements in the array. std::tr1::unordered_set doesn't give the insert guarantees we need, namely: Iterator validity On most cases, all iterators in the container remain valid after the insertion. The only exception being when the growth of the container forces a rehash. In this case, all iterators in the container are invalidated. So if a rehash is forced, all iterators are invalid. This means we have undefined behavior that can result for example in crashes (which was happening in the Nokogiri test suite for example). std::set explicitly states it doesn't affect iterator validity, so it doesn't suffer from this problem. The downside is less performant insert() but there isn't really another option without redoing this completely.
This fixes the following valgrind error: ==13303== Thread 4: ==13303== Conditional jump or move depends on uninitialised value(s) ==13303== at 0x7826ED: rubinius::Inliner::inline_for_class(rubinius::Class*, int) (inline.cpp:159) ==13303== by 0x782312: rubinius::Inliner::consider_mono() (inline.cpp:35) ==13303== by 0x7A9EFE: rubinius::JITVisit::visit_send_stack(unsigned long, unsigned long) (jit_visit.hpp:1481) ==13303== by 0x7A1CD6: rubinius::VisitInstructions<rubinius::JITVisit>::dispatch(int) (jit_visit.hpp:1565) ==13303== by 0x7A1426: rubinius::jit::Walker::call(rubinius::OpcodeIterator&) (jit_builder.cpp:554) ==13303== by 0x7A11B4: void rubinius::jit::ControlFlowWalker::run<rubinius::jit::Walker>(rubinius::jit::Walker&) (control_flow.hpp:49) ==13303== by 0x79FB30: rubinius::jit::Builder::generate_body() (jit_builder.cpp:591) ==13303== by 0x788576: rubinius::Inliner::emit_inline_block(rubinius::JITInlineBlock*, llvm::Value*) (inline.cpp:648) ==13303== by 0x78809A: rubinius::Inliner::inline_block(rubinius::JITInlineBlock*, llvm::Value*) (inline.cpp:284) ==13303== by 0x7AD231: rubinius::JITVisit::visit_yield_stack(unsigned long) (jit_visit.hpp:2709) ==13303== by 0x7A1E55: rubinius::VisitInstructions<rubinius::JITVisit>::dispatch(int) (instruction_visitors.hpp:62) ==13303== by 0x7A1426: rubinius::jit::Walker::call(rubinius::OpcodeIterator&) (jit_builder.cpp:554) ==13303== This valgrind error is introduced by this commit: a787d83 Don't inline calls for not often called methods