Skip to content

Commit 1128de1

Browse files
committed
8261837: SIGSEGV in ciVirtualCallTypeData::translate_from
Reviewed-by: roland Backport-of: 1bb250c9e6b65d1a7a2b90eeb7d6e3a936fb8e8e
1 parent c6841e0 commit 1128de1

9 files changed

+124
-39
lines changed

src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp

+14-2
Original file line numberDiff line numberDiff line change
@@ -2725,7 +2725,10 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
27252725
__ verify_oop(obj);
27262726

27272727
if (tmp != obj) {
2728+
assert_different_registers(obj, tmp, rscratch1, rscratch2, mdo_addr.base(), mdo_addr.index());
27282729
__ mov(tmp, obj);
2730+
} else {
2731+
assert_different_registers(obj, rscratch1, rscratch2, mdo_addr.base(), mdo_addr.index());
27292732
}
27302733
if (do_null) {
27312734
__ cbnz(tmp, update);
@@ -2782,10 +2785,11 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
27822785
__ cbz(rscratch2, none);
27832786
__ cmp(rscratch2, (u1)TypeEntries::null_seen);
27842787
__ br(Assembler::EQ, none);
2785-
// There is a chance that the checks above (re-reading profiling
2786-
// data from memory) fail if another thread has just set the
2788+
// There is a chance that the checks above
2789+
// fail if another thread has just set the
27872790
// profiling to this obj's klass
27882791
__ dmb(Assembler::ISHLD);
2792+
__ eor(tmp, tmp, rscratch2); // get back original value before XOR
27892793
__ ldr(rscratch2, mdo_addr);
27902794
__ eor(tmp, tmp, rscratch2);
27912795
__ andr(rscratch1, tmp, TypeEntries::type_klass_mask);
@@ -2810,6 +2814,10 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
28102814
__ bind(none);
28112815
// first time here. Set profile type.
28122816
__ str(tmp, mdo_addr);
2817+
#ifdef ASSERT
2818+
__ andr(tmp, tmp, TypeEntries::type_mask);
2819+
__ verify_klass_ptr(tmp);
2820+
#endif
28132821
}
28142822
} else {
28152823
// There's a single possible klass at this profile point
@@ -2841,6 +2849,10 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
28412849
#endif
28422850
// first time here. Set profile type.
28432851
__ str(tmp, mdo_addr);
2852+
#ifdef ASSERT
2853+
__ andr(tmp, tmp, TypeEntries::type_mask);
2854+
__ verify_klass_ptr(tmp);
2855+
#endif
28442856
} else {
28452857
assert(ciTypeEntries::valid_ciklass(current_klass) != NULL &&
28462858
ciTypeEntries::valid_ciklass(current_klass) != exact_klass, "inconsistent");

src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp

+8-4
Original file line numberDiff line numberDiff line change
@@ -1638,7 +1638,7 @@ void InterpreterMacroAssembler::call_VM_base(Register oop_result,
16381638
}
16391639

16401640
void InterpreterMacroAssembler::profile_obj_type(Register obj, const Address& mdo_addr) {
1641-
assert_different_registers(obj, rscratch1);
1641+
assert_different_registers(obj, rscratch1, mdo_addr.base(), mdo_addr.index());
16421642
Label update, next, none;
16431643

16441644
verify_oop(obj);
@@ -1660,13 +1660,13 @@ void InterpreterMacroAssembler::profile_obj_type(Register obj, const Address& md
16601660
tbnz(obj, exact_log2(TypeEntries::type_unknown), next);
16611661
// already unknown. Nothing to do anymore.
16621662

1663-
ldr(rscratch1, mdo_addr);
16641663
cbz(rscratch1, none);
16651664
cmp(rscratch1, (u1)TypeEntries::null_seen);
16661665
br(Assembler::EQ, none);
1667-
// There is a chance that the checks above (re-reading profiling
1668-
// data from memory) fail if another thread has just set the
1666+
// There is a chance that the checks above
1667+
// fail if another thread has just set the
16691668
// profiling to this obj's klass
1669+
eor(obj, obj, rscratch1); // get back original value before XOR
16701670
ldr(rscratch1, mdo_addr);
16711671
eor(obj, obj, rscratch1);
16721672
tst(obj, TypeEntries::type_klass_mask);
@@ -1679,6 +1679,10 @@ void InterpreterMacroAssembler::profile_obj_type(Register obj, const Address& md
16791679
bind(none);
16801680
// first time here. Set profile type.
16811681
str(obj, mdo_addr);
1682+
#ifdef ASSERT
1683+
andr(obj, obj, TypeEntries::type_mask);
1684+
verify_klass_ptr(obj);
1685+
#endif
16821686

16831687
bind(next);
16841688
}

src/hotspot/cpu/riscv/c1_LIRAssembler_riscv.cpp

+11-2
Original file line numberDiff line numberDiff line change
@@ -1649,10 +1649,11 @@ void LIR_Assembler::check_conflict(ciKlass* exact_klass, intptr_t current_klass,
16491649
__ beqz(t1, none);
16501650
__ mv(t0, (u1)TypeEntries::null_seen);
16511651
__ beq(t0, t1, none);
1652-
// There is a chance that the checks above (re-reading profiling
1653-
// data from memory) fail if another thread has just set the
1652+
// There is a chance that the checks above
1653+
// fail if another thread has just set the
16541654
// profiling to this obj's klass
16551655
__ membar(MacroAssembler::LoadLoad);
1656+
__ xorr(tmp, tmp, t1); // get back original value before XOR
16561657
__ ld(t1, mdo_addr);
16571658
__ xorr(tmp, tmp, t1);
16581659
__ andi(t0, tmp, TypeEntries::type_klass_mask);
@@ -1679,6 +1680,10 @@ void LIR_Assembler::check_conflict(ciKlass* exact_klass, intptr_t current_klass,
16791680
__ bind(none);
16801681
// first time here. Set profile type.
16811682
__ sd(tmp, mdo_addr);
1683+
#ifdef ASSERT
1684+
__ andi(tmp, tmp, TypeEntries::type_mask);
1685+
__ verify_klass_ptr(tmp);
1686+
#endif
16821687
}
16831688
}
16841689

@@ -1713,6 +1718,10 @@ void LIR_Assembler::check_no_conflict(ciKlass* exact_klass, intptr_t current_kla
17131718
#endif
17141719
// first time here. Set profile type.
17151720
__ sd(tmp, mdo_addr);
1721+
#ifdef ASSERT
1722+
__ andi(tmp, tmp, TypeEntries::type_mask);
1723+
__ verify_klass_ptr(tmp);
1724+
#endif
17161725
} else {
17171726
assert(ciTypeEntries::valid_ciklass(current_klass) != NULL &&
17181727
ciTypeEntries::valid_ciklass(current_klass) != exact_klass, "inconsistent");

src/hotspot/cpu/riscv/interp_masm_riscv.cpp

+14-10
Original file line numberDiff line numberDiff line change
@@ -1682,8 +1682,8 @@ void InterpreterMacroAssembler::profile_obj_type(Register obj, const Address& md
16821682
bind(update);
16831683
load_klass(obj, obj);
16841684

1685-
ld(t0, mdo_addr);
1686-
xorr(obj, obj, t0);
1685+
ld(tmp, mdo_addr);
1686+
xorr(obj, obj, tmp);
16871687
andi(t0, obj, TypeEntries::type_klass_mask);
16881688
beqz(t0, next); // klass seen before, nothing to
16891689
// do. The unknown bit may have been
@@ -1693,15 +1693,15 @@ void InterpreterMacroAssembler::profile_obj_type(Register obj, const Address& md
16931693
bnez(t0, next);
16941694
// already unknown. Nothing to do anymore.
16951695

1696-
ld(t0, mdo_addr);
1697-
beqz(t0, none);
1698-
mv(tmp, (u1)TypeEntries::null_seen);
1699-
beq(t0, tmp, none);
1700-
// There is a chance that the checks above (re-reading profiling
1701-
// data from memory) fail if another thread has just set the
1696+
beqz(tmp, none);
1697+
mv(t0, (u1)TypeEntries::null_seen);
1698+
beq(tmp, t0, none);
1699+
// There is a chance that the checks above
1700+
// fail if another thread has just set the
17021701
// profiling to this obj's klass
1703-
ld(t0, mdo_addr);
1704-
xorr(obj, obj, t0);
1702+
xorr(obj, obj, tmp); // get back original value before XOR
1703+
ld(tmp, mdo_addr);
1704+
xorr(obj, obj, tmp);
17051705
andi(t0, obj, TypeEntries::type_klass_mask);
17061706
beqz(t0, next);
17071707

@@ -1712,6 +1712,10 @@ void InterpreterMacroAssembler::profile_obj_type(Register obj, const Address& md
17121712
bind(none);
17131713
// first time here. Set profile type.
17141714
sd(obj, mdo_addr);
1715+
#ifdef ASSERT
1716+
andi(obj, obj, TypeEntries::type_mask);
1717+
verify_klass_ptr(obj);
1718+
#endif
17151719

17161720
bind(next);
17171721
}

src/hotspot/cpu/x86/assembler_x86.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -5603,6 +5603,14 @@ void Assembler::testb(Address dst, int imm8) {
56035603
emit_int8(imm8);
56045604
}
56055605

5606+
void Assembler::testl(Address dst, int32_t imm32) {
5607+
InstructionMark im(this);
5608+
prefix(dst);
5609+
emit_int8((unsigned char)0xF7);
5610+
emit_operand(as_Register(0), dst, 4);
5611+
emit_int32(imm32);
5612+
}
5613+
56065614
void Assembler::testl(Register dst, int32_t imm32) {
56075615
// not using emit_arith because test
56085616
// doesn't support sign-extension of

src/hotspot/cpu/x86/assembler_x86.hpp

+1
Original file line numberDiff line numberDiff line change
@@ -2063,6 +2063,7 @@ class Assembler : public AbstractAssembler {
20632063
void testb(Register dst, int imm8);
20642064
void testb(Address dst, int imm8);
20652065

2066+
void testl(Address dst, int32_t imm32);
20662067
void testl(Register dst, int32_t imm32);
20672068
void testl(Register dst, Register src);
20682069
void testl(Register dst, Address src);

src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp

+47-21
Original file line numberDiff line numberDiff line change
@@ -3632,13 +3632,33 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
36323632

36333633
__ verify_oop(obj);
36343634

3635-
if (tmp != obj) {
3636-
__ mov(tmp, obj);
3635+
#ifdef ASSERT
3636+
if (obj == tmp) {
3637+
#ifdef _LP64
3638+
assert_different_registers(obj, rscratch1, mdo_addr.base(), mdo_addr.index());
3639+
#else
3640+
assert_different_registers(obj, mdo_addr.base(), mdo_addr.index());
3641+
#endif
3642+
} else {
3643+
#ifdef _LP64
3644+
assert_different_registers(obj, tmp, rscratch1, mdo_addr.base(), mdo_addr.index());
3645+
#else
3646+
assert_different_registers(obj, tmp, mdo_addr.base(), mdo_addr.index());
3647+
#endif
36373648
}
3649+
#endif
36383650
if (do_null) {
3639-
__ testptr(tmp, tmp);
3651+
__ testptr(obj, obj);
36403652
__ jccb(Assembler::notZero, update);
36413653
if (!TypeEntries::was_null_seen(current_klass)) {
3654+
__ testptr(mdo_addr, TypeEntries::null_seen);
3655+
#ifndef ASSERT
3656+
__ jccb(Assembler::notZero, next); // already set
3657+
#else
3658+
__ jcc(Assembler::notZero, next); // already set
3659+
#endif
3660+
// atomic update to prevent overwriting Klass* with 0
3661+
__ lock();
36423662
__ orptr(mdo_addr, TypeEntries::null_seen);
36433663
}
36443664
if (do_update) {
@@ -3649,7 +3669,7 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
36493669
__ jmp(next);
36503670
}
36513671
} else {
3652-
__ testptr(tmp, tmp);
3672+
__ testptr(obj, obj);
36533673
__ jcc(Assembler::notZero, update);
36543674
__ stop("unexpect null obj");
36553675
#endif
@@ -3661,7 +3681,7 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
36613681
#ifdef ASSERT
36623682
if (exact_klass != NULL) {
36633683
Label ok;
3664-
__ load_klass(tmp, tmp, tmp_load_klass);
3684+
__ load_klass(tmp, obj, tmp_load_klass);
36653685
__ push(tmp);
36663686
__ mov_metadata(tmp, exact_klass->constant_encoding());
36673687
__ cmpptr(tmp, Address(rsp, 0));
@@ -3676,9 +3696,11 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
36763696
if (exact_klass != NULL) {
36773697
__ mov_metadata(tmp, exact_klass->constant_encoding());
36783698
} else {
3679-
__ load_klass(tmp, tmp, tmp_load_klass);
3699+
__ load_klass(tmp, obj, tmp_load_klass);
36803700
}
3681-
3701+
#ifdef _LP64
3702+
__ mov(rscratch1, tmp); // save original value before XOR
3703+
#endif
36823704
__ xorptr(tmp, mdo_addr);
36833705
__ testptr(tmp, TypeEntries::type_klass_mask);
36843706
// klass seen before, nothing to do. The unknown bit may have been
@@ -3689,23 +3711,23 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
36893711
__ jccb(Assembler::notZero, next); // already unknown. Nothing to do anymore.
36903712

36913713
if (TypeEntries::is_type_none(current_klass)) {
3692-
__ cmpptr(mdo_addr, 0);
3693-
__ jccb(Assembler::equal, none);
3694-
__ cmpptr(mdo_addr, TypeEntries::null_seen);
3695-
__ jccb(Assembler::equal, none);
3714+
__ testptr(mdo_addr, TypeEntries::type_mask);
3715+
__ jccb(Assembler::zero, none);
3716+
#ifdef _LP64
36963717
// There is a chance that the checks above (re-reading profiling
36973718
// data from memory) fail if another thread has just set the
36983719
// profiling to this obj's klass
3720+
__ mov(tmp, rscratch1); // get back original value before XOR
36993721
__ xorptr(tmp, mdo_addr);
37003722
__ testptr(tmp, TypeEntries::type_klass_mask);
37013723
__ jccb(Assembler::zero, next);
3724+
#endif
37023725
}
37033726
} else {
37043727
assert(ciTypeEntries::valid_ciklass(current_klass) != NULL &&
37053728
ciTypeEntries::valid_ciklass(current_klass) != exact_klass, "conflict only");
37063729

3707-
__ movptr(tmp, mdo_addr);
3708-
__ testptr(tmp, TypeEntries::type_unknown);
3730+
__ testptr(mdo_addr, TypeEntries::type_unknown);
37093731
__ jccb(Assembler::notZero, next); // already unknown. Nothing to do anymore.
37103732
}
37113733

@@ -3718,6 +3740,10 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
37183740
__ bind(none);
37193741
// first time here. Set profile type.
37203742
__ movptr(mdo_addr, tmp);
3743+
#ifdef ASSERT
3744+
__ andptr(tmp, TypeEntries::type_klass_mask);
3745+
__ verify_klass_ptr(tmp);
3746+
#endif
37213747
}
37223748
} else {
37233749
// There's a single possible klass at this profile point
@@ -3732,10 +3758,8 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
37323758
{
37333759
Label ok;
37343760
__ push(tmp);
3735-
__ cmpptr(mdo_addr, 0);
3736-
__ jcc(Assembler::equal, ok);
3737-
__ cmpptr(mdo_addr, TypeEntries::null_seen);
3738-
__ jcc(Assembler::equal, ok);
3761+
__ testptr(mdo_addr, TypeEntries::type_mask);
3762+
__ jcc(Assembler::zero, ok);
37393763
// may have been set by another thread
37403764
__ mov_metadata(tmp, exact_klass->constant_encoding());
37413765
__ xorptr(tmp, mdo_addr);
@@ -3751,20 +3775,22 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
37513775
#endif
37523776
// first time here. Set profile type.
37533777
__ movptr(mdo_addr, tmp);
3778+
#ifdef ASSERT
3779+
__ andptr(tmp, TypeEntries::type_klass_mask);
3780+
__ verify_klass_ptr(tmp);
3781+
#endif
37543782
} else {
37553783
assert(ciTypeEntries::valid_ciklass(current_klass) != NULL &&
37563784
ciTypeEntries::valid_ciklass(current_klass) != exact_klass, "inconsistent");
37573785

3758-
__ movptr(tmp, mdo_addr);
3759-
__ testptr(tmp, TypeEntries::type_unknown);
3786+
__ testptr(mdo_addr, TypeEntries::type_unknown);
37603787
__ jccb(Assembler::notZero, next); // already unknown. Nothing to do anymore.
37613788

37623789
__ orptr(mdo_addr, TypeEntries::type_unknown);
37633790
}
37643791
}
3765-
3766-
__ bind(next);
37673792
}
3793+
__ bind(next);
37683794
}
37693795

37703796
void LIR_Assembler::emit_delay(LIR_OpDelay*) {

src/hotspot/cpu/x86/interp_masm_x86.cpp

+20
Original file line numberDiff line numberDiff line change
@@ -52,16 +52,29 @@ void InterpreterMacroAssembler::jump_to_entry(address entry) {
5252
void InterpreterMacroAssembler::profile_obj_type(Register obj, const Address& mdo_addr) {
5353
Label update, next, none;
5454

55+
#ifdef _LP64
56+
assert_different_registers(obj, rscratch1, mdo_addr.base(), mdo_addr.index());
57+
#else
58+
assert_different_registers(obj, mdo_addr.base(), mdo_addr.index());
59+
#endif
60+
5561
interp_verify_oop(obj, atos);
5662

5763
testptr(obj, obj);
5864
jccb(Assembler::notZero, update);
65+
testptr(mdo_addr, TypeEntries::null_seen);
66+
jccb(Assembler::notZero, next); // null already seen. Nothing to do anymore.
67+
// atomic update to prevent overwriting Klass* with 0
68+
lock();
5969
orptr(mdo_addr, TypeEntries::null_seen);
6070
jmpb(next);
6171

6272
bind(update);
6373
Register tmp_load_klass = LP64_ONLY(rscratch1) NOT_LP64(noreg);
6474
load_klass(obj, obj, tmp_load_klass);
75+
#ifdef _LP64
76+
mov(rscratch1, obj);
77+
#endif
6578

6679
xorptr(obj, mdo_addr);
6780
testptr(obj, TypeEntries::type_klass_mask);
@@ -76,12 +89,15 @@ void InterpreterMacroAssembler::profile_obj_type(Register obj, const Address& md
7689
jccb(Assembler::equal, none);
7790
cmpptr(mdo_addr, TypeEntries::null_seen);
7891
jccb(Assembler::equal, none);
92+
#ifdef _LP64
7993
// There is a chance that the checks above (re-reading profiling
8094
// data from memory) fail if another thread has just set the
8195
// profiling to this obj's klass
96+
mov(obj, rscratch1);
8297
xorptr(obj, mdo_addr);
8398
testptr(obj, TypeEntries::type_klass_mask);
8499
jccb(Assembler::zero, next);
100+
#endif
85101

86102
// different than before. Cannot keep accurate profile.
87103
orptr(mdo_addr, TypeEntries::type_unknown);
@@ -90,6 +106,10 @@ void InterpreterMacroAssembler::profile_obj_type(Register obj, const Address& md
90106
bind(none);
91107
// first time here. Set profile type.
92108
movptr(mdo_addr, obj);
109+
#ifdef ASSERT
110+
andptr(obj, TypeEntries::type_klass_mask);
111+
verify_klass_ptr(obj);
112+
#endif
93113

94114
bind(next);
95115
}

0 commit comments

Comments
 (0)