diff --git a/src/cpu/x86/vm/assembler_x86.cpp b/src/cpu/x86/vm/assembler_x86.cpp index 7076d606650e4fd0909527acad38dc37d76bfdc7..844322092fae472f3f0863c109f196772bddafd7 100644 --- a/src/cpu/x86/vm/assembler_x86.cpp +++ b/src/cpu/x86/vm/assembler_x86.cpp @@ -1465,8 +1465,14 @@ void Assembler::jccb(Condition cc, Label& L) { if (L.is_bound()) { const int short_size = 2; address entry = target(L); - assert(is8bit((intptr_t)entry - ((intptr_t)_code_pos + short_size)), - "Dispacement too large for a short jmp"); +#ifdef ASSERT + intptr_t dist = (intptr_t)entry - ((intptr_t)_code_pos + short_size); + intptr_t delta = short_branch_delta(); + if (delta != 0) { + dist += (dist < 0 ? (-delta) :delta); + } + assert(is8bit(dist), "Dispacement too large for a short jmp"); +#endif intptr_t offs = (intptr_t)entry - (intptr_t)_code_pos; // 0111 tttn #8-bit disp emit_byte(0x70 | cc); @@ -1532,9 +1538,15 @@ void Assembler::jmpb(Label& L) { if (L.is_bound()) { const int short_size = 2; address entry = target(L); - assert(is8bit((entry - _code_pos) + short_size), - "Dispacement too large for a short jmp"); assert(entry != NULL, "jmp most probably wrong"); +#ifdef ASSERT + intptr_t dist = (intptr_t)entry - ((intptr_t)_code_pos + short_size); + intptr_t delta = short_branch_delta(); + if (delta != 0) { + dist += (dist < 0 ? (-delta) :delta); + } + assert(is8bit(dist), "Dispacement too large for a short jmp"); +#endif intptr_t offs = entry - _code_pos; emit_byte(0xEB); emit_byte((offs - short_size) & 0xFF); @@ -9280,6 +9292,7 @@ void MacroAssembler::string_indexofC8(Register str1, Register str2, Register cnt1, Register cnt2, int int_cnt2, Register result, XMMRegister vec, Register tmp) { + ShortBranchVerifier sbv(this); assert(UseSSE42Intrinsics, "SSE4.2 is required"); // This method uses pcmpestri inxtruction with bound registers @@ -9409,9 +9422,9 @@ void MacroAssembler::string_indexofC8(Register str1, Register str2, pcmpestri(vec, Address(result, tmp, Address::times_2, 0), 0x0d); } // Need to reload strings pointers if not matched whole vector - jccb(Assembler::noOverflow, RELOAD_SUBSTR); // OF == 0 + jcc(Assembler::noOverflow, RELOAD_SUBSTR); // OF == 0 addptr(cnt2, 8); - jccb(Assembler::negative, SCAN_SUBSTR); + jcc(Assembler::negative, SCAN_SUBSTR); // Fall through if found full substring } // (int_cnt2 > 8) @@ -9430,6 +9443,7 @@ void MacroAssembler::string_indexof(Register str1, Register str2, Register cnt1, Register cnt2, int int_cnt2, Register result, XMMRegister vec, Register tmp) { + ShortBranchVerifier sbv(this); assert(UseSSE42Intrinsics, "SSE4.2 is required"); // // int_cnt2 is length of small (< 8 chars) constant substring @@ -9691,6 +9705,7 @@ void MacroAssembler::string_indexof(Register str1, Register str2, void MacroAssembler::string_compare(Register str1, Register str2, Register cnt1, Register cnt2, Register result, XMMRegister vec1) { + ShortBranchVerifier sbv(this); Label LENGTH_DIFF_LABEL, POP_LABEL, DONE_LABEL, WHILE_HEAD_LABEL; // Compute the minimum of the string lengths and the @@ -9827,6 +9842,7 @@ void MacroAssembler::string_compare(Register str1, Register str2, void MacroAssembler::char_arrays_equals(bool is_array_equ, Register ary1, Register ary2, Register limit, Register result, Register chr, XMMRegister vec1, XMMRegister vec2) { + ShortBranchVerifier sbv(this); Label TRUE_LABEL, FALSE_LABEL, DONE, COMPARE_VECTORS, COMPARE_CHAR; int length_offset = arrayOopDesc::length_offset_in_bytes(); @@ -9946,6 +9962,7 @@ void MacroAssembler::char_arrays_equals(bool is_array_equ, Register ary1, Regist void MacroAssembler::generate_fill(BasicType t, bool aligned, Register to, Register value, Register count, Register rtmp, XMMRegister xtmp) { + ShortBranchVerifier sbv(this); assert_different_registers(to, value, count, rtmp); Label L_exit, L_skip_align1, L_skip_align2, L_fill_byte; Label L_fill_2_bytes, L_fill_4_bytes; diff --git a/src/share/vm/asm/assembler.cpp b/src/share/vm/asm/assembler.cpp index 86011e97496e31f7ba210311e6f525c0e7e8b882..2bcdcbc884db1dc786b7b36b0a3b462706e0c64e 100644 --- a/src/share/vm/asm/assembler.cpp +++ b/src/share/vm/asm/assembler.cpp @@ -61,6 +61,7 @@ AbstractAssembler::AbstractAssembler(CodeBuffer* code) { _code_limit = cs->limit(); _code_pos = cs->end(); _oop_recorder= code->oop_recorder(); + DEBUG_ONLY( _short_branch_delta = 0; ) if (_code_begin == NULL) { vm_exit_out_of_memory(0, err_msg("CodeCache: no room for %s", code->name())); diff --git a/src/share/vm/asm/assembler.hpp b/src/share/vm/asm/assembler.hpp index 8db7eef2ea5aa316cacc6a1e96e785ce604e7bd8..c25aa3fca3f87402ab1470a4b35dc5d355de8e1e 100644 --- a/src/share/vm/asm/assembler.hpp +++ b/src/share/vm/asm/assembler.hpp @@ -241,6 +241,33 @@ class AbstractAssembler : public ResourceObj { // Make it return true on platforms which need to verify // instruction boundaries for some operations. inline static bool pd_check_instruction_mark(); + + // Add delta to short branch distance to verify that it still fit into imm8. + int _short_branch_delta; + + int short_branch_delta() const { return _short_branch_delta; } + void set_short_branch_delta() { _short_branch_delta = 32; } + void clear_short_branch_delta() { _short_branch_delta = 0; } + + class ShortBranchVerifier: public StackObj { + private: + AbstractAssembler* _assm; + + public: + ShortBranchVerifier(AbstractAssembler* assm) : _assm(assm) { + assert(assm->short_branch_delta() == 0, "overlapping instructions"); + _assm->set_short_branch_delta(); + } + ~ShortBranchVerifier() { + _assm->clear_short_branch_delta(); + } + }; + #else + // Dummy in product. + class ShortBranchVerifier: public StackObj { + public: + ShortBranchVerifier(AbstractAssembler* assm) {} + }; #endif // Label functions