Print this page


Split Close
Expand all
Collapse all
          --- old/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp
          +++ new/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp
↓ open down ↓ 140 lines elided ↑ open up ↑
 141  141  
 142  142  #define __ sasm->
 143  143  
 144  144  static int cpu_reg_save_offsets[FrameMap::nof_cpu_regs];
 145  145  static int fpu_reg_save_offsets[FrameMap::nof_fpu_regs];
 146  146  static int reg_save_size_in_words;
 147  147  static int frame_size_in_bytes = -1;
 148  148  
 149  149  static OopMap* generate_oop_map(StubAssembler* sasm, bool save_fpu_registers) {
 150  150    assert(frame_size_in_bytes == __ total_frame_size_in_bytes(reg_save_size_in_words),
 151      -         " mismatch in calculation");
      151 +         "mismatch in calculation");
 152  152    sasm->set_frame_size(frame_size_in_bytes / BytesPerWord);
 153  153    int frame_size_in_slots = frame_size_in_bytes / sizeof(jint);
 154  154    OopMap* oop_map = new OopMap(frame_size_in_slots, 0);
 155  155  
 156  156    int i;
 157  157    for (i = 0; i < FrameMap::nof_cpu_regs; i++) {
 158  158      Register r = as_Register(i);
 159  159      if (r == G1 || r == G3 || r == G4 || r == G5) {
 160  160        int sp_offset = cpu_reg_save_offsets[i];
 161  161        oop_map->set_callee_saved(VMRegImpl::stack2reg(sp_offset),
↓ open down ↓ 7 lines elided ↑ open up ↑
 169  169        int sp_offset = fpu_reg_save_offsets[i];
 170  170        oop_map->set_callee_saved(VMRegImpl::stack2reg(sp_offset),
 171  171                                  r->as_VMReg());
 172  172      }
 173  173    }
 174  174    return oop_map;
 175  175  }
 176  176  
 177  177  static OopMap* save_live_registers(StubAssembler* sasm, bool save_fpu_registers = true) {
 178  178    assert(frame_size_in_bytes == __ total_frame_size_in_bytes(reg_save_size_in_words),
 179      -         " mismatch in calculation");
      179 +         "mismatch in calculation");
 180  180    __ save_frame_c1(frame_size_in_bytes);
 181      -  sasm->set_frame_size(frame_size_in_bytes / BytesPerWord);
 182  181  
 183  182    // Record volatile registers as callee-save values in an OopMap so their save locations will be
 184  183    // propagated to the caller frame's RegisterMap during StackFrameStream construction (needed for
 185  184    // deoptimization; see compiledVFrame::create_stack_value).  The caller's I, L and O registers
 186  185    // are saved in register windows - I's and L's in the caller's frame and O's in the stub frame
 187  186    // (as the stub's I's) when the runtime routine called by the stub creates its frame.
 188  187    // OopMap frame sizes are in c2 stack slot sizes (sizeof(jint))
 189  188  
 190  189    int i;
 191  190    for (i = 0; i < FrameMap::nof_cpu_regs; i++) {
↓ open down ↓ 168 lines elided ↑ open up ↑
 360  359  
 361  360    OopMapSet* oop_maps = NULL;
 362  361    // for better readability
 363  362    const bool must_gc_arguments = true;
 364  363    const bool dont_gc_arguments = false;
 365  364  
 366  365    // stub code & info for the different stubs
 367  366    switch (id) {
 368  367      case forward_exception_id:
 369  368        {
 370      -        // we're handling an exception in the context of a compiled
 371      -        // frame.  The registers have been saved in the standard
 372      -        // places.  Perform an exception lookup in the caller and
 373      -        // dispatch to the handler if found.  Otherwise unwind and
 374      -        // dispatch to the callers exception handler.
 375      -
 376      -        oop_maps = new OopMapSet();
 377      -        OopMap* oop_map = generate_oop_map(sasm, true);
 378      -
 379      -        // transfer the pending exception to the exception_oop
 380      -        __ ld_ptr(G2_thread, in_bytes(JavaThread::pending_exception_offset()), Oexception);
 381      -        __ ld_ptr(Oexception, 0, G0);
 382      -        __ st_ptr(G0, G2_thread, in_bytes(JavaThread::pending_exception_offset()));
 383      -        __ add(I7, frame::pc_return_offset, Oissuing_pc);
 384      -
 385      -        generate_handle_exception(sasm, oop_maps, oop_map);
 386      -        __ should_not_reach_here();
      369 +        oop_maps = generate_handle_exception(id, sasm);
 387  370        }
 388  371        break;
 389  372  
 390  373      case new_instance_id:
 391  374      case fast_new_instance_id:
 392  375      case fast_new_instance_init_check_id:
 393  376        {
 394  377          Register G5_klass = G5; // Incoming
 395  378          Register O0_obj   = O0; // Outgoing
 396  379  
↓ open down ↓ 267 lines elided ↑ open up ↑
 664  647        }
 665  648        break;
 666  649  
 667  650      case throw_null_pointer_exception_id:
 668  651        { __ set_info("throw_null_pointer_exception", dont_gc_arguments);
 669  652          oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_null_pointer_exception), false);
 670  653        }
 671  654        break;
 672  655  
 673  656      case handle_exception_id:
 674      -      {
 675      -        __ set_info("handle_exception", dont_gc_arguments);
 676      -        // make a frame and preserve the caller's caller-save registers
      657 +      { __ set_info("handle_exception", dont_gc_arguments);
      658 +        oop_maps = generate_handle_exception(id, sasm);
      659 +      }
      660 +      break;
 677  661  
 678      -        oop_maps = new OopMapSet();
 679      -        OopMap* oop_map = save_live_registers(sasm);
 680      -        __ mov(Oexception->after_save(),  Oexception);
 681      -        __ mov(Oissuing_pc->after_save(), Oissuing_pc);
 682      -        generate_handle_exception(sasm, oop_maps, oop_map);
      662 +    case handle_exception_from_callee_id:
      663 +      { __ set_info("handle_exception_from_callee", dont_gc_arguments);
      664 +        oop_maps = generate_handle_exception(id, sasm);
 683  665        }
 684  666        break;
 685  667  
 686  668      case unwind_exception_id:
 687  669        {
 688  670          // O0: exception
 689  671          // I7: address of call to this method
 690  672  
 691  673          __ set_info("unwind_exception", dont_gc_arguments);
 692  674          __ mov(Oexception, Oexception->after_save());
 693  675          __ add(I7, frame::pc_return_offset, Oissuing_pc->after_save());
 694  676  
 695  677          __ call_VM_leaf(L7_thread_cache, CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address),
 696  678                          G2_thread, Oissuing_pc->after_save());
 697  679          __ verify_not_null_oop(Oexception->after_save());
 698  680  
 699      -        // Restore SP from L7 if the exception PC is a MethodHandle call site.
      681 +        // Restore SP from L7 if the exception PC is a method handle call site.
 700  682          __ mov(O0, G5);  // Save the target address.
 701  683          __ lduw(Address(G2_thread, JavaThread::is_method_handle_return_offset()), L0);
 702  684          __ tst(L0);  // Condition codes are preserved over the restore.
 703  685          __ restore();
 704  686  
 705  687          __ jmp(G5, 0);
 706  688          __ delayed()->movcc(Assembler::notZero, false, Assembler::icc, L7_mh_SP_save, SP);  // Restore SP if required.
 707  689        }
 708  690        break;
 709  691  
↓ open down ↓ 289 lines elided ↑ open up ↑
 999  981          __ set((int)id, O1);
1000  982          __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, unimplemented_entry), O1);
1001  983          __ should_not_reach_here();
1002  984        }
1003  985        break;
1004  986    }
1005  987    return oop_maps;
1006  988  }
1007  989  
1008  990  
1009      -void Runtime1::generate_handle_exception(StubAssembler* sasm, OopMapSet* oop_maps, OopMap* oop_map, bool) {
1010      -  Label no_deopt;
      991 +OopMapSet* Runtime1::generate_handle_exception(StubID id, StubAssembler* sasm) {
      992 +  __ block_comment("generate_handle_exception");
      993 +
      994 +  // Save registers, if required.
      995 +  OopMapSet* oop_maps = new OopMapSet();
      996 +  OopMap* oop_map = NULL;
      997 +  switch (id) {
      998 +  case forward_exception_id:
      999 +    // We're handling an exception in the context of a compiled frame.
     1000 +    // The registers have been saved in the standard places.  Perform
     1001 +    // an exception lookup in the caller and dispatch to the handler
     1002 +    // if found.  Otherwise unwind and dispatch to the callers
     1003 +    // exception handler.
     1004 +     oop_map = generate_oop_map(sasm, true);
     1005 +
     1006 +     // transfer the pending exception to the exception_oop
     1007 +     __ ld_ptr(G2_thread, in_bytes(JavaThread::pending_exception_offset()), Oexception);
     1008 +     __ ld_ptr(Oexception, 0, G0);
     1009 +     __ st_ptr(G0, G2_thread, in_bytes(JavaThread::pending_exception_offset()));
     1010 +     __ add(I7, frame::pc_return_offset, Oissuing_pc);
     1011 +    break;
     1012 +  case handle_exception_id:
     1013 +    // At this point all registers MAY be live.
     1014 +    oop_map = save_live_registers(sasm);
     1015 +    __ mov(Oexception->after_save(),  Oexception);
     1016 +    __ mov(Oissuing_pc->after_save(), Oissuing_pc);
     1017 +    break;
     1018 +  case handle_exception_from_callee_id:
     1019 +    // At this point all registers except exception oop (Oexception)
     1020 +    // and exception pc (Oissuing_pc) are dead.
     1021 +    oop_map = new OopMap(frame_size_in_bytes / sizeof(jint), 0);
     1022 +    sasm->set_frame_size(frame_size_in_bytes / BytesPerWord);
     1023 +    __ save_frame_c1(frame_size_in_bytes);
     1024 +    __ mov(Oexception->after_save(),  Oexception);
     1025 +    __ mov(Oissuing_pc->after_save(), Oissuing_pc);
     1026 +    break;
     1027 +  default:  ShouldNotReachHere();
     1028 +  }
1011 1029  
1012 1030    __ verify_not_null_oop(Oexception);
1013 1031  
1014 1032    // save the exception and issuing pc in the thread
1015      -  __ st_ptr(Oexception, G2_thread, in_bytes(JavaThread::exception_oop_offset()));
     1033 +  __ st_ptr(Oexception,  G2_thread, in_bytes(JavaThread::exception_oop_offset()));
1016 1034    __ st_ptr(Oissuing_pc, G2_thread, in_bytes(JavaThread::exception_pc_offset()));
1017 1035  
1018      -  // save the real return address and use the throwing pc as the return address to lookup (has bci & oop map)
1019      -  __ mov(I7, L0);
     1036 +  // use the throwing pc as the return address to lookup (has bci & oop map)
1020 1037    __ mov(Oissuing_pc, I7);
1021 1038    __ sub(I7, frame::pc_return_offset, I7);
1022 1039    int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, exception_handler_for_pc));
     1040 +  oop_maps->add_gc_map(call_offset, oop_map);
1023 1041  
1024 1042    // Note: if nmethod has been deoptimized then regardless of
1025 1043    // whether it had a handler or not we will deoptimize
1026 1044    // by entering the deopt blob with a pending exception.
1027 1045  
1028      -#ifdef ASSERT
1029      -  Label done;
1030      -  __ tst(O0);
1031      -  __ br(Assembler::notZero, false, Assembler::pn, done);
1032      -  __ delayed()->nop();
1033      -  __ stop("should have found address");
1034      -  __ bind(done);
1035      -#endif
1036      -
1037      -  // restore the registers that were saved at the beginning and jump to the exception handler.
1038      -  restore_live_registers(sasm);
1039      -
1040      -  __ jmp(O0, 0);
1041      -  __ delayed()->restore();
     1046 +  // Restore the registers that were saved at the beginning, remove
     1047 +  // the frame and jump to the exception handler.
     1048 +  switch (id) {
     1049 +  case forward_exception_id:
     1050 +  case handle_exception_id:
     1051 +    restore_live_registers(sasm);
     1052 +    __ jmp(O0, 0);
     1053 +    __ delayed()->restore();
     1054 +    break;
     1055 +  case handle_exception_from_callee_id:
     1056 +    // Restore SP from L7 if the exception PC is a method handle call site.
     1057 +    __ mov(O0, G5);  // Save the target address.
     1058 +    __ lduw(Address(G2_thread, JavaThread::is_method_handle_return_offset()), L0);
     1059 +    __ tst(L0);  // Condition codes are preserved over the restore.
     1060 +    __ restore();
     1061 +
     1062 +    __ jmp(G5, 0);  // jump to the exception handler
     1063 +    __ delayed()->movcc(Assembler::notZero, false, Assembler::icc, L7_mh_SP_save, SP);  // Restore SP if required.
     1064 +    break;
     1065 +  default:  ShouldNotReachHere();
     1066 +  }
1042 1067  
1043      -  oop_maps->add_gc_map(call_offset, oop_map);
     1068 +  return oop_maps;
1044 1069  }
1045 1070  
1046 1071  
1047 1072  #undef __
1048 1073  
1049      -#define __ masm->
1050      -
1051 1074  const char *Runtime1::pd_name_for_address(address entry) {
1052 1075    return "<unknown function>";
1053 1076  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX