openj9 icon indicating copy to clipboard operation
openj9 copied to clipboard

Loom: JVMTI support

Open tajila opened this issue 3 years ago • 78 comments

Depends on https://github.com/eclipse-openj9/openj9/issues/15177

JVMTI

  • can_support_virtual_threads //new capbility
  • Suspend/ResumeAllVirtualThreads //new APIs
    • finds all vthreads and suspends or resumes them
  • StopThread
    • disallowerd on vthreads
  • GetThreadInfo
    • vthread is always daemon
    • vthread priotity is always normal
  • RunAgentThread
    • cannot be vthread
  • GetThreadGroupChildren
    • does not include vthreads
  • GetAllStackTraces
    • does not include vthreads
  • PopFrame/ForceEarlyReturnXXX/SetLocalXXX
    • allowed to fail if vthread
    • intial approach, do not allow for unmounted vthreads
    • if mounted, should just work, although should behave as pinned
      • cant modify pin state here, since effectively threadlocal
  • GetCurrentThreadCpuTime/GetThreadCpuTime
    • disallowed on vthreads
  • JVMTI_THREAD_STATE_PARKED
    • includes sleep state for vthreads

See https://download.java.net/java/early_access/jdk19/docs/specs/jvmti.html

tajila avatar Jun 01 '22 15:06 tajila

Revised List

Potentially, the following JVMTI methods are impacted by Loom:

  1. SetThreadLocalStorage (assigned to @EricYangIBM; covered by the TLS work): https://download.java.net/java/early_access/jdk19/docs/specs/jvmti.html#SetThreadLocalStorage
  2. GetThreadLocalStorage (assigned to @EricYangIBM; covered by the TLS work): https://download.java.net/java/early_access/jdk19/docs/specs/jvmti.html#GetThreadLocalStorage
  3. SetEventCallbacks (assigned to @EricYangIBM; covered by the TLS work): https://download.java.net/java/early_access/jdk19/docs/specs/jvmti.html#SetEventCallbacks
  4. SetEventNotificationMode (assigned to @EricYangIBM; covered by the TLS work): https://download.java.net/java/early_access/jdk19/docs/specs/jvmti.html#SetEventNotificationMode
  5. For JVMTI event callbacks, each jvmtiHook* function invokes prepareForEvent, which accesses J9JVMTIThreadData->threadEventEnable (assigned to @EricYangIBM; covered by the TLS work): https://download.java.net/java/early_access/jdk19/docs/specs/jvmti.html#jvmtiEventCallbacks.
  6. GetThreadState: https://download.java.net/java/early_access/jdk19/docs/specs/jvmti.html#GetThreadState
    • Implementation details: See https://github.com/eclipse-openj9/openj9/issues/15183#issuecomment-1167767823.
  7. ~GetCurrentThread: https://download.java.net/java/early_access/jdk19/docs/specs/jvmti.html#GetCurrentThread~
    • No change needed. See https://github.com/eclipse-openj9/openj9/issues/15183#issuecomment-1167767823.
  8. SuspendThread: https://download.java.net/java/early_access/jdk19/docs/specs/jvmti.html#SuspendThread
  9. SuspendThreadList: https://download.java.net/java/early_access/jdk19/docs/specs/jvmti.html#SuspendThreadList
  10. SuspendAllVirtualThreads: https://download.java.net/java/early_access/jdk19/docs/specs/jvmti.html#SuspendAllVirtualThreads
  11. ResumeThread: https://download.java.net/java/early_access/jdk19/docs/specs/jvmti.html#ResumeThread
  12. ResumeThreadList: https://download.java.net/java/early_access/jdk19/docs/specs/jvmti.html#ResumeThreadList
  13. ResumeAllVirtualThreads: https://download.java.net/java/early_access/jdk19/docs/specs/jvmti.html#ResumeAllVirtualThreads
  14. ~StopThread: https://download.java.net/java/early_access/jdk19/docs/specs/jvmti.html#StopThread~
    • Completed. See https://github.com/eclipse-openj9/openj9/pull/15418.
  15. InterruptThread: https://download.java.net/java/early_access/jdk19/docs/specs/jvmti.html#InterruptThread
    • Phase 1: https://github.com/eclipse-openj9/openj9/pull/15690.
    • Phase 2: Ignore the interrupt code for (NULL == targetThread) i.e. a yielded virtual thread, and avoid pinning a yielded virtual thread in jvmtiHelpers.c::getVMThread to evade the omthread_monitor_* costs.
  16. GetThreadInfo: https://download.java.net/java/early_access/jdk19/docs/specs/jvmti.html#GetThreadInfo
    • Implementation details: See https://github.com/eclipse-openj9/openj9/issues/15183#issuecomment-1187580033.
  17. GetOwnedMonitorInfo: https://download.java.net/java/early_access/jdk19/docs/specs/jvmti.html#GetOwnedMonitorInfo
    • Phase 1: https://github.com/eclipse-openj9/openj9/pull/15690.
    • Phase 2: https://github.com/eclipse-openj9/openj9/issues/15183#issuecomment-1219243366.
  18. GetOwnedMonitorStackDepthInfo: https://download.java.net/java/early_access/jdk19/docs/specs/jvmti.html#GetOwnedMonitorStackDepthInfo
    • Phase 1: https://github.com/eclipse-openj9/openj9/pull/15690.
    • Phase 2: https://github.com/eclipse-openj9/openj9/issues/15183#issuecomment-1219243366.
  19. GetCurrentContendedMonitor: https://download.java.net/java/early_access/jdk19/docs/specs/jvmti.html#GetCurrentContendedMonitor
    • Phase 1: https://github.com/eclipse-openj9/openj9/pull/15690.
    • Phase 2: https://github.com/eclipse-openj9/openj9/issues/15183#issuecomment-1219243366.
  20. ~GetThreadGroupChildren: https://download.java.net/java/early_access/jdk19/docs/specs/jvmti.html#GetThreadGroupChildren.~
    • Completed. See https://github.com/eclipse-openj9/openj9/pull/15539.
  21. GetStackTrace: https://download.java.net/java/early_access/jdk19/docs/specs/jvmti.html#GetStackTrace
    • Phase 1: https://github.com/eclipse-openj9/openj9/pull/15690.
    • Phase 2: https://github.com/eclipse-openj9/openj9/issues/15183#issuecomment-1219243366.
  22. GetThreadListStackTraces: https://download.java.net/java/early_access/jdk19/docs/specs/jvmti.html#GetThreadListStackTraces
    • Phase 1: https://github.com/eclipse-openj9/openj9/pull/15690.
    • Phase 2: https://github.com/eclipse-openj9/openj9/issues/15183#issuecomment-1219243366.
  23. GetFrameCount (assigned to @thallium): https://download.java.net/java/early_access/jdk19/docs/specs/jvmti.html#GetFrameCount
    • Phase 1: https://github.com/eclipse-openj9/openj9/pull/15690.
    • Phase 2: https://github.com/eclipse-openj9/openj9/issues/15183#issuecomment-1219243366.
  24. ~PopFrame: https://download.java.net/java/early_access/jdk19/docs/specs/jvmti.html#PopFrame~
    • Completed: https://github.com/eclipse-openj9/openj9/pull/15710.
  25. GetFrameLocation: https://download.java.net/java/early_access/jdk19/docs/specs/jvmti.html#GetFrameLocation
    • Phase 1: https://github.com/eclipse-openj9/openj9/pull/15690.
    • Phase 2: https://github.com/eclipse-openj9/openj9/issues/15183#issuecomment-1219243366.
  26. NotifyFramePop: https://download.java.net/java/early_access/jdk19/docs/specs/jvmti.html#NotifyFramePop
    • Phase 1: https://github.com/eclipse-openj9/openj9/pull/15690.
    • Phase 2: https://github.com/eclipse-openj9/openj9/issues/15183#issuecomment-1219243366.
  27. GetLocal(Object|Instance|Int|Long|Float|Double): https://download.java.net/java/early_access/jdk19/docs/specs/jvmti.html#GetLocalObject
    • Phase 1: https://github.com/eclipse-openj9/openj9/pull/15690.
    • Phase 2: https://github.com/eclipse-openj9/openj9/issues/15183#issuecomment-1219243366.
  28. SetLocal(Object|Int|Long|Float|Double): https://download.java.net/java/early_access/jdk19/docs/specs/jvmti.html#SetLocalObject
    • Phase 1: https://github.com/eclipse-openj9/openj9/pull/15690.
    • Phase 2: https://github.com/eclipse-openj9/openj9/issues/15183#issuecomment-1219243366.
  29. ~ForceEarlyReturn(Object|Int|Long|Float|Double|Void): https://download.java.net/java/early_access/jdk19/docs/specs/jvmti.html#ForceEarlyReturnObject~
    • Completed: https://github.com/eclipse-openj9/openj9/pull/15710.
  30. ~GetCurrentThreadCpuTime: https://download.java.net/java/early_access/jdk19/docs/specs/jvmti.html#GetCurrentThreadCpuTime~
    • Completed. See https://github.com/eclipse-openj9/openj9/pull/15418.
  31. ~GetThreadCpuTime: https://download.java.net/java/early_access/jdk19/docs/specs/jvmti.html#GetThreadCpuTime~
    • Completed. See https://github.com/eclipse-openj9/openj9/pull/15418.
  32. ~RunAgentThread: https://download.java.net/java/early_access/jdk19/docs/specs/jvmti.html#RunAgentThread~
    • Completed. See https://github.com/eclipse-openj9/openj9/pull/15418.
  33. ~GetAllThreads: https://download.java.net/java/early_access/jdk19/docs/specs/jvmti.html#GetAllThreads~
    • Completed: https://github.com/eclipse-openj9/openj9/pull/15635.
  34. ~can_support_virtual_threads: https://download.java.net/java/early_access/jdk19/docs/specs/jvmti.html#jvmtiCapabilities.can_support_virtual_threads~
    • Completed. See https://github.com/eclipse-openj9/openj9/pull/15254 and https://github.com/eclipse-openj9/openj9/pull/15451.
  35. GetAllStackTraces: https://download.java.net/java/early_access/jdk19/docs/specs/jvmti.html#GetAllStackTraces
    • Phase 1: https://github.com/eclipse-openj9/openj9/pull/15690.
    • Phase 2: https://github.com/eclipse-openj9/openj9/issues/15183#issuecomment-1219287248.

babsingh avatar Jun 20 '22 17:06 babsingh

Task 1: Handle error cases

re https://github.com/eclipse-openj9/openj9/issues/15183#issuecomment-1160712504

Examples: 29. GetCurrentThreadCpuTime: https://download.java.net/java/early_access/jdk19/docs/specs/jvmti.html#GetCurrentThreadCpuTime 30. GetThreadCpuTime: https://download.java.net/java/early_access/jdk19/docs/specs/jvmti.html#GetThreadCpuTime

Return JVMTI_ERROR_UNSUPPORTED_OPERATION for virtual threads
vmconstantpool.xml:
    <classref name="java/lang/VirtualThread"/>

bool isVirtualThread(J9VMThread *vmThread, jthread jthrd) {
   bool result = false;
   if (isSameOrSuperClassOf(
           J9VMJAVALANGVIRTUALTHREAD_OR_NULL(vmThread->javaVM),
           J9OBJECT_CLAZZ(vmThread, *(j9object_t *)jthrd)
   ) {
      result = true;
   }
   return result;
}

babsingh avatar Jun 20 '22 19:06 babsingh

@tajila Will J9VMThread->threadObject always be up-to-date for Loom?

jvmtiGetCurrentThreadCpuTime(jvmtiEnv *env, jlong *nanos_ptr) {
    ...
    J9VMThread * currentThread = NULL;
    j9object_t threadObject = NULL;
    jvmtiError rc = JVMTI_ERROR_NONE;

    rc = getCurrentVMThread(vm, &currentThread);
    if (JVMTI_ERROR_NONE != rc) {
        return rc;
    } 
    threadObject = currentThread->threadObject;

    if (isSameOrSuperClassOf(
           J9VMJAVALANGVIRTUALTHREAD_OR_NULL(currentThread->javaVM),
           J9OBJECT_CLAZZ(currentThread, threadObject)
   ) {
       return JVMTI_ERROR_UNSUPPORTED_OPERATION;
   }
   ...
}

babsingh avatar Jun 20 '22 19:06 babsingh

@tajila Will J9VMThread->threadObject always be up-to-date for Loom?

yes

tajila avatar Jun 20 '22 20:06 tajila

Is there a priority for functions to update or should I just go down the list in the spec?

EricYangIBM avatar Jun 27 '22 14:06 EricYangIBM

Is there a priority for functions to update or should I just go down the list in the spec?

Some functions will require the changes for https://github.com/eclipse-openj9/openj9/issues/15177. You can support the easiest ones first, and the ones not dependent on https://github.com/eclipse-openj9/openj9/issues/15177.

babsingh avatar Jun 27 '22 17:06 babsingh

Looking at the first three thread functions, do they need to be updated?

  1. GetThreadState Are there any changes needed for getVMThreadStateHelper()? Thread flags used differently for virtual threads?
  2. GetCurrentState Depends on vm->internalVMFunctions->currentVMThread, I don't think it needs any other changes. https://github.com/eclipse-openj9/openj9/blob/master/runtime/jvmti/jvmtiThread.c#L1096
  3. GetAllThreads Iterates over J9VMThread.linkNext, does this include virtual threads? https://github.com/eclipse-openj9/openj9/blob/master/runtime/jvmti/jvmtiThread.c#L163

EricYangIBM avatar Jun 27 '22 17:06 EricYangIBM

re https://github.com/eclipse-openj9/openj9/issues/15183#issuecomment-1167668040:

  1. GetThreadState: There are some differences between Thread.state and VirtualThread.state. Example: A virtual thread that is sleeping, in Thread.sleep, may have JVMTI_THREAD_STATE_PARKED set instead of JVMTI_THREAD_STATE_SLEEPING. JVMTI_THREAD_STATE_RUNNABLE means that a thread is runnable. A virtual thread has two similar states: RUNNABLE and RUNNING. Also, a virtual thread has a PINNED state.
  2. GetCurrentThread: ((J9VMThread *)(vm->internalVMFunctions->currentVMThread()))->threadObject should provide the correct Java programming language thread. No change needed for this method.
  3. GetAllThreads: J9VMThread.linkNext should only include platform and carrier threads. It should not have virtual threads. The JVMTI doc tells us to ignore virtual threads for this method. So, no change is needed for this method.

We can also use the JVMTI tests in the extensions repo to verify our functionality. These tests have been updated for Project Loom.

  • GetThreadState tests: https://github.com/ibmruntimes/openj9-openjdk-jdk19/tree/openj9/test/hotspot/jtreg/serviceability/jvmti/thread/GetThreadState

Other Project Loom related JVMTI tests: https://github.com/ibmruntimes/openj9-openjdk-jdk19/tree/openj9/test/hotspot/jtreg/serviceability/jvmti/thread

babsingh avatar Jun 27 '22 19:06 babsingh

How will we implement Get/SetThreadLocalStorage for virtual threads? The tls for platform threads is attached to omr thread.

EricYangIBM avatar Jun 30 '22 14:06 EricYangIBM

How will we implement Get/SetThreadLocalStorage for virtual threads? The tls for platform threads is attached to omr thread.

It can be moved as a hidden field into java.lang.Thread (class). In the Loom world, this will allow us to associate a pointer value with each environment-thread pair.

Old:
   struct J9Thread {
         void* tls[J9THREAD_MAX_TLS_KEYS];

New:
    Add hidden field into java.lang.Thread to store the above TLS array. It can be dynamically initialized.

Old:
    #define THREAD_DATA_FOR_VMTHREAD(j9env, vmThread) \
	((J9JVMTIThreadData *) omrthread_tls_get((vmThread)->osThread, (j9env)->tlsKey))

New:
    Get TLS from java.lang.Thread's hidden field
    (J9JVMTIThreadData *)READU(TLS[j9env->tlsKey - 1]);

We will also need to account for the initialization and destruction of the native structures associated to this hidden field.

@tajila @gacholio Can you provide feedback on the above approach?

babsingh avatar Jun 30 '22 16:06 babsingh

At a glance, no, this is not correct. Our TLS is effectively useless in the presence of vthreads, so we will simply have to stop using it in many places.

Correct answer here is probably to add a hidden field to Thread to contain the JVMTI data itself, not some fake TLS implementation.

gacholio avatar Jun 30 '22 16:06 gacholio

Correct answer here is probably to add a hidden field to Thread to contain the JVMTI data itself, not some fake TLS implementation.

Will JVMTI data be a struct as follows?

struct JVMTIThreadData {
   List of {J9JVMTIEnv, J9JVMTIThreadData} pairs;
   Other thread specific JVMTI details if needed;
}

babsingh avatar Jun 30 '22 16:06 babsingh

To avoid searching a list, we could essentially reimplement TLS - store a fixed-size array in the Thread hidden field, and manage the keys ourselves. This will mean freeing the TLS when the Thread is collected (which may be a pain).

gacholio avatar Jun 30 '22 17:06 gacholio

Currently the TLS data struct gets allocated for each existing os thread when a jvmti env is allocated (allocateEnvironment in jvmtiHelpers.c) and new threads when a J9VMThread is created. TLS gets deallocated upon jvmti env deallocation or J9VMThread death. (J9HOOK_VM_THREAD_CREATED and J9HOOK_VM_THREAD_DESTROY) Could we change these hooks to when a Thread is started/destroyed? Or maybe use the J9HOOK_VM_THREAD_STARTED/J9HOOK_VM_THREAD_END events instead? Also I don't think the jvmtiEventThreadStart ThreadStart; and jvmtiEventThreadEnd ThreadEnd; callback functions exist/are used (same with the virtual thread versions), could they be used?

Also note the TLS only has to exist while the thread is alive (JVMTI_ERROR_THREAD_NOT_ALIVE)

EricYangIBM avatar Jul 05 '22 18:07 EricYangIBM

J9HOOK_VM_THREAD_CREATED is special in that it's fired under lock (it does not report any JVMTI events) and is allowed to fail (e.g. malloc fail for TLS).

gacholio avatar Jul 05 '22 18:07 gacholio

(J9HOOK_VM_THREAD_CREATED and J9HOOK_VM_THREAD_DESTROY) Could we change these hooks to when a Thread is started/destroyed?

We will need new hooks for j.l.Thread creation/destruction. Reusing VM_THREAD hooks will be misleading since multiple j.l.Threads can be associated to a single VM_THREAD.

Also I don't think the jvmtiEventThreadStart ThreadStart; and jvmtiEventThreadEnd ThreadEnd; callback functions exist/are used (same with the virtual thread versions), could they be used?

Callbacks are defined by the user. Example ThreadStart use-case: https://github.com/eclipse-openj9/openj9/blob/24b14b4743f82a648712bdca71a5b870828e65f9/runtime/tests/jvmtitests/src/com/ibm/jvmti/tests/eventThreadStart/ets001.c#L46

babsingh avatar Jul 05 '22 19:07 babsingh

@gacholio @tajila Can we init and destroy j.l.Thread specific structures in jvmtiHookThreadStarted and jvmtiHookThreadDestroy before the callback is invoked? With this approach, can we avoid new J9 hooks for j.l.Thread creation/destruction?

babsingh avatar Jul 05 '22 19:07 babsingh

Doesnt that have the same problem as J9HOOK_VM_THREAD_CREATED since those hooks apply to vmthreads which may be mapped to multiple virtual threads?

tajila avatar Jul 06 '22 02:07 tajila

Doesnt that have the same problem as J9HOOK_VM_THREAD_CREATED since those hooks apply to vmthreads which may be mapped to multiple virtual threads?

There are also the newly added jvmtiEventVirtualThreadStart VirtualThreadStart; and jvmtiEventVirtualThreadEnd VirtualThreadEnd; for which we have jvmtiHookVirtualThreadStarted and jvmtiHookVirtualThreadEnd

EricYangIBM avatar Jul 06 '22 14:07 EricYangIBM

Doesnt that have the same problem as J9HOOK_VM_THREAD_CREATED since those hooks apply to vmthreads which may be mapped to multiple virtual threads?

These events should work for Java threads (not VM threads): https://download.java.net/java/early_access/jdk19/docs/specs/jvmti.html#ThreadStart. But they may just be restricted to the threads launched by RunAgentThread.

Approach 1

Finalization is deprecated and expensive for GC.

Thread object {
   Constructor {
      Allocate data-struct to store JVMTI thread-local storage
      Allocation can also be delayed to first use.
   }

   GC collect/destroy {
       // Is there a way to coordinate with the GC to free this data-struct during collection?
       Free data-struct if allocated
   }
}

Approach 2

Requires more footprint. But, less overhead on the GC.

JVM startup {
    Allocate a global struct. E.g. HashTable<key=threadObj, value=Data>.
    Allocation can also be delayed to first use.
}

SetThreadLocalStorage {
    // Entries will be unused if thread objects are collected by the GC
    HashTable.put(threadObj, ...)
}

GetThreadLocalStorage {
    HashTable.get(threadObj, ...)
}

JVM destroy {
   Free the global struct
}

babsingh avatar Jul 06 '22 14:07 babsingh

How are vthreads created? Do you call start on them like normal threads (presumably overridden)?

gacholio avatar Jul 06 '22 16:07 gacholio

But they may just be restricted to the threads launched by RunAgentThread.

I don't see why this is the case, especially since the thread object associated with the agent thread cannot be a virtual thread and VirtualThreadStartEvents seem to be generated: https://github.com/ibmruntimes/openj9-openjdk-jdk/blob/openj9/src/java.base/share/classes/java/lang/VirtualThread.java#L280 Why can't we allocate the array upon this event?

EricYangIBM avatar Jul 06 '22 16:07 EricYangIBM

The thread start even currently cannot fail, so allocating here would mean either changing the internal APIs or asserting instead of failing (a bad idea). Please answer my previous question - if a native is run to start vthreads, we can fire the CREATED event there.

gacholio avatar Jul 06 '22 16:07 gacholio

Just had a discussion with @EricYangIBM I believe the following natives are all we need. These are in j.l.VirtualThread

     @JvmtiMountTransition
    private native void notifyJvmtiMountBegin(boolean firstMount);

    @JvmtiMountTransition
    private native void notifyJvmtiMountEnd(boolean firstMount);

    @JvmtiMountTransition
    private native void notifyJvmtiUnmountBegin(boolean lastUnmount);

    @JvmtiMountTransition
    private native void notifyJvmtiUnmountEnd(boolean lastUnmount);

notifyJvmtiMountBegin(true) is called when the vthread is started. notifyJvmtiUnmountEnd(true) is called when the vthread ends.

We can use these natives to implement jvmtiEventVirtualThreadStart/End hooks.

Additionally, we can also use these natives to keep track of which vthreads are currently live.

As for the TLS question, I think Approach 2 makes more sense to me. We can associated a hashtable which each jvmtiEnv where the key is the threadobj and the value is the tls data

tajila avatar Jul 06 '22 17:07 tajila

Do you have enough control to guarantee you can call a native when a vthread ends (don't these threads "end" when they are collected by the GC?)?

Also, hash tables containing objects will be problematic.

gacholio avatar Jul 06 '22 17:07 gacholio

Do you have enough control to guarantee you can call a native when a vthread ends (don't these threads "end" when they are collected by the GC?)?

The natives are effectively the first and last things that the vthreads do when they are live. The vthread can't run more code once notifyJvmtiUnmountEnd(true) is called, the threadObject may still exist but its thread state will be TERMINATED

tajila avatar Jul 06 '22 17:07 tajila

Also, hash tables containing objects will be problematic.

True, we will need some other kind of ID

tajila avatar Jul 06 '22 17:07 tajila

Summary:

  • Add pointer hidden field in java/lang/Thread to store pointers to J9JVMTIThreadData
  • Keys will be managed similarly to omrthread_tls_ functions, one per jvmtiEnv
  • ~~For each platform thread when jvmti env is created, allocate 124 size array (if not allocated already from another env) and J9JVMTIThreadData at array[key]~~ Allocate at SetThreadLocalStorage or SetEventNotificationMode for a given thread under a lock
  • ~~For each live virtual thread when jvmti env is created, also allocate 124 size array and J9JVMTIThreadData~~
  • When a platform thread is created (J9HOOK_VM_THREAD_CREATED) allocate array and J9JVMTIThreadData
  • ~~When a virtual thread is created (new J9Hook similar to above) also allocate array and J9JVMTIThreadData~~
  • When a jvmtiEnv is destroyed loop through all platform ~~and virtual~~ threads and free the key associated with the env
  • Deallocate J9JVMTIThreadData and hidden field array when ~~platform (J9HOOK_VM_THREAD_DESTROY) and~~ virtual threads die
  • ~~The notifyJvmtiMountBegin(true) and notifyJvmtiUnmountEnd(true) natives will update the list of live virtual threads and also call the new hooks~~

Please correct if wrong

Edit - Updated to reflect lazy init approach

EricYangIBM avatar Jul 07 '22 18:07 EricYangIBM

When a jvmtiEnv is destroyed loop through all platform and virtual threads and free the key associated with the env

Is the key not a field of jvmtiEnv? Is looping through threads required?

Keys will be managed similarly to omrthread_tls_ functions, one per jvmtiEnv

TLS: Can you describe the new functions which will be implemented on the J9 side? Which OMR functions will be reused?

babsingh avatar Jul 07 '22 19:07 babsingh

Is looping through threads required?

Won't we need to free the tls data for each thread's tls[env->key] since the thread destroy hooks will be unregistered? Also I think we will need a global array for each env to keep track of used keys. Currently omr does lib->tls_finalizers[key - 1] = NULL; to free a key, we will need something similar to this array. (Also I don't think it currently frees the tls data in omrthread_tls_free, it only sets it to null)

I think we will have to reimplement all of the omr functions since omr uses tls keys for non-jvmti tls as well

EricYangIBM avatar Jul 07 '22 20:07 EricYangIBM