Skip to content

Commit 4d80528

Browse files
Espresso Management: implement thread allocated memory tracking
Also improve startup state of thread cpu time tracking to match hotspot.
1 parent a256c2a commit 4d80528

File tree

2 files changed

+77
-24
lines changed

2 files changed

+77
-24
lines changed

espresso/mx.espresso/suite.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@
175175
"java.logging",
176176
"jdk.unsupported", # sun.misc.Signal
177177
"java.management",
178+
"jdk.management",
178179
],
179180
"uses": [
180181
"com.oracle.truffle.espresso.ffi.NativeAccess.Provider",

espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/vm/Management.java

Lines changed: 76 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -215,13 +215,12 @@ private record OptionalSupportRecord(
215215
* GetOptionalSupport and initOptionalSupportFields.
216216
*/
217217
private OptionalSupportRecord getOptionalSupportRecord() {
218-
ThreadMXBean hostBean = getHostThreadMXBean();
219218
return new OptionalSupportRecord(
220219
/* compTimeMonitoringSupport */ false,
221220
/* threadContentionMonitoringSupport */ false,
222-
/* currentThreadCpuTimeSupport */ hostBean.isCurrentThreadCpuTimeSupported(),
223-
/* otherThreadCpuTimeSupport */ hostBean.isThreadCpuTimeSupported(),
224-
/* threadAllocatedMemorySupport */ false,
221+
/* currentThreadCpuTimeSupport */ isCurrentThreadCpuTimeSupported(),
222+
/* otherThreadCpuTimeSupport */ isThreadCpuTimeSupported(),
223+
/* threadAllocatedMemorySupport */ isThreadAllocatedMemorySupported(),
225224
/* remoteDiagnosticCommandsSupport */ false,
226225
/* objectMonitorUsageSupport */ false,
227226
/* synchronizerUsageSupport */ false);
@@ -264,13 +263,7 @@ public TruffleObject getManagement(int version) {
264263
if (!isSupportedManagementVersion(version)) {
265264
return RawPointer.nullInstance();
266265
}
267-
if (managementPtr == null) {
268-
CompilerDirectives.transferToInterpreterAndInvalidate();
269-
managementPtr = initializeAndGetEnv(initializeManagementContext, version);
270-
managementVersion = version;
271-
assert getUncached().isPointer(managementPtr);
272-
assert managementPtr != null && !getUncached().isNull(managementPtr);
273-
} else if (version != managementVersion) {
266+
if (!initializeManagement(version) && version != managementVersion) {
274267
CompilerDirectives.transferToInterpreterAndInvalidate();
275268
getContext().getLogger().warning("Asking for a different management version that previously requested.\n" +
276269
"Previously requested: " + managementVersion + ", currently requested: " + version);
@@ -279,6 +272,44 @@ public TruffleObject getManagement(int version) {
279272
return managementPtr;
280273
}
281274

275+
private boolean initializeManagement(int version) {
276+
if (managementPtr != null) {
277+
return false;
278+
}
279+
CompilerDirectives.transferToInterpreterAndInvalidate();
280+
managementPtr = initializeAndGetEnv(initializeManagementContext, version);
281+
managementVersion = version;
282+
assert getUncached().isPointer(managementPtr);
283+
assert managementPtr != null && !getUncached().isNull(managementPtr);
284+
285+
// start in the same state as hotspot
286+
if (isThreadCpuTimeSupported()) {
287+
JMM_THREAD_CPU_TIME_state = true;
288+
}
289+
if (isThreadAllocatedMemorySupported()) {
290+
JMM_THREAD_ALLOCATED_MEMORY_state = true;
291+
}
292+
return true;
293+
}
294+
295+
private boolean isThreadCpuTimeSupported() {
296+
ThreadMXBean hostBean = getHostThreadMXBean();
297+
return hostBean.isThreadCpuTimeSupported() && hostBean.isThreadCpuTimeEnabled();
298+
}
299+
300+
private boolean isCurrentThreadCpuTimeSupported() {
301+
ThreadMXBean hostBean = getHostThreadMXBean();
302+
return hostBean.isCurrentThreadCpuTimeSupported() && hostBean.isThreadCpuTimeEnabled();
303+
}
304+
305+
private boolean isThreadAllocatedMemorySupported() {
306+
ThreadMXBean hostBean = getHostThreadMXBean();
307+
if (!(hostBean instanceof com.sun.management.ThreadMXBean hostBeanEx)) {
308+
return false;
309+
}
310+
return hostBeanEx.isThreadAllocatedMemorySupported() && hostBeanEx.isThreadAllocatedMemoryEnabled();
311+
}
312+
282313
public void dispose() {
283314
if (managementPtr != null) {
284315
try {
@@ -398,15 +429,23 @@ public int GetThreadInfo(@JavaType(long[].class) StaticObject ids, int maxDepth,
398429

399430
private StaticObject findThreadById(StaticObject[] activeThreads, long id) {
400431
StaticObject thread = StaticObject.NULL;
401-
for (int j = 0; j < activeThreads.length; ++j) {
402-
if (getThreadAccess().getThreadId(activeThreads[j]) == id) {
403-
thread = activeThreads[j];
432+
for (StaticObject activeThread : activeThreads) {
433+
if (getThreadAccess().getThreadId(activeThread) == id) {
434+
thread = activeThread;
404435
break;
405436
}
406437
}
407438
return thread;
408439
}
409440

441+
private Thread findHostThreadByGuestPlatformThreadId(StaticObject[] activeThreads, long id) {
442+
StaticObject guestThread = findThreadById(activeThreads, id);
443+
if (StaticObject.isNull(guestThread) || getThreadAccess().isVirtualThread(guestThread) || !getThreadAccess().isAlive(guestThread)) {
444+
return null;
445+
}
446+
return getThreadAccess().getHost(guestThread);
447+
}
448+
410449
private void fillThreadInfos(StaticObject[] threads, StaticObject infoArray, int maxDepth, EspressoLanguage language, Meta meta, Node node) {
411450
if (StaticObject.isNull(infoArray)) {
412451
throw meta.throwNullPointerExceptionBoundary();
@@ -875,13 +914,26 @@ public int GetVMGlobals(@JavaType(Object[].class) StaticObject names, /* jmmVMGl
875914

876915
@ManagementImpl
877916
public long GetOneThreadAllocatedMemory(long threadId) {
878-
StaticObject[] activeThreads = getContext().getActiveThreads();
879-
StaticObject thread = findThreadById(activeThreads, threadId);
880-
if (StaticObject.isNull(thread)) {
881-
return -1L;
917+
Thread hostThread;
918+
if (threadId == 0) {
919+
hostThread = Thread.currentThread();
882920
} else {
921+
StaticObject[] activeThreads = getContext().getActiveThreads();
922+
hostThread = findHostThreadByGuestPlatformThreadId(activeThreads, threadId);
923+
if (hostThread == null) {
924+
return -1L;
925+
}
926+
}
927+
return getHostThreadAllocatedBytes(hostThread);
928+
}
929+
930+
private long getHostThreadAllocatedBytes(Thread hostThread) {
931+
ThreadMXBean hostBean = getHostThreadMXBean();
932+
if (!(hostBean instanceof com.sun.management.ThreadMXBean hostBeanEx)) {
883933
return 0L;
884934
}
935+
long hostId = EspressoThreadRegistry.getThreadId(hostThread);
936+
return hostBeanEx.getThreadAllocatedBytes(hostId);
885937
}
886938

887939
@ManagementImpl
@@ -901,11 +953,12 @@ public void GetThreadAllocatedMemory(
901953

902954
for (int i = 0; i < ids.length(language); i++) {
903955
long id = getInterpreterToVM().getArrayLong(language, i, ids);
904-
StaticObject thread = findThreadById(activeThreads, id);
905-
if (StaticObject.isNull(thread)) {
956+
Thread hostThread = findHostThreadByGuestPlatformThreadId(activeThreads, id);
957+
if (hostThread == null) {
906958
getInterpreterToVM().setArrayLong(language, -1L, i, sizeArray);
907959
} else {
908-
getInterpreterToVM().setArrayLong(language, 0L, i, sizeArray);
960+
long value = getHostThreadAllocatedBytes(hostThread);
961+
getInterpreterToVM().setArrayLong(language, value, i, sizeArray);
909962
}
910963
}
911964
}
@@ -958,11 +1011,10 @@ public long GetThreadCpuTimeWithKind(long threadId, boolean withSysTime,
9581011
return withSysTime ? hostBean.getThreadCpuTime(id) : hostBean.getThreadUserTime(id);
9591012
}
9601013
StaticObject[] activeThreads = getContext().getActiveThreads();
961-
StaticObject thread = findThreadById(activeThreads, threadId);
962-
if (StaticObject.isNull(thread) || getThreadAccess().isVirtualThread(thread) || !getThreadAccess().isAlive(thread)) {
1014+
Thread host = findHostThreadByGuestPlatformThreadId(activeThreads, threadId);
1015+
if (host == null) {
9631016
return -1;
9641017
}
965-
Thread host = getThreadAccess().getHost(thread);
9661018
long hostId = EspressoThreadRegistry.getThreadId(host);
9671019
return withSysTime ? hostBean.getThreadCpuTime(hostId) : hostBean.getThreadUserTime(hostId);
9681020
}

0 commit comments

Comments
 (0)