Skip to content

Commit

Permalink
Merge pull request #10955 from gacholio/mangle23
Browse files Browse the repository at this point in the history
(0.23) Support new JNI name mangling
  • Loading branch information
pshipton committed Oct 21, 2020
2 parents 5bc5d63 + 4a494dc commit b49c867
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 14 deletions.
1 change: 1 addition & 0 deletions runtime/oti/j9consts.h
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,7 @@ extern "C" {
#define J9_EXTENDED_RUNTIME2_SHOW_EXTENDED_NPEMSG 0x100
#define J9_EXTENDED_RUNTIME2_ENABLE_PORTABLE_SHARED_CACHE 0x200
#define J9_EXTENDED_RUNTIME2_ENABLE_AOT 0x400
#define J9_EXTENDED_RUNTIME2_LEGACY_MANGLING 0x800

/* TODO: Define this until the JIT removes it */
#define J9_EXTENDED_RUNTIME_ALLOW_GET_CALLER_CLASS 0
Expand Down
2 changes: 2 additions & 0 deletions runtime/oti/jvminit.h
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,8 @@ enum INIT_STAGE {
#define VMOPT_XXDISABLEPOSITIVEHASHCODE "-XX:-PositiveIdentityHash"
#define VMOPT_XXENABLEORIGINALJDK8HEAPSIZECOMPATIBILITY "-XX:+OriginalJDK8HeapSizeCompatibilityMode"
#define VMOPT_XXDISABLEORIGINALJDK8HEAPSIZECOMPATIBILITY "-XX:-OriginalJDK8HeapSizeCompatibilityMode"
#define VMOPT_XXDISABLELEGACYMANGLING "-XX:-UseLegacyJNINameEscaping"
#define VMOPT_XXENABLELEGACYMANGLING "-XX:+UseLegacyJNINameEscaping"

#if defined(J9VM_OPT_VALHALLA_VALUE_TYPES)
#define VMOPT_XXENABLEVALHALLA "-XX:+EnableValhalla"
Expand Down
60 changes: 46 additions & 14 deletions runtime/vm/bindnatv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ extern "C" {
/**
* Prototypes for locally defined functions.
*/
static IDATA mangledSize (U_8 * data, U_16 length);
static IDATA mangledSize (U_8 * data, U_16 length, BOOLEAN legacyMangling);
static void mangledData (U_8** pBuffer, U_8 * data, U_16 length);
static void nativeSignature(J9Method* nativeMethod, char *resultBuffer);
static UDATA nativeMethodHash(void *key, void *userData);
Expand Down Expand Up @@ -347,7 +347,10 @@ inlIntercept(J9VMThread *currentThread, J9Method *nativeMethod, const char *symb
* \param ramMethod The method for signature computation.
* \param ramClass The class which contains the method.
* \param nameOffset Buffer into which the mangled signature will be written.
* \return A buffer containing the mangled JNI names, separated by nulls.
* \return A buffer containing the mangled JNI names, separated by nulls
* Failure is indicated by:
* NULL (failure to allocate native memory)
* UDATA_MAX (identifiers are invalid)
*
* Sample Input:
* boolean pkg.X.foo(String,int);
Expand All @@ -365,6 +368,8 @@ buildNativeFunctionNames(J9JavaVM * javaVM, J9Method* ramMethod, J9Class* ramCla
UDATA size, shortSize;
U_8 *classNameData, *methodNameData, *methodSigData;
U_16 classNameLength, methodNameLength, methodSigLength;
IDATA tempSize = 0;
BOOLEAN legacyMangling = J9_ARE_ANY_BITS_SET(javaVM->extendedRuntimeFlags2, J9_EXTENDED_RUNTIME2_LEGACY_MANGLING);

PORT_ACCESS_FROM_JAVAVM(javaVM);

Expand All @@ -381,22 +386,36 @@ buildNativeFunctionNames(J9JavaVM * javaVM, J9Method* ramMethod, J9Class* ramCla

/* First add the common part: Java_<cls>_<name> */
size = 6;
size += mangledSize(classNameData, classNameLength);
size += mangledSize(methodNameData, methodNameLength);
tempSize = mangledSize(classNameData, classNameLength, legacyMangling);
if (tempSize < 0) {
error:
buffer = (U_8*)UDATA_MAX;
goto done;
}
size += tempSize;
tempSize = mangledSize(methodNameData, methodNameLength, legacyMangling);
if (tempSize < 0) {
goto error;
}
size += tempSize;
shortSize = size;
size <<= 1;

/* Now add for the signature part: __<parm1><parm2> */
size += 2;
size += mangledSize(methodSigData, methodSigLength);
tempSize = mangledSize(methodSigData, methodSigLength, legacyMangling);
if (tempSize < 0) {
goto error;
}
size += tempSize;

/* Null terminate both strings */
size += 2;

/* Allocate enough memory */
buffer = (U_8*)j9mem_allocate_memory(size, OMRMEM_CATEGORY_VM);
if(buffer == NULL) {
return NULL;
if (NULL == buffer) {
goto done;
}

/* Dump the long name */
Expand All @@ -414,7 +433,7 @@ buildNativeFunctionNames(J9JavaVM * javaVM, J9Method* ramMethod, J9Class* ramCla
/* Memcopy the short name from the long name */
memcpy(current, buffer, shortSize);
current[shortSize] = '\0';

done:
return buffer;
}

Expand Down Expand Up @@ -506,15 +525,16 @@ mangledData(U_8** pBuffer, U_8 * data, U_16 length)
* mangled JNI name for a method.
* \param data Method signature in canonical UTF8 form.
* \param length The number of bytes in data.
* \return The number of ASCII characters required for the mangled JNI name.
* \return The number of ASCII characters required for the mangled JNI name, or a negative value for illegal identifiers
*/
static IDATA
mangledSize(U_8 * data, U_16 length)
mangledSize(U_8 * data, U_16 length, BOOLEAN legacyMangling)
{
/* Return the size in ASCII characters of the JNI mangled version of utf
Assumes verified canonical UTF8 strings */
IDATA size;
U_16 i, ch;
BOOLEAN disallow0to3 = !legacyMangling;

size = 0;
i = 0;
Expand All @@ -525,11 +545,12 @@ mangledSize(U_8 * data, U_16 length)
break;

case ')': /* End of signature -- done */
return size;
goto done;

case '/': /* / -> _ */
size += 1;
break;
disallow0to3 = !legacyMangling;
continue;

case '_': /* _ -> _1 */
case ';': /* ; -> _2 */
Expand All @@ -548,11 +569,19 @@ mangledSize(U_8 * data, U_16 length)
/* Multibyte encoding: two or three bytes? */
i += 1;
if((ch & 0xE0) == 0xE0) i += 1;
} else {
if (disallow0to3) {
if ((ch >= (U_16)'0') && (ch <= (U_16)'3')) {
size = -1;
goto done;
}
}
size += 1;
}
else size += 1;
}
disallow0to3 = FALSE;
}

done:
return size;
}

Expand Down Expand Up @@ -807,6 +836,7 @@ nativeMethodEqual(void *leftKey, void *rightKey, void *userData)
* \warning This function may release VM access.
* \return
* J9_NATIVE_METHOD_BIND_SUCCESS on success.
* J9_NATIVE_METHOD_BIND_FAIL if native cannot be bound, or mangling is illegal.
* J9_NATIVE_METHOD_BIND_RECURSIVE if another thread is binding the method.
* J9_NATIVE_METHOD_BIND_OUT_OF_MEMORY if scratch space cannot be allocated.
*/
Expand Down Expand Up @@ -866,6 +896,8 @@ resolveNativeAddress(J9VMThread *currentThread, J9Method *nativeMethod, UDATA ru
namesBuffer = (char *) buildNativeFunctionNames(vm, nativeMethod, J9_CLASS_FROM_METHOD(nativeMethod), 0);
if (namesBuffer == NULL) {
rc = J9_NATIVE_METHOD_BIND_OUT_OF_MEMORY;
} else if (namesBuffer == (char*)UDATA_MAX) {
rc = J9_NATIVE_METHOD_BIND_FAIL;
} else {
/* exemplar.nativeMethod already set above */
/* exemplar.bindThread is set below */
Expand Down
10 changes: 10 additions & 0 deletions runtime/vm/jvminit.c
Original file line number Diff line number Diff line change
Expand Up @@ -3464,6 +3464,16 @@ processVMArgsFromFirstToLast(J9JavaVM * vm)
}
}

{
IDATA enableLegacyMangling = FIND_AND_CONSUME_ARG(EXACT_MATCH, VMOPT_XXENABLELEGACYMANGLING, NULL);
IDATA disableLegacyMangling = FIND_AND_CONSUME_ARG(EXACT_MATCH, VMOPT_XXDISABLELEGACYMANGLING, NULL);
if (enableLegacyMangling > disableLegacyMangling) {
vm->extendedRuntimeFlags2 |= J9_EXTENDED_RUNTIME2_LEGACY_MANGLING;
} else if (enableLegacyMangling < disableLegacyMangling) {
vm->extendedRuntimeFlags2 &= ~(UDATA)J9_EXTENDED_RUNTIME2_LEGACY_MANGLING;
}
}

/* -Xbootclasspath and -Xbootclasspath/p are not supported from Java 9 onwards */
if (J2SE_VERSION(vm) >= J2SE_V11) {
PORT_ACCESS_FROM_JAVAVM(vm);
Expand Down

0 comments on commit b49c867

Please sign in to comment.