RFR: 8343789: Move mutable nmethod data out of CodeCache [v9]
Tobias Hartmann
thartmann at openjdk.org
Mon Feb 3 09:28:54 UTC 2025
On Fri, 24 Jan 2025 20:37:32 GMT, Boris Ulasevich <bulasevich at openjdk.org> wrote:
>> This change relocates mutable data (such as relocations, oops, and metadata) from the nmethod. The change follows the recent PR #18984, which relocated immutable nmethod data from the CodeCache.
>>
>> The core idea remains the same: use the CodeCache for executable code while moving additional data to the C heap. The primary motivations are improving security and enhancing code density.
>>
>> Although performance is not the main focus, testing on AArch64 CPUs, where code density plays a significant role, has shown a 1–2% performance improvement in specific scenarios, such as the CodeCacheStress test and the Renaissance Dotty benchmark.
>>
>> The numbers. Immutable data constitutes **~30%** on the nmehtod. Mutable data constitutes **~8%** of nmethod. Example (statistics collected on the CodeCacheStress benchmark):
>> - nmethod_count:134000, total_compilation_time: 510460ms
>> - total allocation time malloc_mutable/malloc_immutable/CodeCache_alloc: 62ms/114ms/6333ms,
>> - total allocation size (mutable/immutable/nmentod): 64MB/192MB/488MB
>>
>> Functional testing: jtreg on arm/aarch/x86.
>> Performance testing: renaissance/dacapo/SPECjvm2008 benchmarks.
>>
>> Alternative solution (see comments): In the future, relocations can be moved to _immutable_data.
>
> Boris Ulasevich has updated the pull request incrementally with one additional commit since the last revision:
>
> Force the use of movk in combination with adrp and ldr instructions to address scenarios
> where os::malloc allocates buffers beyond the typical ±4GB range accessible with adrp
I see more failures in testing:
compiler/jsr292/CallSiteDepContextTest.java fails on Windows with -XX:+UseZGC:
# A fatal error has been detected by the Java Runtime Environment:
#
# Internal Error (workspace\open\src\hotspot\share\code\dependencies.cpp:2038), pid=109676, tid=68072
# assert(call_site->is_a(vmClasses::CallSite_klass())) failed: sanity
Current thread (0x000002b4343ac600): JavaThread "MainThread" [_thread_in_vm, id=68072, stack(0x000000f121300000,0x000000f121400000) (1024K)]
Stack: [0x000000f121300000,0x000000f121400000], sp=0x000000f1213fe9f0, free space=1018k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
V [jvm.dll+0x601c63] Dependencies::check_call_site_target_value+0x3e3 (dependencies.cpp:2038)
V [jvm.dll+0x60182f] Dependencies::DepStream::check_call_site_dependency+0x6f (dependencies.cpp:2145)
V [jvm.dll+0xd0898d] nmethod::check_dependency_on+0x7d (nmethod.cpp:2853)
V [jvm.dll+0x609a19] DependencyContext::mark_dependent_nmethods+0xb9 (dependencyContext.cpp:74)
V [jvm.dll+0xcd2ff2] MethodHandles::mark_dependent_nmethods+0xa2 (methodHandles.cpp:953)
V [jvm.dll+0xccbf2e] MHN_setCallSiteTargetNormal+0x1ee (methodHandles.cpp:1211)
C 0x000002b02377ebac (no source info available)
Same test also fails with:
# A fatal error has been detected by the Java Runtime Environment:
#
# Internal Error (/workspace/open/src/hotspot/share/oops/compressedKlass.inline.hpp:88), pid=95938, tid=35843
# assert(nk >= _lowest_valid_narrow_klass_id && nk <= _highest_valid_narrow_klass_id) failed: narrowKlass ID out of range (3131947710)
--------------- T H R E A D ---------------
Current thread (0x0000000142865e10): JavaThread "MainThread" [_thread_in_vm, id=35843, stack(0x0000000170c4c000,0x0000000170e4f000) (2060K)]
Stack: [0x0000000170c4c000,0x0000000170e4f000], sp=0x0000000170e4dd00, free space=2055k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
V [libjvm.dylib+0x1161294] VMError::report(outputStream*, bool)+0x1aac (compressedKlass.inline.hpp:88)
V [libjvm.dylib+0x1164880] VMError::report_and_die(int, char const*, char const*, char*, Thread*, unsigned char*, void const*, void const*, char const*, int, unsigned long)+0x548
V [libjvm.dylib+0x576b0c] print_error_for_unit_test(char const*, char const*, char*)+0x0
V [libjvm.dylib+0x70a898] CompressedKlassPointers::check_encodable(void const*)+0x0
V [libjvm.dylib+0x585d24] oopDesc::klass() const+0x104
V [libjvm.dylib+0x5afbec] Dependencies::check_call_site_target_value(oop, oop, CallSiteDepChange*)+0xcc
V [libjvm.dylib+0x5b09e4] Dependencies::DepStream::check_call_site_dependency(CallSiteDepChange*)+0x84
V [libjvm.dylib+0xde663c] nmethod::check_dependency_on(DepChange&)+0x50
V [libjvm.dylib+0x5b291c] DependencyContext::mark_dependent_nmethods(DeoptimizationScope*, DepChange&)+0xa4
V [libjvm.dylib+0xda4dfc] MethodHandles::mark_dependent_nmethods(DeoptimizationScope*, Handle, Handle)+0xec
V [libjvm.dylib+0xda7ea4] MHN_setCallSiteTargetNormal+0x304
j java.lang.invoke.MethodHandleNatives.setCallSiteTargetNormal(Ljava/lang/invoke/CallSite;Ljava/lang/invoke/MethodHandle;)V+0 java.base at 25-internal
j java.lang.invoke.CallSite.setTargetNormal(Ljava/lang/invoke/MethodHandle;)V+7 java.base at 25-internal
j java.lang.invoke.MutableCallSite.setTarget(Ljava/lang/invoke/MethodHandle;)V+2 java.base at 25-internal
j compiler.jsr292.CallSiteDepContextTest.testGC(ZZ)V+267
j compiler.jsr292.CallSiteDepContextTest.main([Ljava/lang/String;)V+11
j java.lang.invoke.LambdaForm$DMH+0x00000c0000001c00.invokeStatic(Ljava/lang/Object;Ljava/lang/Object;)V+10 java.base at 25-internal
j java.lang.invoke.LambdaForm$MH+0x00000c0000003400.invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;+33 java.base at 25-internal
j java.lang.invoke.Invokers$Holder.invokeExact_MT(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;+20 java.base at 25-internal
j jdk.internal.reflect.DirectMethodHandleAccessor.invokeImpl(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;+55 java.base at 25-internal
j jdk.internal.reflect.DirectMethodHandleAccessor.invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;+23 java.base at 25-internal
j java.lang.reflect.Method.invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;+102 java.base at 25-internal
j com.sun.javatest.regtest.agent.MainWrapper$MainTask.run()V+134
j java.lang.Thread.runWith(Ljava/lang/Object;Ljava/lang/Runnable;)V+5 java.base at 25-internal
j java.lang.Thread.run()V+19 java.base at 25-internal
v ~StubRoutines::call_stub 0x00000001160d0180
V [libjvm.dylib+0x88beec] JavaCalls::call_helper(JavaValue*, methodHandle const&, JavaCallArguments*, JavaThread*)+0x448
V [libjvm.dylib+0x88ac08] JavaCalls::call_virtual(JavaValue*, Klass*, Symbol*, Symbol*, JavaCallArguments*, JavaThread*)+0x1c4
V [libjvm.dylib+0x88ada4] JavaCalls::call_virtual(JavaValue*, Handle, Klass*, Symbol*, Symbol*, JavaThread*)+0x6c
V [libjvm.dylib+0xa1289c] thread_entry(JavaThread*, JavaThread*)+0x12c
V [libjvm.dylib+0x8c2088] JavaThread::thread_main_inner()+0x1a8
V [libjvm.dylib+0x10ae844] Thread::call_run()+0xf4
V [libjvm.dylib+0xe467f0] thread_native_entry(Thread*)+0x138
C [libsystem_pthread.dylib+0x6f94] _pthread_start+0x88
Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
j java.lang.invoke.MethodHandleNatives.setCallSiteTargetNormal(Ljava/lang/invoke/CallSite;Ljava/lang/invoke/MethodHandle;)V+0 java.base at 25-internal
j java.lang.invoke.CallSite.setTargetNormal(Ljava/lang/invoke/MethodHandle;)V+7 java.base at 25-internal
j java.lang.invoke.MutableCallSite.setTarget(Ljava/lang/invoke/MethodHandle;)V+2 java.base at 25-internal
j compiler.jsr292.CallSiteDepContextTest.testGC(ZZ)V+267
j compiler.jsr292.CallSiteDepContextTest.main([Ljava/lang/String;)V+11
j java.lang.invoke.LambdaForm$DMH+0x00000c0000001c00.invokeStatic(Ljava/lang/Object;Ljava/lang/Object;)V+10 java.base at 25-internal
j java.lang.invoke.LambdaForm$MH+0x00000c0000003400.invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;+33 java.base at 25-internal
j java.lang.invoke.Invokers$Holder.invokeExact_MT(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;+20 java.base at 25-internal
j jdk.internal.reflect.DirectMethodHandleAccessor.invokeImpl(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;+55 java.base at 25-internal
j jdk.internal.reflect.DirectMethodHandleAccessor.invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;+23 java.base at 25-internal
j java.lang.reflect.Method.invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;+102 java.base at 25-internal
j com.sun.javatest.regtest.agent.MainWrapper$MainTask.run()V+134
j java.lang.Thread.runWith(Ljava/lang/Object;Ljava/lang/Runnable;)V+5 java.base at 25-internal
j java.lang.Thread.run()V+19 java.base at 25-internal
v ~StubRoutines::call_stub 0x00000001160d0180
Lock stack of current Java thread (top to bottom):
-------------
PR Comment: https://git.openjdk.org/jdk/pull/21276#issuecomment-2630399291
More information about the hotspot-compiler-dev
mailing list