RFR: 8221554: aarch64 cross-modifying code

David Holmes david.holmes at oracle.com
Thu Oct 1 02:18:35 UTC 2020


Hi Alan,

On 1/10/2020 2:30 am, Alan Hayward wrote:
> The AArch64 port uses maybe_isb in places where an ISB might be required
> because the code may have safepointed. These maybe_isbs are very conservative
> and are used in many places are used when a safepoint has not happened.
> 
> cross_modify_fence was added in common code to place a barrier in all the
> places after a safepoint has occurred. All the uses of it are in common code,
> yet it remains unimplemented on AArch64.
> 
> This set of patches implements cross_modify_fence for AArch64 and reconsiders
> every uses of maybe_isb, discarding many of them. In addition, it introduces
> a new diagnostic option, which when enabled on AArch64 tests the correct
> usage of the barriers.
> 
> Advantage of this patch is threefold:
> * Reducing the number of ISBs - giving a theoretical performance improvement.
> * Use of common code instead of backend specific code.
> * Additional test diagnostic options
> 
> Patch 1: Split cross_modify_fence
> =================================
> This is simply refactoring work split out to simplify the other two patches.
> 
> instruction_fence() is provided by each target and simply places
> a fence for the instruction stream.
> 
> cross_modify_fence() is now a member of JavaThread and just calls
> instruction_fence. This function will be extended in Patch 3.

I don't agree with the change here. The cross_modify_fence() is not 
related to thread API imo, it belongs in OrderAccess. The name was 
deliberately selected to abstract away from the specific details of why 
a given platform may need this fence:

http://mail.openjdk.java.net/pipermail/hotspot-dev/2019-March/037153.html

"The name "instruction_pipeline" seems a bit implementation specific 
about what HW architectural features need to be taken care of due to 
cross-modifying code, which may or may not apply to a given platform. 
Perhaps cross_modify_fence(), or something along those lines, would be 
better. That makes it more clear what we are protecting against, as 
opposed to what HW architectural features that might concern on a given 
platform."

@robehn , @fisk please chime in here. :)

Thanks,
David

> Patch 2: Use cross_modify_fence instead of maybe_isb
> ====================================================
> 
> The [n] References refer to the comments for cross_modify_fence in
> thread.hpp.
> 
> This is all the existing uses of maybe_isb in the AArch64 target:
> 
> 1) Instances of Java code calling a VM function
>     * This encapsulates the changes to:
>     ** MacroAssembler::call_VM_leaf_base()
>     ** generate_fast_get_int_field0()
>     ** stubGenerator_aarch64 generate_throw_exception()
>     ** sharedRuntime_aarch64 generate_handler_blob()
>     ** SharedRuntime::generate_resolve_blob()
>     ** C1 LIR_Assembler::rt_call
>     ** C1 StubAssembler::call_RT(): used by Used by generate_exception_throw,
>                                     generate_handle_exception, generate_code_for.
>     ** OptoRuntime::generate_exception_blob()
>     * Any changes will be caught due to calls to [2] or [3] by the VM function.
>     * Any calls that do not call [2] or [3] do not require an ISB.
>     * This patch is more optimal for these cases.
> 
> 2) Instances of Java code calling a JNI function
>     * This encapsulates the changes to:
>     ** SharedRuntime::generate_native_wrapper()
>     ** TemplateInterpreterGenerator::generate_native_entry()
>     * A safepoint still in progress after the call with be caught by [4].
>     * An ISB is still required for the case where there was a safepoint
>       but it completed during the call. This happens if the code doesn't
>       branch on safepoint_in_progress
>     * In the SharedRuntime version, the two possible calls to
>       reguard_yellow_pages and complete_monitor_unlocking_C are after the thread
>       goes back into it's original state, so are covered by [2] and [3], the
>       same as a normal VM call.
>     * This patch is only more optimal for the two post-JNI calls.
> 
> 3) Patching functions
>     * This encapsulates the changes to:
>     ** patch_callers_callsite() (called by gen_c2i_adapter())
>     * This results in code being patched, but does not safepoint
>     * Therefore an ISB is required.
>     * This patch introduces no change here.
> 
> 4) C1 MacroAssembler::emit_static_call_stub()
>     * Calls ISB (not maybe_isb)
>     * By design, the patching doesn't require that the up-to-date
>       destination is required for proper functioning.
>     * However, the ISB makes it most likely that the new destination will
>       be picked up.
>     * This patch introduces no change here.
> 
> Patch 3: Add cross modify fence verification
> ============================================
> 
> The VerifyCrossModifyFence diagnostic flag enables confirmation to the correct
> usage of instruction barriers. It can safely be enabled on any Java run.
> 
> Enabling it will cause the following:
> 
> * Once all threads have been brought to a safepoint, each thread will be
>    marked.
> 
> * On a cross_modify_fence and safepoint_fence the mark for that thread
>    will be cleared.
> 
> * On entry to a method and in a safepoint poll, then the thread is checked.
>    If it is marked, then the code will error.
> 
> -------------
> 
> Commit messages:
>   - AArch64: Add cross modify fence verification
>   - AArch64: Use cross_modify_fence instead of maybe_isb
>   - Split cross_modify_fence
> 
> Changes: https://git.openjdk.java.net/jdk/pull/428/files
>   Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=428&range=00
>    Issue: https://bugs.openjdk.java.net/browse/JDK-8221554
>    Stats: 179 lines in 26 files changed: 127 ins; 7 del; 45 mod
>    Patch: https://git.openjdk.java.net/jdk/pull/428.diff
>    Fetch: git fetch https://git.openjdk.java.net/jdk pull/428/head:pull/428
> 
> PR: https://git.openjdk.java.net/jdk/pull/428
> 


More information about the hotspot-dev mailing list