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