@@ -57,6 +57,8 @@ static UDATA classLocationHashEqualFn(void *leftKey, void *rightKey, void *userD
57
57
58
58
static void addLocationGeneratedClass (J9VMThread * vmThread , J9ClassLoader * classLoader , KeyHashTableClassEntry * existingPackageEntry , IDATA entryIndex , I_32 locationType );
59
59
60
+ static BOOLEAN isMHProxyPackage (J9ROMClass * romClass );
61
+
60
62
#if defined(J9_EXTENDED_DEBUG )
61
63
static void checkClassAlignment (J9Class * clazz , char const * caller )
62
64
{
@@ -439,6 +441,28 @@ hashClassTableDelete(J9ClassLoader *classLoader, U_8 *className, UDATA className
439
441
return hashTableRemove (table , & key );
440
442
}
441
443
444
+ UDATA
445
+ hashClassTablePackageDelete (J9VMThread * vmThread , J9ClassLoader * classLoader , J9ROMClass * romClass )
446
+ {
447
+ if (isMHProxyPackage (romClass )) {
448
+ /* This generated package only exists for one hidden class and should be
449
+ * removed when its rom class is unloaded. hashClassTable package id's rely
450
+ * on there being a valid rom class.
451
+ */
452
+ UDATA result = 0 ;
453
+ KeyHashTableClassEntry key ;
454
+ key .tag = (UDATA )romClass | TAG_ROM_CLASS ;
455
+ omrthread_monitor_enter (vmThread -> javaVM -> classTableMutex );
456
+ result = hashTableRemove (classLoader -> classHashTable , & key );
457
+ J9UTF8 * className = J9ROMCLASS_CLASSNAME (romClass );
458
+ Trc_VM_hashClassTablePackageDelete (vmThread , romClass , J9UTF8_LENGTH (className ), J9UTF8_DATA (className ));
459
+ omrthread_monitor_exit (vmThread -> javaVM -> classTableMutex );
460
+ return result ;
461
+ } else {
462
+ return 0 ;
463
+ }
464
+ }
465
+
442
466
void
443
467
hashClassTableReplace (J9VMThread * vmThread , J9ClassLoader * classLoader , J9Class * originalClass , J9Class * replacementClass )
444
468
{
@@ -543,6 +567,16 @@ hashClassTableNextDo(J9HashTableState *walkState)
543
567
return (NULL == next ) ? NULL : next -> ramClass ;
544
568
}
545
569
570
+ static BOOLEAN
571
+ isMHProxyPackage (J9ROMClass * romClass ) {
572
+ const char * mhproxy = "jdk/MHProxy" ;
573
+ /* Classes that are not strongly tied to the classloader will have
574
+ * J9AccClassAnonClass set. See java.lang.invoke.MethodHandles
575
+ */
576
+ return _J9ROMCLASS_J9MODIFIER_IS_SET (romClass , J9AccClassAnonClass ) &&
577
+ J9UTF8_LITERAL_EQUALS (J9UTF8_DATA (J9ROMCLASS_CLASSNAME (romClass )), sizeof (mhproxy ) - 1 , mhproxy );
578
+ }
579
+
546
580
UDATA
547
581
hashPkgTableIDFor (J9VMThread * vmThread , J9ClassLoader * classLoader , J9ROMClass * romClass , IDATA entryIndex , I_32 locationType )
548
582
{
@@ -567,6 +601,16 @@ hashPkgTableIDFor(J9VMThread *vmThread, J9ClassLoader *classLoader, J9ROMClass *
567
601
KeyHashTableClassEntry * result = NULL ;
568
602
BOOLEAN peekOnly = (J9_CP_INDEX_PEEK == entryIndex );
569
603
604
+ #if JAVA_SPEC_VERSION >= 22
605
+ /* OpenJ9 issue 18907 fix rely's on this assertion.
606
+ * Generated package names for hidden classes have a
607
+ * one to one relationship with the generated class.
608
+ */
609
+ if (isMHProxyPackage (romClass )) {
610
+ Assert_VM_true (NULL == hashTableFind (table , & key ));
611
+ }
612
+ #endif /* JAVA_SPEC_VERSION >= 22 */
613
+
570
614
if (peekOnly ) {
571
615
result = hashTableFind (table , & key );
572
616
if (NULL == result ) {
0 commit comments