Skip to content

Commit

Permalink
[FFI] Adjust the code with the release of the thunk heap
Browse files Browse the repository at this point in the history
The changes move the code intended for the release of thunk heap
to UpcallThunkMem.cpp so as to consolidate the code specific to
the thunk heap operations to one place, which includes:
1) move freeUpcallMetaDataDoFn() to UpcallThunkMem.cpp
2) move alll the code with the release of the thunk heap
   in freeJavaVM() to releaseThunkHeap() at UpcallThunkMem.cpp

Related: #19714

Signed-off-by: ChengJin01 <[email protected]>
  • Loading branch information
ChengJin01 committed Jul 15, 2024
1 parent 31badae commit 4b6f2fd
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 94 deletions.
9 changes: 4 additions & 5 deletions runtime/oti/vm_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -5179,7 +5179,7 @@ throwNewJavaIoIOException(JNIEnv *env, const char *message);
/* ------------------- UpcallThunkGen.cpp ----------------- */

/**
* @brief Generate the appropriate thunk/adaptor for a given J9UpcallMetaData
* @brief Generate the appropriate thunk/adaptor for a given J9UpcallMetaData.
*
* @param metaData[in/out] a pointer to the given J9UpcallMetaData
* @return the address for this future upcall function handle, either the thunk or the thunk-descriptor
Expand All @@ -5188,7 +5188,7 @@ void *
createUpcallThunk(J9UpcallMetaData *data);

/**
* @brief Calculate the requested argument in-stack memory address to return
* @brief Calculate the requested argument in-stack memory address to return.
*
* @param nativeSig a pointer to the J9UpcallNativeSignature
* @param argListPtr a pointer to the argument list prepared by the thunk
Expand All @@ -5203,7 +5203,7 @@ void *
getArgPointer(J9UpcallNativeSignature *nativeSig, void *argListPtr, int argIdx);

/**
* @brief Allocate a piece of thunk memory with a given size from the existing virtual memory block
* @brief Allocate a piece of thunk memory with a given size from the existing virtual memory block.
*
* @param data a pointer to J9UpcallMetaData
* @return the start address of the upcall thunk memory, or NULL on failure.
Expand All @@ -5213,11 +5213,10 @@ allocateUpcallThunkMemory(J9UpcallMetaData *data);


/**
* @brief Flush the generated thunk to the memory
* @brief Flush the generated thunk to the memory.
*
* @param data a pointer to J9UpcallMetaData
* @param thunkAddress the address of the generated thunk
* @return void
*/
void
doneUpcallThunkGeneration(J9UpcallMetaData *data, void *thunkAddress);
Expand Down
94 changes: 87 additions & 7 deletions runtime/vm/UpcallThunkMem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,13 @@ static void * subAllocateThunkFromHeap(J9UpcallMetaData *data);
static J9UpcallThunkHeapList * allocateThunkHeap(J9UpcallMetaData *data);
static UDATA upcallMetaDataHashFn(void *key, void *userData);
static UDATA upcallMetaDataEqualFn(void *leftKey, void *rightKey, void *userData);
static UDATA freeUpcallMetaDataDoFn(J9UpcallMetaDataEntry *entry, void *userData);

/**
* @brief Flush the generated thunk to the memory
* @brief Flush the generated thunk to the memory.
*
* @param data a pointer to J9UpcallMetaData
* @param thunkAddress The address of the generated thunk
* @return void
*/
void
doneUpcallThunkGeneration(J9UpcallMetaData *data, void *thunkAddress)
Expand All @@ -54,10 +54,10 @@ doneUpcallThunkGeneration(J9UpcallMetaData *data, void *thunkAddress)
}

/**
* @brief Allocate a piece of thunk memory with a given size from the existing virtual memory block
* @brief Allocate a piece of thunk memory with a given size from the existing virtual memory block.
*
* @param data a pointer to J9UpcallMetaData
* @return the start address of the upcall thunk memory, or NULL on failure.
* @return the start address of the upcall thunk memory, or NULL on failure
*/
void *
allocateUpcallThunkMemory(J9UpcallMetaData *data)
Expand Down Expand Up @@ -204,7 +204,7 @@ allocateThunkHeap(J9UpcallMetaData *data)

omrthread_jit_write_protect_disable();

/* Initialize the allocated memory as a J9Heap */
/* Initialize the allocated memory as a J9Heap. */
thunkHeap = j9heap_create(allocMemPtr, pageSize, 0);
if (NULL == thunkHeap) {
Trc_VM_allocateThunkHeap_create_heap_failed(allocMemPtr, pageSize);
Expand Down Expand Up @@ -265,7 +265,50 @@ allocateThunkHeap(J9UpcallMetaData *data)
}

/**
* Compute the hash code (namely the thunk address value) for the supplied J9UpcallMetaDataEntry
* @brief Release the thunk heap list if exists.
*
* @param vm a pointer to J9JavaVM
*
* Note:
* This function empties the thunk heap list by cleaning up all resources
* created via allocateUpcallThunkMemory, including the generated thunk
* and the corresponding metadata of each entry in the hashtable.
*/
void
releaseThunkHeap(J9JavaVM *vm)
{
J9UpcallThunkHeapList *thunkHeapHead = vm->thunkHeapHead;
J9UpcallThunkHeapList *thunkHeapNode = NULL;
PORT_ACCESS_FROM_JAVAVM(vm);
UDATA byteAmount = j9vmem_supported_page_sizes()[0];

if (NULL != thunkHeapHead->metaDataHashTable) {
J9HashTable *metaDataHashTable = thunkHeapHead->metaDataHashTable;
hashTableForEachDo(metaDataHashTable, (J9HashTableDoFn)freeUpcallMetaDataDoFn, NULL);
hashTableFree(metaDataHashTable);
metaDataHashTable = NULL;
}

thunkHeapNode = thunkHeapHead->next;
thunkHeapHead->next = NULL;
thunkHeapHead = thunkHeapNode;
while (NULL != thunkHeapHead) {
J9UpcallThunkHeapWrapper *thunkHeapWrapper = thunkHeapHead->thunkHeapWrapper;
if (NULL != thunkHeapWrapper) {
J9PortVmemIdentifier vmemID = thunkHeapWrapper->vmemID;
j9vmem_free_memory(vmemID.address, byteAmount, &vmemID);
j9mem_free_memory(thunkHeapWrapper);
thunkHeapWrapper = NULL;
}
thunkHeapNode = thunkHeapHead;
thunkHeapHead = thunkHeapHead->next;
j9mem_free_memory(thunkHeapNode);
}
vm->thunkHeapHead = NULL;
}

/**
* Compute the hash code (namely the thunk address value) for the supplied J9UpcallMetaDataEntry.
*/
static UDATA
upcallMetaDataHashFn(void *key, void *userData)
Expand All @@ -274,14 +317,51 @@ upcallMetaDataHashFn(void *key, void *userData)
}

/**
* Determines if leftKey and rightKey refer to the same entry in the upcall metadata hashtable
* Determine if leftKey and rightKey refer to the same entry in the upcall metadata hashtable.
*/
static UDATA
upcallMetaDataEqualFn(void *leftKey, void *rightKey, void *userData)
{
return ((J9UpcallMetaDataEntry *)leftKey)->thunkAddrValue == ((J9UpcallMetaDataEntry *)rightKey)->thunkAddrValue;
}

/**
* Release the memory of the generated thunk and the metadata in the
* specified entry of the metadata hashtable intended for upcall.
*/
static UDATA
freeUpcallMetaDataDoFn(J9UpcallMetaDataEntry *entry, void *userData)
{
void *thunkAddr = (void *)(entry->thunkAddrValue);
J9UpcallMetaData *metaData = entry->upcallMetaData;

if ((NULL != thunkAddr) && (NULL != metaData)) {
J9JavaVM *vm = metaData->vm;
const J9InternalVMFunctions *vmFuncs = vm->internalVMFunctions;
J9VMThread *currentThread = vmFuncs->currentVMThread(vm);
J9UpcallNativeSignature *nativeFuncSig = metaData->nativeFuncSignature;
J9Heap *thunkHeap = metaData->thunkHeapWrapper->heap;
PORT_ACCESS_FROM_JAVAVM(vm);

if (NULL != nativeFuncSig) {
j9mem_free_memory(nativeFuncSig->sigArray);
j9mem_free_memory(nativeFuncSig);
nativeFuncSig = NULL;
}
vmFuncs->j9jni_deleteGlobalRef((JNIEnv *)currentThread, metaData->mhMetaData, JNI_FALSE);
j9mem_free_memory(metaData);
metaData = NULL;

if (NULL != thunkHeap) {
omrthread_jit_write_protect_disable();
j9heap_free(thunkHeap, thunkAddr);
omrthread_jit_write_protect_enable();
}
entry->thunkAddrValue = 0;
}
return JNI_OK;
}

#endif /* JAVA_SPEC_VERSION >= 16 */

} /* extern "C" */
83 changes: 2 additions & 81 deletions runtime/vm/jvminit.c
Original file line number Diff line number Diff line change
Expand Up @@ -327,10 +327,6 @@ static UDATA parseGlrOption(J9JavaVM* jvm, char* option);
static void cleanupEnsureHashedConfig(J9JavaVM *jvm);
static UDATA parseEnsureHashedConfig(J9JavaVM *jvm, char *options, BOOLEAN isAdd);

#if JAVA_SPEC_VERSION >= 16
static UDATA freeUpcallMetaDataDoFn(J9UpcallMetaDataEntry *entry, void *userData);
#endif /* JAVA_SPEC_VERSION >= 16 */

J9_DECLARE_CONSTANT_UTF8(j9_int_void, "(I)V");
J9_DECLARE_CONSTANT_UTF8(j9_dispatch, "dispatch");

Expand Down Expand Up @@ -674,41 +670,9 @@ freeJavaVM(J9JavaVM * vm)
vm->cifArgumentTypesCache = NULL;
}

/* Empty the thunk heap list by cleaning up all resources created via allocateUpcallThunkMemory,
* including the generated thunk and the corresponding metadata of each entry in the hashtable.
* See UpcallThunkMem.cpp for details.
*/
/* Empty the thunk heap list if exists. */
if (NULL != vm->thunkHeapHead) {
J9UpcallThunkHeapList *thunkHeapHead = vm->thunkHeapHead;
J9UpcallThunkHeapList *thunkHeapNode = NULL;
UDATA byteAmount = j9vmem_supported_page_sizes()[0];

if (NULL != thunkHeapHead->metaDataHashTable) {
J9HashTable *metaDataHashTable = thunkHeapHead->metaDataHashTable;
UDATA entryCount = hashTableGetCount(metaDataHashTable);
if (entryCount > 0) {
hashTableForEachDo(metaDataHashTable, (J9HashTableDoFn)freeUpcallMetaDataDoFn, NULL);
}
hashTableFree(metaDataHashTable);
metaDataHashTable = NULL;
}

thunkHeapNode = thunkHeapHead->next;
thunkHeapHead->next = NULL;
thunkHeapHead = thunkHeapNode;
while (NULL != thunkHeapHead) {
J9UpcallThunkHeapWrapper *thunkHeapWrapper = thunkHeapHead->thunkHeapWrapper;
if (NULL != thunkHeapWrapper) {
J9PortVmemIdentifier vmemID = thunkHeapWrapper->vmemID;
j9vmem_free_memory(vmemID.address, byteAmount, &vmemID);
j9mem_free_memory(thunkHeapWrapper);
thunkHeapWrapper = NULL;
}
thunkHeapNode = thunkHeapHead;
thunkHeapHead = thunkHeapHead->next;
j9mem_free_memory(thunkHeapNode);
}
vm->thunkHeapHead = NULL;
releaseThunkHeap(vm);
}
#endif /* JAVA_SPEC_VERSION >= 16 */

Expand Down Expand Up @@ -8839,46 +8803,3 @@ parseEnsureHashedConfig(J9JavaVM *jvm, char *options, BOOLEAN isAdd)

return result;
}

#if JAVA_SPEC_VERSION >= 16
/**
* This function free the memory of the generated thunk and the metadata
* in the specified entry of the metadata hashtable intended for upcall.
*
* @param entry A pointer to J9UpcallMetaDataEntry
* @param userData An optional parameter which is unused
* @returns JNI_OK on success
*/
static UDATA
freeUpcallMetaDataDoFn(J9UpcallMetaDataEntry *entry, void *userData)
{
void *thunkAddr = (void *)(entry->thunkAddrValue);
J9UpcallMetaData *metaData = entry->upcallMetaData;

if ((NULL != thunkAddr) && (NULL != metaData)) {
J9JavaVM *vm = metaData->vm;
const J9InternalVMFunctions *vmFuncs = vm->internalVMFunctions;
J9VMThread *currentThread = vmFuncs->currentVMThread(vm);
J9UpcallNativeSignature *nativeFuncSig = metaData->nativeFuncSignature;
J9Heap *thunkHeap = metaData->thunkHeapWrapper->heap;
PORT_ACCESS_FROM_JAVAVM(vm);

if (NULL != nativeFuncSig) {
j9mem_free_memory(nativeFuncSig->sigArray);
j9mem_free_memory(nativeFuncSig);
nativeFuncSig = NULL;
}
vmFuncs->j9jni_deleteGlobalRef((JNIEnv *)currentThread, metaData->mhMetaData, JNI_FALSE);
j9mem_free_memory(metaData);
metaData = NULL;

if (NULL != thunkHeap) {
omrthread_jit_write_protect_disable();
j9heap_free(thunkHeap, thunkAddr);
omrthread_jit_write_protect_enable();
}
entry->thunkAddrValue = 0;
}
return JNI_OK;
}
#endif /* JAVA_SPEC_VERSION >= 16 */
17 changes: 16 additions & 1 deletion runtime/vm/vm_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -541,7 +541,7 @@ UDATA initializeExclusiveAccess(J9JavaVM *vm);
void shutDownExclusiveAccess(J9JavaVM *vm);

#if JAVA_SPEC_VERSION >= 16
/* LayoutFFITypeHelpers.cpp */
/* ------------------- LayoutFFITypeHelpers.cpp ----------------- */

/**
* Release the memory of struct specific ffi_types if exist in the argument/return types
Expand All @@ -551,6 +551,21 @@ void shutDownExclusiveAccess(J9JavaVM *vm);
*/
void
freeAllStructFFITypes(J9VMThread *currentThread, void *cifNode);

/* ------------------- UpcallThunkMem.cpp ----------------- */

/**
* @brief Release the thunk heap list if exists.
*
* @param vm a pointer to J9JavaVM
*
* Note:
* This function empties the thunk heap list by cleaning up all resources
* created via allocateUpcallThunkMemory, including the generated thunk
* and the corresponding metadata of each entry in the hashtable.
*/
void
releaseThunkHeap(J9JavaVM *vm);
#endif /* JAVA_SPEC_VERSION >= 16 */

/* ------------------- jnimisc.cpp ----------------- */
Expand Down

0 comments on commit 4b6f2fd

Please sign in to comment.