Skip to content

Commit f5b155b

Browse files
committed
8369946: Bytecode rewriting causes Java heap corruption on PPC
Reviewed-by: rrich Backport-of: 6bf3581bbacc2ed8f6411d23a5ab332376c53c87
1 parent cc434af commit f5b155b

File tree

3 files changed

+19
-7
lines changed

3 files changed

+19
-7
lines changed

src/hotspot/cpu/ppc/interp_masm_ppc.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,8 @@ class InterpreterMacroAssembler: public MacroAssembler {
126126

127127
void get_cache_index_at_bcp(Register Rdst, int bcp_offset, size_t index_size);
128128

129-
void get_cache_and_index_at_bcp(Register cache, int bcp_offset, size_t index_size = sizeof(u2));
129+
void get_cache_and_index_at_bcp(Register cache, int bcp_offset, size_t index_size = sizeof(u2),
130+
bool for_fast_bytecode = false);
130131
void load_resolved_indy_entry(Register cache, Register index);
131132

132133
void get_u4(Register Rdst, Register Rsrc, int offset, signedOrNot is_signed);

src/hotspot/cpu/ppc/interp_masm_ppc_64.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -451,10 +451,18 @@ void InterpreterMacroAssembler::get_cache_index_at_bcp(Register Rdst, int bcp_of
451451
}
452452

453453
void InterpreterMacroAssembler::get_cache_and_index_at_bcp(Register cache, int bcp_offset,
454-
size_t index_size) {
454+
size_t index_size, bool for_fast_bytecode) {
455455
get_cache_index_at_bcp(cache, bcp_offset, index_size);
456456
sldi(cache, cache, exact_log2(in_words(ConstantPoolCacheEntry::size()) * BytesPerWord));
457457
add(cache, R27_constPoolCache, cache);
458+
459+
if (for_fast_bytecode) {
460+
// Prevent speculative loading from ConstantPoolCacheEntry as it can miss the info written by another thread.
461+
// TemplateTable::patch_bytecode uses release-store.
462+
// We reached here via control dependency (Bytecode dispatch has used the rewritten Bytecode).
463+
// So, we can use control-isync based ordering.
464+
isync();
465+
}
458466
}
459467

460468
// Load 4-byte signed or unsigned integer in Java format (that is, big-endian format)

src/hotspot/cpu/ppc/templateTable_ppc_64.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,9 @@ void TemplateTable::patch_bytecode(Bytecodes::Code new_bc, Register Rnew_bc, Reg
147147
__ bind(L_fast_patch);
148148
}
149149

150-
// Patch bytecode.
150+
// Patch bytecode with release store to coordinate with ConstantPoolCacheEntry
151+
// loads in fast bytecode codelets.
152+
__ release();
151153
__ stb(Rnew_bc, 0, R14_bcp);
152154

153155
__ bind(L_patch_done);
@@ -311,6 +313,7 @@ void TemplateTable::fast_aldc(LdcType type) {
311313
// We are resolved if the resolved reference cache entry contains a
312314
// non-null object (CallSite, etc.)
313315
__ get_cache_index_at_bcp(R31, 1, index_size); // Load index.
316+
// Only rewritten during link time. So, no need for memory barriers for accessing resolved info.
314317
__ load_resolved_reference_at_index(R17_tos, R31, R11_scratch1, R12_scratch2, &is_null);
315318

316319
// Convert null sentinel to null
@@ -2377,7 +2380,7 @@ void TemplateTable::load_invoke_cp_cache_entry(int byte_no,
23772380
if (is_invokevfinal) {
23782381
assert(Ritable_index == noreg, "register not used");
23792382
// Already resolved.
2380-
__ get_cache_and_index_at_bcp(Rcache, 1);
2383+
__ get_cache_and_index_at_bcp(Rcache, 1, sizeof(u2), /* for_fast_bytecode */ true);
23812384
} else {
23822385
resolve_cache_and_index(byte_no, Rcache, /* temp */ Rmethod, sizeof(u2));
23832386
}
@@ -3084,7 +3087,7 @@ void TemplateTable::fast_storefield(TosState state) {
30843087
const ConditionRegister CR_is_vol = CCR2; // Non-volatile condition register (survives runtime call in do_oop_store).
30853088

30863089
// Constant pool already resolved => Load flags and offset of field.
3087-
__ get_cache_and_index_at_bcp(Rcache, 1);
3090+
__ get_cache_and_index_at_bcp(Rcache, 1, sizeof(u2), /* for_fast_bytecode */ true);
30883091
jvmti_post_field_mod(Rcache, Rscratch, false /* not static */);
30893092
load_field_cp_cache_entry(noreg, Rcache, noreg, Roffset, Rflags, false); // Uses R11, R12
30903093

@@ -3165,7 +3168,7 @@ void TemplateTable::fast_accessfield(TosState state) {
31653168
// R12_scratch2 used by load_field_cp_cache_entry
31663169

31673170
// Constant pool already resolved. Get the field offset.
3168-
__ get_cache_and_index_at_bcp(Rcache, 1);
3171+
__ get_cache_and_index_at_bcp(Rcache, 1, sizeof(u2), /* for_fast_bytecode */ true);
31693172
load_field_cp_cache_entry(noreg, Rcache, noreg, Roffset, Rflags, false); // Uses R11, R12
31703173

31713174
// JVMTI support
@@ -3304,7 +3307,7 @@ void TemplateTable::fast_xaccess(TosState state) {
33043307
__ ld(Rclass_or_obj, 0, R18_locals);
33053308

33063309
// Constant pool already resolved. Get the field offset.
3307-
__ get_cache_and_index_at_bcp(Rcache, 2);
3310+
__ get_cache_and_index_at_bcp(Rcache, 2, sizeof(u2), /* for_fast_bytecode */ true);
33083311
load_field_cp_cache_entry(noreg, Rcache, noreg, Roffset, Rflags, false); // Uses R11, R12
33093312

33103313
// JVMTI support not needed, since we switch back to single bytecode as soon as debugger attaches.

0 commit comments

Comments
 (0)