Permalink
Switch branches/tags
Commits on Mar 26, 2013
  1. Fix Crash with ObjectSpace.define_finalizer(obj)

    ryoqun committed Mar 26, 2013
    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
  2. Don't return before waking up condition

    dbussink committed Mar 26, 2013
    Fixes #2220
  3. Don't setup GC state around waiting for JIT requests in sync mode

    dbussink committed Mar 26, 2013
    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
  4. Make StringIO operations byte based

    dbussink committed Mar 26, 2013
    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.
  5. Prevent having to search twice when adding handle to slow handle set

    dbussink committed Mar 26, 2013
    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.
  6. Use std::set since it never invalidates on insert()

    dbussink committed Mar 26, 2013
    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.
  7. Merge pull request #2235 from ryoqun/valgrind-error-hits

    dbussink committed Mar 26, 2013
    Set hits to 0 for inline block's JITMethodInfo
  8. Set hits to 0 for inline block's JITMethodInfo

    ryoqun committed Mar 25, 2013
    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
  9. Use RBOOL and CBOOL where appropriate

    dbussink committed Mar 26, 2013
    In a lot of places we used ? : or multiple return style to return Ruby
    boolean values. We have a helper for that, RBOOL so we might as well use
    it. Also switch to using CBOOL where it's appropriate for Ruby to C(++)
    boolean checks.
Commits on Mar 25, 2013
  1. Remove stale spec tags files

    dbussink committed Mar 25, 2013
  2. Properly mark things as on stack in variable scope

    dbussink committed Mar 25, 2013
    Because of the reordering (and because there were lingering bugs here in
    the first place), we need to guard places properly with on stack guards
    when allocation might happen.
    
    This is also in the spin loop for getting and setting a local, because a
    heap tuple might be allocated that could have caused a gc. We put the
    guard inside the loop though, so we don't have to setup the on stack
    guard for the common case of not having to spin loop here.
  3. Don't ignore encodings from strings without it set

    dbussink committed Mar 25, 2013
    Those strings should be treated as strings with ASCII-8BIT encoding.
    This change doesn't break any existing specs and also a regression spec
    was added to make sure this behavior keeps working properly.
    
    Fixes #2222
  4. Add Rubinius specific spec for string building

    dbussink committed Mar 25, 2013
    This ensures that we cover the behavior of string interpolation where
    the string doesn't have an encoding yet. This is possible on Rubinius,
    we only setup the encoding then in the method retrieving the encoding
    from the string.
    
    This is an extraction from issue #2222 and is added to prevent
    regressions in this behavior.
  5. Merge pull request #2225 from ryoqun/compiled-code-leak

    dbussink committed Mar 25, 2013
    Trigger full GC from CodeManager to fix memory use
  6. Trigger full GC from CodeManager to fix memory use

    ryoqun committed Mar 21, 2013
    There is a possible situation of excessive memory usage.
    
    It's when many CompiledCode objects are repeatedly created and internalized. In
    that case, many MachineCode objects are internally created but never collected.
    Thus, memory usage increases forever.
    
    The following test code exhibits the problem:
    
        prc = proc do
        end
    
        loop do
          prc.block.instance_variable_set(:@compiled_code,
                                          prc.block.compiled_code.dup)
          prc.call
        end
    
    In such a situation, CompiledCode objects are collected immediately as young
    objects by GC. It means that the full (mature) GC is never triggered.
    
    When CompiledCode is internalized, it creates a MachineCode object, a kind of
    CodeResource, which is managed and garbage-collected by CodeManager.
    
    Currently, CodeManager only collects unneeded code resources in full (mature)
    GC. So, if there is no trigger for the full GC, code resources are never
    collected. This is usually fine because code resources are created very
    spontaneously under normal conditions.
    
    To fix this, when centain number of code resources (currently, 64 MiB in data
    size wise) are newly added, trigger the full GC from CodeManager.
    
    Closes #2224.
  7. Merge pull request #2234 from ryoqun/jit-scope-bug

    dbussink committed Mar 25, 2013
    Use correct scope by setting CompiledCode::scope
  8. Use correct scope by setting CompiledCode::scope

    ryoqun committed Mar 25, 2013
    In some cases, wrong ConstantScope can be used when JIT is enabled.
    
    For example, ConstantScope should be different with each invocation of
    class_exec in the following code:
    
        definition_block = proc do
          proc do
            def baz
            end
          end.call
        end
        Foo.class_exec(&definition_block)
        Bar.class_exec(&definition_block)
    
    But, it becomes always same after this code is JIT-ted.
    
    The cause is the following commit's modification for perfmance. It changed to
    only initialize CompiledCode::scope if it's nil:
    
        e3e2306 Improve block creation speed
    
        // TODO: We don't need to be doing this everytime.
        -    cm->scope(state, call_frame->static_scope());
        +    if(cm->scope()->nil_p()) {
        +      cm->scope(state, call_frame->static_scope());
        +    }
    
    But this is wrong, as shown above, there are cases where unconditional
    overwriting of ConstantScope is needed.
    
    Also, this diverges from the code of the create_block VM instruction defined
    at vm/instructions.def. This also indicates something wrong.
    
    So, always initialize CompiledCode::scope here too.
  9. Fix File.basename and File.extname

    dbussink committed Mar 25, 2013
    Makes sure we treat the strings here as all binary, since we only have
    to search for direct matches and work with those. Prevents having to
    convert back and forth to character vs. byte indexes all the time and we
    already have the helpers for working with this byte based.
    
    Fixes #2227
  10. Add spec for File.basename and File.extname

    dbussink committed Mar 25, 2013
    Verifies the behavior when filenames have names with multibyte
    characters.
  11. Fix indent

    ryoqun committed Mar 25, 2013
  12. Fix thread safety issue for flushing variable scopes

    dbussink committed Mar 25, 2013
    There was a race condition when flushing the variable scope, because
    another thread might already see isolated set to true, before the heap
    locals were properly initialized.
    
    This result in this other thread seeing nil as the local value instead
    of the proper value. This commit changes the flushing strategy to be
    both safe for reads and writes of the locals.
    
    The first step is to delay the allocation of the heap locals tuple. We
    then atomically indicate that this scope uses heap locals. If any other
    thread also wants to use the scope, it will spin until the heap locals
    have been allocated. Spinning for both the read and write ensures that
    we don't see any intermediate state during the move from stack to heap
    locals. This means no writes are lost and no stale reads occur.
    
    We then create the heap locals and only store then in the heap_locals_
    ivar after initializing them, so any reads or writes will see the proper
    locals and write to the correct slots.
    
    Fixes #2124
Commits on Mar 24, 2013
  1. Merge pull request #2231 from kachick/update-spec-tags

    jc00ke committed Mar 24, 2013
    Remove disused tags in String for 1.9+
  2. Merge pull request #2230 from kachick/fix-array-delete

    jc00ke committed Mar 24, 2013
    Fix Array#delete for 1.9
  3. Fix Array#delete for 1.9

    kachick committed Mar 24, 2013
  4. Remove disused tags

    kachick committed Mar 24, 2013
Commits on Mar 23, 2013
  1. Fix typos.

    carlosgaldino committed Mar 23, 2013