8369947: Bytecode rewriting causes Java heap corruption on RISC-V

Reviewed-by: aph, jcking, fyang
This commit is contained in:
Feilong Jiang 2025-10-18 01:09:41 +00:00
parent 181657084a
commit 4625199358
3 changed files with 22 additions and 1 deletions

View File

@ -1841,6 +1841,15 @@ void InterpreterMacroAssembler::load_method_entry(Register cache, Register index
}
#ifdef ASSERT
void InterpreterMacroAssembler::verify_field_offset(Register reg) {
// Verify the field offset is not in the header, implicitly checks for 0
Label L;
mv(t0, oopDesc::base_offset_in_bytes());
bge(reg, t0, L);
stop("bad field offset");
bind(L);
}
void InterpreterMacroAssembler::verify_access_flags(Register access_flags, uint32_t flag,
const char* msg, bool stop_by_hit) {
Label L;

View File

@ -300,6 +300,8 @@ class InterpreterMacroAssembler: public MacroAssembler {
void load_field_entry(Register cache, Register index, int bcp_offset = 1);
void load_method_entry(Register cache, Register index, int bcp_offset = 1);
void verify_field_offset(Register reg) NOT_DEBUG_RETURN;
#ifdef ASSERT
void verify_access_flags(Register access_flags, uint32_t flag,
const char* msg, bool stop_by_hit = true);

View File

@ -133,6 +133,7 @@ Address TemplateTable::at_bcp(int offset) {
void TemplateTable::patch_bytecode(Bytecodes::Code bc, Register bc_reg,
Register temp_reg, bool load_bc_into_bc_reg /*=true*/,
int byte_no) {
assert_different_registers(bc_reg, temp_reg);
if (!RewriteBytecodes) { return; }
Label L_patch_done;
@ -196,7 +197,11 @@ void TemplateTable::patch_bytecode(Bytecodes::Code bc, Register bc_reg,
__ bind(L_okay);
#endif
// patch bytecode
// Patch bytecode with release store to coordinate with ResolvedFieldEntry loads
// in fast bytecode codelets. load_field_entry has a memory barrier that gains
// the needed ordering, together with control dependency on entering the fast codelet
// itself.
__ membar(MacroAssembler::LoadStore | MacroAssembler::StoreStore);
__ sb(bc_reg, at_bcp(0));
__ bind(L_patch_done);
}
@ -3028,6 +3033,7 @@ void TemplateTable::fast_storefield(TosState state) {
// X11: field offset, X12: field holder, X13: flags
load_resolved_field_entry(x12, x12, noreg, x11, x13);
__ verify_field_offset(x11);
{
Label notVolatile;
@ -3115,6 +3121,8 @@ void TemplateTable::fast_accessfield(TosState state) {
__ load_field_entry(x12, x11);
__ load_sized_value(x11, Address(x12, in_bytes(ResolvedFieldEntry::field_offset_offset())), sizeof(int), true /*is_signed*/);
__ verify_field_offset(x11);
__ load_unsigned_byte(x13, Address(x12, in_bytes(ResolvedFieldEntry::flags_offset())));
// x10: object
@ -3170,7 +3178,9 @@ void TemplateTable::fast_xaccess(TosState state) {
__ ld(x10, aaddress(0));
// access constant pool cache
__ load_field_entry(x12, x13, 2);
__ load_sized_value(x11, Address(x12, in_bytes(ResolvedFieldEntry::field_offset_offset())), sizeof(int), true /*is_signed*/);
__ verify_field_offset(x11);
// make sure exception is reported in correct bcp range (getfield is
// next instruction)