< prev index next >

src/cpu/aarch64/vm/c1_Runtime1_aarch64.cpp

Print this page




 155     mov(c_rarg1, arg1);
 156     mov(c_rarg2, arg2);
 157     mov(c_rarg3, arg3);
 158   }
 159   return call_RT(oop_result1, metadata_result, entry, 3);
 160 }
 161 
 162 // Implementation of StubFrame
 163 
 164 class StubFrame: public StackObj {
 165  private:
 166   StubAssembler* _sasm;
 167 
 168  public:
 169   StubFrame(StubAssembler* sasm, const char* name, bool must_gc_arguments);
 170   void load_argument(int offset_in_words, Register reg);
 171 
 172   ~StubFrame();
 173 };;
 174 









 175 
 176 #define __ _sasm->
 177 
 178 StubFrame::StubFrame(StubAssembler* sasm, const char* name, bool must_gc_arguments) {
 179   _sasm = sasm;
 180   __ set_info(name, must_gc_arguments);
 181   __ enter();
 182 }
 183 
 184 // load parameters that were stored with LIR_Assembler::store_parameter
 185 // Note: offsets for store_parameter and load_argument must match
 186 void StubFrame::load_argument(int offset_in_words, Register reg) {
 187   // rbp, + 0: link
 188   //     + 1: return address
 189   //     + 2: argument with offset 0
 190   //     + 3: argument with offset 1
 191   //     + 4: ...
 192 
 193   __ ldr(reg, Address(rfp, (offset_in_words + 2) * BytesPerWord));
 194 }
 195 
 196 
 197 StubFrame::~StubFrame() {
 198   __ leave();
 199   __ ret(lr);
 200 }
 201 
 202 #undef __
 203 
 204 
 205 // Implementation of Runtime1
 206 
 207 #define __ sasm->
 208 
 209 const int float_regs_as_doubles_size_in_slots = pd_nof_fpu_regs_frame_map * 2;
 210 
 211 // Stack layout for saving/restoring  all the registers needed during a runtime
 212 // call (this includes deoptimization)
 213 // Note: note that users of this frame may well have arguments to some runtime
 214 // while these values are on the stack. These positions neglect those arguments
 215 // but the code in save_live_registers will take the argument count into
 216 // account.
 217 //
 218 
 219 enum reg_save_layout {


1134 
1135     case handle_exception_from_callee_id:
1136       { StubFrame f(sasm, "handle_exception_from_callee", dont_gc_arguments);
1137         oop_maps = generate_handle_exception(id, sasm);
1138       }
1139       break;
1140 
1141     case throw_index_exception_id:
1142       { StubFrame f(sasm, "index_range_check_failed", dont_gc_arguments);
1143         oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_index_exception), true);
1144       }
1145       break;
1146 
1147     case throw_array_store_exception_id:
1148       { StubFrame f(sasm, "throw_array_store_exception", dont_gc_arguments);
1149         // tos + 0: link
1150         //     + 1: return address
1151         oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_array_store_exception), true);
1152       }
1153       break;
1154 
1155 #if INCLUDE_ALL_GCS
1156 
1157     case g1_pre_barrier_slow_id:
1158       {
1159         StubFrame f(sasm, "g1_pre_barrier", dont_gc_arguments);
1160         // arg0 : previous value of memory
1161 
1162         BarrierSet* bs = Universe::heap()->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         const Register pre_val = r0;
1171         const Register thread = rthread;
1172         const Register tmp = rscratch1;
1173 
1174         Address in_progress(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
1175                                              SATBMarkQueue::byte_offset_of_active()));
1176 
1177         Address queue_index(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
1178                                              SATBMarkQueue::byte_offset_of_index()));
1179         Address buffer(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
1180                                         SATBMarkQueue::byte_offset_of_buf()));
1181 
1182         Label done;
1183         Label runtime;
1184 
1185         // Is marking still active?
1186         if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) {
1187           __ ldrw(tmp, in_progress);
1188         } else {
1189           assert(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "Assumption");
1190           __ ldrb(tmp, in_progress);
1191         }
1192         __ cbzw(tmp, done);
1193 
1194         // Can we store original value in the thread's buffer?
1195         __ ldr(tmp, queue_index);
1196         __ cbz(tmp, runtime);
1197 
1198         __ sub(tmp, tmp, wordSize);
1199         __ str(tmp, queue_index);
1200         __ ldr(rscratch2, buffer);
1201         __ add(tmp, tmp, rscratch2);
1202         f.load_argument(0, rscratch2);
1203         __ str(rscratch2, Address(tmp, 0));
1204         __ b(done);
1205 
1206         __ bind(runtime);
1207         __ push_call_clobbered_registers();
1208         f.load_argument(0, pre_val);
1209         __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_pre), pre_val, thread);
1210         __ pop_call_clobbered_registers();
1211         __ bind(done);
1212       }
1213       break;
1214     case g1_post_barrier_slow_id:
1215       {
1216         StubFrame f(sasm, "g1_post_barrier", dont_gc_arguments);
1217 
1218         // arg0: store_address
1219         Address store_addr(rfp, 2*BytesPerWord);
1220 
1221         BarrierSet* bs = Universe::heap()->barrier_set();
1222         CardTableModRefBS* ctbs = barrier_set_cast<CardTableModRefBS>(bs);
1223         CardTable* ct = ctbs->card_table();
1224         assert(sizeof(*ct->byte_map_base()) == sizeof(jbyte), "adjust this code");
1225 
1226         Label done;
1227         Label runtime;
1228 
1229         // At this point we know new_value is non-NULL and the new_value crosses regions.
1230         // Must check to see if card is already dirty
1231 
1232         const Register thread = rthread;
1233 
1234         Address queue_index(thread, in_bytes(JavaThread::dirty_card_queue_offset() +
1235                                              DirtyCardQueue::byte_offset_of_index()));
1236         Address buffer(thread, in_bytes(JavaThread::dirty_card_queue_offset() +
1237                                         DirtyCardQueue::byte_offset_of_buf()));
1238 
1239         const Register card_offset = rscratch2;
1240         // LR is free here, so we can use it to hold the byte_map_base.
1241         const Register byte_map_base = lr;
1242 
1243         assert_different_registers(card_offset, byte_map_base, rscratch1);
1244 
1245         f.load_argument(0, card_offset);
1246         __ lsr(card_offset, card_offset, CardTable::card_shift);
1247         __ load_byte_map_base(byte_map_base);
1248         __ ldrb(rscratch1, Address(byte_map_base, card_offset));
1249         __ cmpw(rscratch1, (int)G1CardTable::g1_young_card_val());
1250         __ br(Assembler::EQ, done);
1251 
1252         assert((int)CardTable::dirty_card_val() == 0, "must be 0");
1253 
1254         __ membar(Assembler::StoreLoad);
1255         __ ldrb(rscratch1, Address(byte_map_base, card_offset));
1256         __ cbzw(rscratch1, done);
1257 
1258         // storing region crossing non-NULL, card is clean.
1259         // dirty card and log.
1260         __ strb(zr, Address(byte_map_base, card_offset));
1261 
1262         // Convert card offset into an address in card_addr
1263         Register card_addr = card_offset;
1264         __ add(card_addr, byte_map_base, card_addr);
1265 
1266         __ ldr(rscratch1, queue_index);
1267         __ cbz(rscratch1, runtime);
1268         __ sub(rscratch1, rscratch1, wordSize);
1269         __ str(rscratch1, queue_index);
1270 
1271         // Reuse LR to hold buffer_addr
1272         const Register buffer_addr = lr;
1273 
1274         __ ldr(buffer_addr, buffer);
1275         __ str(card_addr, Address(buffer_addr, rscratch1));
1276         __ b(done);
1277 
1278         __ bind(runtime);
1279         __ push_call_clobbered_registers();
1280         __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_post), card_addr, thread);
1281         __ pop_call_clobbered_registers();
1282         __ bind(done);
1283 
1284       }
1285       break;
1286 #endif
1287 
1288     case predicate_failed_trap_id:
1289       {
1290         StubFrame f(sasm, "predicate_failed_trap", dont_gc_arguments);
1291 
1292         OopMap* map = save_live_registers(sasm);
1293 
1294         int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, predicate_failed_trap));
1295         oop_maps = new OopMapSet();
1296         oop_maps->add_gc_map(call_offset, map);
1297         restore_live_registers(sasm);
1298         __ leave();
1299         DeoptimizationBlob* deopt_blob = SharedRuntime::deopt_blob();
1300         assert(deopt_blob != NULL, "deoptimization blob must have been created");
1301 
1302         __ far_jump(RuntimeAddress(deopt_blob->unpack_with_reexecution()));
1303       }
1304       break;
1305 
1306 


 155     mov(c_rarg1, arg1);
 156     mov(c_rarg2, arg2);
 157     mov(c_rarg3, arg3);
 158   }
 159   return call_RT(oop_result1, metadata_result, entry, 3);
 160 }
 161 
 162 // Implementation of StubFrame
 163 
 164 class StubFrame: public StackObj {
 165  private:
 166   StubAssembler* _sasm;
 167 
 168  public:
 169   StubFrame(StubAssembler* sasm, const char* name, bool must_gc_arguments);
 170   void load_argument(int offset_in_words, Register reg);
 171 
 172   ~StubFrame();
 173 };;
 174 
 175 void StubAssembler::prologue(const char* name, bool must_gc_arguments) {
 176   set_info(name, must_gc_arguments);
 177   enter();
 178 }
 179 
 180 void StubAssembler::epilogue() {
 181   leave();
 182   ret(lr);
 183 }
 184 
 185 #define __ _sasm->
 186 
 187 StubFrame::StubFrame(StubAssembler* sasm, const char* name, bool must_gc_arguments) {
 188   _sasm = sasm;
 189   __ prologue(name, must_gc_arguments);

 190 }
 191 
 192 // load parameters that were stored with LIR_Assembler::store_parameter
 193 // Note: offsets for store_parameter and load_argument must match
 194 void StubFrame::load_argument(int offset_in_words, Register reg) {
 195   __ load_parameter(offset_in_words, reg);






 196 }
 197 
 198 
 199 StubFrame::~StubFrame() {
 200   __ epilogue();

 201 }
 202 
 203 #undef __
 204 
 205 
 206 // Implementation of Runtime1
 207 
 208 #define __ sasm->
 209 
 210 const int float_regs_as_doubles_size_in_slots = pd_nof_fpu_regs_frame_map * 2;
 211 
 212 // Stack layout for saving/restoring  all the registers needed during a runtime
 213 // call (this includes deoptimization)
 214 // Note: note that users of this frame may well have arguments to some runtime
 215 // while these values are on the stack. These positions neglect those arguments
 216 // but the code in save_live_registers will take the argument count into
 217 // account.
 218 //
 219 
 220 enum reg_save_layout {


1135 
1136     case handle_exception_from_callee_id:
1137       { StubFrame f(sasm, "handle_exception_from_callee", dont_gc_arguments);
1138         oop_maps = generate_handle_exception(id, sasm);
1139       }
1140       break;
1141 
1142     case throw_index_exception_id:
1143       { StubFrame f(sasm, "index_range_check_failed", dont_gc_arguments);
1144         oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_index_exception), true);
1145       }
1146       break;
1147 
1148     case throw_array_store_exception_id:
1149       { StubFrame f(sasm, "throw_array_store_exception", dont_gc_arguments);
1150         // tos + 0: link
1151         //     + 1: return address
1152         oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_array_store_exception), true);
1153       }
1154       break;





































































































































1155 
1156     case predicate_failed_trap_id:
1157       {
1158         StubFrame f(sasm, "predicate_failed_trap", dont_gc_arguments);
1159 
1160         OopMap* map = save_live_registers(sasm);
1161 
1162         int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, predicate_failed_trap));
1163         oop_maps = new OopMapSet();
1164         oop_maps->add_gc_map(call_offset, map);
1165         restore_live_registers(sasm);
1166         __ leave();
1167         DeoptimizationBlob* deopt_blob = SharedRuntime::deopt_blob();
1168         assert(deopt_blob != NULL, "deoptimization blob must have been created");
1169 
1170         __ far_jump(RuntimeAddress(deopt_blob->unpack_with_reexecution()));
1171       }
1172       break;
1173 
1174 
< prev index next >