hotspot/src/cpu/sparc/vm/assembler_sparc.cpp
changeset 13881 a326d528f3e1
parent 13728 882756847a04
child 13969 d2a189b83b87
equal deleted inserted replaced
13751:7fd047780d47 13881:a326d528f3e1
   723 void MacroAssembler::jump(const AddressLiteral& addrlit, Register temp, int offset, const char* file, int line) {
   723 void MacroAssembler::jump(const AddressLiteral& addrlit, Register temp, int offset, const char* file, int line) {
   724   jumpl(addrlit, temp, G0, offset, file, line);
   724   jumpl(addrlit, temp, G0, offset, file, line);
   725 }
   725 }
   726 
   726 
   727 
   727 
   728 // Convert to C varargs format
       
   729 void MacroAssembler::set_varargs( Argument inArg, Register d ) {
       
   730   // spill register-resident args to their memory slots
       
   731   // (SPARC calling convention requires callers to have already preallocated these)
       
   732   // Note that the inArg might in fact be an outgoing argument,
       
   733   // if a leaf routine or stub does some tricky argument shuffling.
       
   734   // This routine must work even though one of the saved arguments
       
   735   // is in the d register (e.g., set_varargs(Argument(0, false), O0)).
       
   736   for (Argument savePtr = inArg;
       
   737        savePtr.is_register();
       
   738        savePtr = savePtr.successor()) {
       
   739     st_ptr(savePtr.as_register(), savePtr.address_in_frame());
       
   740   }
       
   741   // return the address of the first memory slot
       
   742   Address a = inArg.address_in_frame();
       
   743   add(a.base(), a.disp(), d);
       
   744 }
       
   745 
       
   746 // Conditional breakpoint (for assertion checks in assembly code)
   728 // Conditional breakpoint (for assertion checks in assembly code)
   747 void MacroAssembler::breakpoint_trap(Condition c, CC cc) {
   729 void MacroAssembler::breakpoint_trap(Condition c, CC cc) {
   748   trap(c, cc, G0, ST_RESERVED_FOR_USER_0);
   730   trap(c, cc, G0, ST_RESERVED_FOR_USER_0);
   749 }
   731 }
   750 
   732 
  2941                                              Label& L_no_such_interface) {
  2923                                              Label& L_no_such_interface) {
  2942   assert_different_registers(recv_klass, intf_klass, method_result, scan_temp);
  2924   assert_different_registers(recv_klass, intf_klass, method_result, scan_temp);
  2943   assert(itable_index.is_constant() || itable_index.as_register() == method_result,
  2925   assert(itable_index.is_constant() || itable_index.as_register() == method_result,
  2944          "caller must use same register for non-constant itable index as for method");
  2926          "caller must use same register for non-constant itable index as for method");
  2945 
  2927 
       
  2928   Label L_no_such_interface_restore;
       
  2929   bool did_save = false;
       
  2930   if (scan_temp == noreg || sethi_temp == noreg) {
       
  2931     Register recv_2 = recv_klass->is_global() ? recv_klass : L0;
       
  2932     Register intf_2 = intf_klass->is_global() ? intf_klass : L1;
       
  2933     assert(method_result->is_global(), "must be able to return value");
       
  2934     scan_temp  = L2;
       
  2935     sethi_temp = L3;
       
  2936     save_frame_and_mov(0, recv_klass, recv_2, intf_klass, intf_2);
       
  2937     recv_klass = recv_2;
       
  2938     intf_klass = intf_2;
       
  2939     did_save = true;
       
  2940   }
       
  2941 
  2946   // Compute start of first itableOffsetEntry (which is at the end of the vtable)
  2942   // Compute start of first itableOffsetEntry (which is at the end of the vtable)
  2947   int vtable_base = InstanceKlass::vtable_start_offset() * wordSize;
  2943   int vtable_base = InstanceKlass::vtable_start_offset() * wordSize;
  2948   int scan_step   = itableOffsetEntry::size() * wordSize;
  2944   int scan_step   = itableOffsetEntry::size() * wordSize;
  2949   int vte_size    = vtableEntry::size() * wordSize;
  2945   int vte_size    = vtableEntry::size() * wordSize;
  2950 
  2946 
  2979   // for (scan = klass->itable(); scan->interface() != NULL; scan += scan_step) {
  2975   // for (scan = klass->itable(); scan->interface() != NULL; scan += scan_step) {
  2980   //   if (scan->interface() == intf) {
  2976   //   if (scan->interface() == intf) {
  2981   //     result = (klass + scan->offset() + itable_index);
  2977   //     result = (klass + scan->offset() + itable_index);
  2982   //   }
  2978   //   }
  2983   // }
  2979   // }
  2984   Label search, found_method;
  2980   Label L_search, L_found_method;
  2985 
  2981 
  2986   for (int peel = 1; peel >= 0; peel--) {
  2982   for (int peel = 1; peel >= 0; peel--) {
  2987     // %%%% Could load both offset and interface in one ldx, if they were
  2983     // %%%% Could load both offset and interface in one ldx, if they were
  2988     // in the opposite order.  This would save a load.
  2984     // in the opposite order.  This would save a load.
  2989     ld_ptr(scan_temp, itableOffsetEntry::interface_offset_in_bytes(), method_result);
  2985     ld_ptr(scan_temp, itableOffsetEntry::interface_offset_in_bytes(), method_result);
  2990 
  2986 
  2991     // Check that this entry is non-null.  A null entry means that
  2987     // Check that this entry is non-null.  A null entry means that
  2992     // the receiver class doesn't implement the interface, and wasn't the
  2988     // the receiver class doesn't implement the interface, and wasn't the
  2993     // same as when the caller was compiled.
  2989     // same as when the caller was compiled.
  2994     bpr(Assembler::rc_z, false, Assembler::pn, method_result, L_no_such_interface);
  2990     bpr(Assembler::rc_z, false, Assembler::pn, method_result, did_save ? L_no_such_interface_restore : L_no_such_interface);
  2995     delayed()->cmp(method_result, intf_klass);
  2991     delayed()->cmp(method_result, intf_klass);
  2996 
  2992 
  2997     if (peel) {
  2993     if (peel) {
  2998       brx(Assembler::equal,    false, Assembler::pt, found_method);
  2994       brx(Assembler::equal,    false, Assembler::pt, L_found_method);
  2999     } else {
  2995     } else {
  3000       brx(Assembler::notEqual, false, Assembler::pn, search);
  2996       brx(Assembler::notEqual, false, Assembler::pn, L_search);
  3001       // (invert the test to fall through to found_method...)
  2997       // (invert the test to fall through to found_method...)
  3002     }
  2998     }
  3003     delayed()->add(scan_temp, scan_step, scan_temp);
  2999     delayed()->add(scan_temp, scan_step, scan_temp);
  3004 
  3000 
  3005     if (!peel)  break;
  3001     if (!peel)  break;
  3006 
  3002 
  3007     bind(search);
  3003     bind(L_search);
  3008   }
  3004   }
  3009 
  3005 
  3010   bind(found_method);
  3006   bind(L_found_method);
  3011 
  3007 
  3012   // Got a hit.
  3008   // Got a hit.
  3013   int ito_offset = itableOffsetEntry::offset_offset_in_bytes();
  3009   int ito_offset = itableOffsetEntry::offset_offset_in_bytes();
  3014   // scan_temp[-scan_step] points to the vtable offset we need
  3010   // scan_temp[-scan_step] points to the vtable offset we need
  3015   ito_offset -= scan_step;
  3011   ito_offset -= scan_step;
  3016   lduw(scan_temp, ito_offset, scan_temp);
  3012   lduw(scan_temp, ito_offset, scan_temp);
  3017   ld_ptr(recv_klass, scan_temp, method_result);
  3013   ld_ptr(recv_klass, scan_temp, method_result);
       
  3014 
       
  3015   if (did_save) {
       
  3016     Label L_done;
       
  3017     ba(L_done);
       
  3018     delayed()->restore();
       
  3019 
       
  3020     bind(L_no_such_interface_restore);
       
  3021     ba(L_no_such_interface);
       
  3022     delayed()->restore();
       
  3023 
       
  3024     bind(L_done);
       
  3025   }
  3018 }
  3026 }
  3019 
  3027 
  3020 
  3028 
  3021 // virtual method calling
  3029 // virtual method calling
  3022 void MacroAssembler::lookup_virtual_method(Register recv_klass,
  3030 void MacroAssembler::lookup_virtual_method(Register recv_klass,