diff --git a/ddprof-lib/src/main/cpp/hotspot/hotspotSupport.h b/ddprof-lib/src/main/cpp/hotspot/hotspotSupport.h index 2fe809139..e905d55c4 100644 --- a/ddprof-lib/src/main/cpp/hotspot/hotspotSupport.h +++ b/ddprof-lib/src/main/cpp/hotspot/hotspotSupport.h @@ -46,6 +46,10 @@ class HotspotSupport { return JitCodeCache::isJitCode(p); } + static inline long long runtimeStubsMemoryUsage() { + return JitCodeCache::runtimeStubsMemoryUsage(); + } + // If should load all jmethodIDs static inline bool shouldPreloadJmethodIDs(Arguments& args) { CStack cstack = args._cstack; diff --git a/ddprof-lib/src/main/cpp/hotspot/jitCodeCache.cpp b/ddprof-lib/src/main/cpp/hotspot/jitCodeCache.cpp index 00ec522bf..a45483686 100644 --- a/ddprof-lib/src/main/cpp/hotspot/jitCodeCache.cpp +++ b/ddprof-lib/src/main/cpp/hotspot/jitCodeCache.cpp @@ -52,3 +52,10 @@ CodeBlob* JitCodeCache::findRuntimeStub(const void *address) { _stubs_lock.unlockShared(); return stub; } + +long long JitCodeCache::runtimeStubsMemoryUsage() { + _stubs_lock.lockShared(); + long long usage = _runtime_stubs.memoryUsage(); + _stubs_lock.unlockShared(); + return usage; +} diff --git a/ddprof-lib/src/main/cpp/hotspot/jitCodeCache.h b/ddprof-lib/src/main/cpp/hotspot/jitCodeCache.h index 005223384..0d116ca61 100644 --- a/ddprof-lib/src/main/cpp/hotspot/jitCodeCache.h +++ b/ddprof-lib/src/main/cpp/hotspot/jitCodeCache.h @@ -38,6 +38,11 @@ class JitCodeCache { } static CodeBlob* findRuntimeStub(const void *address); + + // Heap usage of the runtime-stubs code cache, via CodeCache::memoryUsage(). + // Read under the shared stubs lock because DynamicCodeGenerated() mutates + // _runtime_stubs (add()/expand()) concurrently. + static long long runtimeStubsMemoryUsage(); static bool isJitCode(const void* pc) { return CodeHeap::contains(pc); } diff --git a/ddprof-lib/src/main/cpp/jvmSupport.h b/ddprof-lib/src/main/cpp/jvmSupport.h index 5ba33ae5a..f3d664d2d 100644 --- a/ddprof-lib/src/main/cpp/jvmSupport.h +++ b/ddprof-lib/src/main/cpp/jvmSupport.h @@ -55,6 +55,9 @@ class JVMSupport { static int walkJavaStack(StackWalkRequest& request); static inline bool canUnwind(const StackFrame& frame, const void*& pc); static inline bool isJitCode(const void* pc); + // Live heap usage of the JIT runtime-stubs code cache. HotSpot-only; 0 on + // other VMs (J9/Zing), which have no such cache. + static inline long long runtimeStubsMemoryUsage(); static void loadAllMethodIDsIfNeeded(jvmtiEnv *jvmti, JNIEnv *jni); static bool loadMethodIDsIfNeeded(jvmtiEnv *jvmti, JNIEnv *jni, jclass klass); diff --git a/ddprof-lib/src/main/cpp/jvmSupport.inline.h b/ddprof-lib/src/main/cpp/jvmSupport.inline.h index 6d1ca0639..3be11d590 100644 --- a/ddprof-lib/src/main/cpp/jvmSupport.inline.h +++ b/ddprof-lib/src/main/cpp/jvmSupport.inline.h @@ -26,6 +26,14 @@ bool JVMSupport::isJitCode(const void* pc) { } } +long long JVMSupport::runtimeStubsMemoryUsage() { + if (VM::isHotspot()) { + return HotspotSupport::runtimeStubsMemoryUsage(); + } else { + return 0; + } +} + // Resolve method pointer to jmethodID jmethodID JVMSupport::resolve(const void* method) { if (VM::isHotspot()) { diff --git a/ddprof-lib/src/main/cpp/profiler.cpp b/ddprof-lib/src/main/cpp/profiler.cpp index 2820ee8c6..7c8e24318 100644 --- a/ddprof-lib/src/main/cpp/profiler.cpp +++ b/ddprof-lib/src/main/cpp/profiler.cpp @@ -24,6 +24,7 @@ #include "j9/j9Support.h" #include "j9/j9WallClock.h" #include "jvmSupport.h" +#include "jvmSupport.inline.h" #include "jvmThread.h" #include "libraryPatcher.h" #include "objectSampler.h" @@ -1737,8 +1738,12 @@ Error Profiler::dump(const char *path, const int length) { const CodeCacheArray& native_libs = _libs->native_libs(); Counters::set(CODECACHE_NATIVE_COUNT, native_libs.count()); Counters::set(CODECACHE_NATIVE_SIZE_BYTES, native_libs.memoryUsage()); + // The runtime-stubs counter reflects the JIT runtime-stubs code cache, a + // separate cache from the native libraries. Routed through JVMSupport so + // the HotSpot-only implementation stays behind the VM abstraction (0 on + // J9/Zing). Read under its shared lock. Counters::set(CODECACHE_RUNTIME_STUBS_SIZE_BYTES, - native_libs.memoryUsage()); + JVMSupport::runtimeStubsMemoryUsage()); Error err = Error::OK; // rotateDictsAndRun rotates the dictionaries, takes lockAll() around the