@@ -2303,13 +2303,6 @@ void jitDiscardPendingCompilationsOfNatives(J9VMThread *vmThread, J9Class *clazz
2303
2303
compInfo->releaseCompilationLock ();
2304
2304
}
2305
2305
2306
- static bool classesAreRedefinedInPlace ()
2307
- {
2308
- if (TR::Options::getCmdLineOptions ()->getOption (TR_EnableHCR))
2309
- return true ;
2310
- else return false ;
2311
- }
2312
-
2313
2306
static bool methodsAreRedefinedInPlace ()
2314
2307
{
2315
2308
// NOTE: making this return "true" will require careful thought.
@@ -2320,8 +2313,78 @@ static bool methodsAreRedefinedInPlace()
2320
2313
return false ;
2321
2314
}
2322
2315
2323
- // Hack markers
2324
- #define VM_PASSES_SAME_CLASS_TWICE 1
2316
+ namespace { // file-local
2317
+
2318
+ /* *
2319
+ * \brief A pair of corresponding classes related by redefinition,
2320
+ * distinguished from each other in two ways: old/new and fresh/stale.
2321
+ *
2322
+ * NOTE: Neither set of terminology, i.e. neither old/new nor fresh/stale as
2323
+ * used here, is necessarily consistent with terminology elsewhere in the VM.
2324
+ */
2325
+ struct ElaboratedClassPair
2326
+ {
2327
+ /* *
2328
+ * \brief The original class that existed before HCR.
2329
+ *
2330
+ * This is always different from newClass.
2331
+ */
2332
+ TR_OpaqueClassBlock *oldClass;
2333
+
2334
+ /* *
2335
+ * \brief The class that was created in order to carry out HCR.
2336
+ *
2337
+ * This is always different from oldClass.
2338
+ */
2339
+ TR_OpaqueClassBlock *newClass;
2340
+
2341
+ /* *
2342
+ * \brief The class whose methods have the old bytecode.
2343
+ *
2344
+ * This is always different from freshClass. It is equal to newClass if the
2345
+ * class has been redefined in-place, and oldClass otherwise.
2346
+ */
2347
+ TR_OpaqueClassBlock *staleClass;
2348
+
2349
+ /* *
2350
+ * \brief The class whose methods have the new bytecode.
2351
+ *
2352
+ * This is always different from staleClass. It is equal to oldClass if the
2353
+ * class has been redefined in-place, and newClass otherwise.
2354
+ */
2355
+ TR_OpaqueClassBlock *freshClass;
2356
+ };
2357
+
2358
+ void setElaboratedClassPair (ElaboratedClassPair *ecp, J9JITRedefinedClass *classPair)
2359
+ {
2360
+ // The VM tells us the old J9Class and the fresh one (which here it calls "new").
2361
+ J9Class *oldJ9Class = classPair->oldClass ;
2362
+ J9Class *freshJ9Class = classPair->newClass ;
2363
+ J9Class *staleJ9Class = freshJ9Class->replacedClass ;
2364
+
2365
+ ecp->oldClass = TR::Compiler->cls .convertClassPtrToClassOffset (oldJ9Class);
2366
+ ecp->freshClass = TR::Compiler->cls .convertClassPtrToClassOffset (freshJ9Class);
2367
+ ecp->staleClass = TR::Compiler->cls .convertClassPtrToClassOffset (staleJ9Class);
2368
+
2369
+ TR_ASSERT_FATAL (
2370
+ ecp->freshClass != ecp->staleClass ,
2371
+ " fresh and stale classes are the same: %p" ,
2372
+ ecp->freshClass );
2373
+
2374
+ TR_ASSERT_FATAL (
2375
+ ecp->oldClass == ecp->freshClass || ecp->oldClass == ecp->staleClass ,
2376
+ " oldClass %p matches neither freshClass %p nor staleClass %p" ,
2377
+ ecp->oldClass ,
2378
+ ecp->freshClass ,
2379
+ ecp->staleClass );
2380
+
2381
+ // Don't try to predict whether classes should be redefined in-place.
2382
+ // Instead just check whether this one was in fact redefined in-place.
2383
+ ecp->newClass =
2384
+ ecp->oldClass == ecp->freshClass ? ecp->staleClass : ecp->freshClass ;
2385
+ }
2386
+
2387
+ } // anonymous namespace
2325
2388
2326
2389
#if (defined(TR_HOST_X86) || defined(TR_HOST_POWER) || defined(TR_HOST_S390) || defined(TR_HOST_ARM) || defined(TR_HOST_ARM64))
2327
2390
void jitClassesRedefined (J9VMThread * currentThread, UDATA classCount, J9JITRedefinedClass *classList, UDATA extensionsUsed)
@@ -2343,23 +2406,19 @@ void jitClassesRedefined(J9VMThread * currentThread, UDATA classCount, J9JITRede
2343
2406
2344
2407
TR_RuntimeAssumptionTable * rat = compInfo->getPersistentInfo ()->getRuntimeAssumptionTable ();
2345
2408
2346
- TR_OpaqueClassBlock *oldClass, *newClass;
2347
- J9Method *oldMethod, *newMethod;
2409
+ ElaboratedClassPair elaboratedPair = {};
2348
2410
2349
- // A few definitions. In the jit's terminology:
2350
- // The "stale method" is the one that points at the old bytecodes from before the hot swap.
2351
- // The "stale class" is the one that points at the stale methods.
2352
- // The "old class" is the j9class struct that existed before the hot swap.
2353
- // The "new class" is the one created in response to the hot swap.
2354
- //
2355
- // NOTE: THIS MAY NOT MATCH THE VM'S TERMINOLOGY!
2356
- //
2357
- // Here we define various aliases so we can freely use the terminology we want.
2358
- //
2359
- TR_OpaqueClassBlock *&freshClass = classesAreRedefinedInPlace ()? oldClass : newClass;
2360
- TR_OpaqueClassBlock *&staleClass = classesAreRedefinedInPlace ()? newClass : oldClass;
2361
- J9Method *&freshMethod = methodsAreRedefinedInPlace ()? oldMethod : newMethod;
2362
- J9Method *&staleMethod = methodsAreRedefinedInPlace ()? newMethod : oldMethod;
2411
+ // Local aliases to avoid elaboratedPair.someClass everywhere.
2412
+ // These will reflect changes to elaboratedPair.
2413
+ TR_OpaqueClassBlock * const &oldClass = elaboratedPair.oldClass ;
2414
+ TR_OpaqueClassBlock * const &newClass = elaboratedPair.newClass ;
2415
+ TR_OpaqueClassBlock * const &staleClass = elaboratedPair.staleClass ;
2416
+ TR_OpaqueClassBlock * const &freshClass = elaboratedPair.freshClass ;
2417
+
2418
+ // Here old/new and stale/fresh have the same meaning as in ElaboratedClassPair.
2419
+ J9Method *oldMethod, *newMethod;
2420
+ J9Method *&freshMethod = methodsAreRedefinedInPlace () ? oldMethod : newMethod;
2421
+ J9Method *&staleMethod = methodsAreRedefinedInPlace () ? newMethod : oldMethod;
2363
2422
2364
2423
int methodCount;
2365
2424
J9JITMethodEquivalence *methodList;
@@ -2375,11 +2434,7 @@ void jitClassesRedefined(J9VMThread * currentThread, UDATA classCount, J9JITRede
2375
2434
{
2376
2435
for (i = 0 ; i < classCount; i++)
2377
2436
{
2378
- freshClass = ((TR_J9VMBase *)fe)->convertClassPtrToClassOffset (classPair->newClass );
2379
- if (VM_PASSES_SAME_CLASS_TWICE)
2380
- staleClass = ((TR_J9VMBase *)fe)->convertClassPtrToClassOffset (((J9Class*)freshClass)->replacedClass );
2381
- else
2382
- staleClass = ((TR_J9VMBase *)fe)->convertClassPtrToClassOffset (classPair->oldClass );
2437
+ setElaboratedClassPair (&elaboratedPair, classPair); // affects oldClass, etc.
2383
2438
methodCount = classPair->methodCount ;
2384
2439
methodList = classPair->methodList ;
2385
2440
@@ -2472,11 +2527,8 @@ void jitClassesRedefined(J9VMThread * currentThread, UDATA classCount, J9JITRede
2472
2527
deserializer->invalidateClass (currentThread, classPair->oldClass );
2473
2528
}
2474
2529
#endif
2475
- freshClass = ((TR_J9VMBase *)fe)->convertClassPtrToClassOffset (classPair->newClass );
2476
- if (VM_PASSES_SAME_CLASS_TWICE)
2477
- staleClass = ((TR_J9VMBase *)fe)->convertClassPtrToClassOffset (((J9Class*)freshClass)->replacedClass );
2478
- else
2479
- staleClass = ((TR_J9VMBase *)fe)->convertClassPtrToClassOffset (classPair->oldClass );
2530
+
2531
+ setElaboratedClassPair (&elaboratedPair, classPair); // affects oldClass, etc.
2480
2532
methodCount = classPair->methodCount ;
2481
2533
methodList = classPair->methodList ;
2482
2534
0 commit comments