< prev index next >
src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp
Print this page
*** 230,351 ****
}
}
}
- // Optimized Library calls
- // This is the fast version of java.lang.String.compare; it has not
- // OSR-entry and therefore, we generate a slow version for OSR's
- void LIR_Assembler::emit_string_compare(LIR_Opr left, LIR_Opr right, LIR_Opr dst, CodeEmitInfo* info) {
- Register str0 = left->as_register();
- Register str1 = right->as_register();
-
- Label Ldone;
-
- Register result = dst->as_register();
- {
- // Get a pointer to the first character of string0 in tmp0
- // and get string0.length() in str0
- // Get a pointer to the first character of string1 in tmp1
- // and get string1.length() in str1
- // Also, get string0.length()-string1.length() in
- // o7 and get the condition code set
- // Note: some instructions have been hoisted for better instruction scheduling
-
- Register tmp0 = L0;
- Register tmp1 = L1;
- Register tmp2 = L2;
-
- int value_offset = java_lang_String:: value_offset_in_bytes(); // char array
- if (java_lang_String::has_offset_field()) {
- int offset_offset = java_lang_String::offset_offset_in_bytes(); // first character position
- int count_offset = java_lang_String:: count_offset_in_bytes();
- __ load_heap_oop(str0, value_offset, tmp0);
- __ ld(str0, offset_offset, tmp2);
- __ add(tmp0, arrayOopDesc::base_offset_in_bytes(T_CHAR), tmp0);
- __ ld(str0, count_offset, str0);
- __ sll(tmp2, exact_log2(sizeof(jchar)), tmp2);
- } else {
- __ load_heap_oop(str0, value_offset, tmp1);
- __ add(tmp1, arrayOopDesc::base_offset_in_bytes(T_CHAR), tmp0);
- __ ld(tmp1, arrayOopDesc::length_offset_in_bytes(), str0);
- }
-
- // str1 may be null
- add_debug_info_for_null_check_here(info);
-
- if (java_lang_String::has_offset_field()) {
- int offset_offset = java_lang_String::offset_offset_in_bytes(); // first character position
- int count_offset = java_lang_String:: count_offset_in_bytes();
- __ load_heap_oop(str1, value_offset, tmp1);
- __ add(tmp0, tmp2, tmp0);
-
- __ ld(str1, offset_offset, tmp2);
- __ add(tmp1, arrayOopDesc::base_offset_in_bytes(T_CHAR), tmp1);
- __ ld(str1, count_offset, str1);
- __ sll(tmp2, exact_log2(sizeof(jchar)), tmp2);
- __ add(tmp1, tmp2, tmp1);
- } else {
- __ load_heap_oop(str1, value_offset, tmp2);
- __ add(tmp2, arrayOopDesc::base_offset_in_bytes(T_CHAR), tmp1);
- __ ld(tmp2, arrayOopDesc::length_offset_in_bytes(), str1);
- }
- __ subcc(str0, str1, O7);
- }
-
- {
- // Compute the minimum of the string lengths, scale it and store it in limit
- Register count0 = I0;
- Register count1 = I1;
- Register limit = L3;
-
- Label Lskip;
- __ sll(count0, exact_log2(sizeof(jchar)), limit); // string0 is shorter
- __ br(Assembler::greater, true, Assembler::pt, Lskip);
- __ delayed()->sll(count1, exact_log2(sizeof(jchar)), limit); // string1 is shorter
- __ bind(Lskip);
-
- // If either string is empty (or both of them) the result is the difference in lengths
- __ cmp(limit, 0);
- __ br(Assembler::equal, true, Assembler::pn, Ldone);
- __ delayed()->mov(O7, result); // result is difference in lengths
- }
-
- {
- // Neither string is empty
- Label Lloop;
-
- Register base0 = L0;
- Register base1 = L1;
- Register chr0 = I0;
- Register chr1 = I1;
- Register limit = L3;
-
- // Shift base0 and base1 to the end of the arrays, negate limit
- __ add(base0, limit, base0);
- __ add(base1, limit, base1);
- __ neg(limit); // limit = -min{string0.length(), string1.length()}
-
- __ lduh(base0, limit, chr0);
- __ bind(Lloop);
- __ lduh(base1, limit, chr1);
- __ subcc(chr0, chr1, chr0);
- __ br(Assembler::notZero, false, Assembler::pn, Ldone);
- assert(chr0 == result, "result must be pre-placed");
- __ delayed()->inccc(limit, sizeof(jchar));
- __ br(Assembler::notZero, true, Assembler::pt, Lloop);
- __ delayed()->lduh(base0, limit, chr0);
- }
-
- // If strings are equal up to min length, return the length difference.
- __ mov(O7, result);
-
- // Otherwise, return the difference between the first mismatched chars.
- __ bind(Ldone);
- }
-
-
// --------------------------------------------------------------------------------------------
void LIR_Assembler::monitorexit(LIR_Opr obj_opr, LIR_Opr lock_opr, Register hdr, int monitor_no) {
if (!GenerateSynchronizationCode) return;
--- 230,239 ----
< prev index next >