Esempio n. 1
0
  VMMethod* CompiledMethod::formalize(STATE, bool ondemand) {
    if(!backend_method_) {
      VMMethod* vmm = NULL;
#ifdef ENABLE_LLVM
      /* Controls whether we use LLVM out of the gate or not. */
      if(state->config.compile_up_front) {
        if(ondemand) {
          set_executor(VMLLVMMethod::uncompiled_execute);
        } else {
          VMLLVMMethod* llvm = new VMLLVMMethod(state, this);
          llvm->compile(state);
          vmm = llvm;
        }
      } else {
        vmm = new VMMethod(state, this);
      }
#else
      vmm = new VMMethod(state, this);
#endif
      backend_method_ = vmm;

      if(!primitive()->nil_p()) {
        if(Symbol* name = try_as<Symbol>(primitive())) {
          set_executor(Primitives::resolve_primitive(state, name));
        }
      }
      return vmm;
    }

    return backend_method_;
  }
Esempio n. 2
0
  bool Executable::resolve_primitive(STATE) {
    if(!primitive_->nil_p()) {
      if(Symbol* name = try_as<Symbol>(primitive_)) {
        set_executor(Primitives::resolve_primitive(state, name, &prim_index_));
        return true;
      }
    }

    return false;
  }
Esempio n. 3
0
  MachineCode* CompiledCode::internalize(STATE, GCToken gct,
                                        const char** reason, int* ip)
  {
    MachineCode* mcode = machine_code_;

    atomic::memory_barrier();

    if(mcode) return mcode;

    CompiledCode* self = this;
    OnStack<1> os(state, self);

    self->hard_lock(state, gct);

    mcode = self->machine_code_;
    if(!mcode) {
      {
        BytecodeVerification bv(self);
        if(!bv.verify(state)) {
          if(reason) *reason = bv.failure_reason();
          if(ip) *ip = bv.failure_ip();
          std::cerr << "Error validating bytecode: " << bv.failure_reason() << "\n";
          return 0;
        }
      }

      mcode = new MachineCode(state, self);

      if(self->resolve_primitive(state)) {
        mcode->fallback = execute;
      } else {
        mcode->setup_argument_handler();
      }

      // We need to have an explicit memory barrier here, because we need to
      // be sure that mcode is completely initialized before it's set.
      // Otherwise another thread might see a partially initialized
      // MachineCode.
      atomic::write(&self->machine_code_, mcode);

      set_executor(mcode->fallback);
    }

    self->hard_unlock(state, gct);
    return mcode;
  }
Esempio n. 4
0
  MachineCode* CompiledCode::internalize(STATE) {
    timer::StopWatch<timer::microseconds> timer(
        state->vm()->metrics().machine.bytecode_internalizer_us);

    atomic::memory_barrier();

    MachineCode* mcode = machine_code();

    if(mcode) return mcode;

    {
      BytecodeVerifier bytecode_verifier(this);
      bytecode_verifier.verify(state);
    }

    mcode = new MachineCode(state, this);

    if(resolve_primitive(state)) {
      mcode->fallback = execute;
    } else {
      mcode->setup_argument_handler();
    }

    /* There is a race here because another Thread may have run this
     * CompiledCode instance and internalized it. We attempt to store our
     * version assuming that we are the only ones to do so and throw away our
     * work if someone else has beat us to it.
     */
    MachineCode** mcode_ptr = &_machine_code_;
    if(atomic::compare_and_swap(reinterpret_cast<void**>(mcode_ptr), 0, mcode)) {
      set_executor(mcode->fallback);
      return mcode;
    } else {
      return machine_code();
    }
  }
Esempio n. 5
0
 void CompiledCode::set_interpreter(executor interp) {
   set_executor(interp);
   machine_code_->fallback = interp;
 }
Esempio n. 6
0
 void CompiledMethod::set_interpreter(executor interp) {
   set_executor(interp);
   backend_method_->fallback = interp;
 }