void LIR_OopMapGenerator::process_move(LIR_Op* op) {
  LIR_Op1* op1 = op->as_Op1();
  LIR_Opr src = op1->in_opr();
  LIR_Opr dst = op1->result_opr();
  
  assert(!src->is_stack() || !dst->is_stack(), "No memory-memory moves allowed");
  if ((src->is_stack() && frame_map()->is_spill_pos(src)) ||
      (dst->is_stack() && frame_map()->is_spill_pos(dst))) {
    // Oops in the spill area are handled by another mechanism (see
    // CodeEmitInfo::record_spilled_oops)
    return;
  }
  if (dst->is_oop()) {
    assert((src->is_oop() &&
            (src->is_stack() || src->is_register() || src->is_constant())
           ) ||
           src->is_address(), "Wrong tracking of oops/non-oops in LIR");
    assert(!src->is_stack() || is_marked(src->single_stack_ix()),
           "Error in tracking of oop stores to stack");
    if (dst->is_stack()) {
      mark(dst->single_stack_ix());
    } else if (dst->is_register()) {
      if (LIRCacheLocals) {
        if (local_mapping()->is_cache_reg(dst)) {
          mark(dst);
        }
      } else {
        assert(local_mapping() == NULL, "expected no local mapping");
      }
    }
  } else {
    // !dst->is_oop()
    // Note that dst may be an address
    assert(!src->is_single_stack() || !is_marked(src->single_stack_ix()), "Error in tracking of oop stores to stack");
    assert(!src->is_double_stack() || !is_marked(src->double_stack_ix()), "Error in tracking of oop stores to stack");
    assert(!src->is_double_stack() || !is_marked(1 + src->double_stack_ix()), "Error in tracking of oop stores to stack");
    if (dst->is_stack()) {
      if (dst->is_single_stack()) {
        clear_all(dst->single_stack_ix());
      } else {
        clear_all(dst->double_stack_ix());
        clear_all(1 + dst->double_stack_ix());
      }
    } else if (dst->is_register()) {
      if (LIRCacheLocals) {
        if (local_mapping()->is_cache_reg(dst)) {
          clear_all(dst);
        }
      } else {
        assert(local_mapping() == NULL, "expected no local mapping");
      }
    }
  }
}
int Compilation::emit_code_body() {
  // emit code
  Runtime1::setup_code_buffer(code(), allocator()->num_calls());
  code()->initialize_oop_recorder(env()->oop_recorder());

  _masm = new C1_MacroAssembler(code());
  _masm->set_oop_recorder(env()->oop_recorder());

  LIR_Assembler lir_asm(this);

  lir_asm.emit_code(hir()->code());
  CHECK_BAILOUT_(0);

  emit_code_epilog(&lir_asm);
  CHECK_BAILOUT_(0);

  generate_exception_handler_table();

#ifndef PRODUCT
  if (PrintExceptionHandlers && Verbose) {
    exception_handler_table()->print();
  }
#endif /* PRODUCT */

  return frame_map()->framesize();
}
void Compilation::emit_lir() {
  CHECK_BAILOUT();

  LIRGenerator gen(this, method());
  {
    PhaseTraceTime timeit(_t_lirGeneration);
    hir()->iterate_linear_scan_order(&gen);
  }

  CHECK_BAILOUT();

  {
    PhaseTraceTime timeit(_t_linearScan);

    LinearScan* allocator = new LinearScan(hir(), &gen, frame_map());
    set_allocator(allocator);
    // Assign physical registers to LIR operands using a linear scan algorithm.
    allocator->do_linear_scan();
    CHECK_BAILOUT();

    _max_spills = allocator->max_spills();
  }

  if (BailoutAfterLIR) {
    if (PrintLIR && !bailed_out()) {
      print_LIR(hir()->code());
    }
    bailout("Bailing out because of -XX:+BailoutAfterLIR");
  }
}
void Compilation::install_code(int frame_size) {
  // frame_size is in 32-bit words so adjust it intptr_t words
  assert(frame_size == frame_map()->framesize(), "must match");
  assert(in_bytes(frame_map()->framesize_in_bytes()) % sizeof(intptr_t) == 0, "must be at least pointer aligned");
  _env->register_method(
    method(),
    osr_bci(),
    &_offsets,
    in_bytes(_frame_map->sp_offset_for_orig_pc()),
    code(),
    in_bytes(frame_map()->framesize_in_bytes()) / sizeof(intptr_t),
    debug_info_recorder()->_oopmaps,
    exception_handler_table(),
    implicit_exception_table(),
    compiler(),
    _env->comp_level(),
    needs_debug_information(),
    has_unsafe_access()
  );
}
void LIR_OopMapGenerator::generate() {
  // Initialize by iterating down the method's signature and marking
  // oop locals in the state

  assert((int) oop_map()->size() == frame_map()->num_local_names(), "just checking");
  oop_map()->clear();
  ciSignature* sig = ir()->method()->signature();
  int idx = 0;
  // Handle receiver for non-static methods
  if (!ir()->method()->is_static()) {
    mark(frame_map()->name_for_argument(idx));
    ++idx;
  }
  for (int i = 0; i < sig->count(); i++) {
    ciType* type = sig->type_at(i);
    if (!type->is_primitive_type()) {
      mark(frame_map()->name_for_argument(idx));
    }
    idx += type->size();
  }

  // The start block contains a Base instruction, which causes the LIR
  // for ref-uninit conflicts to be generated. We need to handle this
  // block specially so we don't traverse its "osr_entry" successor,
  // because we don't know how to set up the state appropriately for
  // that entry point.
  _base = ir()->start()->end()->as_Base();

  // Always start iterating at the start (even for OSR compiles)
  merge_state(ir()->start());
  
  BlockBegin* block = work_list_dequeue();
  while (block != NULL) {
    oop_map()->set_from(*block->lir_oop_map());
    iterate_one(block);
    block = work_list_dequeue();
  }
}
// for  _ladd, _lmul, _lsub, _ldiv, _lrem
void LIRGenerator::do_ArithmeticOp_Long(ArithmeticOp* x) {
  if (x->op() == Bytecodes::_ldiv || x->op() == Bytecodes::_lrem ) {
    // long division is implemented as a direct call into the runtime
    LIRItem left(x->x(), this);
    LIRItem right(x->y(), this);

    // the check for division by zero destroys the right operand
    right.set_destroys_register();

    BasicTypeList signature(2);
    signature.append(T_LONG);
    signature.append(T_LONG);
    CallingConvention* cc = frame_map()->c_calling_convention(&signature);

    // check for division by zero (destroys registers of right operand!)
    CodeEmitInfo* info = state_for(x);

    const LIR_Opr result_reg = result_register_for(x->type());
    left.load_item_force(cc->at(1));
    right.load_item();

    __ move(right.result(), cc->at(0));

    __ cmp(lir_cond_equal, right.result(), LIR_OprFact::longConst(0));
    __ branch(lir_cond_equal, T_LONG, new DivByZeroStub(info));

    address entry;
    switch (x->op()) {
    case Bytecodes::_lrem:
      entry = CAST_FROM_FN_PTR(address, SharedRuntime::lrem);
      break; // check if dividend is 0 is done elsewhere
    case Bytecodes::_ldiv:
      entry = CAST_FROM_FN_PTR(address, SharedRuntime::ldiv);
      break; // check if dividend is 0 is done elsewhere
    case Bytecodes::_lmul:
      entry = CAST_FROM_FN_PTR(address, SharedRuntime::lmul);
      break;
    default:
      ShouldNotReachHere();
    }

    LIR_Opr result = rlock_result(x);
    __ call_runtime_leaf(entry, getThreadTemp(), result_reg, cc->args());
    __ move(result_reg, result);
  } else if (x->op() == Bytecodes::_lmul) {
    // missing test if instr is commutative and if we should swap
    LIRItem left(x->x(), this);
    LIRItem right(x->y(), this);

    // right register is destroyed by the long mul, so it must be
    // copied to a new register.
    right.set_destroys_register();

    left.load_item();
    right.load_item();

    LIR_Opr reg = FrameMap::long0_opr;
    arithmetic_op_long(x->op(), reg, left.result(), right.result(), NULL);
    LIR_Opr result = rlock_result(x);
    __ move(reg, result);
  } else {
    // missing test if instr is commutative and if we should swap
    LIRItem left(x->x(), this);
    LIRItem right(x->y(), this);

    left.load_item();
    // don't load constants to save register
    right.load_nonconstant();
    rlock_result(x);
    arithmetic_op_long(x->op(), x->operand(), left.result(), right.result(), NULL);
  }
}
void LIR_Assembler::build_frame() {
_masm->build_frame(frame_map());
}