227 __ st_ptr(O7, frame_map()->address_for_monitor_lock(i)); |
227 __ st_ptr(O7, frame_map()->address_for_monitor_lock(i)); |
228 __ ld_ptr(OSR_buf, slot_offset + 1*BytesPerWord, O7); |
228 __ ld_ptr(OSR_buf, slot_offset + 1*BytesPerWord, O7); |
229 __ st_ptr(O7, frame_map()->address_for_monitor_object(i)); |
229 __ st_ptr(O7, frame_map()->address_for_monitor_object(i)); |
230 } |
230 } |
231 } |
231 } |
232 } |
|
233 |
|
234 |
|
235 // Optimized Library calls |
|
236 // This is the fast version of java.lang.String.compare; it has not |
|
237 // OSR-entry and therefore, we generate a slow version for OSR's |
|
238 void LIR_Assembler::emit_string_compare(LIR_Opr left, LIR_Opr right, LIR_Opr dst, CodeEmitInfo* info) { |
|
239 Register str0 = left->as_register(); |
|
240 Register str1 = right->as_register(); |
|
241 |
|
242 Label Ldone; |
|
243 |
|
244 Register result = dst->as_register(); |
|
245 { |
|
246 // Get a pointer to the first character of string0 in tmp0 |
|
247 // and get string0.length() in str0 |
|
248 // Get a pointer to the first character of string1 in tmp1 |
|
249 // and get string1.length() in str1 |
|
250 // Also, get string0.length()-string1.length() in |
|
251 // o7 and get the condition code set |
|
252 // Note: some instructions have been hoisted for better instruction scheduling |
|
253 |
|
254 Register tmp0 = L0; |
|
255 Register tmp1 = L1; |
|
256 Register tmp2 = L2; |
|
257 |
|
258 int value_offset = java_lang_String:: value_offset_in_bytes(); // char array |
|
259 if (java_lang_String::has_offset_field()) { |
|
260 int offset_offset = java_lang_String::offset_offset_in_bytes(); // first character position |
|
261 int count_offset = java_lang_String:: count_offset_in_bytes(); |
|
262 __ load_heap_oop(str0, value_offset, tmp0); |
|
263 __ ld(str0, offset_offset, tmp2); |
|
264 __ add(tmp0, arrayOopDesc::base_offset_in_bytes(T_CHAR), tmp0); |
|
265 __ ld(str0, count_offset, str0); |
|
266 __ sll(tmp2, exact_log2(sizeof(jchar)), tmp2); |
|
267 } else { |
|
268 __ load_heap_oop(str0, value_offset, tmp1); |
|
269 __ add(tmp1, arrayOopDesc::base_offset_in_bytes(T_CHAR), tmp0); |
|
270 __ ld(tmp1, arrayOopDesc::length_offset_in_bytes(), str0); |
|
271 } |
|
272 |
|
273 // str1 may be null |
|
274 add_debug_info_for_null_check_here(info); |
|
275 |
|
276 if (java_lang_String::has_offset_field()) { |
|
277 int offset_offset = java_lang_String::offset_offset_in_bytes(); // first character position |
|
278 int count_offset = java_lang_String:: count_offset_in_bytes(); |
|
279 __ load_heap_oop(str1, value_offset, tmp1); |
|
280 __ add(tmp0, tmp2, tmp0); |
|
281 |
|
282 __ ld(str1, offset_offset, tmp2); |
|
283 __ add(tmp1, arrayOopDesc::base_offset_in_bytes(T_CHAR), tmp1); |
|
284 __ ld(str1, count_offset, str1); |
|
285 __ sll(tmp2, exact_log2(sizeof(jchar)), tmp2); |
|
286 __ add(tmp1, tmp2, tmp1); |
|
287 } else { |
|
288 __ load_heap_oop(str1, value_offset, tmp2); |
|
289 __ add(tmp2, arrayOopDesc::base_offset_in_bytes(T_CHAR), tmp1); |
|
290 __ ld(tmp2, arrayOopDesc::length_offset_in_bytes(), str1); |
|
291 } |
|
292 __ subcc(str0, str1, O7); |
|
293 } |
|
294 |
|
295 { |
|
296 // Compute the minimum of the string lengths, scale it and store it in limit |
|
297 Register count0 = I0; |
|
298 Register count1 = I1; |
|
299 Register limit = L3; |
|
300 |
|
301 Label Lskip; |
|
302 __ sll(count0, exact_log2(sizeof(jchar)), limit); // string0 is shorter |
|
303 __ br(Assembler::greater, true, Assembler::pt, Lskip); |
|
304 __ delayed()->sll(count1, exact_log2(sizeof(jchar)), limit); // string1 is shorter |
|
305 __ bind(Lskip); |
|
306 |
|
307 // If either string is empty (or both of them) the result is the difference in lengths |
|
308 __ cmp(limit, 0); |
|
309 __ br(Assembler::equal, true, Assembler::pn, Ldone); |
|
310 __ delayed()->mov(O7, result); // result is difference in lengths |
|
311 } |
|
312 |
|
313 { |
|
314 // Neither string is empty |
|
315 Label Lloop; |
|
316 |
|
317 Register base0 = L0; |
|
318 Register base1 = L1; |
|
319 Register chr0 = I0; |
|
320 Register chr1 = I1; |
|
321 Register limit = L3; |
|
322 |
|
323 // Shift base0 and base1 to the end of the arrays, negate limit |
|
324 __ add(base0, limit, base0); |
|
325 __ add(base1, limit, base1); |
|
326 __ neg(limit); // limit = -min{string0.length(), string1.length()} |
|
327 |
|
328 __ lduh(base0, limit, chr0); |
|
329 __ bind(Lloop); |
|
330 __ lduh(base1, limit, chr1); |
|
331 __ subcc(chr0, chr1, chr0); |
|
332 __ br(Assembler::notZero, false, Assembler::pn, Ldone); |
|
333 assert(chr0 == result, "result must be pre-placed"); |
|
334 __ delayed()->inccc(limit, sizeof(jchar)); |
|
335 __ br(Assembler::notZero, true, Assembler::pt, Lloop); |
|
336 __ delayed()->lduh(base0, limit, chr0); |
|
337 } |
|
338 |
|
339 // If strings are equal up to min length, return the length difference. |
|
340 __ mov(O7, result); |
|
341 |
|
342 // Otherwise, return the difference between the first mismatched chars. |
|
343 __ bind(Ldone); |
|
344 } |
232 } |
345 |
233 |
346 |
234 |
347 // -------------------------------------------------------------------------------------------- |
235 // -------------------------------------------------------------------------------------------- |
348 |
236 |