Skip to content

Commit 5696c75

Browse files
author
duke
committed
Backport 6bf3581bbacc2ed8f6411d23a5ab332376c53c87
1 parent f597463 commit 5696c75

File tree

3 files changed

+32
-24
lines changed

3 files changed

+32
-24
lines changed

src/hotspot/cpu/ppc/interp_masm_ppc.hpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,8 +133,13 @@ class InterpreterMacroAssembler: public MacroAssembler {
133133
void get_cache_index_at_bcp(Register Rdst, int bcp_offset, size_t index_size);
134134

135135
void load_resolved_indy_entry(Register cache, Register index);
136-
void load_field_entry(Register cache, Register index, int bcp_offset = 1);
137-
void load_method_entry(Register cache, Register index, int bcp_offset = 1);
136+
void load_field_or_method_entry(bool is_method, Register cache, Register index, int bcp_offset, bool for_fast_bytecode);
137+
void load_field_entry(Register cache, Register index, int bcp_offset = 1, bool for_fast_bytecode = false) {
138+
load_field_or_method_entry(false, cache, index, bcp_offset, for_fast_bytecode);
139+
}
140+
void load_method_entry(Register cache, Register index, int bcp_offset = 1, bool for_fast_bytecode = false) {
141+
load_field_or_method_entry(true, cache, index, bcp_offset, for_fast_bytecode);
142+
}
138143

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

src/hotspot/cpu/ppc/interp_masm_ppc_64.cpp

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -468,33 +468,33 @@ void InterpreterMacroAssembler::load_resolved_indy_entry(Register cache, Registe
468468
add(cache, cache, index);
469469
}
470470

471-
void InterpreterMacroAssembler::load_field_entry(Register cache, Register index, int bcp_offset) {
471+
void InterpreterMacroAssembler::load_field_or_method_entry(bool is_method, Register cache, Register index, int bcp_offset, bool for_fast_bytecode) {
472+
const int entry_size = is_method ? sizeof(ResolvedMethodEntry) : sizeof(ResolvedFieldEntry),
473+
base_offset = is_method ? Array<ResolvedMethodEntry>::base_offset_in_bytes() : Array<ResolvedFieldEntry>::base_offset_in_bytes(),
474+
entries_offset = is_method ? in_bytes(ConstantPoolCache::method_entries_offset()) : in_bytes(ConstantPoolCache::field_entries_offset());
475+
472476
// Get index out of bytecode pointer
473477
get_cache_index_at_bcp(index, bcp_offset, sizeof(u2));
474478
// Take shortcut if the size is a power of 2
475-
if (is_power_of_2(sizeof(ResolvedFieldEntry))) {
479+
if (is_power_of_2(entry_size)) {
476480
// Scale index by power of 2
477-
sldi(index, index, log2i_exact(sizeof(ResolvedFieldEntry)));
481+
sldi(index, index, log2i_exact(entry_size));
478482
} else {
479483
// Scale the index to be the entry index * sizeof(ResolvedFieldEntry)
480-
mulli(index, index, sizeof(ResolvedFieldEntry));
484+
mulli(index, index, entry_size);
481485
}
482486
// Get address of field entries array
483-
ld_ptr(cache, in_bytes(ConstantPoolCache::field_entries_offset()), R27_constPoolCache);
484-
addi(cache, cache, Array<ResolvedFieldEntry>::base_offset_in_bytes());
487+
ld_ptr(cache, entries_offset, R27_constPoolCache);
488+
addi(cache, cache, base_offset);
485489
add(cache, cache, index);
486-
}
487490

488-
void InterpreterMacroAssembler::load_method_entry(Register cache, Register index, int bcp_offset) {
489-
// Get index out of bytecode pointer
490-
get_cache_index_at_bcp(index, bcp_offset, sizeof(u2));
491-
// Scale the index to be the entry index * sizeof(ResolvedMethodEntry)
492-
mulli(index, index, sizeof(ResolvedMethodEntry));
493-
494-
// Get address of field entries array
495-
ld_ptr(cache, ConstantPoolCache::method_entries_offset(), R27_constPoolCache);
496-
addi(cache, cache, Array<ResolvedMethodEntry>::base_offset_in_bytes());
497-
add(cache, cache, index); // method_entries + base_offset + scaled index
491+
if (for_fast_bytecode) {
492+
// Prevent speculative loading from ResolvedFieldEntry/ResolvedMethodEntry as it can miss the info written by another thread.
493+
// TemplateTable::patch_bytecode uses release-store.
494+
// We reached here via control dependency (Bytecode dispatch has used the rewritten Bytecode).
495+
// So, we can use control-isync based ordering.
496+
isync();
497+
}
498498
}
499499

500500
// Load object from cpool->resolved_references(index).

src/hotspot/cpu/ppc/templateTable_ppc_64.cpp

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

151-
// Patch bytecode.
151+
// Patch bytecode with release store to coordinate with ResolvedFieldEntry
152+
// and ResolvedMethodEntry loads in fast bytecode codelets.
153+
__ release();
152154
__ stb(Rnew_bc, 0, R14_bcp);
153155

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

317320
// Convert null sentinel to null
@@ -3109,7 +3112,7 @@ void TemplateTable::fast_storefield(TosState state) {
31093112
const ConditionRegister CR_is_vol = CR2; // Non-volatile condition register (survives runtime call in do_oop_store).
31103113

31113114
// Constant pool already resolved => Load flags and offset of field.
3112-
__ load_field_entry(Rcache, Rscratch);
3115+
__ load_field_entry(Rcache, Rscratch, 1, /* for_fast_bytecode */ true);
31133116
jvmti_post_field_mod(Rcache, Rscratch, false /* not static */);
31143117
load_resolved_field_entry(noreg, Rcache, noreg, Roffset, Rflags, false); // Uses R11, R12
31153118

@@ -3190,7 +3193,7 @@ void TemplateTable::fast_accessfield(TosState state) {
31903193
// R12_scratch2 used by load_field_cp_cache_entry
31913194

31923195
// Constant pool already resolved. Get the field offset.
3193-
__ load_field_entry(Rcache, Rscratch);
3196+
__ load_field_entry(Rcache, Rscratch, 1, /* for_fast_bytecode */ true);
31943197
load_resolved_field_entry(noreg, Rcache, noreg, Roffset, Rflags, false); // Uses R11, R12
31953198

31963199
// JVMTI support
@@ -3329,7 +3332,7 @@ void TemplateTable::fast_xaccess(TosState state) {
33293332
__ ld(Rclass_or_obj, 0, R18_locals);
33303333

33313334
// Constant pool already resolved. Get the field offset.
3332-
__ load_field_entry(Rcache, Rscratch, 2);
3335+
__ load_field_entry(Rcache, Rscratch, 2, /* for_fast_bytecode */ true);
33333336
load_resolved_field_entry(noreg, Rcache, noreg, Roffset, Rflags, false); // Uses R11, R12
33343337

33353338
// JVMTI support not needed, since we switch back to single bytecode as soon as debugger attaches.
@@ -3490,7 +3493,7 @@ void TemplateTable::fast_invokevfinal(int byte_no) {
34903493

34913494
assert(byte_no == f2_byte, "use this argument");
34923495
Register Rcache = R31;
3493-
__ load_method_entry(Rcache, R11_scratch1);
3496+
__ load_method_entry(Rcache, R11_scratch1, 1, /* for_fast_bytecode */ true);
34943497
invokevfinal_helper(Rcache, R11_scratch1, R12_scratch2, R22_tmp2, R23_tmp3);
34953498
}
34963499

0 commit comments

Comments
 (0)