Skip to content

Commit 1bb250c

Browse files
dean-longRealFYang
andcommitted
8261837: SIGSEGV in ciVirtualCallTypeData::translate_from
Co-authored-by: Fei Yang <fyang@openjdk.org> Reviewed-by: iveresov, vlivanov, kvn
1 parent 5f7f2c4 commit 1bb250c

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
@@ -2699,7 +2699,10 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
26992699
__ verify_oop(obj);
27002700

27012701
if (tmp != obj) {
2702+
assert_different_registers(obj, tmp, rscratch1, rscratch2, mdo_addr.base(), mdo_addr.index());
27022703
__ mov(tmp, obj);
2704+
} else {
2705+
assert_different_registers(obj, rscratch1, rscratch2, mdo_addr.base(), mdo_addr.index());
27032706
}
27042707
if (do_null) {
27052708
__ cbnz(tmp, update);
@@ -2756,10 +2759,11 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
27562759
__ cbz(rscratch2, none);
27572760
__ cmp(rscratch2, (u1)TypeEntries::null_seen);
27582761
__ br(Assembler::EQ, none);
2759-
// There is a chance that the checks above (re-reading profiling
2760-
// data from memory) fail if another thread has just set the
2762+
// There is a chance that the checks above
2763+
// fail if another thread has just set the
27612764
// profiling to this obj's klass
27622765
__ dmb(Assembler::ISHLD);
2766+
__ eor(tmp, tmp, rscratch2); // get back original value before XOR
27632767
__ ldr(rscratch2, mdo_addr);
27642768
__ eor(tmp, tmp, rscratch2);
27652769
__ andr(rscratch1, tmp, TypeEntries::type_klass_mask);
@@ -2784,6 +2788,10 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
27842788
__ bind(none);
27852789
// first time here. Set profile type.
27862790
__ str(tmp, mdo_addr);
2791+
#ifdef ASSERT
2792+
__ andr(tmp, tmp, TypeEntries::type_mask);
2793+
__ verify_klass_ptr(tmp);
2794+
#endif
27872795
}
27882796
} else {
27892797
// There's a single possible klass at this profile point
@@ -2815,6 +2823,10 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
28152823
#endif
28162824
// first time here. Set profile type.
28172825
__ str(tmp, mdo_addr);
2826+
#ifdef ASSERT
2827+
__ andr(tmp, tmp, TypeEntries::type_mask);
2828+
__ verify_klass_ptr(tmp);
2829+
#endif
28182830
} else {
28192831
assert(ciTypeEntries::valid_ciklass(current_klass) != nullptr &&
28202832
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
@@ -1562,7 +1562,7 @@ void InterpreterMacroAssembler::call_VM_base(Register oop_result,
15621562
}
15631563

15641564
void InterpreterMacroAssembler::profile_obj_type(Register obj, const Address& mdo_addr) {
1565-
assert_different_registers(obj, rscratch1);
1565+
assert_different_registers(obj, rscratch1, mdo_addr.base(), mdo_addr.index());
15661566
Label update, next, none;
15671567

15681568
verify_oop(obj);
@@ -1584,13 +1584,13 @@ void InterpreterMacroAssembler::profile_obj_type(Register obj, const Address& md
15841584
tbnz(obj, exact_log2(TypeEntries::type_unknown), next);
15851585
// already unknown. Nothing to do anymore.
15861586

1587-
ldr(rscratch1, mdo_addr);
15881587
cbz(rscratch1, none);
15891588
cmp(rscratch1, (u1)TypeEntries::null_seen);
15901589
br(Assembler::EQ, none);
1591-
// There is a chance that the checks above (re-reading profiling
1592-
// data from memory) fail if another thread has just set the
1590+
// There is a chance that the checks above
1591+
// fail if another thread has just set the
15931592
// profiling to this obj's klass
1593+
eor(obj, obj, rscratch1); // get back original value before XOR
15941594
ldr(rscratch1, mdo_addr);
15951595
eor(obj, obj, rscratch1);
15961596
tst(obj, TypeEntries::type_klass_mask);
@@ -1603,6 +1603,10 @@ void InterpreterMacroAssembler::profile_obj_type(Register obj, const Address& md
16031603
bind(none);
16041604
// first time here. Set profile type.
16051605
str(obj, mdo_addr);
1606+
#ifdef ASSERT
1607+
andr(obj, obj, TypeEntries::type_mask);
1608+
verify_klass_ptr(obj);
1609+
#endif
16061610

16071611
bind(next);
16081612
}

src/hotspot/cpu/riscv/c1_LIRAssembler_riscv.cpp

+11-2
Original file line numberDiff line numberDiff line change
@@ -1653,10 +1653,11 @@ void LIR_Assembler::check_conflict(ciKlass* exact_klass, intptr_t current_klass,
16531653
__ beqz(t1, none);
16541654
__ mv(t0, (u1)TypeEntries::null_seen);
16551655
__ beq(t0, t1, none);
1656-
// There is a chance that the checks above (re-reading profiling
1657-
// data from memory) fail if another thread has just set the
1656+
// There is a chance that the checks above
1657+
// fail if another thread has just set the
16581658
// profiling to this obj's klass
16591659
__ membar(MacroAssembler::LoadLoad);
1660+
__ xorr(tmp, tmp, t1); // get back original value before XOR
16601661
__ ld(t1, mdo_addr);
16611662
__ xorr(tmp, tmp, t1);
16621663
__ andi(t0, tmp, TypeEntries::type_klass_mask);
@@ -1683,6 +1684,10 @@ void LIR_Assembler::check_conflict(ciKlass* exact_klass, intptr_t current_klass,
16831684
__ bind(none);
16841685
// first time here. Set profile type.
16851686
__ sd(tmp, mdo_addr);
1687+
#ifdef ASSERT
1688+
__ andi(tmp, tmp, TypeEntries::type_mask);
1689+
__ verify_klass_ptr(tmp);
1690+
#endif
16861691
}
16871692
}
16881693

@@ -1717,6 +1722,10 @@ void LIR_Assembler::check_no_conflict(ciKlass* exact_klass, intptr_t current_kla
17171722
#endif
17181723
// first time here. Set profile type.
17191724
__ sd(tmp, mdo_addr);
1725+
#ifdef ASSERT
1726+
__ andi(tmp, tmp, TypeEntries::type_mask);
1727+
__ verify_klass_ptr(tmp);
1728+
#endif
17201729
} else {
17211730
assert(ciTypeEntries::valid_ciklass(current_klass) != nullptr &&
17221731
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
@@ -1627,8 +1627,8 @@ void InterpreterMacroAssembler::profile_obj_type(Register obj, const Address& md
16271627
bind(update);
16281628
load_klass(obj, obj);
16291629

1630-
ld(t0, mdo_addr);
1631-
xorr(obj, obj, t0);
1630+
ld(tmp, mdo_addr);
1631+
xorr(obj, obj, tmp);
16321632
andi(t0, obj, TypeEntries::type_klass_mask);
16331633
beqz(t0, next); // klass seen before, nothing to
16341634
// do. The unknown bit may have been
@@ -1638,15 +1638,15 @@ void InterpreterMacroAssembler::profile_obj_type(Register obj, const Address& md
16381638
bnez(t0, next);
16391639
// already unknown. Nothing to do anymore.
16401640

1641-
ld(t0, mdo_addr);
1642-
beqz(t0, none);
1643-
mv(tmp, (u1)TypeEntries::null_seen);
1644-
beq(t0, tmp, none);
1645-
// There is a chance that the checks above (re-reading profiling
1646-
// data from memory) fail if another thread has just set the
1641+
beqz(tmp, none);
1642+
mv(t0, (u1)TypeEntries::null_seen);
1643+
beq(tmp, t0, none);
1644+
// There is a chance that the checks above
1645+
// fail if another thread has just set the
16471646
// profiling to this obj's klass
1648-
ld(t0, mdo_addr);
1649-
xorr(obj, obj, t0);
1647+
xorr(obj, obj, tmp); // get back original value before XOR
1648+
ld(tmp, mdo_addr);
1649+
xorr(obj, obj, tmp);
16501650
andi(t0, obj, TypeEntries::type_klass_mask);
16511651
beqz(t0, next);
16521652

@@ -1657,6 +1657,10 @@ void InterpreterMacroAssembler::profile_obj_type(Register obj, const Address& md
16571657
bind(none);
16581658
// first time here. Set profile type.
16591659
sd(obj, mdo_addr);
1660+
#ifdef ASSERT
1661+
andi(obj, obj, TypeEntries::type_mask);
1662+
verify_klass_ptr(obj);
1663+
#endif
16601664

16611665
bind(next);
16621666
}

src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp

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

36303630
__ verify_oop(obj);
36313631

3632-
if (tmp != obj) {
3633-
__ mov(tmp, obj);
3632+
#ifdef ASSERT
3633+
if (obj == tmp) {
3634+
#ifdef _LP64
3635+
assert_different_registers(obj, rscratch1, mdo_addr.base(), mdo_addr.index());
3636+
#else
3637+
assert_different_registers(obj, mdo_addr.base(), mdo_addr.index());
3638+
#endif
3639+
} else {
3640+
#ifdef _LP64
3641+
assert_different_registers(obj, tmp, rscratch1, mdo_addr.base(), mdo_addr.index());
3642+
#else
3643+
assert_different_registers(obj, tmp, mdo_addr.base(), mdo_addr.index());
3644+
#endif
36343645
}
3646+
#endif
36353647
if (do_null) {
3636-
__ testptr(tmp, tmp);
3648+
__ testptr(obj, obj);
36373649
__ jccb(Assembler::notZero, update);
36383650
if (!TypeEntries::was_null_seen(current_klass)) {
3651+
__ testptr(mdo_addr, TypeEntries::null_seen);
3652+
#ifndef ASSERT
3653+
__ jccb(Assembler::notZero, next); // already set
3654+
#else
3655+
__ jcc(Assembler::notZero, next); // already set
3656+
#endif
3657+
// atomic update to prevent overwriting Klass* with 0
3658+
__ lock();
36393659
__ orptr(mdo_addr, TypeEntries::null_seen);
36403660
}
36413661
if (do_update) {
@@ -3646,7 +3666,7 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
36463666
__ jmp(next);
36473667
}
36483668
} else {
3649-
__ testptr(tmp, tmp);
3669+
__ testptr(obj, obj);
36503670
__ jcc(Assembler::notZero, update);
36513671
__ stop("unexpected null obj");
36523672
#endif
@@ -3658,7 +3678,7 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
36583678
#ifdef ASSERT
36593679
if (exact_klass != nullptr) {
36603680
Label ok;
3661-
__ load_klass(tmp, tmp, tmp_load_klass);
3681+
__ load_klass(tmp, obj, tmp_load_klass);
36623682
__ push(tmp);
36633683
__ mov_metadata(tmp, exact_klass->constant_encoding());
36643684
__ cmpptr(tmp, Address(rsp, 0));
@@ -3673,9 +3693,11 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
36733693
if (exact_klass != nullptr) {
36743694
__ mov_metadata(tmp, exact_klass->constant_encoding());
36753695
} else {
3676-
__ load_klass(tmp, tmp, tmp_load_klass);
3696+
__ load_klass(tmp, obj, tmp_load_klass);
36773697
}
3678-
3698+
#ifdef _LP64
3699+
__ mov(rscratch1, tmp); // save original value before XOR
3700+
#endif
36793701
__ xorptr(tmp, mdo_addr);
36803702
__ testptr(tmp, TypeEntries::type_klass_mask);
36813703
// klass seen before, nothing to do. The unknown bit may have been
@@ -3686,23 +3708,23 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
36863708
__ jccb(Assembler::notZero, next); // already unknown. Nothing to do anymore.
36873709

36883710
if (TypeEntries::is_type_none(current_klass)) {
3689-
__ cmpptr(mdo_addr, 0);
3690-
__ jccb(Assembler::equal, none);
3691-
__ cmpptr(mdo_addr, TypeEntries::null_seen);
3692-
__ jccb(Assembler::equal, none);
3711+
__ testptr(mdo_addr, TypeEntries::type_mask);
3712+
__ jccb(Assembler::zero, none);
3713+
#ifdef _LP64
36933714
// There is a chance that the checks above (re-reading profiling
36943715
// data from memory) fail if another thread has just set the
36953716
// profiling to this obj's klass
3717+
__ mov(tmp, rscratch1); // get back original value before XOR
36963718
__ xorptr(tmp, mdo_addr);
36973719
__ testptr(tmp, TypeEntries::type_klass_mask);
36983720
__ jccb(Assembler::zero, next);
3721+
#endif
36993722
}
37003723
} else {
37013724
assert(ciTypeEntries::valid_ciklass(current_klass) != nullptr &&
37023725
ciTypeEntries::valid_ciklass(current_klass) != exact_klass, "conflict only");
37033726

3704-
__ movptr(tmp, mdo_addr);
3705-
__ testptr(tmp, TypeEntries::type_unknown);
3727+
__ testptr(mdo_addr, TypeEntries::type_unknown);
37063728
__ jccb(Assembler::notZero, next); // already unknown. Nothing to do anymore.
37073729
}
37083730

@@ -3715,6 +3737,10 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
37153737
__ bind(none);
37163738
// first time here. Set profile type.
37173739
__ movptr(mdo_addr, tmp);
3740+
#ifdef ASSERT
3741+
__ andptr(tmp, TypeEntries::type_klass_mask);
3742+
__ verify_klass_ptr(tmp);
3743+
#endif
37183744
}
37193745
} else {
37203746
// There's a single possible klass at this profile point
@@ -3729,10 +3755,8 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
37293755
{
37303756
Label ok;
37313757
__ push(tmp);
3732-
__ cmpptr(mdo_addr, 0);
3733-
__ jcc(Assembler::equal, ok);
3734-
__ cmpptr(mdo_addr, TypeEntries::null_seen);
3735-
__ jcc(Assembler::equal, ok);
3758+
__ testptr(mdo_addr, TypeEntries::type_mask);
3759+
__ jcc(Assembler::zero, ok);
37363760
// may have been set by another thread
37373761
__ mov_metadata(tmp, exact_klass->constant_encoding());
37383762
__ xorptr(tmp, mdo_addr);
@@ -3748,20 +3772,22 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
37483772
#endif
37493773
// first time here. Set profile type.
37503774
__ movptr(mdo_addr, tmp);
3775+
#ifdef ASSERT
3776+
__ andptr(tmp, TypeEntries::type_klass_mask);
3777+
__ verify_klass_ptr(tmp);
3778+
#endif
37513779
} else {
37523780
assert(ciTypeEntries::valid_ciklass(current_klass) != nullptr &&
37533781
ciTypeEntries::valid_ciklass(current_klass) != exact_klass, "inconsistent");
37543782

3755-
__ movptr(tmp, mdo_addr);
3756-
__ testptr(tmp, TypeEntries::type_unknown);
3783+
__ testptr(mdo_addr, TypeEntries::type_unknown);
37573784
__ jccb(Assembler::notZero, next); // already unknown. Nothing to do anymore.
37583785

37593786
__ orptr(mdo_addr, TypeEntries::type_unknown);
37603787
}
37613788
}
3762-
3763-
__ bind(next);
37643789
}
3790+
__ bind(next);
37653791
}
37663792

37673793
void LIR_Assembler::emit_delay(LIR_OpDelay*) {

src/hotspot/cpu/x86/interp_masm_x86.cpp

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

57+
#ifdef _LP64
58+
assert_different_registers(obj, rscratch1, mdo_addr.base(), mdo_addr.index());
59+
#else
60+
assert_different_registers(obj, mdo_addr.base(), mdo_addr.index());
61+
#endif
62+
5763
interp_verify_oop(obj, atos);
5864

5965
testptr(obj, obj);
6066
jccb(Assembler::notZero, update);
67+
testptr(mdo_addr, TypeEntries::null_seen);
68+
jccb(Assembler::notZero, next); // null already seen. Nothing to do anymore.
69+
// atomic update to prevent overwriting Klass* with 0
70+
lock();
6171
orptr(mdo_addr, TypeEntries::null_seen);
6272
jmpb(next);
6373

6474
bind(update);
6575
load_klass(obj, obj, rscratch1);
76+
#ifdef _LP64
77+
mov(rscratch1, obj);
78+
#endif
6679

6780
xorptr(obj, mdo_addr);
6881
testptr(obj, TypeEntries::type_klass_mask);
@@ -77,12 +90,15 @@ void InterpreterMacroAssembler::profile_obj_type(Register obj, const Address& md
7790
jccb(Assembler::equal, none);
7891
cmpptr(mdo_addr, TypeEntries::null_seen);
7992
jccb(Assembler::equal, none);
93+
#ifdef _LP64
8094
// There is a chance that the checks above (re-reading profiling
8195
// data from memory) fail if another thread has just set the
8296
// profiling to this obj's klass
97+
mov(obj, rscratch1);
8398
xorptr(obj, mdo_addr);
8499
testptr(obj, TypeEntries::type_klass_mask);
85100
jccb(Assembler::zero, next);
101+
#endif
86102

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

95115
bind(next);
96116
}

src/hotspot/cpu/x86/macroAssembler_x86.hpp

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

895895
void testptr(Register src, int32_t imm32) { LP64_ONLY(testq(src, imm32)) NOT_LP64(testl(src, imm32)); }
896896
void testptr(Register src1, Address src2) { LP64_ONLY(testq(src1, src2)) NOT_LP64(testl(src1, src2)); }
897+
void testptr(Address src, int32_t imm32) { LP64_ONLY(testq(src, imm32)) NOT_LP64(testl(src, imm32)); }
897898
void testptr(Register src1, Register src2);
898899

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

0 commit comments

Comments
 (0)