Esempio n. 1
0
static OopMap* save_live_registers(StubAssembler* sasm, bool save_fpu_registers = true) {
  assert(frame_size_in_bytes == __ total_frame_size_in_bytes(reg_save_size_in_words),
         "mismatch in calculation");
  __ save_frame_c1(frame_size_in_bytes);

  // Record volatile registers as callee-save values in an OopMap so their save locations will be
  // propagated to the caller frame's RegisterMap during StackFrameStream construction (needed for
  // deoptimization; see compiledVFrame::create_stack_value).  The caller's I, L and O registers
  // are saved in register windows - I's and L's in the caller's frame and O's in the stub frame
  // (as the stub's I's) when the runtime routine called by the stub creates its frame.
  // OopMap frame sizes are in c2 stack slot sizes (sizeof(jint))

  int i;
  for (i = 0; i < FrameMap::nof_cpu_regs; i++) {
    Register r = as_Register(i);
    if (r == G1 || r == G3 || r == G4 || r == G5) {
      int sp_offset = cpu_reg_save_offsets[i];
      __ st_ptr(r, SP, (sp_offset * BytesPerWord) + STACK_BIAS);
    }
  }

  if (save_fpu_registers) {
    for (i = 0; i < FrameMap::nof_fpu_regs; i++) {
      FloatRegister r = as_FloatRegister(i);
      int sp_offset = fpu_reg_save_offsets[i];
      __ stf(FloatRegisterImpl::S, r, SP, (sp_offset * BytesPerWord) + STACK_BIAS);
    }
  }

  return generate_oop_map(sasm, save_fpu_registers);
}
Esempio n. 2
0
void C1_MacroAssembler::build_frame(int frame_size_in_bytes) {

    generate_stack_overflow_check(frame_size_in_bytes);
    // Create the frame.
    save_frame_c1(frame_size_in_bytes);
}
Esempio n. 3
0
OopMapSet* Runtime1::generate_handle_exception(StubID id, StubAssembler* sasm) {
  __ block_comment("generate_handle_exception");

  // Save registers, if required.
  OopMapSet* oop_maps = new OopMapSet();
  OopMap* oop_map = NULL;
  switch (id) {
  case forward_exception_id:
    // We're handling an exception in the context of a compiled frame.
    // The registers have been saved in the standard places.  Perform
    // an exception lookup in the caller and dispatch to the handler
    // if found.  Otherwise unwind and dispatch to the callers
    // exception handler.
     oop_map = generate_oop_map(sasm, true);

     // transfer the pending exception to the exception_oop
     __ ld_ptr(G2_thread, in_bytes(JavaThread::pending_exception_offset()), Oexception);
     __ ld_ptr(Oexception, 0, G0);
     __ st_ptr(G0, G2_thread, in_bytes(JavaThread::pending_exception_offset()));
     __ add(I7, frame::pc_return_offset, Oissuing_pc);
    break;
  case handle_exception_id:
    // At this point all registers MAY be live.
    oop_map = save_live_registers(sasm);
    __ mov(Oexception->after_save(),  Oexception);
    __ mov(Oissuing_pc->after_save(), Oissuing_pc);
    break;
  case handle_exception_from_callee_id:
    // At this point all registers except exception oop (Oexception)
    // and exception pc (Oissuing_pc) are dead.
    oop_map = new OopMap(frame_size_in_bytes / sizeof(jint), 0);
    sasm->set_frame_size(frame_size_in_bytes / BytesPerWord);
    __ save_frame_c1(frame_size_in_bytes);
    __ mov(Oexception->after_save(),  Oexception);
    __ mov(Oissuing_pc->after_save(), Oissuing_pc);
    break;
  default:  ShouldNotReachHere();
  }

  __ verify_not_null_oop(Oexception);

  // save the exception and issuing pc in the thread
  __ st_ptr(Oexception,  G2_thread, in_bytes(JavaThread::exception_oop_offset()));
  __ st_ptr(Oissuing_pc, G2_thread, in_bytes(JavaThread::exception_pc_offset()));

  // use the throwing pc as the return address to lookup (has bci & oop map)
  __ mov(Oissuing_pc, I7);
  __ sub(I7, frame::pc_return_offset, I7);
  int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, exception_handler_for_pc));
  oop_maps->add_gc_map(call_offset, oop_map);

  // Note: if nmethod has been deoptimized then regardless of
  // whether it had a handler or not we will deoptimize
  // by entering the deopt blob with a pending exception.

  // Restore the registers that were saved at the beginning, remove
  // the frame and jump to the exception handler.
  switch (id) {
  case forward_exception_id:
  case handle_exception_id:
    restore_live_registers(sasm);
    __ jmp(O0, 0);
    __ delayed()->restore();
    break;
  case handle_exception_from_callee_id:
    // Restore SP from L7 if the exception PC is a method handle call site.
    __ mov(O0, G5);  // Save the target address.
    __ lduw(Address(G2_thread, JavaThread::is_method_handle_return_offset()), L0);
    __ tst(L0);  // Condition codes are preserved over the restore.
    __ restore();

    __ jmp(G5, 0);  // jump to the exception handler
    __ delayed()->movcc(Assembler::notZero, false, Assembler::icc, L7_mh_SP_save, SP);  // Restore SP if required.
    break;
  default:  ShouldNotReachHere();
  }

  return oop_maps;
}
void C1_MacroAssembler::build_frame(int frame_size_in_bytes, int bang_size_in_bytes) {
  assert(bang_size_in_bytes >= frame_size_in_bytes, "stack bang size incorrect");
  generate_stack_overflow_check(bang_size_in_bytes);
  // Create the frame.
  save_frame_c1(frame_size_in_bytes);
}