Skip to content

Commit f4d4fa5

Browse files
fiskTheRealMDoerrxmas92Yadong Wang
committed
8300255: Introduce interface for GC oop verification in the assembler
Co-authored-by: Martin Doerr <mdoerr@openjdk.org> Co-authored-by: Axel Boldt-Christmas <aboldtch@openjdk.org> Co-authored-by: Yadong Wang <yadongwang@openjdk.org> Reviewed-by: fyang, aboldtch, coleenp
1 parent 99b6c0e commit f4d4fa5

18 files changed

+124
-68
lines changed

src/hotspot/cpu/aarch64/gc/shared/barrierSetAssembler_aarch64.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,3 +299,18 @@ void BarrierSetAssembler::c2i_entry_barrier(MacroAssembler* masm) {
299299
__ bind(method_live);
300300
}
301301

302+
void BarrierSetAssembler::check_oop(MacroAssembler* masm, Register obj, Register tmp1, Register tmp2, Label& error) {
303+
// Check if the oop is in the right area of memory
304+
__ mov(tmp2, (intptr_t) Universe::verify_oop_mask());
305+
__ andr(tmp1, obj, tmp2);
306+
__ mov(tmp2, (intptr_t) Universe::verify_oop_bits());
307+
308+
// Compare tmp1 and tmp2. We don't use a compare
309+
// instruction here because the flags register is live.
310+
__ eor(tmp1, tmp1, tmp2);
311+
__ cbnz(tmp1, error);
312+
313+
// make sure klass is 'reasonable', which is not zero.
314+
__ load_klass(obj, obj); // get klass
315+
__ cbz(obj, error); // if klass is NULL it is broken
316+
}

src/hotspot/cpu/aarch64/gc/shared/barrierSetAssembler_aarch64.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ class BarrierSetAssembler: public CHeapObj<mtGC> {
7272
virtual void nmethod_entry_barrier(MacroAssembler* masm, Label* slow_path, Label* continuation, Label* guard);
7373
virtual void c2i_entry_barrier(MacroAssembler* masm);
7474

75+
virtual void check_oop(MacroAssembler* masm, Register obj, Register tmp1, Register tmp2, Label& error);
76+
7577
virtual bool supports_instruction_patching() {
7678
NMethodPatchingType patching_type = nmethod_patching_type();
7779
return patching_type == NMethodPatchingType::conc_instruction_and_data_patch ||

src/hotspot/cpu/aarch64/gc/z/zBarrierSetAssembler_aarch64.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,3 +447,17 @@ void ZBarrierSetAssembler::generate_c2_load_barrier_stub(MacroAssembler* masm, Z
447447
#undef __
448448

449449
#endif // COMPILER2
450+
451+
#define __ masm->
452+
453+
void ZBarrierSetAssembler::check_oop(MacroAssembler* masm, Register obj, Register tmp1, Register tmp2, Label& error) {
454+
// Check if mask is good.
455+
// verifies that ZAddressBadMask & r0 == 0
456+
__ ldr(tmp2, Address(rthread, ZThreadLocalData::address_bad_mask_offset()));
457+
__ andr(tmp1, obj, tmp2);
458+
__ cbnz(tmp1, error);
459+
460+
BarrierSetAssembler::check_oop(masm, obj, tmp1, tmp2, error);
461+
}
462+
463+
#undef __

src/hotspot/cpu/aarch64/gc/z/zBarrierSetAssembler_aarch64.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@ class ZBarrierSetAssembler : public ZBarrierSetAssemblerBase {
9797
void generate_c2_load_barrier_stub(MacroAssembler* masm,
9898
ZLoadBarrierStubC2* stub) const;
9999
#endif // COMPILER2
100+
101+
void check_oop(MacroAssembler* masm, Register obj, Register tmp1, Register tmp2, Label& error);
100102
};
101103

102104
#endif // CPU_AARCH64_GC_Z_ZBARRIERSETASSEMBLER_AARCH64_HPP

src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -568,29 +568,8 @@ class StubGenerator: public StubCodeGenerator {
568568
// make sure object is 'reasonable'
569569
__ cbz(r0, exit); // if obj is NULL it is OK
570570

571-
#if INCLUDE_ZGC
572-
if (UseZGC) {
573-
// Check if mask is good.
574-
// verifies that ZAddressBadMask & r0 == 0
575-
__ ldr(c_rarg3, Address(rthread, ZThreadLocalData::address_bad_mask_offset()));
576-
__ andr(c_rarg2, r0, c_rarg3);
577-
__ cbnz(c_rarg2, error);
578-
}
579-
#endif
580-
581-
// Check if the oop is in the right area of memory
582-
__ mov(c_rarg3, (intptr_t) Universe::verify_oop_mask());
583-
__ andr(c_rarg2, r0, c_rarg3);
584-
__ mov(c_rarg3, (intptr_t) Universe::verify_oop_bits());
585-
586-
// Compare c_rarg2 and c_rarg3. We don't use a compare
587-
// instruction here because the flags register is live.
588-
__ eor(c_rarg2, c_rarg2, c_rarg3);
589-
__ cbnz(c_rarg2, error);
590-
591-
// make sure klass is 'reasonable', which is not zero.
592-
__ load_klass(r0, r0); // get klass
593-
__ cbz(r0, error); // if klass is NULL it is broken
571+
BarrierSetAssembler* bs_asm = BarrierSet::barrier_set()->barrier_set_assembler();
572+
bs_asm->check_oop(_masm, r0, c_rarg2, c_rarg3, error);
594573

595574
// return if everything seems ok
596575
__ bind(exit);

src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -731,7 +731,10 @@ int LIR_Assembler::store(LIR_Opr from_reg, Register base, int offset, BasicType
731731
__ verify_coop(from_reg->as_register(), FILE_AND_LINE);
732732
} else {
733733
__ std(from_reg->as_register(), offset, base);
734-
__ verify_oop(from_reg->as_register(), FILE_AND_LINE);
734+
if (VerifyOops) {
735+
BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
736+
bs->check_oop(_masm, from_reg->as_register(), FILE_AND_LINE); // kills R0
737+
}
735738
}
736739
break;
737740
}
@@ -772,7 +775,10 @@ int LIR_Assembler::store(LIR_Opr from_reg, Register base, Register disp, BasicTy
772775
__ verify_coop(from_reg->as_register(), FILE_AND_LINE); // kills R0
773776
} else {
774777
__ stdx(from_reg->as_register(), base, disp);
775-
__ verify_oop(from_reg->as_register(), FILE_AND_LINE); // kills R0
778+
if (VerifyOops) {
779+
BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
780+
bs->check_oop(_masm, from_reg->as_register(), FILE_AND_LINE); // kills R0
781+
}
776782
}
777783
break;
778784
}
@@ -813,7 +819,10 @@ int LIR_Assembler::load(Register base, int offset, LIR_Opr to_reg, BasicType typ
813819
} else {
814820
__ ld(to_reg->as_register(), offset, base);
815821
}
816-
__ verify_oop(to_reg->as_register(), FILE_AND_LINE);
822+
if (VerifyOops) {
823+
BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
824+
bs->check_oop(_masm, to_reg->as_register(), FILE_AND_LINE); // kills R0
825+
}
817826
break;
818827
}
819828
case T_FLOAT: __ lfs(to_reg->as_float_reg(), offset, base); break;
@@ -844,7 +853,10 @@ int LIR_Assembler::load(Register base, Register disp, LIR_Opr to_reg, BasicType
844853
} else {
845854
__ ldx(to_reg->as_register(), base, disp);
846855
}
847-
__ verify_oop(to_reg->as_register(), FILE_AND_LINE);
856+
if (VerifyOops) {
857+
BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
858+
bs->check_oop(_masm, to_reg->as_register(), FILE_AND_LINE); // kills R0
859+
}
848860
break;
849861
}
850862
case T_FLOAT: __ lfsx(to_reg->as_float_reg() , base, disp); break;

src/hotspot/cpu/ppc/gc/shared/barrierSetAssembler_ppc.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,3 +255,7 @@ void BarrierSetAssembler::c2i_entry_barrier(MacroAssembler *masm, Register tmp1,
255255

256256
__ block_comment("} c2i_entry_barrier (c2i_entry_barrier)");
257257
}
258+
259+
void BarrierSetAssembler::check_oop(MacroAssembler *masm, Register oop, const char* msg) {
260+
__ verify_oop(oop, msg);
261+
}

src/hotspot/cpu/ppc/gc/shared/barrierSetAssembler_ppc.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ class BarrierSetAssembler: public CHeapObj<mtGC> {
6969

7070
virtual void nmethod_entry_barrier(MacroAssembler* masm, Register tmp);
7171
virtual void c2i_entry_barrier(MacroAssembler* masm, Register tmp1, Register tmp2, Register tmp3);
72+
73+
virtual void check_oop(MacroAssembler *masm, Register oop, const char* msg);
7274
};
7375

7476
#endif // CPU_PPC_GC_SHARED_BARRIERSETASSEMBLER_PPC_HPP

src/hotspot/cpu/riscv/gc/shared/barrierSetAssembler_riscv.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,3 +308,17 @@ void BarrierSetAssembler::c2i_entry_barrier(MacroAssembler* masm) {
308308
__ far_jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub()));
309309
__ bind(method_live);
310310
}
311+
312+
void BarrierSetAssembler::check_oop(MacroAssembler* masm, Register obj, Register tmp1, Register tmp2, Label& error) {
313+
// Check if the oop is in the right area of memory
314+
__ mv(tmp2, (intptr_t) Universe::verify_oop_mask());
315+
__ andr(tmp1, obj, tmp2);
316+
__ mv(tmp2, (intptr_t) Universe::verify_oop_bits());
317+
318+
// Compare tmp1 and tmp2.
319+
__ bne(tmp1, tmp2, error);
320+
321+
// Make sure klass is 'reasonable', which is not zero.
322+
__ load_klass(obj, obj, tmp1); // get klass
323+
__ beqz(obj, error); // if klass is NULL it is broken
324+
}

src/hotspot/cpu/riscv/gc/shared/barrierSetAssembler_riscv.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ class BarrierSetAssembler: public CHeapObj<mtGC> {
7474
virtual void nmethod_entry_barrier(MacroAssembler* masm, Label* slow_path, Label* continuation, Label* guard);
7575
virtual void c2i_entry_barrier(MacroAssembler* masm);
7676

77+
virtual void check_oop(MacroAssembler* masm, Register obj, Register tmp1, Register tmp2, Label& error);
78+
7779
virtual bool supports_instruction_patching() {
7880
NMethodPatchingType patching_type = nmethod_patching_type();
7981
return patching_type == NMethodPatchingType::conc_instruction_and_data_patch ||

src/hotspot/cpu/riscv/gc/z/zBarrierSetAssembler_riscv.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,3 +444,17 @@ void ZBarrierSetAssembler::generate_c1_load_barrier_runtime_stub(StubAssembler*
444444

445445
#undef __
446446
#endif // COMPILER1
447+
448+
#define __ masm->
449+
450+
void ZBarrierSetAssembler::check_oop(MacroAssembler* masm, Register obj, Register tmp1, Register tmp2, Label& error) {
451+
// Check if mask is good.
452+
// verifies that ZAddressBadMask & obj == 0
453+
__ ld(tmp2, Address(xthread, ZThreadLocalData::address_bad_mask_offset()));
454+
__ andr(tmp1, obj, tmp2);
455+
__ bnez(tmp1, error);
456+
457+
BarrierSetAssembler::check_oop(masm, obj, tmp1, tmp2, error);
458+
}
459+
460+
#undef __

src/hotspot/cpu/riscv/gc/z/zBarrierSetAssembler_riscv.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,8 @@ class ZBarrierSetAssembler : public ZBarrierSetAssemblerBase {
9999
void generate_c2_load_barrier_stub(MacroAssembler* masm,
100100
ZLoadBarrierStubC2* stub) const;
101101
#endif // COMPILER2
102+
103+
void check_oop(MacroAssembler* masm, Register obj, Register tmp1, Register tmp2, Label& error);
102104
};
103105

104106
#endif // CPU_RISCV_GC_Z_ZBARRIERSETASSEMBLER_RISCV_HPP

src/hotspot/cpu/riscv/stubGenerator_riscv.cpp

Lines changed: 2 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -614,27 +614,8 @@ class StubGenerator: public StubCodeGenerator {
614614
// make sure object is 'reasonable'
615615
__ beqz(x10, exit); // if obj is NULL it is OK
616616

617-
#if INCLUDE_ZGC
618-
if (UseZGC) {
619-
// Check if mask is good.
620-
// verifies that ZAddressBadMask & x10 == 0
621-
__ ld(c_rarg3, Address(xthread, ZThreadLocalData::address_bad_mask_offset()));
622-
__ andr(c_rarg2, x10, c_rarg3);
623-
__ bnez(c_rarg2, error);
624-
}
625-
#endif
626-
627-
// Check if the oop is in the right area of memory
628-
__ mv(c_rarg3, (intptr_t) Universe::verify_oop_mask());
629-
__ andr(c_rarg2, x10, c_rarg3);
630-
__ mv(c_rarg3, (intptr_t) Universe::verify_oop_bits());
631-
632-
// Compare c_rarg2 and c_rarg3.
633-
__ bne(c_rarg2, c_rarg3, error);
634-
635-
// make sure klass is 'reasonable', which is not zero.
636-
__ load_klass(x10, x10); // get klass
637-
__ beqz(x10, error); // if klass is NULL it is broken
617+
BarrierSetAssembler* bs_asm = BarrierSet::barrier_set()->barrier_set_assembler();
618+
bs_asm->check_oop(_masm, x10, c_rarg2, c_rarg3, error);
638619

639620
// return if everything seems ok
640621
__ bind(exit);

src/hotspot/cpu/x86/gc/shared/barrierSetAssembler_x86.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,3 +366,18 @@ void BarrierSetAssembler::c2i_entry_barrier(MacroAssembler* masm) {
366366
__ pop(tmp1);
367367
#endif
368368
}
369+
370+
void BarrierSetAssembler::check_oop(MacroAssembler* masm, Register obj, Register tmp1, Register tmp2, Label& error) {
371+
// Check if the oop is in the right area of memory
372+
__ movptr(tmp1, obj);
373+
__ movptr(tmp2, (intptr_t) Universe::verify_oop_mask());
374+
__ andptr(tmp1, tmp2);
375+
__ movptr(tmp2, (intptr_t) Universe::verify_oop_bits());
376+
__ cmpptr(tmp1, tmp2);
377+
__ jcc(Assembler::notZero, error);
378+
379+
// make sure klass is 'reasonable', which is not zero.
380+
__ load_klass(obj, obj, tmp1); // get klass
381+
__ testptr(obj, obj);
382+
__ jcc(Assembler::zero, error); // if klass is NULL it is broken
383+
}

src/hotspot/cpu/x86/gc/shared/barrierSetAssembler_x86.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ class BarrierSetAssembler: public CHeapObj<mtGC> {
6464

6565
virtual void nmethod_entry_barrier(MacroAssembler* masm, Label* slow_path, Label* continuation);
6666
virtual void c2i_entry_barrier(MacroAssembler* masm);
67+
68+
virtual void check_oop(MacroAssembler* masm, Register obj, Register tmp1, Register tmp2, Label& error);
6769
};
6870

6971
#endif // CPU_X86_GC_SHARED_BARRIERSETASSEMBLER_X86_HPP

src/hotspot/cpu/x86/gc/z/zBarrierSetAssembler_x86.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "gc/z/zBarrierSet.hpp"
3030
#include "gc/z/zBarrierSetAssembler.hpp"
3131
#include "gc/z/zBarrierSetRuntime.hpp"
32+
#include "gc/z/zThreadLocalData.hpp"
3233
#include "memory/resourceArea.hpp"
3334
#include "runtime/sharedRuntime.hpp"
3435
#include "utilities/macros.hpp"
@@ -700,3 +701,14 @@ void ZBarrierSetAssembler::generate_c2_load_barrier_stub(MacroAssembler* masm, Z
700701
#undef __
701702

702703
#endif // COMPILER2
704+
705+
#define __ masm->
706+
707+
void ZBarrierSetAssembler::check_oop(MacroAssembler* masm, Register obj, Register tmp1, Register tmp2, Label& error) {
708+
// Check if metadata bits indicate a bad oop
709+
__ testptr(obj, Address(r15_thread, ZThreadLocalData::address_bad_mask_offset()));
710+
__ jcc(Assembler::notZero, error);
711+
BarrierSetAssembler::check_oop(masm, obj, tmp1, tmp2, error);
712+
}
713+
714+
#undef __

src/hotspot/cpu/x86/gc/z/zBarrierSetAssembler_x86.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,8 @@ class ZBarrierSetAssembler : public ZBarrierSetAssemblerBase {
9696
void generate_c2_load_barrier_stub(MacroAssembler* masm,
9797
ZLoadBarrierStubC2* stub) const;
9898
#endif // COMPILER2
99+
100+
void check_oop(MacroAssembler* masm, Register obj, Register tmp1, Register tmp2, Label& error);
99101
};
100102

101103
#endif // CPU_X86_GC_Z_ZBARRIERSETASSEMBLER_X86_HPP

src/hotspot/cpu/x86/stubGenerator_x86_64.cpp

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1093,26 +1093,8 @@ address StubGenerator::generate_verify_oop() {
10931093
__ testptr(rax, rax);
10941094
__ jcc(Assembler::zero, exit); // if obj is NULL it is OK
10951095

1096-
#if INCLUDE_ZGC
1097-
if (UseZGC) {
1098-
// Check if metadata bits indicate a bad oop
1099-
__ testptr(rax, Address(r15_thread, ZThreadLocalData::address_bad_mask_offset()));
1100-
__ jcc(Assembler::notZero, error);
1101-
}
1102-
#endif
1103-
1104-
// Check if the oop is in the right area of memory
1105-
__ movptr(c_rarg2, rax);
1106-
__ movptr(c_rarg3, (intptr_t) Universe::verify_oop_mask());
1107-
__ andptr(c_rarg2, c_rarg3);
1108-
__ movptr(c_rarg3, (intptr_t) Universe::verify_oop_bits());
1109-
__ cmpptr(c_rarg2, c_rarg3);
1110-
__ jcc(Assembler::notZero, error);
1111-
1112-
// make sure klass is 'reasonable', which is not zero.
1113-
__ load_klass(rax, rax, rscratch1); // get klass
1114-
__ testptr(rax, rax);
1115-
__ jcc(Assembler::zero, error); // if klass is NULL it is broken
1096+
BarrierSetAssembler* bs_asm = BarrierSet::barrier_set()->barrier_set_assembler();
1097+
bs_asm->check_oop(_masm, rax, c_rarg2, c_rarg3, error);
11161098

11171099
// return if everything seems ok
11181100
__ bind(exit);

0 commit comments

Comments
 (0)