Mercurial > hg > graal-compiler
comparison src/cpu/x86/vm/assembler_x86.cpp @ 4766:40c2484c09e1
7110832: ctw/.../org_apache_avalon_composition_util_StringHelper crashes the VM
Summary: Distance is too large for one short branch in string_indexofC8().
Reviewed-by: iveresov
author | kvn |
---|---|
date | Fri, 23 Dec 2011 15:24:36 -0800 |
parents | 069ab3f976d3 |
children | 8940fd98d540 |
comparison
equal
deleted
inserted
replaced
4765:b642b49f9738 | 4766:40c2484c09e1 |
---|---|
1463 | 1463 |
1464 void Assembler::jccb(Condition cc, Label& L) { | 1464 void Assembler::jccb(Condition cc, Label& L) { |
1465 if (L.is_bound()) { | 1465 if (L.is_bound()) { |
1466 const int short_size = 2; | 1466 const int short_size = 2; |
1467 address entry = target(L); | 1467 address entry = target(L); |
1468 assert(is8bit((intptr_t)entry - ((intptr_t)_code_pos + short_size)), | 1468 #ifdef ASSERT |
1469 "Dispacement too large for a short jmp"); | 1469 intptr_t dist = (intptr_t)entry - ((intptr_t)_code_pos + short_size); |
1470 intptr_t delta = short_branch_delta(); | |
1471 if (delta != 0) { | |
1472 dist += (dist < 0 ? (-delta) :delta); | |
1473 } | |
1474 assert(is8bit(dist), "Dispacement too large for a short jmp"); | |
1475 #endif | |
1470 intptr_t offs = (intptr_t)entry - (intptr_t)_code_pos; | 1476 intptr_t offs = (intptr_t)entry - (intptr_t)_code_pos; |
1471 // 0111 tttn #8-bit disp | 1477 // 0111 tttn #8-bit disp |
1472 emit_byte(0x70 | cc); | 1478 emit_byte(0x70 | cc); |
1473 emit_byte((offs - short_size) & 0xFF); | 1479 emit_byte((offs - short_size) & 0xFF); |
1474 } else { | 1480 } else { |
1530 | 1536 |
1531 void Assembler::jmpb(Label& L) { | 1537 void Assembler::jmpb(Label& L) { |
1532 if (L.is_bound()) { | 1538 if (L.is_bound()) { |
1533 const int short_size = 2; | 1539 const int short_size = 2; |
1534 address entry = target(L); | 1540 address entry = target(L); |
1535 assert(is8bit((entry - _code_pos) + short_size), | |
1536 "Dispacement too large for a short jmp"); | |
1537 assert(entry != NULL, "jmp most probably wrong"); | 1541 assert(entry != NULL, "jmp most probably wrong"); |
1542 #ifdef ASSERT | |
1543 intptr_t dist = (intptr_t)entry - ((intptr_t)_code_pos + short_size); | |
1544 intptr_t delta = short_branch_delta(); | |
1545 if (delta != 0) { | |
1546 dist += (dist < 0 ? (-delta) :delta); | |
1547 } | |
1548 assert(is8bit(dist), "Dispacement too large for a short jmp"); | |
1549 #endif | |
1538 intptr_t offs = entry - _code_pos; | 1550 intptr_t offs = entry - _code_pos; |
1539 emit_byte(0xEB); | 1551 emit_byte(0xEB); |
1540 emit_byte((offs - short_size) & 0xFF); | 1552 emit_byte((offs - short_size) & 0xFF); |
1541 } else { | 1553 } else { |
1542 InstructionMark im(this); | 1554 InstructionMark im(this); |
9278 // which don't need to be loaded through stack. | 9290 // which don't need to be loaded through stack. |
9279 void MacroAssembler::string_indexofC8(Register str1, Register str2, | 9291 void MacroAssembler::string_indexofC8(Register str1, Register str2, |
9280 Register cnt1, Register cnt2, | 9292 Register cnt1, Register cnt2, |
9281 int int_cnt2, Register result, | 9293 int int_cnt2, Register result, |
9282 XMMRegister vec, Register tmp) { | 9294 XMMRegister vec, Register tmp) { |
9295 ShortBranchVerifier sbv(this); | |
9283 assert(UseSSE42Intrinsics, "SSE4.2 is required"); | 9296 assert(UseSSE42Intrinsics, "SSE4.2 is required"); |
9284 | 9297 |
9285 // This method uses pcmpestri inxtruction with bound registers | 9298 // This method uses pcmpestri inxtruction with bound registers |
9286 // inputs: | 9299 // inputs: |
9287 // xmm - substring | 9300 // xmm - substring |
9407 addptr(tmp, cnt2); | 9420 addptr(tmp, cnt2); |
9408 movdqu(vec, Address(str2, tmp, Address::times_2, 0)); | 9421 movdqu(vec, Address(str2, tmp, Address::times_2, 0)); |
9409 pcmpestri(vec, Address(result, tmp, Address::times_2, 0), 0x0d); | 9422 pcmpestri(vec, Address(result, tmp, Address::times_2, 0), 0x0d); |
9410 } | 9423 } |
9411 // Need to reload strings pointers if not matched whole vector | 9424 // Need to reload strings pointers if not matched whole vector |
9412 jccb(Assembler::noOverflow, RELOAD_SUBSTR); // OF == 0 | 9425 jcc(Assembler::noOverflow, RELOAD_SUBSTR); // OF == 0 |
9413 addptr(cnt2, 8); | 9426 addptr(cnt2, 8); |
9414 jccb(Assembler::negative, SCAN_SUBSTR); | 9427 jcc(Assembler::negative, SCAN_SUBSTR); |
9415 // Fall through if found full substring | 9428 // Fall through if found full substring |
9416 | 9429 |
9417 } // (int_cnt2 > 8) | 9430 } // (int_cnt2 > 8) |
9418 | 9431 |
9419 bind(RET_FOUND); | 9432 bind(RET_FOUND); |
9428 // Small strings are loaded through stack if they cross page boundary. | 9441 // Small strings are loaded through stack if they cross page boundary. |
9429 void MacroAssembler::string_indexof(Register str1, Register str2, | 9442 void MacroAssembler::string_indexof(Register str1, Register str2, |
9430 Register cnt1, Register cnt2, | 9443 Register cnt1, Register cnt2, |
9431 int int_cnt2, Register result, | 9444 int int_cnt2, Register result, |
9432 XMMRegister vec, Register tmp) { | 9445 XMMRegister vec, Register tmp) { |
9446 ShortBranchVerifier sbv(this); | |
9433 assert(UseSSE42Intrinsics, "SSE4.2 is required"); | 9447 assert(UseSSE42Intrinsics, "SSE4.2 is required"); |
9434 // | 9448 // |
9435 // int_cnt2 is length of small (< 8 chars) constant substring | 9449 // int_cnt2 is length of small (< 8 chars) constant substring |
9436 // or (-1) for non constant substring in which case its length | 9450 // or (-1) for non constant substring in which case its length |
9437 // is in cnt2 register. | 9451 // is in cnt2 register. |
9689 | 9703 |
9690 // Compare strings. | 9704 // Compare strings. |
9691 void MacroAssembler::string_compare(Register str1, Register str2, | 9705 void MacroAssembler::string_compare(Register str1, Register str2, |
9692 Register cnt1, Register cnt2, Register result, | 9706 Register cnt1, Register cnt2, Register result, |
9693 XMMRegister vec1) { | 9707 XMMRegister vec1) { |
9708 ShortBranchVerifier sbv(this); | |
9694 Label LENGTH_DIFF_LABEL, POP_LABEL, DONE_LABEL, WHILE_HEAD_LABEL; | 9709 Label LENGTH_DIFF_LABEL, POP_LABEL, DONE_LABEL, WHILE_HEAD_LABEL; |
9695 | 9710 |
9696 // Compute the minimum of the string lengths and the | 9711 // Compute the minimum of the string lengths and the |
9697 // difference of the string lengths (stack). | 9712 // difference of the string lengths (stack). |
9698 // Do the conditional move stuff | 9713 // Do the conditional move stuff |
9825 | 9840 |
9826 // Compare char[] arrays aligned to 4 bytes or substrings. | 9841 // Compare char[] arrays aligned to 4 bytes or substrings. |
9827 void MacroAssembler::char_arrays_equals(bool is_array_equ, Register ary1, Register ary2, | 9842 void MacroAssembler::char_arrays_equals(bool is_array_equ, Register ary1, Register ary2, |
9828 Register limit, Register result, Register chr, | 9843 Register limit, Register result, Register chr, |
9829 XMMRegister vec1, XMMRegister vec2) { | 9844 XMMRegister vec1, XMMRegister vec2) { |
9845 ShortBranchVerifier sbv(this); | |
9830 Label TRUE_LABEL, FALSE_LABEL, DONE, COMPARE_VECTORS, COMPARE_CHAR; | 9846 Label TRUE_LABEL, FALSE_LABEL, DONE, COMPARE_VECTORS, COMPARE_CHAR; |
9831 | 9847 |
9832 int length_offset = arrayOopDesc::length_offset_in_bytes(); | 9848 int length_offset = arrayOopDesc::length_offset_in_bytes(); |
9833 int base_offset = arrayOopDesc::base_offset_in_bytes(T_CHAR); | 9849 int base_offset = arrayOopDesc::base_offset_in_bytes(T_CHAR); |
9834 | 9850 |
9944 | 9960 |
9945 #define BIND(label) bind(label); BLOCK_COMMENT(#label ":") | 9961 #define BIND(label) bind(label); BLOCK_COMMENT(#label ":") |
9946 void MacroAssembler::generate_fill(BasicType t, bool aligned, | 9962 void MacroAssembler::generate_fill(BasicType t, bool aligned, |
9947 Register to, Register value, Register count, | 9963 Register to, Register value, Register count, |
9948 Register rtmp, XMMRegister xtmp) { | 9964 Register rtmp, XMMRegister xtmp) { |
9965 ShortBranchVerifier sbv(this); | |
9949 assert_different_registers(to, value, count, rtmp); | 9966 assert_different_registers(to, value, count, rtmp); |
9950 Label L_exit, L_skip_align1, L_skip_align2, L_fill_byte; | 9967 Label L_exit, L_skip_align1, L_skip_align2, L_fill_byte; |
9951 Label L_fill_2_bytes, L_fill_4_bytes; | 9968 Label L_fill_2_bytes, L_fill_4_bytes; |
9952 | 9969 |
9953 int shift = -1; | 9970 int shift = -1; |