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); |