Skip to content

Commit 12915c3

Browse files
committed
8261837: SIGSEGV in ciVirtualCallTypeData::translate_from
Backport-of: 1bb250c9e6b65d1a7a2b90eeb7d6e3a936fb8e8e
1 parent e0de68e commit 12915c3

7 files changed

+115
-39
lines changed

src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp

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

27252725
if (tmp != obj) {
2726+
assert_different_registers(obj, tmp, rscratch1, rscratch2, mdo_addr.base(), mdo_addr.index());
27262727
__ mov(tmp, obj);
2728+
} else {
2729+
assert_different_registers(obj, rscratch1, rscratch2, mdo_addr.base(), mdo_addr.index());
27272730
}
27282731
if (do_null) {
27292732
__ cbnz(tmp, update);
@@ -2780,10 +2783,11 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
27802783
__ cbz(rscratch2, none);
27812784
__ cmp(rscratch2, (u1)TypeEntries::null_seen);
27822785
__ br(Assembler::EQ, none);
2783-
// There is a chance that the checks above (re-reading profiling
2784-
// data from memory) fail if another thread has just set the
2786+
// There is a chance that the checks above
2787+
// fail if another thread has just set the
27852788
// profiling to this obj's klass
27862789
__ dmb(Assembler::ISHLD);
2790+
__ eor(tmp, tmp, rscratch2); // get back original value before XOR
27872791
__ ldr(rscratch2, mdo_addr);
27882792
__ eor(tmp, tmp, rscratch2);
27892793
__ andr(rscratch1, tmp, TypeEntries::type_klass_mask);
@@ -2808,6 +2812,10 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
28082812
__ bind(none);
28092813
// first time here. Set profile type.
28102814
__ str(tmp, mdo_addr);
2815+
#ifdef ASSERT
2816+
__ andr(tmp, tmp, TypeEntries::type_mask);
2817+
__ verify_klass_ptr(tmp);
2818+
#endif
28112819
}
28122820
} else {
28132821
// There's a single possible klass at this profile point
@@ -2839,6 +2847,10 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
28392847
#endif
28402848
// first time here. Set profile type.
28412849
__ str(tmp, mdo_addr);
2850+
#ifdef ASSERT
2851+
__ andr(tmp, tmp, TypeEntries::type_mask);
2852+
__ verify_klass_ptr(tmp);
2853+
#endif
28422854
} else {
28432855
assert(ciTypeEntries::valid_ciklass(current_klass) != nullptr &&
28442856
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
@@ -1669,7 +1669,7 @@ void InterpreterMacroAssembler::call_VM_base(Register oop_result,
16691669
}
16701670

16711671
void InterpreterMacroAssembler::profile_obj_type(Register obj, const Address& mdo_addr) {
1672-
assert_different_registers(obj, rscratch1);
1672+
assert_different_registers(obj, rscratch1, mdo_addr.base(), mdo_addr.index());
16731673
Label update, next, none;
16741674

16751675
verify_oop(obj);
@@ -1691,13 +1691,13 @@ void InterpreterMacroAssembler::profile_obj_type(Register obj, const Address& md
16911691
tbnz(obj, exact_log2(TypeEntries::type_unknown), next);
16921692
// already unknown. Nothing to do anymore.
16931693

1694-
ldr(rscratch1, mdo_addr);
16951694
cbz(rscratch1, none);
16961695
cmp(rscratch1, (u1)TypeEntries::null_seen);
16971696
br(Assembler::EQ, none);
1698-
// There is a chance that the checks above (re-reading profiling
1699-
// data from memory) fail if another thread has just set the
1697+
// There is a chance that the checks above
1698+
// fail if another thread has just set the
17001699
// profiling to this obj's klass
1700+
eor(obj, obj, rscratch1); // get back original value before XOR
17011701
ldr(rscratch1, mdo_addr);
17021702
eor(obj, obj, rscratch1);
17031703
tst(obj, TypeEntries::type_klass_mask);
@@ -1710,6 +1710,10 @@ void InterpreterMacroAssembler::profile_obj_type(Register obj, const Address& md
17101710
bind(none);
17111711
// first time here. Set profile type.
17121712
str(obj, mdo_addr);
1713+
#ifdef ASSERT
1714+
andr(obj, obj, TypeEntries::type_mask);
1715+
verify_klass_ptr(obj);
1716+
#endif
17131717

17141718
bind(next);
17151719
}

src/hotspot/cpu/riscv/c1_LIRAssembler_riscv.cpp

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

@@ -1712,6 +1717,10 @@ void LIR_Assembler::check_no_conflict(ciKlass* exact_klass, intptr_t current_kla
17121717
#endif
17131718
// first time here. Set profile type.
17141719
__ sd(tmp, mdo_addr);
1720+
#ifdef ASSERT
1721+
__ andi(tmp, tmp, TypeEntries::type_mask);
1722+
__ verify_klass_ptr(tmp);
1723+
#endif
17151724
} else {
17161725
assert(ciTypeEntries::valid_ciklass(current_klass) != nullptr &&
17171726
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
@@ -1732,8 +1732,8 @@ void InterpreterMacroAssembler::profile_obj_type(Register obj, const Address& md
17321732
bind(update);
17331733
load_klass(obj, obj);
17341734

1735-
ld(t0, mdo_addr);
1736-
xorr(obj, obj, t0);
1735+
ld(tmp, mdo_addr);
1736+
xorr(obj, obj, tmp);
17371737
andi(t0, obj, TypeEntries::type_klass_mask);
17381738
beqz(t0, next); // klass seen before, nothing to
17391739
// do. The unknown bit may have been
@@ -1743,15 +1743,15 @@ void InterpreterMacroAssembler::profile_obj_type(Register obj, const Address& md
17431743
bnez(t0, next);
17441744
// already unknown. Nothing to do anymore.
17451745

1746-
ld(t0, mdo_addr);
1747-
beqz(t0, none);
1748-
mv(tmp, (u1)TypeEntries::null_seen);
1749-
beq(t0, tmp, none);
1750-
// There is a chance that the checks above (re-reading profiling
1751-
// data from memory) fail if another thread has just set the
1746+
beqz(tmp, none);
1747+
mv(t0, (u1)TypeEntries::null_seen);
1748+
beq(tmp, t0, none);
1749+
// There is a chance that the checks above
1750+
// fail if another thread has just set the
17521751
// profiling to this obj's klass
1753-
ld(t0, mdo_addr);
1754-
xorr(obj, obj, t0);
1752+
xorr(obj, obj, tmp); // get back original value before XOR
1753+
ld(tmp, mdo_addr);
1754+
xorr(obj, obj, tmp);
17551755
andi(t0, obj, TypeEntries::type_klass_mask);
17561756
beqz(t0, next);
17571757

@@ -1762,6 +1762,10 @@ void InterpreterMacroAssembler::profile_obj_type(Register obj, const Address& md
17621762
bind(none);
17631763
// first time here. Set profile type.
17641764
sd(obj, mdo_addr);
1765+
#ifdef ASSERT
1766+
andi(obj, obj, TypeEntries::type_mask);
1767+
verify_klass_ptr(obj);
1768+
#endif
17651769

17661770
bind(next);
17671771
}

src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp

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

36413641
__ verify_oop(obj);
36423642

3643-
if (tmp != obj) {
3644-
__ mov(tmp, obj);
3643+
#ifdef ASSERT
3644+
if (obj == tmp) {
3645+
#ifdef _LP64
3646+
assert_different_registers(obj, rscratch1, mdo_addr.base(), mdo_addr.index());
3647+
#else
3648+
assert_different_registers(obj, mdo_addr.base(), mdo_addr.index());
3649+
#endif
3650+
} else {
3651+
#ifdef _LP64
3652+
assert_different_registers(obj, tmp, rscratch1, mdo_addr.base(), mdo_addr.index());
3653+
#else
3654+
assert_different_registers(obj, tmp, mdo_addr.base(), mdo_addr.index());
3655+
#endif
36453656
}
3657+
#endif
36463658
if (do_null) {
3647-
__ testptr(tmp, tmp);
3659+
__ testptr(obj, obj);
36483660
__ jccb(Assembler::notZero, update);
36493661
if (!TypeEntries::was_null_seen(current_klass)) {
3662+
__ testptr(mdo_addr, TypeEntries::null_seen);
3663+
#ifndef ASSERT
3664+
__ jccb(Assembler::notZero, next); // already set
3665+
#else
3666+
__ jcc(Assembler::notZero, next); // already set
3667+
#endif
3668+
// atomic update to prevent overwriting Klass* with 0
3669+
__ lock();
36503670
__ orptr(mdo_addr, TypeEntries::null_seen);
36513671
}
36523672
if (do_update) {
@@ -3657,7 +3677,7 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
36573677
__ jmp(next);
36583678
}
36593679
} else {
3660-
__ testptr(tmp, tmp);
3680+
__ testptr(obj, obj);
36613681
__ jcc(Assembler::notZero, update);
36623682
__ stop("unexpected null obj");
36633683
#endif
@@ -3669,7 +3689,7 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
36693689
#ifdef ASSERT
36703690
if (exact_klass != nullptr) {
36713691
Label ok;
3672-
__ load_klass(tmp, tmp, tmp_load_klass);
3692+
__ load_klass(tmp, obj, tmp_load_klass);
36733693
__ push(tmp);
36743694
__ mov_metadata(tmp, exact_klass->constant_encoding());
36753695
__ cmpptr(tmp, Address(rsp, 0));
@@ -3684,9 +3704,11 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
36843704
if (exact_klass != nullptr) {
36853705
__ mov_metadata(tmp, exact_klass->constant_encoding());
36863706
} else {
3687-
__ load_klass(tmp, tmp, tmp_load_klass);
3707+
__ load_klass(tmp, obj, tmp_load_klass);
36883708
}
3689-
3709+
#ifdef _LP64
3710+
__ mov(rscratch1, tmp); // save original value before XOR
3711+
#endif
36903712
__ xorptr(tmp, mdo_addr);
36913713
__ testptr(tmp, TypeEntries::type_klass_mask);
36923714
// klass seen before, nothing to do. The unknown bit may have been
@@ -3697,23 +3719,23 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
36973719
__ jccb(Assembler::notZero, next); // already unknown. Nothing to do anymore.
36983720

36993721
if (TypeEntries::is_type_none(current_klass)) {
3700-
__ cmpptr(mdo_addr, 0);
3701-
__ jccb(Assembler::equal, none);
3702-
__ cmpptr(mdo_addr, TypeEntries::null_seen);
3703-
__ jccb(Assembler::equal, none);
3722+
__ testptr(mdo_addr, TypeEntries::type_mask);
3723+
__ jccb(Assembler::zero, none);
3724+
#ifdef _LP64
37043725
// There is a chance that the checks above (re-reading profiling
37053726
// data from memory) fail if another thread has just set the
37063727
// profiling to this obj's klass
3728+
__ mov(tmp, rscratch1); // get back original value before XOR
37073729
__ xorptr(tmp, mdo_addr);
37083730
__ testptr(tmp, TypeEntries::type_klass_mask);
37093731
__ jccb(Assembler::zero, next);
3732+
#endif
37103733
}
37113734
} else {
37123735
assert(ciTypeEntries::valid_ciklass(current_klass) != nullptr &&
37133736
ciTypeEntries::valid_ciklass(current_klass) != exact_klass, "conflict only");
37143737

3715-
__ movptr(tmp, mdo_addr);
3716-
__ testptr(tmp, TypeEntries::type_unknown);
3738+
__ testptr(mdo_addr, TypeEntries::type_unknown);
37173739
__ jccb(Assembler::notZero, next); // already unknown. Nothing to do anymore.
37183740
}
37193741

@@ -3726,6 +3748,10 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
37263748
__ bind(none);
37273749
// first time here. Set profile type.
37283750
__ movptr(mdo_addr, tmp);
3751+
#ifdef ASSERT
3752+
__ andptr(tmp, TypeEntries::type_klass_mask);
3753+
__ verify_klass_ptr(tmp);
3754+
#endif
37293755
}
37303756
} else {
37313757
// There's a single possible klass at this profile point
@@ -3740,10 +3766,8 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
37403766
{
37413767
Label ok;
37423768
__ push(tmp);
3743-
__ cmpptr(mdo_addr, 0);
3744-
__ jcc(Assembler::equal, ok);
3745-
__ cmpptr(mdo_addr, TypeEntries::null_seen);
3746-
__ jcc(Assembler::equal, ok);
3769+
__ testptr(mdo_addr, TypeEntries::type_mask);
3770+
__ jcc(Assembler::zero, ok);
37473771
// may have been set by another thread
37483772
__ mov_metadata(tmp, exact_klass->constant_encoding());
37493773
__ xorptr(tmp, mdo_addr);
@@ -3759,20 +3783,22 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
37593783
#endif
37603784
// first time here. Set profile type.
37613785
__ movptr(mdo_addr, tmp);
3786+
#ifdef ASSERT
3787+
__ andptr(tmp, TypeEntries::type_klass_mask);
3788+
__ verify_klass_ptr(tmp);
3789+
#endif
37623790
} else {
37633791
assert(ciTypeEntries::valid_ciklass(current_klass) != nullptr &&
37643792
ciTypeEntries::valid_ciklass(current_klass) != exact_klass, "inconsistent");
37653793

3766-
__ movptr(tmp, mdo_addr);
3767-
__ testptr(tmp, TypeEntries::type_unknown);
3794+
__ testptr(mdo_addr, TypeEntries::type_unknown);
37683795
__ jccb(Assembler::notZero, next); // already unknown. Nothing to do anymore.
37693796

37703797
__ orptr(mdo_addr, TypeEntries::type_unknown);
37713798
}
37723799
}
3773-
3774-
__ bind(next);
37753800
}
3801+
__ bind(next);
37763802
}
37773803

37783804
void LIR_Assembler::emit_delay(LIR_OpDelay*) {

src/hotspot/cpu/x86/interp_masm_x86.cpp

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

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

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

6171
bind(update);
6272
load_klass(obj, obj, rscratch1);
73+
#ifdef _LP64
74+
mov(rscratch1, obj);
75+
#endif
6376

6477
xorptr(obj, mdo_addr);
6578
testptr(obj, TypeEntries::type_klass_mask);
@@ -74,12 +87,15 @@ void InterpreterMacroAssembler::profile_obj_type(Register obj, const Address& md
7487
jccb(Assembler::equal, none);
7588
cmpptr(mdo_addr, TypeEntries::null_seen);
7689
jccb(Assembler::equal, none);
90+
#ifdef _LP64
7791
// There is a chance that the checks above (re-reading profiling
7892
// data from memory) fail if another thread has just set the
7993
// profiling to this obj's klass
94+
mov(obj, rscratch1);
8095
xorptr(obj, mdo_addr);
8196
testptr(obj, TypeEntries::type_klass_mask);
8297
jccb(Assembler::zero, next);
98+
#endif
8399

84100
// different than before. Cannot keep accurate profile.
85101
orptr(mdo_addr, TypeEntries::type_unknown);
@@ -88,6 +104,10 @@ void InterpreterMacroAssembler::profile_obj_type(Register obj, const Address& md
88104
bind(none);
89105
// first time here. Set profile type.
90106
movptr(mdo_addr, obj);
107+
#ifdef ASSERT
108+
andptr(obj, TypeEntries::type_klass_mask);
109+
verify_klass_ptr(obj);
110+
#endif
91111

92112
bind(next);
93113
}

src/hotspot/cpu/x86/macroAssembler_x86.hpp

+1
Original file line numberDiff line numberDiff line change
@@ -893,6 +893,7 @@ class MacroAssembler: public Assembler {
893893

894894
void testptr(Register src, int32_t imm32) { LP64_ONLY(testq(src, imm32)) NOT_LP64(testl(src, imm32)); }
895895
void testptr(Register src1, Address src2) { LP64_ONLY(testq(src1, src2)) NOT_LP64(testl(src1, src2)); }
896+
void testptr(Address src, int32_t imm32) { LP64_ONLY(testq(src, imm32)) NOT_LP64(testl(src, imm32)); }
896897
void testptr(Register src1, Register src2);
897898

898899
void xorptr(Register dst, Register src) { LP64_ONLY(xorq(dst, src)) NOT_LP64(xorl(dst, src)); }

0 commit comments

Comments
 (0)