diff --git a/src/hotspot/cpu/arm/c1_Runtime1_arm.cpp b/src/hotspot/cpu/arm/c1_Runtime1_arm.cpp index 62faa617083..2685514e3ae 100644 --- a/src/hotspot/cpu/arm/c1_Runtime1_arm.cpp +++ b/src/hotspot/cpu/arm/c1_Runtime1_arm.cpp @@ -615,7 +615,21 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { __ b(loop, ne); // We get here if an equal cache entry is found - __ str(R1, Address(R0, Klass::secondary_super_cache_offset())); + uint32_t super_cache_backoff = checked_cast(SecondarySuperMissBackoff); + if (super_cache_backoff > 0) { + __ ldr(R2, Address(Rthread, JavaThread::backoff_secondary_super_miss_offset())); + __ subs(R2, R2, 1); + + // Conditionally store the klass + __ str(R1, Address(R0, Klass::secondary_super_cache_offset()), ge); + __ mov(R2, super_cache_backoff, ge); + + __ str(R2, Address(Rthread, JavaThread::backoff_secondary_super_miss_offset())); + __ movs(R0, 0); // set Z flag + } else { + __ str(R1, Address(R0, Klass::secondary_super_cache_offset())); + } + __ mov(R0, 1); __ raw_pop_and_ret(R2, R3); diff --git a/src/hotspot/cpu/arm/globals_arm.hpp b/src/hotspot/cpu/arm/globals_arm.hpp index cfec562104c..b7225087e13 100644 --- a/src/hotspot/cpu/arm/globals_arm.hpp +++ b/src/hotspot/cpu/arm/globals_arm.hpp @@ -74,7 +74,7 @@ define_pd_global(bool, CompactStrings, false); define_pd_global(intx, InitArrayShortSize, 8*BytesPerLong); // Not implemented yet -define_pd_global(uint, SecondarySuperMissBackoff, 0); +define_pd_global(uint, SecondarySuperMissBackoff, 1000); #define ARCH_FLAGS(develop, \ product, \ diff --git a/src/hotspot/cpu/arm/interp_masm_arm.cpp b/src/hotspot/cpu/arm/interp_masm_arm.cpp index 643aea681dd..890ca6d8833 100644 --- a/src/hotspot/cpu/arm/interp_masm_arm.cpp +++ b/src/hotspot/cpu/arm/interp_masm_arm.cpp @@ -413,8 +413,28 @@ void InterpreterMacroAssembler::gen_subtype_check(Register Rsub_klass, b(not_subtype); bind(update_cache); + // Must be equal but missed in cache. Update cache. - str(Rsuper_klass, Address(Rsub_klass, Klass::secondary_super_cache_offset())); + + uint32_t super_cache_backoff = checked_cast(SecondarySuperMissBackoff); + if (false && super_cache_backoff > 0) { + // FIXME: This path needs bug fixes + Register tmp = tmp2; + ldr(tmp, Address(Rthread, JavaThread::backoff_secondary_super_miss_offset())); + subs(tmp, tmp, 1); + + // Conditionally store the klass + str(Rsuper_klass, Address(Rsub_klass, Klass::secondary_super_cache_offset()), ge); + mov(tmp, super_cache_backoff, ge); + + str(tmp, Address(Rthread, JavaThread::backoff_secondary_super_miss_offset())); + + // The operations above destroy condition codes set by scan. + // This is success path, restore them ourselves. + movs(tmp, 0); // set Z flag + } else { + // str(Rsuper_klass, Address(Rsub_klass, Klass::secondary_super_cache_offset())); + } bind(ok_is_subtype); } diff --git a/src/hotspot/cpu/arm/macroAssembler_arm.cpp b/src/hotspot/cpu/arm/macroAssembler_arm.cpp index b827e69d022..0176885a839 100644 --- a/src/hotspot/cpu/arm/macroAssembler_arm.cpp +++ b/src/hotspot/cpu/arm/macroAssembler_arm.cpp @@ -265,8 +265,25 @@ void MacroAssembler::check_klass_subtype_slow_path(Register sub_klass, // Note: temp_reg/cmp_temp is already 0 and flag Z is set - // Success. Cache the super we found and proceed in triumph. - str(super_klass, Address(sub_klass, sc_offset)); + // Success. Try to cache the super we found and proceed in triumph. + + uint32_t super_cache_backoff = checked_cast(SecondarySuperMissBackoff); + if (super_cache_backoff > 0) { + ldr(temp_reg, Address(Rthread, JavaThread::backoff_secondary_super_miss_offset())); + subs(temp_reg, temp_reg, 1); + + // Conditionally store the klass + str(super_klass, Address(temp_reg, sc_offset), ge); + mov(temp_reg, super_cache_backoff, ge); + + str(temp_reg, Address(Rthread, JavaThread::backoff_secondary_super_miss_offset())); + + // the operations above destroy condition codes set by scan. + // this is success path, restore them ourselves. + movs(temp_reg, 0); // set Z flag + } else { + str(super_klass, Address(sub_klass, sc_offset)); + } if (saved_reg != noreg) { // Return success diff --git a/src/hotspot/cpu/arm/stubGenerator_arm.cpp b/src/hotspot/cpu/arm/stubGenerator_arm.cpp index 6e5484c98cb..c4b0eb17b97 100644 --- a/src/hotspot/cpu/arm/stubGenerator_arm.cpp +++ b/src/hotspot/cpu/arm/stubGenerator_arm.cpp @@ -762,7 +762,23 @@ class StubGenerator: public StubCodeGenerator { // Falling out the bottom means we found a hit; we ARE a subtype // Success. Cache the super we found and proceed in triumph. - __ str(super_klass, Address(sub_klass, sc_offset)); + uint32_t super_cache_backoff = checked_cast(SecondarySuperMissBackoff); + if (super_cache_backoff > 0) { + __ ldr(R0, Address(Rthread, JavaThread::backoff_secondary_super_miss_offset())); + __ subs(R0, R0, 1); + + // Conditionally store the klass + __ str(super_klass, Address(sub_klass, sc_offset), ge); + __ mov(R0, super_cache_backoff, ge); + + __ str(R0, Address(Rthread, JavaThread::backoff_secondary_super_miss_offset())); + + // The operations above destroy condition codes set by scan. + // This is success path, restore them ourselves. + __ movs(R0, 0); // set Z flag + } else { + __ str(super_klass, Address(sub_klass, sc_offset)); + } // Return success // R0 is already 0 and flags are already set to eq