Beispiel #1
0
  /*
   * Turns a CompiledMethod's InstructionSequence into a C array of opcodes.
   */
  VMMethod::VMMethod(STATE, CompiledMethod* meth)
    : parent_(NULL)
    , run(standard_interpreter)
    , type(NULL)
    , number_of_caches_(0)
    , caches(0)
#ifdef ENABLE_LLVM
    , llvm_function_(NULL)
    , jitted_impl_(NULL)
#endif
    , name_(meth->name())
  {
    meth->set_executor(&VMMethod::execute);

    total = meth->iseq()->opcodes()->num_fields();

    opcodes = new opcode[total];
    addresses = new void*[total];

    fill_opcodes(state, meth);
    stack_size =    meth->stack_size()->to_native();
    number_of_locals = meth->number_of_locals();

    total_args =    meth->total_args()->to_native();
    required_args = meth->required_args()->to_native();
    if(meth->splat()->nil_p()) {
      splat_position = -1;
    } else {
      splat_position = as<Integer>(meth->splat())->to_native();
    }

    setup_argument_handler(meth);

    // Disable JIT for large methods
    if(meth->primitive()->nil_p() &&
        !state->shared.config.jit_disabled &&
        total < (size_t)state->shared.config.jit_max_method_size) {
      call_count = 0;
    } else {
      call_count = -1;
    }

    state->shared.om->add_code_resource(this);
  }
Beispiel #2
0
  void VMMethod::deoptimize(STATE, CompiledMethod* original) {
#ifdef ENABLE_LLVM
    // This resets execute to use the interpreter
    setup_argument_handler(original);

    // Don't call LLVMState::get(state)->remove(llvm_function_)
    // here. We let the CodeManager do that later, when we're sure
    // the llvm function is no longer used.
    llvm_function_ = 0;

    // Remove any JIT data, which will be cleanup by the CodeManager
    // later.
    original->set_jit_data(0);

    // Don't reset call_count if it's -1
    // (why would it be -1, it shouldn't be if we got this far)
    if(call_count >= 0) call_count = 0;
#endif
  }
Beispiel #3
0
  /*
   * Turns a CompiledMethod's InstructionSequence into a C array of opcodes.
   */
  VMMethod::VMMethod(STATE, CompiledMethod* meth) :
      original(state, meth), type(NULL) {

    meth->set_executor(VMMethod::execute);

    total = meth->iseq()->opcodes()->num_fields();
    if(Tuple* tup = try_as<Tuple>(meth->literals())) {
      blocks.resize(tup->num_fields(), NULL);
    }

    opcodes = new opcode[total];
    Tuple* literals = meth->literals();
    if(literals->nil_p()) {
      sendsites = NULL;
    } else {
      sendsites = new TypedRoot<SendSite*>[literals->num_fields()];
    }

    Tuple* ops = meth->iseq()->opcodes();
    Object* val;
    for(size_t index = 0; index < total;) {
      val = ops->at(state, index);
      if(val->nil_p()) {
        opcodes[index++] = 0;
      } else {
        opcodes[index] = as<Fixnum>(val)->to_native();
        size_t width = InstructionSequence::instruction_width(opcodes[index]);

        switch(width) {
        case 2:
          opcodes[index + 1] = as<Fixnum>(ops->at(state, index + 1))->to_native();
          break;
        case 3:
          opcodes[index + 1] = as<Fixnum>(ops->at(state, index + 1))->to_native();
          opcodes[index + 2] = as<Fixnum>(ops->at(state, index + 2))->to_native();
          break;
        }

        switch(opcodes[index]) {
        case InstructionSequence::insn_send_method:
        case InstructionSequence::insn_send_stack:
        case InstructionSequence::insn_send_stack_with_block:
        case InstructionSequence::insn_send_stack_with_splat:
        case InstructionSequence::insn_send_super_stack_with_block:
        case InstructionSequence::insn_send_super_stack_with_splat:
          native_int which = opcodes[index + 1];
          sendsites[which].set(as<SendSite>(literals->at(state, which)), &state->globals.roots);
        }

        index += width;
      }
    }

    stack_size =    meth->stack_size()->to_native();
    number_of_locals = meth->number_of_locals();

    total_args =    meth->total_args()->to_native();
    required_args = meth->required_args()->to_native();
    if(meth->splat()->nil_p()) {
      splat_position = -1;
    } else {
      splat_position = as<Integer>(meth->splat())->to_native();
    }

    setup_argument_handler(meth);
  }