@@ -61,7 +61,7 @@ extern J9JavaVM *BFUjavaVM; /* from jvm.c */
61
61
* b) If performing a hash operation, it assumes the caller has already locked vm->classLoaderModuleAndLocationMutex
62
62
*/
63
63
static UDATA hashPackageTableDelete (J9VMThread * currentThread , J9ClassLoader * classLoader , const char * packageName );
64
- static J9Package * createPackage (J9VMThread * currentThread , J9Module * fromModule , const char * package );
64
+ static J9Package * createPackage (J9VMThread * currentThread , J9Module * fromModule , J9UTF8 * package );
65
65
static void freePackageDefinition (J9VMThread * currentThread , J9ClassLoader * classLoader , const char * packageName );
66
66
static BOOLEAN removePackageDefinition (J9VMThread * currentThread , J9Module * fromModule , const char * packageName );
67
67
static BOOLEAN addPackageDefinition (J9VMThread * currentThread , J9Module * fromModule , const char * package );
@@ -80,9 +80,12 @@ static void trcModulesAddModuleExports(J9VMThread * currentThread, J9Module * fr
80
80
static void trcModulesAddModulePackage (J9VMThread * currentThread , J9Module * j9mod , const char * package );
81
81
static UDATA hashTableAtPut (J9HashTable * table , void * value , BOOLEAN collisionIsFailure );
82
82
static void throwExceptionHelper (J9VMThread * currentThread , UDATA errCode );
83
- static void freePackage (J9VMThread * currentThread , J9Package * j9package );
83
+ static void freePackage (J9VMThread * currentThread , J9Package * j9package );
84
84
static J9ClassLoader * getModuleObjectClassLoader (J9VMThread * currentThread , j9object_t moduleObject );
85
85
static J9Module * createModule (J9VMThread * currentThread , j9object_t moduleObject , J9ClassLoader * classLoader , J9UTF8 * moduleName );
86
+ #if defined(J9VM_OPT_SNAPSHOTS )
87
+ static J9Module * restoreModule (J9VMThread * currentThread , J9ClassLoader * classLoader , J9UTF8 * moduleName , j9object_t moduleObject , jstring moduleVersion );
88
+ #endif /* defined(J9VM_OPT_SNAPSHOTS) */
86
89
static J9Module * getJ9Module (J9VMThread * currentThread , jobject module );
87
90
static BOOLEAN isModuleNameValid (j9object_t moduleName );
88
91
static BOOLEAN isModuleJavaBase (j9object_t moduleName );
@@ -200,37 +203,41 @@ throwExceptionHelper(J9VMThread *currentThread, UDATA errCode)
200
203
}
201
204
202
205
static void
203
- freePackage (J9VMThread * currentThread , J9Package * j9package )
206
+ freePackage (J9VMThread * currentThread , J9Package * j9package )
204
207
{
205
208
if (NULL != j9package ) {
206
- J9JavaVM * const vm = currentThread -> javaVM ;
209
+ J9JavaVM * const vm = currentThread -> javaVM ;
207
210
PORT_ACCESS_FROM_JAVAVM (vm );
208
211
209
212
if (NULL != j9package -> exportsHashTable ) {
210
213
hashTableFree (j9package -> exportsHashTable );
211
214
}
212
- j9mem_free_memory ((void * ) j9package -> packageName );
215
+ #if defined(J9VM_OPT_SNAPSHOTS )
216
+ if (IS_SNAPSHOTTING_ENABLED (vm )) {
217
+ VMSNAPSHOTIMPLPORT_ACCESS_FROM_JAVAVM (vm );
218
+ vmsnapshot_free_memory ((void * )j9package -> packageName );
219
+ } else
220
+ #endif /* defined(J9VM_OPT_SNAPSHOTS) */
221
+ {
222
+ j9mem_free_memory ((void * )j9package -> packageName );
223
+ }
213
224
pool_removeElement (vm -> modularityPool , j9package );
214
225
}
215
226
}
216
227
217
228
static J9Package *
218
- createPackage (J9VMThread * currentThread , J9Module * fromModule , const char * package )
229
+ createPackage (J9VMThread * currentThread , J9Module * fromModule , J9UTF8 * packageName )
219
230
{
220
- J9JavaVM * const vm = currentThread -> javaVM ;
221
- J9InternalVMFunctions const * const vmFuncs = vm -> internalVMFunctions ;
222
- J9Package * retval = NULL ;
231
+ J9JavaVM * const vm = currentThread -> javaVM ;
232
+ J9InternalVMFunctions const * const vmFuncs = vm -> internalVMFunctions ;
233
+ J9Package * retval = NULL ;
223
234
224
- J9ClassLoader * const classLoader = fromModule -> classLoader ;
225
- J9Package * j9package = pool_newElement (vm -> modularityPool );
235
+ J9Package * j9package = pool_newElement (vm -> modularityPool );
226
236
227
237
if (NULL != j9package ) {
228
238
j9package -> module = fromModule ;
229
239
j9package -> classLoader = fromModule -> classLoader ;
230
- if (!addUTFNameToPackage (currentThread , j9package , package , NULL , 0 )) {
231
- freePackage (currentThread , j9package );
232
- return retval ;
233
- }
240
+ j9package -> packageName = packageName ;
234
241
j9package -> exportsHashTable = vmFuncs -> hashModulePointerTableNew (vm , INITIAL_INTERNAL_MODULE_HASHTABLE_SIZE );
235
242
if (NULL != j9package -> exportsHashTable ) {
236
243
retval = j9package ;
@@ -315,6 +322,107 @@ createModule(J9VMThread *currentThread, j9object_t moduleObject, J9ClassLoader *
315
322
return retval ;
316
323
}
317
324
325
+ #if defined(J9VM_OPT_SNAPSHOTS )
326
+ static J9Module *
327
+ restoreModule (J9VMThread * currentThread , J9ClassLoader * classLoader , J9UTF8 * moduleName , j9object_t moduleObject , jstring moduleVersion )
328
+ {
329
+ J9JavaVM * vm = currentThread -> javaVM ;
330
+ J9InternalVMFunctions const * const vmFuncs = vm -> internalVMFunctions ;
331
+ J9ClassLoader * systemClassLoader = vm -> systemClassLoader ;
332
+ BOOLEAN firstModule = J9_ARE_NO_BITS_SET (vm -> runtimeFlags , J9_RUNTIME_JAVA_BASE_MODULE_CREATED );
333
+ J9Module * ret = NULL ;
334
+ PORT_ACCESS_FROM_VMC (currentThread );
335
+
336
+ J9Module * module = hashModuleTableAtWithUTF8Name (currentThread , classLoader , moduleName );
337
+
338
+ if (NULL != module ) {
339
+ const char * moduleNameData = (const char * )J9UTF8_DATA (moduleName );
340
+ module -> moduleObject = moduleObject ;
341
+ /* Bind J9Module and module object via the hidden field. */
342
+ J9OBJECT_ADDRESS_STORE (currentThread , moduleObject , vm -> modulePointerOffset , module );
343
+
344
+ if (NULL != moduleVersion ) {
345
+ module -> version = J9_JNI_UNWRAP_REFERENCE (moduleVersion );
346
+ }
347
+
348
+ if (firstModule ) {
349
+ /* The first module must be "java.base". */
350
+ J9ClassWalkState classWalkState = {0 };
351
+ J9Class * clazz = NULL ;
352
+
353
+ Assert_SC_true (0 == strcmp (moduleNameData , JAVA_BASE_MODULE ));
354
+
355
+ clazz = vmFuncs -> allClassesStartDo (& classWalkState , vm , systemClassLoader );
356
+ /* TODO: There are clazz objects from systemClassLoader that are not in the java.base
357
+ * module (e.g. other modules include openj9.jvm and jdk.proxy1). For now, rather than
358
+ * asserting like the non-persisted path, do a string compare with the moduleName so
359
+ * that only the proper clazz->classObjects are being restored.
360
+ * Revisit this to ensure proper functionality. Also, clean this up. There is duplicated
361
+ * code with with non-restore (and else) path.
362
+ */
363
+ while (NULL != clazz ) {
364
+ J9Module * clazzModule = clazz -> module ;
365
+
366
+ if (NULL != clazzModule ) {
367
+ const char * clazzModuleName = (const char * )J9UTF8_DATA (clazzModule -> moduleName );
368
+
369
+ if (0 == strcmp (clazzModuleName , JAVA_BASE_MODULE )) {
370
+ J9VMJAVALANGCLASS_SET_MODULE (currentThread , clazz -> classObject , moduleObject );
371
+ } else {
372
+ if (classLoader == systemClassLoader ) {
373
+ const char * moduleName = "openj9.sharedclasses" ;
374
+
375
+ if (0 == strcmp (moduleNameData , moduleName )) {
376
+ J9VMDllLoadInfo * entry = FIND_DLL_TABLE_ENTRY (J9_SHARED_DLL_NAME );
377
+
378
+ if ((NULL == entry ) || (J9_ARE_ALL_BITS_SET (entry -> loadFlags , FAILED_TO_LOAD ))) {
379
+ j9nls_printf (PORTLIB , J9NLS_WARNING , J9NLS_VM_FAILED_TO_LOAD_MODULE_REQUIRED_DLL , J9_SHARED_DLL_NAME , moduleName );
380
+ }
381
+ }
382
+ }
383
+ }
384
+ }
385
+ clazz = vmFuncs -> allClassesNextDo (& classWalkState );
386
+ }
387
+ vmFuncs -> allClassesEndDo (& classWalkState );
388
+
389
+ if (vm -> anonClassCount > 0 ) {
390
+ J9ClassWalkState classWalkStateAnon = {0 };
391
+ J9Class * clazzAnon = NULL ;
392
+
393
+ Assert_SC_notNull (vm -> anonClassLoader );
394
+ clazzAnon = vmFuncs -> allClassesStartDo (& classWalkStateAnon , vm , vm -> anonClassLoader );
395
+ while (NULL != clazzAnon ) {
396
+ Assert_SC_true (clazzAnon -> module == vm -> javaBaseModule );
397
+ J9VMJAVALANGCLASS_SET_MODULE (currentThread , clazzAnon -> classObject , moduleObject );
398
+ clazzAnon = vmFuncs -> allClassesNextDo (& classWalkStateAnon );
399
+ }
400
+ vmFuncs -> allClassesEndDo (& classWalkStateAnon );
401
+ }
402
+ vm -> runtimeFlags |= J9_RUNTIME_JAVA_BASE_MODULE_CREATED ;
403
+ Trc_MODULE_defineModule (currentThread , "java.base" , module );
404
+ } else {
405
+ Trc_MODULE_defineModule (currentThread , moduleNameData , module );
406
+ if (classLoader == systemClassLoader ) {
407
+ const char * moduleName = "openj9.sharedclasses" ;
408
+
409
+ if (0 == strcmp (moduleNameData , moduleName )) {
410
+ J9VMDllLoadInfo * entry = FIND_DLL_TABLE_ENTRY (J9_SHARED_DLL_NAME );
411
+
412
+ if ((NULL == entry ) || (J9_ARE_ALL_BITS_SET (entry -> loadFlags , FAILED_TO_LOAD ))) {
413
+ j9nls_printf (PORTLIB , J9NLS_WARNING , J9NLS_VM_FAILED_TO_LOAD_MODULE_REQUIRED_DLL , J9_SHARED_DLL_NAME , moduleName );
414
+ }
415
+ }
416
+ }
417
+ }
418
+ TRIGGER_J9HOOK_VM_MODULE_LOAD (vm -> hookInterface , currentThread , module );
419
+ ret = module ;
420
+ }
421
+
422
+ return ret ;
423
+ }
424
+ #endif /* defined(J9VM_OPT_SNAPSHOTS) */
425
+
318
426
static void
319
427
freePackageDefinition (J9VMThread * currentThread , J9ClassLoader * classLoader , const char * packageName )
320
428
{
@@ -348,13 +456,54 @@ trcModulesCreationPackage(J9VMThread *currentThread, J9Module *fromModule, const
348
456
}
349
457
350
458
static BOOLEAN
351
- addPackageDefinition (J9VMThread * currentThread , J9Module * fromModule , const char * package )
459
+ addPackageDefinition (J9VMThread * currentThread , J9Module * fromModule , const char * package )
352
460
{
353
- J9ClassLoader * const classLoader = fromModule -> classLoader ;
461
+ J9JavaVM * vm = currentThread -> javaVM ;
462
+ J9InternalVMFunctions const * const vmFuncs = vm -> internalVMFunctions ;
463
+ J9ClassLoader * const classLoader = fromModule -> classLoader ;
354
464
355
465
BOOLEAN retval = FALSE;
356
466
357
- J9Package * j9package = createPackage (currentThread , fromModule , package );
467
+ PORT_ACCESS_FROM_VMC (currentThread );
468
+ #if defined(J9VM_OPT_SNAPSHOTS )
469
+ VMSNAPSHOTIMPLPORT_ACCESS_FROM_JAVAVM (vm );
470
+ #endif /* defined(J9VM_OPT_SNAPSHOTS) */
471
+ J9Package * j9package = NULL ;
472
+ J9UTF8 * packageName = NULL ;
473
+ UDATA packageNameLength = strlen (package );
474
+ if (packageNameLength < J9VM_PACKAGE_NAME_BUFFER_LENGTH ) {
475
+ UDATA packageNameJ9UTF8Size = packageNameLength + sizeof (J9UTF8 ) + 1 ; /* +1 for null-terminator. */
476
+ #if defined(J9VM_OPT_SNAPSHOTS )
477
+ if (IS_SNAPSHOTTING_ENABLED (vm )) {
478
+ packageName = (J9UTF8 * )vmsnapshot_allocate_memory (packageNameJ9UTF8Size , OMRMEM_CATEGORY_VM );
479
+ } else
480
+ #endif /* defined(J9VM_OPT_SNAPSHOTS) */
481
+ {
482
+ packageName = (J9UTF8 * )j9mem_allocate_memory (packageNameJ9UTF8Size , OMRMEM_CATEGORY_VM );
483
+ }
484
+ if (NULL == packageName ) {
485
+ vmFuncs -> setNativeOutOfMemoryError (currentThread , 0 , 0 );
486
+ return retval ;
487
+ }
488
+ memcpy (J9UTF8_DATA (packageName ), (void * )package , packageNameLength );
489
+ J9UTF8_DATA (packageName )[packageNameLength ] = '\0' ;
490
+ J9UTF8_SET_LENGTH (packageName , (U_16 )packageNameLength );
491
+ } else {
492
+ vmFuncs -> setCurrentExceptionUTF (currentThread , J9VMCONSTANTPOOL_JAVALANGINTERNALERROR , NULL );
493
+ return retval ;
494
+ }
495
+
496
+ #if defined(J9VM_OPT_SNAPSHOTS )
497
+ if (IS_RESTORE_RUN (vm )) {
498
+ j9package = hashPackageTableAtWithUTF8Name (currentThread , classLoader , packageName );
499
+ if (NULL != j9package ) {
500
+ vmsnapshot_free_memory (packageName );
501
+ return TRUE;
502
+ }
503
+ }
504
+ #endif /* defined(J9VM_OPT_SNAPSHOTS) */
505
+
506
+ j9package = createPackage (currentThread , fromModule , packageName );
358
507
359
508
if (NULL != j9package ) {
360
509
Trc_MODULE_invokeHashTableAtPut (currentThread , "addPackageDefinition" , classLoader , classLoader -> packageHashTable , & j9package , j9package , "true" );
@@ -810,8 +959,17 @@ JVM_DefineModule(JNIEnv * env, jobject module, jboolean isOpen, jstring version,
810
959
/* An exception should be pending if classLoader is null */
811
960
Assert_SC_true (NULL != currentThread -> currentException );
812
961
} else {
813
- J9UTF8 * moduleName = vmFuncs -> copyStringToJ9UTF8WithMemAlloc (
814
- currentThread , moduleNameObject , J9_STR_NULL_TERMINATE_RESULT , "" , 0 , NULL , 0 );
962
+ J9UTF8 * moduleName = NULL ;
963
+ #if defined(J9VM_OPT_SNAPSHOTS )
964
+ if (IS_SNAPSHOTTING_ENABLED (vm )) {
965
+ moduleName = vmFuncs -> copyStringToJ9UTF8WithPortLib (
966
+ currentThread , moduleNameObject , J9_STR_NULL_TERMINATE_RESULT , "" , 0 , VMSNAPSHOTIMPL_OMRPORT_FROM_JAVAVM (vm ));
967
+ } else
968
+ #endif /* defined(J9VM_OPT_SNAPSHOTS) */
969
+ {
970
+ moduleName = vmFuncs -> copyStringToJ9UTF8WithMemAlloc (
971
+ currentThread , moduleNameObject , J9_STR_NULL_TERMINATE_RESULT , "" , 0 , NULL , 0 );
972
+ }
815
973
if (NULL == moduleName ) {
816
974
vmFuncs -> setNativeOutOfMemoryError (currentThread , 0 , 0 );
817
975
goto done ;
@@ -820,7 +978,18 @@ JVM_DefineModule(JNIEnv * env, jobject module, jboolean isOpen, jstring version,
820
978
if ((classLoader != systemClassLoader ) && (0 == strcmp (moduleNameData , JAVA_BASE_MODULE ))) {
821
979
vmFuncs -> setCurrentExceptionNLS (currentThread , J9VMCONSTANTPOOL_JAVALANGLAYERINSTANTIATIONEXCEPTION , J9NLS_VM_ONLY_BOOTCLASSLOADER_LOAD_MODULE_JAVABASE );
822
980
} else {
823
- J9Module * j9mod = createModule (currentThread , modObj , classLoader , moduleName );
981
+ J9Module * j9mod = NULL ;
982
+
983
+ #if defined(J9VM_OPT_SNAPSHOTS )
984
+ if (IS_RESTORE_RUN (vm )) {
985
+ j9mod = restoreModule (currentThread , classLoader , moduleName , modObj , version );
986
+ if (NULL != j9mod ) {
987
+ goto done ;
988
+ }
989
+ }
990
+ #endif /* defined(J9VM_OPT_SNAPSHOTS) */
991
+
992
+ j9mod = createModule (currentThread , modObj , classLoader , moduleName );
824
993
if (NULL != j9mod ) {
825
994
BOOLEAN success = FALSE;
826
995
UDATA rc = addModuleDefinition (currentThread , j9mod , packages , (U_32 ) numPackages , version );
@@ -1488,13 +1657,28 @@ JVM_SetBootLoaderUnnamedModule(JNIEnv *env, jobject module)
1488
1657
} else if (NULL != unnamedModuleForSystemLoader -> moduleObject ) {
1489
1658
vmFuncs -> setCurrentExceptionUTF (currentThread , J9VMCONSTANTPOOL_JAVALANGINTERNALERROR , "module is already set in the unnamedModuleForSystemLoader" );
1490
1659
} else {
1491
- J9Module * j9mod = createModule (currentThread , modObj , systemClassLoader , NULL /* NULL name field */ );
1660
+ J9Module * j9mod = NULL ;
1661
+ if (IS_RESTORE_RUN (vm )) {
1662
+ j9mod = unnamedModuleForSystemLoader ;
1663
+ /* Bind J9Module and module object via the hidden field. */
1664
+ J9OBJECT_ADDRESS_STORE (currentThread , modObj , vm -> modulePointerOffset , j9mod );
1665
+ } else {
1666
+ j9mod = createModule (currentThread , modObj , systemClassLoader , NULL /* NULL name field */ );
1667
+ }
1492
1668
unnamedModuleForSystemLoader -> moduleObject = modObj ;
1493
1669
Trc_MODULE_setUnnamedModuleForSystemLoaderModuleObject (currentThread , j9mod , unnamedModuleForSystemLoader );
1494
1670
}
1495
1671
#else /* JAVA_SPEC_VERSION >= 21 */
1496
1672
if (NULL == J9VMJAVALANGCLASSLOADER_UNNAMEDMODULE (currentThread , systemClassLoader -> classLoaderObject )) {
1497
- J9Module * j9mod = createModule (currentThread , modObj , systemClassLoader , NULL /* NULL name field */ );
1673
+ J9Module * j9mod = NULL ;
1674
+ if (IS_RESTORE_RUN (vm )) {
1675
+ j9mod = vm -> unnamedModuleForSystemLoader ;
1676
+ vm -> unnamedModuleForSystemLoader -> moduleObject = modObj ;
1677
+ /* Bind J9Module and module object via the hidden field. */
1678
+ J9OBJECT_ADDRESS_STORE (currentThread , modObj , vm -> modulePointerOffset , j9mod );
1679
+ } else {
1680
+ j9mod = createModule (currentThread , modObj , systemClassLoader , NULL /* NULL name field */ );
1681
+ }
1498
1682
J9VMJAVALANGCLASSLOADER_SET_UNNAMEDMODULE (currentThread , systemClassLoader -> classLoaderObject , modObj );
1499
1683
Trc_MODULE_setBootloaderUnnamedModule (currentThread , j9mod );
1500
1684
} else {
0 commit comments