Skip to content

Commit 8d34c85

Browse files
committed
wip Stable and unique Lambda and LambdaForm class names
1 parent 2f3ea37 commit 8d34c85

12 files changed

Lines changed: 129 additions & 155 deletions

runtime/bcutil/ComparingCursor.cpp

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -428,29 +428,10 @@ ComparingCursor::shouldCheckForEquality(DataType dataType, U_32 u32Value)
428428
}
429429

430430
switch (dataType) {
431-
case SRP_TO_UTF8_CLASS_NAME:
432-
#if JAVA_SPEC_VERSION < 21
433-
if (_context->isLambdaClass() && _romClassIsShared) {
434-
/*
435-
* If the class is a lambda class, don't compare the class names because lambda
436-
* classes might have different index numbers from run to run.
437-
*/
438-
return false;
439-
}
440-
#endif /* JAVA_SPEC_VERSION < 21 */
441-
break;
431+
case SRP_TO_UTF8_CLASS_NAME: /* fall through */
442432
case BYTECODE: /* fall through */
443433
case GENERIC: /* fall through */
444434
case CLASS_FILE_SIZE: /* fall through */
445-
#if JAVA_SPEC_VERSION < 21
446-
if ((CLASS_FILE_SIZE == dataType)
447-
&& _context->isLambdaClass()
448-
&& _romClassIsShared
449-
) {
450-
/* If comparing a lambda class from the shared cache, class file size comparison is already done in ROMClassBuilder::compareROMClassForEquality(). */
451-
return false;
452-
}
453-
#endif /* JAVA_SPEC_VERSION < 21 */
454435
case SRP_TO_DEBUG_DATA: /* fall through */
455436
case SRP_TO_GENERIC: /* fall through */
456437
case SRP_TO_UTF8: /* fall through */

runtime/bcutil/ROMClassBuilder.cpp

Lines changed: 9 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -277,16 +277,6 @@ ROMClassBuilder::handleAnonClassName(J9CfrClassFile *classfile, ROMClassCreation
277277
PORT_ACCESS_FROM_PORT(_portLibrary);
278278

279279
#if defined(J9VM_OPT_OPENJDK_METHODHANDLE)
280-
/*
281-
* Prevent generated LambdaForm classes from MethodHandles to be stored to the shared cache.
282-
* When there are a large number of such classes in the shared cache, they trigger a lot of class comparisons.
283-
* Performance can be much worse (compared to shared cache turned off).
284-
*/
285-
if (isLambdaFormClassName(originalStringBytes, originalStringLength, NULL/*deterministicPrefixLength*/)) {
286-
context->addFindClassFlags(J9_FINDCLASS_FLAG_DO_NOT_SHARE);
287-
context->addFindClassFlags(J9_FINDCLASS_FLAG_LAMBDAFORM);
288-
}
289-
290280
#if JAVA_SPEC_VERSION >= 15
291281
/* InjectedInvoker is a hidden class without the strong attribute set. It
292282
* is created by MethodHandleImpl.makeInjectedInvoker on the OpenJDK side.
@@ -417,22 +407,6 @@ ROMClassBuilder::handleAnonClassName(J9CfrClassFile *classfile, ROMClassCreation
417407
j9str_printf(PORTLIB, buf, ROM_ADDRESS_LENGTH + 1, ROM_ADDRESS_FORMAT, 0);
418408
memcpy(constantPool[newUtfCPEntry].bytes + newHostPackageLength + originalStringLength + 1, buf, ROM_ADDRESS_LENGTH + 1);
419409

420-
/* Mark if the class is a Lambda class. */
421-
#if defined(J9VM_OPT_OPENJDK_METHODHANDLE)
422-
if (!context->isLambdaFormClass()
423-
&& isLambdaClassName(reinterpret_cast<const char *>(_anonClassNameBuffer),
424-
newAnonClassNameLength - 1, NULL/*deterministicPrefixLength*/)
425-
) {
426-
context->addFindClassFlags(J9_FINDCLASS_FLAG_LAMBDA);
427-
}
428-
#else /* defined(J9VM_OPT_OPENJDK_METHODHANDLE) */
429-
if (isLambdaClassName(reinterpret_cast<const char *>(_anonClassNameBuffer),
430-
newAnonClassNameLength - 1, NULL/*deterministicPrefixLength*/)
431-
) {
432-
context->addFindClassFlags(J9_FINDCLASS_FLAG_LAMBDA);
433-
}
434-
#endif /* defined(J9VM_OPT_OPENJDK_METHODHANDLE) */
435-
436410
/* search constantpool for all other identical classRefs. We have not actually
437411
* tested this scenario as javac will not output more than one classRef or utfRef of the
438412
* same kind.
@@ -590,18 +564,6 @@ ROMClassBuilder::prepareAndLaydown( BufferManager *bufferManager, ClassFileParse
590564
getSizeInfo(context, &romClassWriter, &srpOffsetTable, &countDebugDataOutOfLine, &sizeInformation);
591565

592566
U_32 romSize = 0;
593-
#if JAVA_SPEC_VERSION < 21
594-
U_32 sizeToCompareForLambda = 0;
595-
if (context->isLambdaClass()) {
596-
/*
597-
* romSize calculated from getSizeInfo() does not involve StringInternManager. It is only accurate for string intern disabled classes.
598-
* Lambda classes in java 15 and up are strong hidden classes (defined with Option.STONG), which has the same lifecycle as its
599-
* defining class loader. It is string intern enabled. So pass classFileSize instead of romSize to sizeToCompareForLambda.
600-
*/
601-
sizeToCompareForLambda = classFileOracle.getClassFileSize();
602-
}
603-
#endif /* JAVA_SPEC_VERSION < 21 */
604-
605567
if (context->shouldCompareROMClassForEquality()) {
606568
ROMClassVerbosePhase v(context, CompareHashtableROMClass);
607569

@@ -624,9 +586,6 @@ ROMClassBuilder::prepareAndLaydown( BufferManager *bufferManager, ClassFileParse
624586
modifiers,
625587
extraModifiers,
626588
optionalFlags,
627-
#if JAVA_SPEC_VERSION < 21
628-
sizeToCompareForLambda,
629-
#endif /* JAVA_SPEC_VERSION < 21 */
630589
context)
631590
) {
632591
return OK;
@@ -720,9 +679,6 @@ ROMClassBuilder::prepareAndLaydown( BufferManager *bufferManager, ClassFileParse
720679
modifiers,
721680
extraModifiers,
722681
optionalFlags,
723-
#if JAVA_SPEC_VERSION < 21
724-
sizeToCompareForLambda,
725-
#endif /* JAVA_SPEC_VERSION < 21 */
726682
context)
727683

728684
) {
@@ -1479,55 +1435,19 @@ ROMClassBuilder::compareROMClassForEquality(
14791435
U_32 modifiers,
14801436
U_32 extraModifiers,
14811437
U_32 optionalFlags,
1482-
#if JAVA_SPEC_VERSION < 21
1483-
U_32 sizeToCompareForLambda,
1484-
#endif /* JAVA_SPEC_VERSION < 21 */
14851438
ROMClassCreationContext *context)
14861439
{
14871440
bool ret = false;
1441+
ComparingCursor compareCursor(_javaVM, srpOffsetTable, srpKeyProducer, classFileOracle, romClass, romClassIsShared, context);
1442+
romClassWriter->writeROMClass(&compareCursor,
1443+
&compareCursor,
1444+
&compareCursor,
1445+
NULL,
1446+
NULL,
1447+
0, modifiers, extraModifiers, optionalFlags,
1448+
ROMClassWriter::WRITE);
14881449

1489-
#if JAVA_SPEC_VERSION < 21
1490-
if (context->isLambdaClass()) {
1491-
/*
1492-
* Lambda class names are in the format of HostClassName$$Lambda$<IndexNumber>/<zeroed out ROM_ADDRESS>.
1493-
* When we reach this check, the host class names will be the same for both the classes because
1494-
* of the earlier hash-key check. So, the only difference in the size will be the difference
1495-
* between the number of digits of the index number. The same lambda class might have a
1496-
* different index number from run to run and when the number of digits of the index number
1497-
* increases by 1, classFileSize also increases by 1. The indexNumber is the counter for the number of
1498-
* lambda classes defined so far. It is an int in the JCL side. So the it cannot vary more than max
1499-
* integer vs 0, which is maxVariance (9 bytes). This check is different than the romSize check because
1500-
* when the number of digits of the index number increases by 1, classFileSize also increases by 1 but
1501-
* romSize increases by 2.
1502-
*/
1503-
int maxVariance = 9;
1504-
int variance = abs(static_cast<int>((sizeToCompareForLambda - reinterpret_cast<J9ROMClass *>(romClass)->classFileSize)));
1505-
if (variance <= maxVariance) {
1506-
ComparingCursor compareCursor(_javaVM, srpOffsetTable, srpKeyProducer, classFileOracle, romClass, romClassIsShared, context);
1507-
romClassWriter->writeROMClass(&compareCursor,
1508-
&compareCursor,
1509-
&compareCursor,
1510-
NULL,
1511-
NULL,
1512-
0, modifiers, extraModifiers, optionalFlags,
1513-
ROMClassWriter::WRITE);
1514-
1515-
ret = compareCursor.isEqual();
1516-
}
1517-
} else
1518-
#endif /* JAVA_SPEC_VERSION < 21 */
1519-
{
1520-
ComparingCursor compareCursor(_javaVM, srpOffsetTable, srpKeyProducer, classFileOracle, romClass, romClassIsShared, context);
1521-
romClassWriter->writeROMClass(&compareCursor,
1522-
&compareCursor,
1523-
&compareCursor,
1524-
NULL,
1525-
NULL,
1526-
0, modifiers, extraModifiers, optionalFlags,
1527-
ROMClassWriter::WRITE);
1528-
1529-
ret = compareCursor.isEqual();
1530-
}
1450+
ret = compareCursor.isEqual();
15311451
J9UTF8* name = J9ROMCLASS_CLASSNAME((J9ROMClass *)romClass);
15321452
Trc_BCU_compareROMClassForEquality_event(ret, J9UTF8_LENGTH(name), J9UTF8_DATA(name));
15331453
return ret;

runtime/bcutil/ROMClassBuilder.hpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -169,9 +169,6 @@ class ROMClassBuilder
169169
U_32 modifiers,
170170
U_32 extraModifiers,
171171
U_32 optionalFlags,
172-
#if JAVA_SPEC_VERSION < 21
173-
U_32 sizeToCompareForLambda,
174-
#endif /* JAVA_SPEC_VERSION < 21 */
175172
ROMClassCreationContext *context);
176173

177174
SharedCacheRangeInfo getSharedCacheSRPRangeInfo(void *address);

runtime/bcutil/ROMClassCreationContext.hpp

Lines changed: 1 addition & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -240,10 +240,6 @@ class ROMClassCreationContext
240240
bool isHiddenClassOptNestmateSet() const { return J9_ARE_ALL_BITS_SET(_findClassFlags, J9_FINDCLASS_FLAG_CLASS_OPTION_NESTMATE); }
241241
bool isHiddenClassOptStrongSet() const { return J9_ARE_ALL_BITS_SET(_findClassFlags, J9_FINDCLASS_FLAG_CLASS_OPTION_STRONG); }
242242
bool isDoNotShareClassFlagSet() const {return J9_ARE_ALL_BITS_SET(_findClassFlags, J9_FINDCLASS_FLAG_DO_NOT_SHARE);}
243-
bool isLambdaClass() const { return J9_ARE_ALL_BITS_SET(_findClassFlags, J9_FINDCLASS_FLAG_LAMBDA); }
244-
#if defined(J9VM_OPT_OPENJDK_METHODHANDLE)
245-
bool isLambdaFormClass() const { return J9_ARE_ALL_BITS_SET(_findClassFlags, J9_FINDCLASS_FLAG_LAMBDAFORM); }
246-
#endif /* defined(J9VM_OPT_OPENJDK_METHODHANDLE) */
247243

248244
bool isClassUnmodifiable() const {
249245
bool unmodifiable = false;
@@ -406,33 +402,11 @@ class ROMClassCreationContext
406402
if (NULL != _className) {
407403
U_16 classNameLenToCompare0 = static_cast<U_16>(_classNameLength);
408404
U_16 classNameLenToCompare1 = classNameLength;
409-
BOOLEAN misMatch = FALSE;
410405
if (isClassHidden()) {
411406
/* For hidden classes, className has the ROM address appended, _className does not. */
412407
classNameLenToCompare1 = static_cast<U_16>(_classNameLength);
413-
#if JAVA_SPEC_VERSION < 21
414-
if (isROMClassShareable()) {
415-
/*
416-
* Before JDK21, Lambda class names are in the format:
417-
* HostClassName$$Lambda$<IndexNumber>/<zeroed out ROM_ADDRESS>
418-
* Do not compare the IndexNumber as it can be different from run to run.
419-
*/
420-
U_8 *lambdaClass0 = reinterpret_cast<U_8 *>(getLastDollarSignOfLambdaClassName(
421-
reinterpret_cast<const char *>(_className), _classNameLength));
422-
U_8 *lambdaClass1 = reinterpret_cast<U_8 *>(getLastDollarSignOfLambdaClassName(
423-
reinterpret_cast<const char *>(className), classNameLength));
424-
if ((NULL != lambdaClass0) && (NULL != lambdaClass1)) {
425-
classNameLenToCompare0 = static_cast<U_16>(lambdaClass0 - _className + 1);
426-
classNameLenToCompare1 = static_cast<U_16>(lambdaClass1 - className + 1);
427-
} else if ((NULL == lambdaClass0) != (NULL == lambdaClass1)) {
428-
misMatch = TRUE;
429-
}
430-
}
431-
#endif /* JAVA_SPEC_VERSION < 21 */
432408
}
433-
if (misMatch
434-
|| !J9UTF8_DATA_EQUALS(_className, classNameLenToCompare0, className, classNameLenToCompare1)
435-
) {
409+
if (!J9UTF8_DATA_EQUALS(_className, classNameLenToCompare0, className, classNameLenToCompare1)) {
436410
#define J9WRONGNAME " (wrong name: "
437411
PORT_ACCESS_FROM_PORT(_portLibrary);
438412
UDATA errorStringSize = _classNameLength + sizeof(J9WRONGNAME) + 1 + classNameLength;

runtime/jcl/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,9 @@ target_link_libraries(jclse
9292
j9vm_interface
9393
j9vm_gc_includes
9494

95+
j9shrcommon
96+
j9shrutil
97+
j9zip
9598
omrsig
9699
j9hookable
97100
j9zlib

runtime/jcl/common/java_lang_invoke_MethodHandleNatives.cpp

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@
3636
#include <string.h>
3737
#include <assert.h>
3838

39+
#undef UT_MODULE_LOADED
40+
#undef UT_MODULE_UNLOADED
41+
#include "CacheMap.hpp"
3942
#include "VMHelpers.hpp"
4043

4144
extern "C" {
@@ -772,6 +775,115 @@ Java_java_lang_invoke_MethodHandleNatives_expand(JNIEnv *env, jclass clazz, jobj
772775
vmFuncs->internalExitVMToJNI(currentThread);
773776
}
774777

778+
/**
779+
* Find a Lambda or customized LambdaForm class in the SCC.
780+
* Requires non-null input arguments.
781+
* Returns a pointer to a SCC-cached ROMClass if found, otherwise nullptr.
782+
*
783+
* Throws OutOfMemoryError upon failure to allocate memory.
784+
*/
785+
jobject JNICALL
786+
Java_java_lang_invoke_MethodHandleNatives_findInSCC(JNIEnv *env, jclass clazz, jstring classnameObject, jclass lookupClass)
787+
{
788+
#if defined(J9VM_OPT_SHARED_CLASSES)
789+
#if defined(J9VM_ENV_DATA64)
790+
#define J9_ROM_ADDRESS_SUFFIX "/0x0000000000000000"
791+
#else /* defined(J9VM_ENV_DATA64) */
792+
#define J9_ROM_ADDRESS_SUFFIX "/0x00000000"
793+
#endif /* defined(J9VM_ENV_DATA64) */
794+
795+
J9VMThread *currentThread = reinterpret_cast<J9VMThread*>(env);
796+
J9JavaVM *vm = currentThread->javaVM;
797+
const J9InternalVMFunctions *vmFuncs = vm->internalVMFunctions;
798+
PORT_ACCESS_FROM_JAVAVM(vm);
799+
800+
vmFuncs->internalEnterVMFromJNI(currentThread);
801+
802+
J9Class *hostClass = J9VM_J9CLASS_FROM_HEAPCLASS(currentThread, J9_JNI_UNWRAP_REFERENCE(lookupClass));
803+
J9ClassLoader *classloader = hostClass->classLoader;
804+
if (nullptr == classloader) {
805+
vmFuncs->internalEnterVMFromJNI(currentThread);
806+
return nullptr;
807+
}
808+
809+
j9object_t classname = J9_JNI_UNWRAP_REFERENCE(classnameObject);
810+
IDATA classnameLength = vmFuncs->getStringUTF8Length(currentThread, classname);
811+
UDATA romAddressSuffixLength = LITERAL_STRLEN(J9_ROM_ADDRESS_SUFFIX);
812+
UDATA lookupKeyLength = classnameLength + romAddressSuffixLength + /* null terminator */ 1;
813+
char *lookupKey = static_cast<char *>(j9mem_allocate_memory(lookupKeyLength, OMRMEM_CATEGORY_VM));
814+
815+
/* Memory cleanup and exit routine. */
816+
auto cleanup = [=]() {
817+
if (nullptr != lookupKey) {
818+
j9mem_free_memory(lookupKey);
819+
}
820+
vmFuncs->internalExitVMToJNI(currentThread);
821+
};
822+
823+
if (nullptr == lookupKey) {
824+
vmFuncs->setNativeOutOfMemoryError(currentThread, 0, 0);
825+
cleanup();
826+
return nullptr;
827+
}
828+
829+
vmFuncs->copyStringToUTF8Helper(currentThread, classname, J9_STR_NONE, 0, classnameLength, reinterpret_cast<U_8 *>(lookupKey), classnameLength);
830+
memcpy(lookupKey + classnameLength, J9_ROM_ADDRESS_SUFFIX, romAddressSuffixLength);
831+
lookupKey[lookupKeyLength - 1] = '\0';
832+
833+
J9SharedClassConfig *sconfig = currentThread->javaVM->sharedClassConfig;
834+
if (nullptr == sconfig) {
835+
cleanup();
836+
return nullptr;
837+
}
838+
839+
SH_CacheMap* cachemap = reinterpret_cast<SH_CacheMap*>(sconfig->sharedClassCache);
840+
/* TODO Look to see if we should use a different API here. */
841+
void *iterator = nullptr;
842+
void *firstFound = nullptr;
843+
omrthread_monitor_enter(vm->classMemorySegments->segmentMutex);
844+
J9ROMClass *romClass = const_cast<J9ROMClass *>(cachemap->findNextROMClass(currentThread, iterator, firstFound, lookupKeyLength - 1, lookupKey));
845+
omrthread_monitor_exit(vm->classMemorySegments->segmentMutex);
846+
847+
if (nullptr == romClass) {
848+
cleanup();
849+
return nullptr;
850+
}
851+
852+
UDATA options = J9_FINDCLASS_FLAG_NO_CHECK_FOR_EXISTING_CLASS
853+
| J9_FINDCLASS_FLAG_THROW_ON_FAIL
854+
| J9_FINDCLASS_FLAG_UNSAFE
855+
| J9_FINDCLASS_FLAG_HIDDEN
856+
| J9_FINDCLASS_FLAG_ANON
857+
| J9_FINDCLASS_FLAG_CLASS_OPTION_NESTMATE
858+
| J9_FINDCLASS_FLAG_CLASS_OPTION_STRONG;
859+
860+
omrthread_monitor_enter(vm->classTableMutex);
861+
/* internalCreateRAMClassFromROMClass will release the classTableMutex. */
862+
J9Class *ramClass = vmFuncs->internalCreateRAMClassFromROMClass(currentThread,
863+
classloader,
864+
romClass,
865+
options,
866+
nullptr /* elementClass */,
867+
nullptr /* protectionDomain */,
868+
nullptr /* methodRemapArray */,
869+
J9_CP_INDEX_NONE,
870+
LOAD_LOCATION_UNKNOWN,
871+
nullptr /* classBeingRedefined */,
872+
hostClass);
873+
if (nullptr == ramClass || nullptr != currentThread->currentException) {
874+
cleanup();
875+
return nullptr;
876+
}
877+
878+
jobject result = vmFuncs->j9jni_createLocalRef(env, J9VM_J9CLASS_TO_HEAPCLASS(ramClass));
879+
cleanup();
880+
return result;
881+
#undef J9_ROM_ADDRESS_SUFFIX
882+
#else /* J9VM_OPT_SHARED_CLASSES */
883+
return nullptr;
884+
#endif /* J9VM_OPT_SHARED_CLASSES */
885+
}
886+
775887
/**
776888
* [JDK8] static native MemberName resolve(MemberName self, Class<?> caller)
777889
* throws LinkageError, ClassNotFoundException;

runtime/jcl/exports.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -639,6 +639,7 @@ if(J9VM_OPT_OPENJDK_METHODHANDLE)
639639
omr_add_exports(jclse
640640
Java_java_lang_invoke_MethodHandleNatives_init
641641
Java_java_lang_invoke_MethodHandleNatives_expand
642+
Java_java_lang_invoke_MethodHandleNatives_findInSCC
642643
Java_java_lang_invoke_MethodHandleNatives_resolve
643644
Java_java_lang_invoke_MethodHandleNatives_getMembers
644645
Java_java_lang_invoke_MethodHandleNatives_objectFieldOffset

runtime/jcl/uma/java_lang_invoke_MethodHandleNatives_exports.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-ex
2121
<exports group="java_lang_invoke_MethodHandleNatives">
2222
<export name="Java_java_lang_invoke_MethodHandleNatives_init" />
2323
<export name="Java_java_lang_invoke_MethodHandleNatives_expand" />
24+
<export name="Java_java_lang_invoke_MethodHandleNatives_findInSCC" />
2425
<export name="Java_java_lang_invoke_MethodHandleNatives_resolve" />
2526
<export name="Java_java_lang_invoke_MethodHandleNatives_getMembers" />
2627
<export name="Java_java_lang_invoke_MethodHandleNatives_objectFieldOffset" />

runtime/oti/j9consts.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -448,8 +448,6 @@ extern "C" {
448448
#define J9_FINDCLASS_FLAG_CLASS_OPTION_NESTMATE 0x40000
449449
#define J9_FINDCLASS_FLAG_CLASS_OPTION_STRONG 0x80000
450450
#define J9_FINDCLASS_FLAG_DO_NOT_SHARE 0x100000
451-
#define J9_FINDCLASS_FLAG_LAMBDA 0x200000
452-
#define J9_FINDCLASS_FLAG_LAMBDAFORM 0x400000
453451

454452
#define J9_FINDKNOWNCLASS_FLAG_INITIALIZE 0x1
455453
#define J9_FINDKNOWNCLASS_FLAG_EXISTING_ONLY 0x2

runtime/oti/jclprots.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -984,6 +984,7 @@ jobject JNICALL Java_java_lang_invoke_MethodType_makeTenured(JNIEnv *env, jclass
984984
#if defined(J9VM_OPT_OPENJDK_METHODHANDLE)
985985
void JNICALL Java_java_lang_invoke_MethodHandleNatives_init(JNIEnv *env, jclass clazz, jobject self, jobject ref);
986986
void JNICALL Java_java_lang_invoke_MethodHandleNatives_expand(JNIEnv *env, jclass clazz, jobject self);
987+
jobject JNICALL Java_java_lang_invoke_MethodHandleNatives_findInSCC(JNIEnv *env, jclass clazz, jstring classname, jclass lookupClass);
987988
jobject JNICALL Java_java_lang_invoke_MethodHandleNatives_resolve(
988989
#if JAVA_SPEC_VERSION == 8
989990
JNIEnv *env, jclass clazz, jobject self, jclass caller);

0 commit comments

Comments
 (0)