src/hotspot/cpu/sparc/c1_Runtime1_sparc.cpp
changeset 49906 4bb58f644e4e
parent 49754 ee93c1087584
child 50023 bdb627563075
equal deleted inserted replaced
49905:a09af8ef8e5c 49906:4bb58f644e4e
    38 #include "runtime/signature.hpp"
    38 #include "runtime/signature.hpp"
    39 #include "runtime/vframeArray.hpp"
    39 #include "runtime/vframeArray.hpp"
    40 #include "utilities/macros.hpp"
    40 #include "utilities/macros.hpp"
    41 #include "utilities/align.hpp"
    41 #include "utilities/align.hpp"
    42 #include "vmreg_sparc.inline.hpp"
    42 #include "vmreg_sparc.inline.hpp"
    43 #if INCLUDE_ALL_GCS
       
    44 #include "gc/g1/g1BarrierSet.hpp"
       
    45 #include "gc/g1/g1CardTable.hpp"
       
    46 #include "gc/g1/g1ThreadLocalData.hpp"
       
    47 #endif
       
    48 
    43 
    49 // Implementation of StubAssembler
    44 // Implementation of StubAssembler
    50 
    45 
    51 int StubAssembler::call_RT(Register oop_result1, Register metadata_result, address entry_point, int number_of_arguments) {
    46 int StubAssembler::call_RT(Register oop_result1, Register metadata_result, address entry_point, int number_of_arguments) {
    52   // for sparc changing the number of arguments doesn't change
    47   // for sparc changing the number of arguments doesn't change
   143   mov(arg2, O2); assert(arg2 != O1,               "smashed argument");
   138   mov(arg2, O2); assert(arg2 != O1,               "smashed argument");
   144   mov(arg3, O3); assert(arg3 != O1 && arg3 != O2, "smashed argument");
   139   mov(arg3, O3); assert(arg3 != O1 && arg3 != O2, "smashed argument");
   145   return call_RT(oop_result1, metadata_result, entry, 3);
   140   return call_RT(oop_result1, metadata_result, entry, 3);
   146 }
   141 }
   147 
   142 
       
   143 void StubAssembler::prologue(const char* name, bool must_gc_arguments) {
       
   144   set_info(name, must_gc_arguments);
       
   145 }
       
   146 
       
   147 void StubAssembler::epilogue() {
       
   148   delayed()->restore();
       
   149 }
   148 
   150 
   149 // Implementation of Runtime1
   151 // Implementation of Runtime1
   150 
   152 
   151 #define __ sasm->
       
   152 
   153 
   153 static int cpu_reg_save_offsets[FrameMap::nof_cpu_regs];
   154 static int cpu_reg_save_offsets[FrameMap::nof_cpu_regs];
   154 static int fpu_reg_save_offsets[FrameMap::nof_fpu_regs];
   155 static int fpu_reg_save_offsets[FrameMap::nof_fpu_regs];
   155 static int reg_save_size_in_words;
   156 static int reg_save_size_in_words;
   156 static int frame_size_in_bytes = -1;
   157 static int frame_size_in_bytes = -1;
   157 
   158 
   158 static OopMap* generate_oop_map(StubAssembler* sasm, bool save_fpu_registers) {
   159 static OopMap* generate_oop_map(StubAssembler* sasm, bool save_fpu_registers) {
   159   assert(frame_size_in_bytes == __ total_frame_size_in_bytes(reg_save_size_in_words),
   160   assert(frame_size_in_bytes == sasm->total_frame_size_in_bytes(reg_save_size_in_words),
   160          "mismatch in calculation");
   161          "mismatch in calculation");
   161   sasm->set_frame_size(frame_size_in_bytes / BytesPerWord);
   162   sasm->set_frame_size(frame_size_in_bytes / BytesPerWord);
   162   int frame_size_in_slots = frame_size_in_bytes / sizeof(jint);
   163   int frame_size_in_slots = frame_size_in_bytes / sizeof(jint);
   163   OopMap* oop_map = new OopMap(frame_size_in_slots, 0);
   164   OopMap* oop_map = new OopMap(frame_size_in_slots, 0);
   164 
   165 
   181     }
   182     }
   182   }
   183   }
   183   return oop_map;
   184   return oop_map;
   184 }
   185 }
   185 
   186 
   186 static OopMap* save_live_registers(StubAssembler* sasm, bool save_fpu_registers = true) {
   187 #define __ this->
       
   188 
       
   189 void C1_MacroAssembler::save_live_registers_no_oop_map(bool save_fpu_registers) {
   187   assert(frame_size_in_bytes == __ total_frame_size_in_bytes(reg_save_size_in_words),
   190   assert(frame_size_in_bytes == __ total_frame_size_in_bytes(reg_save_size_in_words),
   188          "mismatch in calculation");
   191          "mismatch in calculation");
   189   __ save_frame_c1(frame_size_in_bytes);
   192   __ save_frame_c1(frame_size_in_bytes);
   190 
   193 
   191   // Record volatile registers as callee-save values in an OopMap so their save locations will be
   194   // Record volatile registers as callee-save values in an OopMap so their save locations will be
   209       FloatRegister r = as_FloatRegister(i);
   212       FloatRegister r = as_FloatRegister(i);
   210       int sp_offset = fpu_reg_save_offsets[i];
   213       int sp_offset = fpu_reg_save_offsets[i];
   211       __ stf(FloatRegisterImpl::S, r, SP, (sp_offset * BytesPerWord) + STACK_BIAS);
   214       __ stf(FloatRegisterImpl::S, r, SP, (sp_offset * BytesPerWord) + STACK_BIAS);
   212     }
   215     }
   213   }
   216   }
   214 
   217 }
   215   return generate_oop_map(sasm, save_fpu_registers);
   218 
   216 }
   219 void C1_MacroAssembler::restore_live_registers(bool restore_fpu_registers) {
   217 
       
   218 static void restore_live_registers(StubAssembler* sasm, bool restore_fpu_registers = true) {
       
   219   for (int i = 0; i < FrameMap::nof_cpu_regs; i++) {
   220   for (int i = 0; i < FrameMap::nof_cpu_regs; i++) {
   220     Register r = as_Register(i);
   221     Register r = as_Register(i);
   221     if (r == G1 || r == G3 || r == G4 || r == G5) {
   222     if (r == G1 || r == G3 || r == G4 || r == G5) {
   222       __ ld_ptr(SP, (cpu_reg_save_offsets[i] * BytesPerWord) + STACK_BIAS, r);
   223       __ ld_ptr(SP, (cpu_reg_save_offsets[i] * BytesPerWord) + STACK_BIAS, r);
   223     }
   224     }
   227     for (int i = 0; i < FrameMap::nof_fpu_regs; i++) {
   228     for (int i = 0; i < FrameMap::nof_fpu_regs; i++) {
   228       FloatRegister r = as_FloatRegister(i);
   229       FloatRegister r = as_FloatRegister(i);
   229       __ ldf(FloatRegisterImpl::S, SP, (fpu_reg_save_offsets[i] * BytesPerWord) + STACK_BIAS, r);
   230       __ ldf(FloatRegisterImpl::S, SP, (fpu_reg_save_offsets[i] * BytesPerWord) + STACK_BIAS, r);
   230     }
   231     }
   231   }
   232   }
       
   233 }
       
   234 
       
   235 #undef __
       
   236 #define __ sasm->
       
   237 
       
   238 static OopMap* save_live_registers(StubAssembler* sasm, bool save_fpu_registers = true) {
       
   239   sasm->save_live_registers_no_oop_map(save_fpu_registers);
       
   240   return generate_oop_map(sasm, save_fpu_registers);
       
   241 }
       
   242 
       
   243 static void restore_live_registers(StubAssembler* sasm, bool restore_fpu_registers = true) {
       
   244   sasm->restore_live_registers(restore_fpu_registers);
   232 }
   245 }
   233 
   246 
   234 
   247 
   235 void Runtime1::initialize_pd() {
   248 void Runtime1::initialize_pd() {
   236   // compute word offsets from SP at which live (non-windowed) registers are captured by stub routines
   249   // compute word offsets from SP at which live (non-windowed) registers are captured by stub routines
   757         __ ret();
   770         __ ret();
   758         __ delayed()->restore();
   771         __ delayed()->restore();
   759       }
   772       }
   760       break;
   773       break;
   761 
   774 
   762 #if INCLUDE_ALL_GCS
       
   763     case g1_pre_barrier_slow_id:
       
   764       { // G4: previous value of memory
       
   765         BarrierSet* bs = BarrierSet::barrier_set();
       
   766         if (bs->kind() != BarrierSet::G1BarrierSet) {
       
   767           __ save_frame(0);
       
   768           __ set((int)id, O1);
       
   769           __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, unimplemented_entry), I0);
       
   770           __ should_not_reach_here();
       
   771           break;
       
   772         }
       
   773 
       
   774         __ set_info("g1_pre_barrier_slow_id", dont_gc_arguments);
       
   775 
       
   776         Register pre_val = G4;
       
   777         Register tmp  = G1_scratch;
       
   778         Register tmp2 = G3_scratch;
       
   779 
       
   780         Label refill, restart;
       
   781         int satb_q_active_byte_offset = in_bytes(G1ThreadLocalData::satb_mark_queue_active_offset());
       
   782         int satb_q_index_byte_offset = in_bytes(G1ThreadLocalData::satb_mark_queue_index_offset());
       
   783         int satb_q_buf_byte_offset = in_bytes(G1ThreadLocalData::satb_mark_queue_buffer_offset());
       
   784 
       
   785         // Is marking still active?
       
   786         if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) {
       
   787           __ ld(G2_thread, satb_q_active_byte_offset, tmp);
       
   788         } else {
       
   789           assert(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "Assumption");
       
   790           __ ldsb(G2_thread, satb_q_active_byte_offset, tmp);
       
   791         }
       
   792         __ cmp_and_br_short(tmp, G0, Assembler::notEqual, Assembler::pt, restart);
       
   793         __ retl();
       
   794         __ delayed()->nop();
       
   795 
       
   796         __ bind(restart);
       
   797         // Load the index into the SATB buffer. SATBMarkQueue::_index is a
       
   798         // size_t so ld_ptr is appropriate
       
   799         __ ld_ptr(G2_thread, satb_q_index_byte_offset, tmp);
       
   800 
       
   801         // index == 0?
       
   802         __ cmp_and_brx_short(tmp, G0, Assembler::equal, Assembler::pn, refill);
       
   803 
       
   804         __ ld_ptr(G2_thread, satb_q_buf_byte_offset, tmp2);
       
   805         __ sub(tmp, oopSize, tmp);
       
   806 
       
   807         __ st_ptr(pre_val, tmp2, tmp);  // [_buf + index] := <address_of_card>
       
   808         // Use return-from-leaf
       
   809         __ retl();
       
   810         __ delayed()->st_ptr(tmp, G2_thread, satb_q_index_byte_offset);
       
   811 
       
   812         __ bind(refill);
       
   813 
       
   814         save_live_registers(sasm);
       
   815 
       
   816         __ call_VM_leaf(L7_thread_cache,
       
   817                         CAST_FROM_FN_PTR(address,
       
   818                                          SATBMarkQueueSet::handle_zero_index_for_thread),
       
   819                                          G2_thread);
       
   820 
       
   821         restore_live_registers(sasm);
       
   822 
       
   823         __ br(Assembler::always, /*annul*/false, Assembler::pt, restart);
       
   824         __ delayed()->restore();
       
   825       }
       
   826       break;
       
   827 
       
   828     case g1_post_barrier_slow_id:
       
   829       {
       
   830         BarrierSet* bs = BarrierSet::barrier_set();
       
   831         if (bs->kind() != BarrierSet::G1BarrierSet) {
       
   832           __ save_frame(0);
       
   833           __ set((int)id, O1);
       
   834           __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, unimplemented_entry), I0);
       
   835           __ should_not_reach_here();
       
   836           break;
       
   837         }
       
   838 
       
   839         __ set_info("g1_post_barrier_slow_id", dont_gc_arguments);
       
   840 
       
   841         Register addr = G4;
       
   842         Register cardtable = G5;
       
   843         Register tmp  = G1_scratch;
       
   844         Register tmp2 = G3_scratch;
       
   845         jbyte* byte_map_base = ci_card_table_address();
       
   846 
       
   847         Label not_already_dirty, restart, refill, young_card;
       
   848 
       
   849         __ srlx(addr, CardTable::card_shift, addr);
       
   850 
       
   851         AddressLiteral rs(byte_map_base);
       
   852         __ set(rs, cardtable);         // cardtable := <card table base>
       
   853         __ ldub(addr, cardtable, tmp); // tmp := [addr + cardtable]
       
   854 
       
   855         __ cmp_and_br_short(tmp, G1CardTable::g1_young_card_val(), Assembler::equal, Assembler::pt, young_card);
       
   856 
       
   857         __ membar(Assembler::Membar_mask_bits(Assembler::StoreLoad));
       
   858         __ ldub(addr, cardtable, tmp); // tmp := [addr + cardtable]
       
   859 
       
   860         assert(CardTable::dirty_card_val() == 0, "otherwise check this code");
       
   861         __ cmp_and_br_short(tmp, G0, Assembler::notEqual, Assembler::pt, not_already_dirty);
       
   862 
       
   863         __ bind(young_card);
       
   864         // We didn't take the branch, so we're already dirty: return.
       
   865         // Use return-from-leaf
       
   866         __ retl();
       
   867         __ delayed()->nop();
       
   868 
       
   869         // Not dirty.
       
   870         __ bind(not_already_dirty);
       
   871 
       
   872         // Get cardtable + tmp into a reg by itself
       
   873         __ add(addr, cardtable, tmp2);
       
   874 
       
   875         // First, dirty it.
       
   876         __ stb(G0, tmp2, 0);  // [cardPtr] := 0  (i.e., dirty).
       
   877 
       
   878         Register tmp3 = cardtable;
       
   879         Register tmp4 = tmp;
       
   880 
       
   881         // these registers are now dead
       
   882         addr = cardtable = tmp = noreg;
       
   883 
       
   884         int dirty_card_q_index_byte_offset = in_bytes(G1ThreadLocalData::dirty_card_queue_index_offset());
       
   885         int dirty_card_q_buf_byte_offset = in_bytes(G1ThreadLocalData::dirty_card_queue_buffer_offset());
       
   886 
       
   887         __ bind(restart);
       
   888 
       
   889         // Get the index into the update buffer. DirtyCardQueue::_index is
       
   890         // a size_t so ld_ptr is appropriate here.
       
   891         __ ld_ptr(G2_thread, dirty_card_q_index_byte_offset, tmp3);
       
   892 
       
   893         // index == 0?
       
   894         __ cmp_and_brx_short(tmp3, G0, Assembler::equal,  Assembler::pn, refill);
       
   895 
       
   896         __ ld_ptr(G2_thread, dirty_card_q_buf_byte_offset, tmp4);
       
   897         __ sub(tmp3, oopSize, tmp3);
       
   898 
       
   899         __ st_ptr(tmp2, tmp4, tmp3);  // [_buf + index] := <address_of_card>
       
   900         // Use return-from-leaf
       
   901         __ retl();
       
   902         __ delayed()->st_ptr(tmp3, G2_thread, dirty_card_q_index_byte_offset);
       
   903 
       
   904         __ bind(refill);
       
   905 
       
   906         save_live_registers(sasm);
       
   907 
       
   908         __ call_VM_leaf(L7_thread_cache,
       
   909                         CAST_FROM_FN_PTR(address,
       
   910                                          DirtyCardQueueSet::handle_zero_index_for_thread),
       
   911                                          G2_thread);
       
   912 
       
   913         restore_live_registers(sasm);
       
   914 
       
   915         __ br(Assembler::always, /*annul*/false, Assembler::pt, restart);
       
   916         __ delayed()->restore();
       
   917       }
       
   918       break;
       
   919 #endif // INCLUDE_ALL_GCS
       
   920 
       
   921     case predicate_failed_trap_id:
   775     case predicate_failed_trap_id:
   922       {
   776       {
   923         __ set_info("predicate_failed_trap", dont_gc_arguments);
   777         __ set_info("predicate_failed_trap", dont_gc_arguments);
   924         OopMap* oop_map = save_live_registers(sasm);
   778         OopMap* oop_map = save_live_registers(sasm);
   925 
   779