7110832: ctw/.../org_apache_avalon_composition_util_StringHelper crashes the VM
Distance is too large for one short branch in string_indexofC8(). Reviewed-by: iveresov
This commit is contained in:
parent
59b883333b
commit
6c38bc48ca
@ -1465,8 +1465,14 @@ void Assembler::jccb(Condition cc, Label& L) {
|
|||||||
if (L.is_bound()) {
|
if (L.is_bound()) {
|
||||||
const int short_size = 2;
|
const int short_size = 2;
|
||||||
address entry = target(L);
|
address entry = target(L);
|
||||||
assert(is8bit((intptr_t)entry - ((intptr_t)_code_pos + short_size)),
|
#ifdef ASSERT
|
||||||
"Dispacement too large for a short jmp");
|
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;
|
intptr_t offs = (intptr_t)entry - (intptr_t)_code_pos;
|
||||||
// 0111 tttn #8-bit disp
|
// 0111 tttn #8-bit disp
|
||||||
emit_byte(0x70 | cc);
|
emit_byte(0x70 | cc);
|
||||||
@ -1532,9 +1538,15 @@ void Assembler::jmpb(Label& L) {
|
|||||||
if (L.is_bound()) {
|
if (L.is_bound()) {
|
||||||
const int short_size = 2;
|
const int short_size = 2;
|
||||||
address entry = target(L);
|
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");
|
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;
|
intptr_t offs = entry - _code_pos;
|
||||||
emit_byte(0xEB);
|
emit_byte(0xEB);
|
||||||
emit_byte((offs - short_size) & 0xFF);
|
emit_byte((offs - short_size) & 0xFF);
|
||||||
@ -9280,6 +9292,7 @@ void MacroAssembler::string_indexofC8(Register str1, Register str2,
|
|||||||
Register cnt1, Register cnt2,
|
Register cnt1, Register cnt2,
|
||||||
int int_cnt2, Register result,
|
int int_cnt2, Register result,
|
||||||
XMMRegister vec, Register tmp) {
|
XMMRegister vec, Register tmp) {
|
||||||
|
ShortBranchVerifier sbv(this);
|
||||||
assert(UseSSE42Intrinsics, "SSE4.2 is required");
|
assert(UseSSE42Intrinsics, "SSE4.2 is required");
|
||||||
|
|
||||||
// This method uses pcmpestri inxtruction with bound registers
|
// 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);
|
pcmpestri(vec, Address(result, tmp, Address::times_2, 0), 0x0d);
|
||||||
}
|
}
|
||||||
// Need to reload strings pointers if not matched whole vector
|
// 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);
|
addptr(cnt2, 8);
|
||||||
jccb(Assembler::negative, SCAN_SUBSTR);
|
jcc(Assembler::negative, SCAN_SUBSTR);
|
||||||
// Fall through if found full substring
|
// Fall through if found full substring
|
||||||
|
|
||||||
} // (int_cnt2 > 8)
|
} // (int_cnt2 > 8)
|
||||||
@ -9430,6 +9443,7 @@ void MacroAssembler::string_indexof(Register str1, Register str2,
|
|||||||
Register cnt1, Register cnt2,
|
Register cnt1, Register cnt2,
|
||||||
int int_cnt2, Register result,
|
int int_cnt2, Register result,
|
||||||
XMMRegister vec, Register tmp) {
|
XMMRegister vec, Register tmp) {
|
||||||
|
ShortBranchVerifier sbv(this);
|
||||||
assert(UseSSE42Intrinsics, "SSE4.2 is required");
|
assert(UseSSE42Intrinsics, "SSE4.2 is required");
|
||||||
//
|
//
|
||||||
// int_cnt2 is length of small (< 8 chars) constant substring
|
// 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,
|
void MacroAssembler::string_compare(Register str1, Register str2,
|
||||||
Register cnt1, Register cnt2, Register result,
|
Register cnt1, Register cnt2, Register result,
|
||||||
XMMRegister vec1) {
|
XMMRegister vec1) {
|
||||||
|
ShortBranchVerifier sbv(this);
|
||||||
Label LENGTH_DIFF_LABEL, POP_LABEL, DONE_LABEL, WHILE_HEAD_LABEL;
|
Label LENGTH_DIFF_LABEL, POP_LABEL, DONE_LABEL, WHILE_HEAD_LABEL;
|
||||||
|
|
||||||
// Compute the minimum of the string lengths and the
|
// 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,
|
void MacroAssembler::char_arrays_equals(bool is_array_equ, Register ary1, Register ary2,
|
||||||
Register limit, Register result, Register chr,
|
Register limit, Register result, Register chr,
|
||||||
XMMRegister vec1, XMMRegister vec2) {
|
XMMRegister vec1, XMMRegister vec2) {
|
||||||
|
ShortBranchVerifier sbv(this);
|
||||||
Label TRUE_LABEL, FALSE_LABEL, DONE, COMPARE_VECTORS, COMPARE_CHAR;
|
Label TRUE_LABEL, FALSE_LABEL, DONE, COMPARE_VECTORS, COMPARE_CHAR;
|
||||||
|
|
||||||
int length_offset = arrayOopDesc::length_offset_in_bytes();
|
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,
|
void MacroAssembler::generate_fill(BasicType t, bool aligned,
|
||||||
Register to, Register value, Register count,
|
Register to, Register value, Register count,
|
||||||
Register rtmp, XMMRegister xtmp) {
|
Register rtmp, XMMRegister xtmp) {
|
||||||
|
ShortBranchVerifier sbv(this);
|
||||||
assert_different_registers(to, value, count, rtmp);
|
assert_different_registers(to, value, count, rtmp);
|
||||||
Label L_exit, L_skip_align1, L_skip_align2, L_fill_byte;
|
Label L_exit, L_skip_align1, L_skip_align2, L_fill_byte;
|
||||||
Label L_fill_2_bytes, L_fill_4_bytes;
|
Label L_fill_2_bytes, L_fill_4_bytes;
|
||||||
|
@ -61,6 +61,7 @@ AbstractAssembler::AbstractAssembler(CodeBuffer* code) {
|
|||||||
_code_limit = cs->limit();
|
_code_limit = cs->limit();
|
||||||
_code_pos = cs->end();
|
_code_pos = cs->end();
|
||||||
_oop_recorder= code->oop_recorder();
|
_oop_recorder= code->oop_recorder();
|
||||||
|
DEBUG_ONLY( _short_branch_delta = 0; )
|
||||||
if (_code_begin == NULL) {
|
if (_code_begin == NULL) {
|
||||||
vm_exit_out_of_memory(0, err_msg("CodeCache: no room for %s",
|
vm_exit_out_of_memory(0, err_msg("CodeCache: no room for %s",
|
||||||
code->name()));
|
code->name()));
|
||||||
|
@ -241,6 +241,33 @@ class AbstractAssembler : public ResourceObj {
|
|||||||
// Make it return true on platforms which need to verify
|
// Make it return true on platforms which need to verify
|
||||||
// instruction boundaries for some operations.
|
// instruction boundaries for some operations.
|
||||||
inline static bool pd_check_instruction_mark();
|
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
|
#endif
|
||||||
|
|
||||||
// Label functions
|
// Label functions
|
||||||
|
Loading…
x
Reference in New Issue
Block a user