Esempio n. 1
0
  Executable* MethodTableBucket::get_method(STATE) {
    if(!method()->nil_p()) return as<Executable>(method());

    if(method_id()->nil_p()) return nil<Executable>();

    CompiledCode* code = CodeDB::load(state, as<String>(method_id()));
    if(ConstantScope* cs = try_as<ConstantScope>(scope())) {
      code->scope(state, cs);
    } else {
      code->scope(state, nil<ConstantScope>());
    }
    code->serial(state, serial_);
    method(state, code);

    return as<Executable>(code);
  }
Esempio n. 2
0
  Object* rbx_create_block(STATE, CallFrame* call_frame, int index) {
    CPP_TRY

    Object* _lit = call_frame->cm->literals()->at(state, index);
    CompiledCode* cm = as<CompiledCode>(_lit);

    // TODO: We don't need to be doing this everytime.
    if(cm->scope()->nil_p()) {
      cm->scope(state, call_frame->constant_scope());
    }

    VMMethod* vmm = call_frame->cm->backend_method();
    GCTokenImpl gct;
    return BlockEnvironment::under_call_frame(state, gct, cm, vmm, call_frame);

    CPP_CATCH
  }
Esempio n. 3
0
  Object* rbx_create_block(STATE, CallFrame* call_frame, int index) {
    CPP_TRY

    Object* _lit = call_frame->compiled_code->literals()->at(state, index);
    CompiledCode* code = as<CompiledCode>(_lit);

    // TODO: We don't need to be doing this everytime.
    code->scope(state, call_frame->constant_scope());

    MachineCode* mcode = call_frame->compiled_code->machine_code();
    GCTokenImpl gct;
    return BlockEnvironment::under_call_frame(state, gct, code, mcode, call_frame);

    CPP_CATCH
  }
Esempio n. 4
0
  void CompiledCode::Info::show(STATE, Object* self, int level) {
    CompiledCode* code = as<CompiledCode>(self);

    class_header(state, self);
    indent_attribute(++level, "file"); code->file()->show(state, level);
    indent_attribute(level, "iseq"); code->iseq()->show(state, level);
    indent_attribute(level, "lines"); code->lines()->show_simple(state, level);
    indent_attribute(level, "literals"); code->literals()->show_simple(state, level);
    indent_attribute(level, "local_count"); code->local_count()->show(state, level);
    indent_attribute(level, "local_names"); code->local_names()->show_simple(state, level);
    indent_attribute(level, "name"); code->name()->show(state, level);
    indent_attribute(level, "required_args"); code->required_args()->show(state, level);
    indent_attribute(level, "scope"); code->scope()->show(state, level);
    indent_attribute(level, "splat"); code->splat()->show(state, level);
    indent_attribute(level, "stack_size"); code->stack_size()->show(state, level);
    indent_attribute(level, "total_args"); code->total_args()->show(state, level);

    indent_attribute(level, "internalized");
    if(!code->machine_code_) {
      std::cout << "no\n";
    } else {
      std::cout << "yes\n";

#ifdef ENABLE_LLVM
      MachineCode* v = code->machine_code();

      for(int i = 0; i < MachineCode::cMaxSpecializations; i++) {
        if(!v->specializations[i].jit_data) continue;

        llvm::Function* func = v->specializations[i].jit_data->llvm_function();

        llvm::outs() << "<LLVM>\n"
                     << *func
                     << "</LLVM>\n<MachineCode>\n";

        LLVMState::show_machine_code(
            v->specializations[i].jit_data->native_func(),
            v->specializations[i].jit_data->native_size());
        llvm::outs() << "</MachineCode>\n";
      }
#endif
    }

    close_body(level);
  }
Esempio n. 5
0
 ConstantScope* constant_scope() {
   if(custom_constant_scope_p()) return constant_scope_;
   return compiled_code->scope();
 }
Esempio n. 6
0
 ConstantScope* constant_scope() {
   if(custom_constant_scope_p()) return constant_scope_;
   return cm->scope();
 }
Esempio n. 7
0
    Object* MachineCode::execute_specialized(STATE, CallFrame* previous,
        Executable* exec, Module* mod, Arguments& args) {

      CompiledCode* code = as<CompiledCode>(exec);
      MachineCode* mcode = code->machine_code();

      StackVariables* scope = ALLOCA_STACKVARIABLES(mcode->number_of_locals);
      // Originally, I tried using msg.module directly, but what happens is if
      // super is used, that field is read. If you combine that with the method
      // being called recursively, msg.module can change, causing super() to
      // look in the wrong place.
      //
      // Thus, we have to cache the value in the StackVariables.
      scope->initialize(args.recv(), args.block(), mod, mcode->number_of_locals);

      InterpreterCallFrame* frame = ALLOCA_CALLFRAME(mcode->stack_size);

      // If argument handling fails..
      if(ArgumentHandler::call(state, mcode, scope, args) == false) {
        Exception* exc =
          Exception::make_argument_error(state, mcode->total_args, args.total(), args.name());
        exc->locations(state, Location::from_call_stack(state, previous));
        state->raise_exception(exc);

        return NULL;
      }

      frame->prepare(mcode->stack_size);

      frame->previous = previous;
      frame->constant_scope_ = code->scope();
      frame->dispatch_data = 0;
      frame->compiled_code = code;
      frame->flags = 0;
      frame->optional_jit_data = 0;
      frame->top_scope_ = 0;
      frame->scope = scope;
      frame->arguments = &args;

      GCTokenImpl gct;

#ifdef ENABLE_LLVM
      // A negative call_count means we've disabled usage based JIT
      // for this method.
      if(mcode->call_count >= 0) {
        if(mcode->call_count >= state->shared().config.jit_call_til_compile) {
          LLVMState* ls = LLVMState::get(state);
          OnStack<3> os(state, exec, mod, code);
          ls->compile_callframe(state, gct, code, frame);
        } else {
          mcode->call_count++;
        }
      }
#endif

#ifdef RBX_PROFILER
      if(unlikely(state->vm()->tooling())) {
        // Check the stack and interrupts here rather than in the interpreter
        // loop itself.
        OnStack<2> os(state, exec, code);
        if(!state->check_interrupts(gct, frame, frame)) return NULL;

        state->checkpoint(gct, frame);

        tooling::MethodEntry method(state, exec, scope->module(), args, code);

        RUBINIUS_METHOD_ENTRY_HOOK(state, scope->module(), args.name(), previous);
        Object* result = (*mcode->run)(state, mcode, frame);
        RUBINIUS_METHOD_RETURN_HOOK(state, scope->module(), args.name(), previous);
        return result;
      } else {
        if(!state->check_interrupts(gct, frame, frame)) return NULL;

        state->checkpoint(gct, frame);
        RUBINIUS_METHOD_ENTRY_HOOK(state, scope->module(), args.name(), previous);
        Object* result = (*mcode->run)(state, mcode, frame);
        RUBINIUS_METHOD_RETURN_HOOK(state, scope->module(), args.name(), previous);
        return result;
      }
#else
      if(!state->check_interrupts(gct, frame, frame)) return NULL;

      state->checkpoint(gct, frame);

      RUBINIUS_METHOD_ENTRY_HOOK(state, scope->module(), args.name(), previous);
      Object* result = (*mcode->run)(state, mcode, frame);
      RUBINIUS_METHOD_RETURN_HOOK(state, scope->module(), args.name(), previous);
      return result;
#endif
    }