src/hotspot/cpu/aarch64/c1_Runtime1_aarch64.cpp
changeset 49906 4bb58f644e4e
parent 49754 ee93c1087584
child 50094 2f79462aab9b
equal deleted inserted replaced
49905:a09af8ef8e5c 49906:4bb58f644e4e
    41 #include "runtime/sharedRuntime.hpp"
    41 #include "runtime/sharedRuntime.hpp"
    42 #include "runtime/signature.hpp"
    42 #include "runtime/signature.hpp"
    43 #include "runtime/vframe.hpp"
    43 #include "runtime/vframe.hpp"
    44 #include "runtime/vframeArray.hpp"
    44 #include "runtime/vframeArray.hpp"
    45 #include "vmreg_aarch64.inline.hpp"
    45 #include "vmreg_aarch64.inline.hpp"
    46 #if INCLUDE_ALL_GCS
       
    47 #include "gc/g1/g1BarrierSet.hpp"
       
    48 #include "gc/g1/g1CardTable.hpp"
       
    49 #include "gc/g1/g1ThreadLocalData.hpp"
       
    50 #endif
       
    51 
    46 
    52 
    47 
    53 // Implementation of StubAssembler
    48 // Implementation of StubAssembler
    54 
    49 
    55 int StubAssembler::call_RT(Register oop_result1, Register metadata_result, address entry, int args_size) {
    50 int StubAssembler::call_RT(Register oop_result1, Register metadata_result, address entry, int args_size) {
   171   void load_argument(int offset_in_words, Register reg);
   166   void load_argument(int offset_in_words, Register reg);
   172 
   167 
   173   ~StubFrame();
   168   ~StubFrame();
   174 };;
   169 };;
   175 
   170 
       
   171 void StubAssembler::prologue(const char* name, bool must_gc_arguments) {
       
   172   set_info(name, must_gc_arguments);
       
   173   enter();
       
   174 }
       
   175 
       
   176 void StubAssembler::epilogue() {
       
   177   leave();
       
   178   ret(lr);
       
   179 }
   176 
   180 
   177 #define __ _sasm->
   181 #define __ _sasm->
   178 
   182 
   179 StubFrame::StubFrame(StubAssembler* sasm, const char* name, bool must_gc_arguments) {
   183 StubFrame::StubFrame(StubAssembler* sasm, const char* name, bool must_gc_arguments) {
   180   _sasm = sasm;
   184   _sasm = sasm;
   181   __ set_info(name, must_gc_arguments);
   185   __ prologue(name, must_gc_arguments);
   182   __ enter();
       
   183 }
   186 }
   184 
   187 
   185 // load parameters that were stored with LIR_Assembler::store_parameter
   188 // load parameters that were stored with LIR_Assembler::store_parameter
   186 // Note: offsets for store_parameter and load_argument must match
   189 // Note: offsets for store_parameter and load_argument must match
   187 void StubFrame::load_argument(int offset_in_words, Register reg) {
   190 void StubFrame::load_argument(int offset_in_words, Register reg) {
   188   // rbp, + 0: link
   191   __ load_parameter(offset_in_words, reg);
   189   //     + 1: return address
       
   190   //     + 2: argument with offset 0
       
   191   //     + 3: argument with offset 1
       
   192   //     + 4: ...
       
   193 
       
   194   __ ldr(reg, Address(rfp, (offset_in_words + 2) * BytesPerWord));
       
   195 }
   192 }
   196 
   193 
   197 
   194 
   198 StubFrame::~StubFrame() {
   195 StubFrame::~StubFrame() {
   199   __ leave();
   196   __ epilogue();
   200   __ ret(lr);
       
   201 }
   197 }
   202 
   198 
   203 #undef __
   199 #undef __
   204 
   200 
   205 
   201 
  1098         //     + 1: return address
  1094         //     + 1: return address
  1099         oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_array_store_exception), true);
  1095         oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_array_store_exception), true);
  1100       }
  1096       }
  1101       break;
  1097       break;
  1102 
  1098 
  1103 #if INCLUDE_ALL_GCS
       
  1104 
       
  1105     case g1_pre_barrier_slow_id:
       
  1106       {
       
  1107         StubFrame f(sasm, "g1_pre_barrier", dont_gc_arguments);
       
  1108         // arg0 : previous value of memory
       
  1109 
       
  1110         BarrierSet* bs = BarrierSet::barrier_set();
       
  1111         if (bs->kind() != BarrierSet::G1BarrierSet) {
       
  1112           __ mov(r0, (int)id);
       
  1113           __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, unimplemented_entry), r0);
       
  1114           __ should_not_reach_here();
       
  1115           break;
       
  1116         }
       
  1117 
       
  1118         const Register pre_val = r0;
       
  1119         const Register thread = rthread;
       
  1120         const Register tmp = rscratch1;
       
  1121 
       
  1122         Address in_progress(thread, in_bytes(G1ThreadLocalData::satb_mark_queue_active_offset()));
       
  1123         Address queue_index(thread, in_bytes(G1ThreadLocalData::satb_mark_queue_index_offset()));
       
  1124         Address buffer(thread, in_bytes(G1ThreadLocalData::satb_mark_queue_buffer_offset()));
       
  1125 
       
  1126         Label done;
       
  1127         Label runtime;
       
  1128 
       
  1129         // Is marking still active?
       
  1130         if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) {
       
  1131           __ ldrw(tmp, in_progress);
       
  1132         } else {
       
  1133           assert(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "Assumption");
       
  1134           __ ldrb(tmp, in_progress);
       
  1135         }
       
  1136         __ cbzw(tmp, done);
       
  1137 
       
  1138         // Can we store original value in the thread's buffer?
       
  1139         __ ldr(tmp, queue_index);
       
  1140         __ cbz(tmp, runtime);
       
  1141 
       
  1142         __ sub(tmp, tmp, wordSize);
       
  1143         __ str(tmp, queue_index);
       
  1144         __ ldr(rscratch2, buffer);
       
  1145         __ add(tmp, tmp, rscratch2);
       
  1146         f.load_argument(0, rscratch2);
       
  1147         __ str(rscratch2, Address(tmp, 0));
       
  1148         __ b(done);
       
  1149 
       
  1150         __ bind(runtime);
       
  1151         __ push_call_clobbered_registers();
       
  1152         f.load_argument(0, pre_val);
       
  1153         __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_pre), pre_val, thread);
       
  1154         __ pop_call_clobbered_registers();
       
  1155         __ bind(done);
       
  1156       }
       
  1157       break;
       
  1158     case g1_post_barrier_slow_id:
       
  1159       {
       
  1160         StubFrame f(sasm, "g1_post_barrier", dont_gc_arguments);
       
  1161 
       
  1162         BarrierSet* bs = BarrierSet::barrier_set();
       
  1163         if (bs->kind() != BarrierSet::G1BarrierSet) {
       
  1164           __ mov(r0, (int)id);
       
  1165           __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, unimplemented_entry), r0);
       
  1166           __ should_not_reach_here();
       
  1167           break;
       
  1168         }
       
  1169 
       
  1170         // arg0: store_address
       
  1171         Address store_addr(rfp, 2*BytesPerWord);
       
  1172 
       
  1173         Label done;
       
  1174         Label runtime;
       
  1175 
       
  1176         // At this point we know new_value is non-NULL and the new_value crosses regions.
       
  1177         // Must check to see if card is already dirty
       
  1178 
       
  1179         const Register thread = rthread;
       
  1180 
       
  1181         Address queue_index(thread, in_bytes(G1ThreadLocalData::dirty_card_queue_index_offset()));
       
  1182         Address buffer(thread, in_bytes(G1ThreadLocalData::dirty_card_queue_buffer_offset()));
       
  1183 
       
  1184         const Register card_offset = rscratch2;
       
  1185         // LR is free here, so we can use it to hold the byte_map_base.
       
  1186         const Register byte_map_base = lr;
       
  1187 
       
  1188         assert_different_registers(card_offset, byte_map_base, rscratch1);
       
  1189 
       
  1190         f.load_argument(0, card_offset);
       
  1191         __ lsr(card_offset, card_offset, CardTable::card_shift);
       
  1192         __ load_byte_map_base(byte_map_base);
       
  1193         __ ldrb(rscratch1, Address(byte_map_base, card_offset));
       
  1194         __ cmpw(rscratch1, (int)G1CardTable::g1_young_card_val());
       
  1195         __ br(Assembler::EQ, done);
       
  1196 
       
  1197         assert((int)CardTable::dirty_card_val() == 0, "must be 0");
       
  1198 
       
  1199         __ membar(Assembler::StoreLoad);
       
  1200         __ ldrb(rscratch1, Address(byte_map_base, card_offset));
       
  1201         __ cbzw(rscratch1, done);
       
  1202 
       
  1203         // storing region crossing non-NULL, card is clean.
       
  1204         // dirty card and log.
       
  1205         __ strb(zr, Address(byte_map_base, card_offset));
       
  1206 
       
  1207         // Convert card offset into an address in card_addr
       
  1208         Register card_addr = card_offset;
       
  1209         __ add(card_addr, byte_map_base, card_addr);
       
  1210 
       
  1211         __ ldr(rscratch1, queue_index);
       
  1212         __ cbz(rscratch1, runtime);
       
  1213         __ sub(rscratch1, rscratch1, wordSize);
       
  1214         __ str(rscratch1, queue_index);
       
  1215 
       
  1216         // Reuse LR to hold buffer_addr
       
  1217         const Register buffer_addr = lr;
       
  1218 
       
  1219         __ ldr(buffer_addr, buffer);
       
  1220         __ str(card_addr, Address(buffer_addr, rscratch1));
       
  1221         __ b(done);
       
  1222 
       
  1223         __ bind(runtime);
       
  1224         __ push_call_clobbered_registers();
       
  1225         __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_post), card_addr, thread);
       
  1226         __ pop_call_clobbered_registers();
       
  1227         __ bind(done);
       
  1228 
       
  1229       }
       
  1230       break;
       
  1231 #endif
       
  1232 
       
  1233     case predicate_failed_trap_id:
  1099     case predicate_failed_trap_id:
  1234       {
  1100       {
  1235         StubFrame f(sasm, "predicate_failed_trap", dont_gc_arguments);
  1101         StubFrame f(sasm, "predicate_failed_trap", dont_gc_arguments);
  1236 
  1102 
  1237         OopMap* map = save_live_registers(sasm);
  1103         OopMap* map = save_live_registers(sasm);