Skip to content

Commit

Permalink
Merge pull request #16625 from dsouzai/j2iThunkReloFailure
Browse files Browse the repository at this point in the history
Use VM criteria for J2I Thunk Sharing in AOT Compiles
  • Loading branch information
mpirvu authored Feb 2, 2023
2 parents 219f2e8 + 96d36b7 commit 85007bc
Show file tree
Hide file tree
Showing 4 changed files with 181 additions and 36 deletions.
149 changes: 134 additions & 15 deletions runtime/codert_vm/thunkcrt.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 1991, 2022 IBM Corp. and others
* Copyright (c) 1991, 2023 IBM Corp. and others
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
Expand All @@ -21,6 +21,7 @@
*******************************************************************************/

#include "j9.h"
#include "j9nonbuilder.h"
#include "j9protos.h"
#include "jitprotos.h"
#include "ut_j9codertvm.h"
Expand Down Expand Up @@ -102,10 +103,12 @@ extern void * icallVMprJavaSendInvokeExactL;
#endif

static U_8 j9ThunkGetEncodedSignature(J9ThunkTableEntry * entry, U_8 ** encodedSignaturePtr);
static UDATA j9ThunkEncodeSignatureASCII(char *signatureData, U_8 * encodedSignature);
static UDATA j9ThunkEncodeSignature(char *signatureData, U_8 * encodedSignature);
static UDATA j9ThunkTableHash(void *key, void *userData);
static UDATA j9ThunkTableEquals(void *leftKey, void *rightKey, void *userData);

typedef UDATA (*encodeByteFn)(UDATA encodedTypeByteStored, U_8 *encodedTypeBytePtr, U_8 encodedType);

void *
j9ThunkLookupNameAndSig(void * jitConfig, void *parm)
Expand Down Expand Up @@ -297,21 +300,29 @@ j9ThunkNewSignature(void * jitConfig, int signatureLength, char *signatureChars,
return 0;
}

/* Returns the total number of bytes used in the encodedSignature buffer */
static UDATA
j9ThunkEncodeByte(UDATA encodedTypeByteStored, U_8 *encodedTypeBytePtr, U_8 encodedType)
{
*encodedTypeBytePtr = ((*encodedTypeBytePtr) << 4) | encodedType;
return !encodedTypeByteStored;
}

static UDATA
j9ThunkEncodeSignature(char *signatureData, U_8 * encodedSignature)
j9ThunkEncodeByteASCII(UDATA encodedTypeByteStored, U_8 *encodedTypeBytePtr, U_8 encodedType)
{
U_8 * encodedTypes = encodedSignature + 1;
U_8 argCount = 0;
*encodedTypeBytePtr = (encodedType > 9 ? (encodedType - 10 + 'a') : (encodedType + '0'));
return TRUE;
}

static void
j9ThunkIterateAndEncode(char ** signatureDataPtr, U_8 ** encodedTypesPtr, U_8 * argCountPtr, encodeByteFn encodeByte)
{
UDATA done = FALSE;
U_8 encodedTypeByte = 0;
UDATA encodedTypeByteStored = TRUE;
UDATA done = FALSE;
UDATA totalSize;
#ifdef DEBUG
char * origSig = signatureData;
UDATA i;
#endif
U_8 * encodedTypes = *encodedTypesPtr;
char * signatureData = *signatureDataPtr;
U_8 argCount = *argCountPtr;

/* Skip opening bracket */
++signatureData;
Expand Down Expand Up @@ -365,10 +376,9 @@ j9ThunkEncodeSignature(char *signatureData, U_8 * encodedSignature)
break;
}

/* Store encoded value into nybble */
/* Store encoded value */

encodedTypeByte = (encodedTypeByte << 4) | encodedType;
encodedTypeByteStored = !encodedTypeByteStored;
encodedTypeByteStored = encodeByte(encodedTypeByteStored, &encodedTypeByte, encodedType);
if (encodedTypeByteStored) {
*encodedTypes++ = encodedTypeByte;
}
Expand All @@ -377,9 +387,65 @@ j9ThunkEncodeSignature(char *signatureData, U_8 * encodedSignature)
/* Store the final byte if necessary */

if (!encodedTypeByteStored) {
*encodedTypes++ = (encodedTypeByte << 4) | J9_THUNK_TYPE_FILL;
encodedTypeByteStored = encodeByte(encodedTypeByteStored, &encodedTypeByte, J9_THUNK_TYPE_FILL);
*encodedTypes++ = encodedTypeByte;
}

*argCountPtr = argCount;
*encodedTypesPtr = encodedTypes;
*signatureDataPtr = signatureData;
}

/* Returns the total number of bytes used in the encodedSignature buffer */

static UDATA
j9ThunkEncodeSignatureASCII(char *signatureData, U_8 * encodedSignature)
{
U_8 * encodedTypes = encodedSignature;
U_8 argCount = 0;
UDATA totalSize;
#ifdef DEBUG
char * origSig = signatureData;
UDATA i;
#endif

/* Iterate and encode the signature in signatureData into encodedTypes */

j9ThunkIterateAndEncode(&signatureData, &encodedTypes, &argCount, j9ThunkEncodeByteASCII);

/* Compute total size */

totalSize = encodedTypes - encodedSignature;

#ifdef DEBUG
printf("encode: %.*s -> ", signatureData - origSig, origSig);
for (i = 0; i < totalSize; ++i) {
printf("%c", encodedSignature[i]);
}
printf(" (length %d)\n", totalSize);
#endif

return totalSize;
}

/* Returns the total number of bytes used in the encodedSignature buffer */

static UDATA
j9ThunkEncodeSignature(char *signatureData, U_8 * encodedSignature)
{
/* Leave room for storing argCount */
U_8 * encodedTypes = encodedSignature + 1;
U_8 argCount = 0;
UDATA totalSize;
#ifdef DEBUG
char * origSig = signatureData;
UDATA i;
#endif

/* Iterate and encode the signature from signatureData into encodedTypes */

j9ThunkIterateAndEncode(&signatureData, &encodedTypes, &argCount, j9ThunkEncodeByte);

/* Store arg count and compute total size */

encodedSignature[0] = argCount;
Expand Down Expand Up @@ -493,3 +559,56 @@ j9ThunkVMHelperFromNameAndSig(void * jitConfig, void *parm)

return j9ThunkVMHelperFromSignature(jitConfig, J9UTF8_LENGTH(J9ROMNAMEANDSIGNATURE_SIGNATURE(nameAndSignature)), (char *) J9UTF8_DATA((J9ROMNAMEANDSIGNATURE_SIGNATURE(nameAndSignature))));
}

const void *
j9ThunkPersist(J9JITConfig *jitConfig, char *signatureChars, U_32 signatureLength, U_8 *thunkStart, U_32 totalSize)
{
const void *store = NULL;

#if defined(J9VM_OPT_SHARED_CLASSES)
J9JavaVM *vm = jitConfig->javaVM;
J9VMThread *vmThread = vm->internalVMFunctions->currentVMThread(vm);

U_8 encodedSignatureArray[2 * (J9_THUNK_MAX_ENCODED_BYTES - 1)];
U_8 *encodedSignature = encodedSignatureArray;
UDATA encodedLength;

J9SharedDataDescriptor dataDescriptor;
dataDescriptor.address = (U_8 *)thunkStart;
dataDescriptor.length = totalSize;
dataDescriptor.type = J9SHR_DATA_TYPE_AOTTHUNK;
dataDescriptor.flags = 0;

encodedLength = j9ThunkEncodeSignatureASCII(signatureChars, encodedSignature);

store = vm->sharedClassConfig->storeSharedData(vmThread, (const char *)encodedSignature, encodedLength, &dataDescriptor);
#endif

return store;
}

void *
j9ThunkFindPersistentThunk(J9JITConfig *jitConfig, char *signatureChars, U_32 signatureLength, UDATA *thunkSize)
{
void * thunk = NULL;

#if defined(J9VM_OPT_SHARED_CLASSES)
J9JavaVM *vm = jitConfig->javaVM;
J9VMThread *vmThread = vm->internalVMFunctions->currentVMThread(vm);

U_8 encodedSignatureArray[2 * (J9_THUNK_MAX_ENCODED_BYTES - 1)];
U_8 *encodedSignature = encodedSignatureArray;
UDATA encodedLength;

J9SharedDataDescriptor dataDescriptor;
dataDescriptor.address = NULL;

encodedLength = j9ThunkEncodeSignatureASCII(signatureChars, encodedSignature);

vm->sharedClassConfig->findSharedData(vmThread, (const char *)encodedSignature, encodedLength, J9SHR_DATA_TYPE_AOTTHUNK, FALSE, &dataDescriptor, NULL);
thunk = dataDescriptor.address;
*thunkSize = dataDescriptor.length;
#endif

return thunk;
}
37 changes: 34 additions & 3 deletions runtime/compiler/env/VMJ9.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2000, 2022 IBM Corp. and others
* Copyright (c) 2000, 2023 IBM Corp. and others
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
Expand Down Expand Up @@ -9195,13 +9195,44 @@ TR_J9SharedCacheVM::getDesignatedCodeCache(TR::Compilation *comp)
void *
TR_J9SharedCacheVM::getJ2IThunk(char *signatureChars, uint32_t signatureLength, TR::Compilation *comp)
{
return (void *)findPersistentThunk(signatureChars, signatureLength);
void *thunk = NULL;

#if defined(J9VM_INTERP_AOT_COMPILE_SUPPORT) && defined(J9VM_OPT_SHARED_CLASSES) && (defined(TR_HOST_X86) || defined(TR_HOST_POWER) || defined(TR_HOST_S390) || defined(TR_HOST_ARM) || defined(TR_HOST_ARM64))
uintptr_t length;
thunk = j9ThunkFindPersistentThunk(_jitConfig, signatureChars, signatureLength, &length);
#endif

return thunk;
}

void *
TR_J9SharedCacheVM::setJ2IThunk(char *signatureChars, uint32_t signatureLength, void *thunkptr, TR::Compilation *comp)
{
return persistThunk(signatureChars, signatureLength, (U_8*)thunkptr - 8 /* start of thunk */, *((U_32 *)((U_8*)thunkptr -8)) + 8 /* size of thunk */);
uint8_t *thunkStart = (uint8_t *)thunkptr - 8;
uint32_t totalSize = *((uint32_t *)((uint8_t *)thunkptr - 8)) + 8;

#if defined(J9VM_INTERP_AOT_COMPILE_SUPPORT) && defined(J9VM_OPT_SHARED_CLASSES) && (defined(TR_HOST_X86) || defined(TR_HOST_POWER) || defined(TR_HOST_S390) || defined(TR_HOST_ARM) || defined(TR_HOST_ARM64))
if (TR::Options::getAOTCmdLineOptions()->getOption(TR_TraceRelocatableDataDetailsCG))
{
TR_VerboseLog::writeLine("<relocatableDataThunksDetailsCG>");
TR_VerboseLog::writeLine("%.*s", signatureLength, signatureChars);
TR_VerboseLog::writeLine("thunkAddress: %p, thunkSize: %x", thunkStart, totalSize);
TR_VerboseLog::writeLine("</relocatableDataThunksDetailsCG>");
}

thunkStart = (uint8_t *)j9ThunkPersist(_jitConfig, signatureChars, signatureLength, thunkStart, totalSize);

if (!thunkStart)
{
TR::Compilation* comp = _compInfoPT->getCompilation();
if (comp)
comp->failCompilation<TR::CompilationException>("Failed to persist thunk");
else
throw TR::CompilationException();
}
#endif

return thunkStart;
}

void *
Expand Down
19 changes: 5 additions & 14 deletions runtime/compiler/runtime/RelocationRecord.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2319,21 +2319,12 @@ static TR_RelocationErrorCode relocateAndRegisterThunk(
return TR_RelocationErrorCode::relocationOK; // return successful
}

// search shared cache for thunk, copy it over and create thunk entry
J9SharedDataDescriptor firstDescriptor;
firstDescriptor.address = NULL;

javaVM->sharedClassConfig->findSharedData(reloRuntime->currentThread(),
signatureString,
signatureLength,
J9SHR_DATA_TYPE_AOTTHUNK,
false,
&firstDescriptor,
NULL);
uintptr_t thunkSize;
uint8_t *persistentThunk = (uint8_t *)j9ThunkFindPersistentThunk(jitConfig, signatureString, signatureLength, &thunkSize);

// if found thunk, then need to copy thunk into code cache, create thunk mapping, and register thunk mapping
//
if (firstDescriptor.address)
if (persistentThunk)
{
//Copy thunk from shared cache into local memory and relocate target address
//
Expand All @@ -2344,15 +2335,15 @@ static TR_RelocationErrorCode relocateAndRegisterThunk(
// allocate in the current code cache. The reason is that, when a new code cache is needed
// the reservation of the old cache is cancelled and further allocation attempts from
// the old cache (which is not switched) will fail
U_8 *thunkStart = TR::CodeCacheManager::instance()->allocateCodeMemory(firstDescriptor.length, 0, &codeCache, &coldCode, true);
U_8 *thunkStart = TR::CodeCacheManager::instance()->allocateCodeMemory(thunkSize, 0, &codeCache, &coldCode, true);
U_8 *thunkAddress;
omrthread_jit_write_protect_disable();
if (thunkStart)
{
// Relocate the thunk
//
RELO_LOG(reloRuntime->reloLogger(), 7, "\t\t\trelocateAndRegisterThunk: thunkStart from cache %p\n", thunkStart);
memcpy(thunkStart, firstDescriptor.address, firstDescriptor.length);
memcpy(thunkStart, persistentThunk, thunkSize);

thunkAddress = thunkStart + 2*sizeof(I_32);

Expand Down
12 changes: 8 additions & 4 deletions runtime/oti/jitprotos.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 1991, 2021 IBM Corp. and others
* Copyright (c) 1991, 2023 IBM Corp. and others
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
Expand Down Expand Up @@ -57,11 +57,11 @@ extern J9_CFUNC void jitDecompileMethodForFramePop (J9VMThread * currentThread
extern J9_CFUNC void jitExceptionCaught (J9VMThread * currentThread);
extern J9_CFUNC void jitSingleStepRemoved (J9VMThread * currentThread);
extern J9_CFUNC void jitDataBreakpointAdded (J9VMThread * currentThread);
extern J9_CFUNC void
extern J9_CFUNC void
jitBreakpointedMethodCompiled (J9VMThread * currentThread, J9Method * method, void * startAddress);
extern J9_CFUNC UDATA
initializeFSD (J9JavaVM * vm);
extern J9_CFUNC void
extern J9_CFUNC void
induceOSROnCurrentThread(J9VMThread * currentThread);
#if (defined(J9VM_INTERP_HOT_CODE_REPLACEMENT)) /* priv. proto (autogen) */
extern J9_CFUNC void jitHotswapOccurred (J9VMThread * currentThread);
Expand All @@ -83,6 +83,8 @@ extern J9_CFUNC void c_jitReportExceptionCatch(J9VMThread * currentThread);
extern J9_CFUNC void c_jitDecompileOnReturn(J9VMThread * currentThread);

extern J9_CFUNC void * j9ThunkLookupNameAndSig (void * jitConfig, void *parm);
extern J9_CFUNC const void * j9ThunkPersist(J9JITConfig *jitConfig, char *signatureChars, U_32 signatureLength, U_8 *thunkStart, U_32 totalSize);
extern J9_CFUNC void * j9ThunkFindPersistentThunk(J9JITConfig *jitConfig, char *signatureChars, U_32 signatureLength, UDATA *thunkSize);

extern J9_CFUNC J9JITHashTable *avl_jit_artifact_insert_existing_table (J9AVLTree * tree, J9JITHashTable * hashTable);
extern J9_CFUNC J9AVLTree * jit_allocate_artifacts (J9PortLibrary * portLibrary);
Expand All @@ -97,7 +99,7 @@ extern J9_CFUNC UDATA jitWalkStackFrames (J9StackWalkState *walkState);
*
* @return The metadata corresponding to the method which was JIT compiled at the specified PC if such a method
* exists; NULL if no such method can be found.
*
*
* @note If jitPC is NULL this function will return NULL.
*/
extern J9_CFUNC J9JITExceptionTable * jitGetExceptionTableFromPC (J9VMThread * vmThread, UDATA jitPC);
Expand All @@ -115,6 +117,8 @@ extern J9_CFUNC UDATA jit_artifact_remove (J9PortLibrary * portLibrary, J9AVLTre

/* prototypes from thunkcrt.c */
void * j9ThunkLookupNameAndSig(void * jitConfig, void *parm);
const void * j9ThunkPersist(J9JITConfig *jitConfig, char *signatureChars, U_32 signatureLength, U_8 *thunkStart, U_32 totalSize);
void * j9ThunkFindPersistentThunk(J9JITConfig *jitConfig, char *signatureChars, U_32 signatureLength, UDATA *thunkSize);
UDATA j9ThunkTableAllocate(J9JavaVM * vm);
void j9ThunkTableFree(J9JavaVM * vm);
void * j9ThunkLookupSignature(void * jitConfig, UDATA signatureLength, char *signatureChars);
Expand Down

0 comments on commit 85007bc

Please sign in to comment.