Skip to content

Commit 3336858

Browse files
committed
NMT extended to Java
1 parent c88c8be commit 3336858

File tree

4 files changed

+102
-0
lines changed

4 files changed

+102
-0
lines changed

src/hotspot/share/prims/jvm.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3837,6 +3837,11 @@ JVM_LEAF(jboolean, JVM_PrintWarningAtDynamicAgentLoad(void))
38373837
return (EnableDynamicAgentLoading && !FLAG_IS_CMDLINE(EnableDynamicAgentLoading)) ? JNI_TRUE : JNI_FALSE;
38383838
JVM_END
38393839

3840+
3841+
/*
3842+
* Native Memory Tracking
3843+
*/
3844+
38403845
JNIEXPORT arena_t JNICALL
38413846
JVM_MakeArena(const char *name) {
38423847
return static_cast<arena_t>(MemTagFactory::tag(name));

src/hotspot/share/prims/nativeLookup.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,7 @@ char* NativeLookup::long_jni_name(const methodHandle& method) {
199199
}
200200

201201
extern "C" {
202+
void JNICALL JVM_RegisterNativeMemoryTrackingMethods(JNIEnv *env, jclass unsafecls);
202203
void JNICALL JVM_RegisterMethodHandleMethods(JNIEnv *env, jclass unsafecls);
203204
void JNICALL JVM_RegisterReferencesMethods(JNIEnv *env, jclass unsafecls);
204205
void JNICALL JVM_RegisterUpcallHandlerMethods(JNIEnv *env, jclass unsafecls);
@@ -227,6 +228,7 @@ static JNINativeMethod lookup_special_native_methods[] = {
227228
{ CC"Java_sun_hotspot_WhiteBox_registerNatives", nullptr, FN_PTR(JVM_RegisterWhiteBoxMethods) },
228229
{ CC"Java_jdk_test_whitebox_WhiteBox_registerNatives", nullptr, FN_PTR(JVM_RegisterWhiteBoxMethods) },
229230
{ CC"Java_jdk_internal_vm_vector_VectorSupport_registerNatives", nullptr, FN_PTR(JVM_RegisterVectorSupportMethods)},
231+
{ CC"Java_lang_foreign_NativeMemoryTracking_registerNatives", nullptr, FN_PTR(JVM_RegisterNativeMemoryTrackingMethods)},
230232
#if INCLUDE_JVMCI
231233
{ CC"Java_jdk_vm_ci_runtime_JVMCI_initializeRuntime", nullptr, FN_PTR(JVM_GetJVMCIRuntime) },
232234
{ CC"Java_jdk_vm_ci_services_Services_readSystemPropertiesInfo", nullptr, FN_PTR(JVM_ReadSystemPropertiesInfo) },
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#include "jni.h"
2+
#include "runtime/interfaceSupport.inline.hpp"
3+
#include "runtime/jniHandles.hpp"
4+
#include "nmt/memTagFactory.hpp"
5+
#include "nmt/memTracker.hpp"
6+
7+
#define CC (char*) /*cast a literal from (const char*)*/
8+
#define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f)
9+
10+
JVM_ENTRY(jlong, NMT_makeTag(JNIEnv *env, jobject ignored_this, jobject tag_name_string)) {
11+
oop tn_oop = JNIHandles::resolve(tag_name_string);
12+
Handle tnh(THREAD, tn_oop);
13+
if (tnh.is_null()) {
14+
// TODO: Throw exception
15+
}
16+
17+
if (!java_lang_String::is_instance(tn_oop)) {
18+
// TODO: Throw exception
19+
}
20+
21+
if (!MemTracker::enabled()) {
22+
return (jlong)mtNone;
23+
}
24+
25+
ResourceMark rm;
26+
const char* tag_name = java_lang_String::as_utf8_string(tn_oop);
27+
return (jlong)MemTagFactory::tag(tag_name);
28+
}
29+
JVM_END
30+
31+
JVM_ENTRY(jlong, NMT_allocate(JNIEnv *env, jobject ignored_this, jlong size, jlong mem_tag)) {
32+
return (jlong)os::malloc((size_t)size, (MemTag)mem_tag);
33+
}
34+
JVM_ENTRY(void, NMT_free(JNIEnv *env, jobject ignored_this, jlong ptr)) {
35+
os::free((void*)ptr);
36+
}
37+
38+
static JNINativeMethod NMT_methods[] = {
39+
{CC "makeTag", CC "(Ljava/lang/String)J", FN_PTR(NMT_makeTag)},
40+
{CC "allocate", CC "(JJ)J", FN_PTR(NMT_allocate)},
41+
{CC "freeMemory" CC "(J)V", FN_PTR(NMT_free)}
42+
};
43+
44+
JVM_ENTRY(void, JVM_RegisterNativeMemoryTrackingMethods(JNIEnv *env, jclass NMT_class)) {
45+
ThreadToNativeFromVM ttndv(thread);
46+
47+
int status = env->RegisterNatives(NMT_class, NMT_methods, sizeof(NMT_methods) / sizeof(JNINativeMethod));
48+
guarantee(status == JNI_OK && !env->ExceptionCheck(),
49+
"register java.lang.invoke.MethodHandleNative natives");
50+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package java.lang.foreign;
2+
3+
public class NativeMemoryTracking {
4+
public static native long makeTag(String name);
5+
public static native long allocate(long size, long mem_tag);
6+
public static native void freeMemory(long addr);
7+
8+
private static native void registerNatives();
9+
static {
10+
runtimeSetup();
11+
}
12+
13+
// Unsafe.java has this comment: Called from JVM when loading an AOT cache
14+
// so we imitate the same pattern, maybe it's necessary for us as well???
15+
private static void runtimeSetup() {
16+
registerNatives();
17+
}
18+
19+
public static class NMTArena implements Arena {
20+
private long mem_tag;
21+
22+
public NMTArena(String name) {
23+
this.mem_tag = NativeMemoryTracking.makeTag(name);
24+
}
25+
26+
final Arena arena = Arena.ofConfined();
27+
28+
@Override
29+
public Scope scope() {
30+
return arena.scope();
31+
}
32+
33+
@Override
34+
public void close() {
35+
arena.close();
36+
}
37+
38+
@Override
39+
public MemorySegment allocate(long byteSize, long byteAlignment) {
40+
long address = NativeMemoryTracking.allocate(byteSize, mem_tag);
41+
return MemorySegment.ofAddress(address)
42+
.reinterpret(byteSize, arena, ms -> NativeMemoryTracking.freeMemory(ms.address()));
43+
}
44+
}
45+
}

0 commit comments

Comments
 (0)