Esempio n. 1
0
File: jit.cpp Progetto: rdp/rubinius
  CompiledMethod* LLVMState::find_candidate(CompiledMethod* start, CallFrame* call_frame) {
    if(!config_.jit_inline_generic) {
      return find_first_non_block(call_frame);
    }

    int depth = cInlineMaxDepth;

    if(!start) {
      start = call_frame->cm;
      call_frame = call_frame->previous;
      depth--;
    }

    if(!call_frame || start->backend_method()->total > SMALL_METHOD_SIZE) {
      return start;
    }

    CompiledMethod* caller = start;

    while(depth-- > 0) {
      CompiledMethod* cur = call_frame->cm;
      VMMethod* vmm = cur->backend_method();

      if(call_frame->block_p()
          || vmm->required_args != vmm->total_args // has a splat
          || vmm->call_count < 200 // not called much
          || vmm->jitted() // already jitted
          || vmm->parent() // is a block
        ) return caller;

      CallFrame* next = call_frame->previous;

      if(!next|| cur->backend_method()->total > SMALL_METHOD_SIZE) return cur;

      caller = cur;
      call_frame = next;
    }

    return caller;
  }
Esempio n. 2
0
  VMMethod* LLVMState::find_candidate(VMMethod* start, CallFrame* call_frame) {
    VMMethod* found = start;
    int depth = 0;
    bool consider_block_parents = config_.jit_inline_blocks;

    // No upper call_frames or generic inlining is off, use the start.
    // With generic inlining off, there is no way to inline back to start,
    // so we don't both trying.
    if(!config_.jit_inline_generic) {
      if(!start) start = call_frame->cm->backend_method();
      return find_first_non_block(call_frame);
    }

    /*
    std::cerr << "JIT target search:\n";

    if(start) {
      show_method(this, start);
    } else {
      std::cerr << "  <primitive>\n";
    }
    */

    VMMethod* next = call_frame->cm->backend_method();
    VMMethod* parent = 0;

    while(depth < cInlineMaxDepth) {
      // show_method(this, next);

      // Basic requirements
      if(next->required_args != next->total_args ||
          next->call_count < 200 ||
          next->jitted()) break;

      // Jump to defining methods of blocks?
      parent = next->parent();
      if(parent) {
        if(consider_block_parents) {
          // See if parent is in this call_frame chain properly..
          if(CallFrame* pf = validate_block_parent(call_frame, parent)) {
            depth++;

            // Method parents are valuable, so always use them if we find them.
            if(!parent->parent()) {
              found = parent;
            }
            // show_method(this, parent, " parent!");

            call_frame = pf;
          }
        } else {
          // We hit a block, just bail.
          break;
        }
      } else {
        found = next;
      }

      call_frame = call_frame->previous;
      if(!call_frame) break;

      next = call_frame->cm->backend_method();

      depth++;
    }

    if(!found && !next->parent()) return next;

    return found;
  }