Skip to content

Commit 747e541

Browse files
authored
Merge pull request #19606 from hzongaro/inline-getComponentType-access-classDepthAndFlags-0.46.0
[0.46.0] Inline Class.getComponentType and refactor IL generation to access classDepthAndFlags field of j9Class
2 parents ba64f88 + 8d862c6 commit 747e541

File tree

9 files changed

+235
-56
lines changed

9 files changed

+235
-56
lines changed

runtime/compiler/compile/J9SymbolReferenceTable.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1311,14 +1311,20 @@ J9::SymbolReferenceTable::findOrCreateClassFlagsSymbolRef()
13111311
TR::SymbolReference *
13121312
J9::SymbolReferenceTable::findOrCreateClassAndDepthFlagsSymbolRef()
13131313
{
1314-
if (!element(isClassAndDepthFlagsSymbol))
1314+
return self()->findOrCreateClassDepthAndFlagsSymbolRef();
1315+
}
1316+
1317+
TR::SymbolReference *
1318+
J9::SymbolReferenceTable::findOrCreateClassDepthAndFlagsSymbolRef()
1319+
{
1320+
if (!element(isClassDepthAndFlagsSymbol))
13151321
{
13161322
TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());
13171323
TR::Symbol * sym = TR::Symbol::createShadow(trHeapMemory(), TR::Int32);
1318-
element(isClassAndDepthFlagsSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), isClassAndDepthFlagsSymbol, sym);
1319-
element(isClassAndDepthFlagsSymbol)->setOffset(fej9->getOffsetOfClassAndDepthFlags());
1324+
element(isClassDepthAndFlagsSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), isClassDepthAndFlagsSymbol, sym);
1325+
element(isClassDepthAndFlagsSymbol)->setOffset(fej9->getOffsetOfClassDepthAndFlags());
13201326
}
1321-
return element(isClassAndDepthFlagsSymbol);
1327+
return element(isClassDepthAndFlagsSymbol);
13221328
}
13231329

13241330

runtime/compiler/compile/J9SymbolReferenceTable.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,7 @@ class SymbolReferenceTable : public OMR::SymbolReferenceTableConnector
244244
TR::SymbolReference * findOrCreateDescriptionWordFromPtrSymbolRef();
245245
TR::SymbolReference * findOrCreateClassFlagsSymbolRef();
246246
TR::SymbolReference * findOrCreateClassAndDepthFlagsSymbolRef();
247+
TR::SymbolReference * findOrCreateClassDepthAndFlagsSymbolRef();
247248
TR::SymbolReference * findOrCreateArrayComponentTypeAsPrimitiveSymbolRef();
248249
TR::SymbolReference * findOrCreateMethodTypeCheckSymbolRef(TR::ResolvedMethodSymbol * owningMethodSymbol);
249250
TR::SymbolReference * findOrCreateIncompatibleReceiverSymbolRef(TR::ResolvedMethodSymbol * owningMethodSymbol);

runtime/compiler/env/VMJ9.cpp

Lines changed: 56 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1603,7 +1603,7 @@ UDATA TR_J9VMBase::getOffsetOfClassFromJavaLangClassField()
16031603

16041604
UDATA TR_J9VMBase::getOffsetOfRamStaticsFromClassField() {return offsetof(J9Class, ramStatics);}
16051605
UDATA TR_J9VMBase::getOffsetOfIsArrayFieldFromRomClass() {return offsetof(J9ROMClass, modifiers);}
1606-
UDATA TR_J9VMBase::getOffsetOfClassAndDepthFlags() {return offsetof(J9Class, classDepthAndFlags);}
1606+
UDATA TR_J9VMBase::getOffsetOfClassDepthAndFlags() {return offsetof(J9Class, classDepthAndFlags);}
16071607
UDATA TR_J9VMBase::getOffsetOfClassFlags() {return offsetof(J9Class, classFlags);}
16081608
UDATA TR_J9VMBase::getOffsetOfArrayComponentTypeField() {return offsetof(J9ArrayClass, componentType);}
16091609
UDATA TR_J9VMBase::constReleaseVMAccessOutOfLineMask() {return J9_PUBLIC_FLAGS_VMACCESS_RELEASE_BITS;}
@@ -2902,13 +2902,56 @@ TR_J9VMBase::testIsClassIdentityType(TR::Node *j9ClassRefNode)
29022902
}
29032903

29042904
TR::Node *
2905-
TR_J9VMBase::checkSomeArrayCompClassFlags(TR::Node *arrayBaseAddressNode, TR::ILOpCodes ifCmpOp, uint32_t flagsToTest)
2905+
TR_J9VMBase::loadClassDepthAndFlags(TR::Node *j9ClassRefNode)
2906+
{
2907+
TR::SymbolReference *classDepthAndFlagsSymRef = TR::comp()->getSymRefTab()->findOrCreateClassDepthAndFlagsSymbolRef();
2908+
2909+
TR::Node *classFlagsNode = NULL;
2910+
2911+
if (TR::comp()->target().is32Bit())
2912+
{
2913+
classFlagsNode = TR::Node::createWithSymRef(TR::iloadi, 1, 1, j9ClassRefNode, classDepthAndFlagsSymRef);
2914+
}
2915+
else
2916+
{
2917+
classFlagsNode = TR::Node::createWithSymRef(TR::lloadi, 1, 1, j9ClassRefNode, classDepthAndFlagsSymRef);
2918+
classFlagsNode = TR::Node::create(TR::l2i, 1, classFlagsNode);
2919+
}
2920+
2921+
return classFlagsNode;
2922+
}
2923+
2924+
TR::Node *
2925+
TR_J9VMBase::testAreSomeClassDepthAndFlagsSet(TR::Node *j9ClassRefNode, uint32_t flagsToTest)
2926+
{
2927+
TR::Node *classFlags = loadClassDepthAndFlags(j9ClassRefNode);
2928+
TR::Node *maskedFlags = TR::Node::create(TR::iand, 2, classFlags, TR::Node::iconst(j9ClassRefNode, flagsToTest));
2929+
2930+
return maskedFlags;
2931+
}
2932+
2933+
TR::Node *
2934+
TR_J9VMBase::testIsClassArrayType(TR::Node *j9ClassRefNode)
2935+
{
2936+
return testAreSomeClassDepthAndFlagsSet(j9ClassRefNode, getFlagValueForArrayCheck());
2937+
}
2938+
2939+
TR::Node *
2940+
TR_J9VMBase::loadArrayClassComponentType(TR::Node *j9ClassRefNode)
29062941
{
2907-
TR::SymbolReference *vftSymRef = TR::comp()->getSymRefTab()->findOrCreateVftSymbolRef();
29082942
TR::SymbolReference *arrayCompSymRef = TR::comp()->getSymRefTab()->findOrCreateArrayComponentTypeSymbolRef();
2943+
TR::Node *arrayCompClass = TR::Node::createWithSymRef(TR::aloadi, 1, 1, j9ClassRefNode, arrayCompSymRef);
29092944

2945+
return arrayCompClass;
2946+
}
2947+
2948+
TR::Node *
2949+
TR_J9VMBase::checkSomeArrayCompClassFlags(TR::Node *arrayBaseAddressNode, TR::ILOpCodes ifCmpOp, uint32_t flagsToTest)
2950+
{
2951+
TR::SymbolReference *vftSymRef = TR::comp()->getSymRefTab()->findOrCreateVftSymbolRef();
29102952
TR::Node *vft = TR::Node::createWithSymRef(TR::aloadi, 1, 1, arrayBaseAddressNode, vftSymRef);
2911-
TR::Node *arrayCompClass = TR::Node::createWithSymRef(TR::aloadi, 1, 1, vft, arrayCompSymRef);
2953+
2954+
TR::Node *arrayCompClass = loadArrayClassComponentType(vft);
29122955
TR::Node *maskedFlagsNode = testAreSomeClassFlagsSet(arrayCompClass, flagsToTest);
29132956
TR::Node *ifNode = TR::Node::createif(ifCmpOp, maskedFlagsNode, TR::Node::iconst(arrayBaseAddressNode, 0));
29142957

@@ -7408,14 +7451,14 @@ TR_J9VM::transformJavaLangClassIsArray(TR::Compilation * comp, TR::Node * callNo
74087451
// treetop
74097452
// iushr
74107453
// iand
7411-
// iloadi <classAndDepthFlags>
7454+
// iloadi <ClassDepthAndFlags>
74127455
// aloadi <classFromJavaLangClass>
74137456
// aload <parm 1> <= jlClass
74147457
// iconst J9AccClassArray
74157458
// iconst shiftAmount
74167459

7417-
int andMask = comp->fej9()->getFlagValueForArrayCheck();
7418-
TR::Node * classFlag, *jlClass, * andConstNode;
7460+
int flagMask = comp->fej9()->getFlagValueForArrayCheck();
7461+
TR::Node * classFlagNode, *jlClass;
74197462
TR::SymbolReferenceTable *symRefTab = comp->getSymRefTab();
74207463

74217464
jlClass = callNode->getFirstChild();
@@ -7435,26 +7478,16 @@ TR_J9VM::transformJavaLangClassIsArray(TR::Compilation * comp, TR::Node * callNo
74357478

74367479
TR::Node * vftLoad = TR::Node::createWithSymRef(callNode, TR::aloadi, 1, jlClass, comp->getSymRefTab()->findOrCreateClassFromJavaLangClassSymbolRef());
74377480

7438-
if (comp->target().is32Bit())
7439-
{
7440-
classFlag = TR::Node::createWithSymRef(callNode, TR::iloadi, 1, vftLoad, symRefTab->findOrCreateClassAndDepthFlagsSymbolRef());
7441-
}
7442-
else
7443-
{
7444-
classFlag = TR::Node::createWithSymRef(callNode, TR::lloadi, 1, vftLoad, symRefTab->findOrCreateClassAndDepthFlagsSymbolRef());
7445-
classFlag = TR::Node::create(callNode, TR::l2i, 1, classFlag);
7446-
}
7481+
classFlagNode = testIsClassArrayType(vftLoad);
74477482

74487483
// Decrement the ref count of jlClass since the call is going to be transmuted and its first child is not needed anymore
74497484
callNode->getAndDecChild(0);
74507485
TR::Node::recreate(callNode, TR::iushr);
74517486
callNode->setNumChildren(2);
74527487

7453-
andConstNode = TR::Node::create(callNode, TR::iconst, 0, andMask);
7454-
TR::Node * andNode = TR::Node::create(TR::iand, 2, classFlag, andConstNode);
7455-
callNode->setAndIncChild(0, andNode);
7488+
callNode->setAndIncChild(0, classFlagNode);
74567489

7457-
int32_t shiftAmount = trailingZeroes(andMask);
7490+
int32_t shiftAmount = trailingZeroes(flagMask);
74587491
callNode->setAndIncChild(1, TR::Node::iconst(callNode, shiftAmount));
74597492
}
74607493

@@ -7642,6 +7675,7 @@ TR_J9VM::inlineNativeCall(TR::Compilation * comp, TR::TreeTop * callNodeTreeTop,
76427675
TR::Node::recreate(callNode, TR::aloadi);
76437676
callNode->setSymbolReference(comp->getSymRefTab()->findOrCreateVftSymbolRef());
76447677
callNode = TR::Node::createWithSymRef(TR::aloadi, 1, 1, callNode, comp->getSymRefTab()->findOrCreateJavaLangClassFromClassSymbolRef());
7678+
callNode->setIsNonNull(true);
76457679
return callNode;
76467680

76477681
case TR::java_lang_Class_getStackClass:
@@ -8363,13 +8397,13 @@ TR_J9VM::inlineNativeCall(TR::Compilation * comp, TR::TreeTop * callNodeTreeTop,
83638397
case TR::com_ibm_jit_JITHelpers_getClassDepthAndFlagsFromJ9Class32:
83648398
{
83658399
loadOp = TR::iloadi;
8366-
newSymRef = comp->getSymRefTab()->findOrCreateClassAndDepthFlagsSymbolRef();
8400+
newSymRef = comp->getSymRefTab()->findOrCreateClassDepthAndFlagsSymbolRef();
83678401
break;
83688402
}
83698403
case TR::com_ibm_jit_JITHelpers_getClassDepthAndFlagsFromJ9Class64:
83708404
{
83718405
loadOp = TR::lloadi;
8372-
newSymRef = comp->getSymRefTab()->findOrCreateClassAndDepthFlagsSymbolRef();
8406+
newSymRef = comp->getSymRefTab()->findOrCreateClassDepthAndFlagsSymbolRef();
83738407
break;
83748408
}
83758409
case TR::com_ibm_jit_JITHelpers_getComponentTypeFromJ9Class32:

runtime/compiler/env/VMJ9.h

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -686,7 +686,7 @@ class TR_J9VMBase : public TR_FrontEnd
686686
virtual uintptr_t getConstantPoolFromClass(TR_OpaqueClassBlock *);
687687

688688
virtual uintptr_t getOffsetOfIsArrayFieldFromRomClass();
689-
virtual uintptr_t getOffsetOfClassAndDepthFlags();
689+
virtual uintptr_t getOffsetOfClassDepthAndFlags();
690690
virtual uintptr_t getOffsetOfClassFlags();
691691
virtual uintptr_t getOffsetOfArrayComponentTypeField();
692692
virtual uintptr_t getOffsetOfIndexableSizeField();
@@ -1290,6 +1290,44 @@ class TR_J9VMBase : public TR_FrontEnd
12901290
*/
12911291
TR::Node * testIsClassIdentityType(TR::Node *j9ClassRefNode);
12921292

1293+
/**
1294+
* \brief Generate IL to load the value of the \c componentType field of the specified
1295+
* \ref J9ArrayClass. The class must be a \ref J9ArrayClass or garbage will be loaded.
1296+
* IL might load this field unconditionally, but must only dereference the loaded value
1297+
* if the class actually is an array class.
1298+
* \param j9ClassRefNode A node representing a reference to a \ref J9Class
1299+
* \return A \ref TR::Node that loads the value of the \c componentType field
1300+
*/
1301+
TR::Node * loadArrayClassComponentType(TR::Node *j9ClassRefNode);
1302+
1303+
/**
1304+
* \brief Generate IL to load the value of the \c classDepthAndFlags field of the
1305+
* specified \ref J9Class.
1306+
* \param j9ClassRefNode A node representing a reference to a \ref J9Class
1307+
* \return A \ref TR::Node that loads the value of the \c classDepthAndFlags field
1308+
*/
1309+
TR::Node * loadClassDepthAndFlags(TR::Node *j9ClassRefNode);
1310+
1311+
/**
1312+
* \brief Generate IL to load the \c classDepthAndFlags field of the specified
1313+
* \ref J9Class, and apply the mask specified by \c flagsToTest.
1314+
* \param j9ClassRefNode A node representing a reference to a \ref J9Class
1315+
* \param flagsToTest Flags to use as a mask for the \ref classAndFlags field
1316+
* \return A \ref TR::Node that produces the result of loading \c classDepthAndFlags
1317+
* and applying the \c flagsToTest mask to it.
1318+
*/
1319+
TR::Node * testAreSomeClassDepthAndFlagsSet(TR::Node *j9ClassRefNode, uint32_t flagsToTest);
1320+
1321+
/**
1322+
* \brief Generate IL to test whether the specified \ref J9Class is an array class.
1323+
* \param j9ClassRefNode A node representing a reference to a \ref J9Class
1324+
* \return A \ref TR::Node that will evaluate to zero if the specified \ref J9Class
1325+
* is not an array class, or the value of
1326+
* \c TR::Compiler->cls.flagValueForArrayCheck (which is non-zero) if it is
1327+
* an array class.
1328+
*/
1329+
TR::Node * testIsClassArrayType(TR::Node *j9ClassRefNode);
1330+
12931331
/**
12941332
* \brief Test whether any of the specified flags is set on the array's component class
12951333
* \param arrayBaseAddressNode A node representing a reference to the array base address

runtime/compiler/ilgen/IlGenerator.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2157,7 +2157,7 @@ TR_J9ByteCodeIlGenerator::inlineJitCheckIfFinalizeObject(TR::Block *firstBlock)
21572157

21582158
TR::Node *classDepthAndFlagsNode = TR::Node::createWithSymRef(loadOp, 1, 1,
21592159
vftLoad,
2160-
comp()->getSymRefTab()->findOrCreateClassAndDepthFlagsSymbolRef());
2160+
comp()->getSymRefTab()->findOrCreateClassDepthAndFlagsSymbolRef());
21612161
TR::Node *andConstNode = TR::Node::create(classDepthAndFlagsNode, is64bit ? TR::lconst : TR::iconst, 0);
21622162
if (is64bit)
21632163
andConstNode->setLongInt(fej9()->getFlagValueForFinalizerCheck());

runtime/compiler/ilgen/Walker.cpp

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4606,20 +4606,12 @@ break
46064606
TR::Node* obj = callNode->getChild(1);
46074607
TR::Node* vftLoad = TR::Node::createWithSymRef(callNode, TR::aloadi, 1, obj, symRefTab()->findOrCreateVftSymbolRef());
46084608

4609-
if (comp()->target().is32Bit())
4610-
{
4611-
resultNode = TR::Node::createWithSymRef(callNode, TR::iloadi, 1, vftLoad, symRefTab()->findOrCreateClassAndDepthFlagsSymbolRef());
4612-
}
4613-
else
4614-
{
4615-
resultNode = TR::Node::createWithSymRef(callNode, TR::lloadi, 1, vftLoad, symRefTab()->findOrCreateClassAndDepthFlagsSymbolRef());
4616-
resultNode = TR::Node::create(callNode, TR::l2i, 1, resultNode);
4617-
}
4618-
46194609
int32_t andMask = comp()->fej9()->getFlagValueForArrayCheck();
4610+
resultNode = comp()->fej9()->testIsClassArrayType(vftLoad);
4611+
46204612
int32_t shiftAmount = trailingZeroes(andMask);
4621-
resultNode = TR::Node::create(callNode, TR::iand, 2, resultNode, TR::Node::iconst(callNode, andMask));
46224613
resultNode = TR::Node::create(callNode, TR::iushr, 2, resultNode, TR::Node::iconst(callNode, shiftAmount));
4614+
46234615
// Handle NullCHK
46244616
if (callNodeTreeTop->getNode()->getOpCode().isNullCheck())
46254617
TR::Node::recreate(callNodeTreeTop->getNode(), TR::treetop);

runtime/compiler/optimizer/EscapeAnalysis.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4179,7 +4179,7 @@ static bool isFinalizableInlineTest(TR::Compilation *comp, TR::Node *candidate,
41794179
41804180
if[i/l]cmpne <root>
41814181
[i/l]and <r1>
4182-
[i/l]loadi <classAndDepthFlags> <r11/loadNode>
4182+
[i/l]loadi <classDepthAndFlags> <r11/loadNode>
41834183
aloadi <vft-symbol> <vftLoad>
41844184
... <ref>
41854185
[i/l]const <FlagValueForFinalizerCheck> <r12>
@@ -4190,7 +4190,7 @@ static bool isFinalizableInlineTest(TR::Compilation *comp, TR::Node *candidate,
41904190
ificmpne <root>
41914191
iand <r1>
41924192
l2i <r11>
4193-
lloadi <classAndDepthFlags> <loadNode>
4193+
lloadi <classDepthAndFlags> <loadNode>
41944194
aloadi <vft-symbol> <vftLoad>
41954195
... <ref>
41964196
iconst <FlagValueForFinalizerCheck> <r12>

runtime/compiler/optimizer/InlinerTempForJ9.cpp

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -940,19 +940,9 @@ TR_J9InlinerPolicy::genCodeForUnsafeGetPut(TR::Node* unsafeAddress,
940940
// If we need conversion or java/lang/Class is not loaded yet, we generate old sequence of tests
941941
if (conversionNeeded || javaLangClass == NULL)
942942
{
943-
TR::Node *isArrayField = NULL;
944-
if (comp()->target().is32Bit())
945-
{
946-
isArrayField = TR::Node::createWithSymRef(TR::iloadi, 1, 1, vftLoad, comp()->getSymRefTab()->findOrCreateClassAndDepthFlagsSymbolRef());
947-
}
948-
else
949-
{
950-
isArrayField = TR::Node::createWithSymRef(TR::lloadi, 1, 1, vftLoad, comp()->getSymRefTab()->findOrCreateClassAndDepthFlagsSymbolRef());
951-
isArrayField = TR::Node::create(TR::l2i, 1, isArrayField);
952-
}
953-
TR::Node *andConstNode = TR::Node::create(isArrayField, TR::iconst, 0, TR::Compiler->cls.flagValueForArrayCheck(comp()));
954-
TR::Node * andNode = TR::Node::create(TR::iand, 2, isArrayField, andConstNode);
955-
TR::Node *isArrayNode = TR::Node::createif(TR::ificmpeq, andNode, andConstNode, NULL);
943+
TR::Node *testIsArrayFlag = comp()->fej9()->testIsClassArrayType(vftLoad);
944+
TR::Node *flagConstNode = TR::Node::create(testIsArrayFlag, TR::iconst, 0, TR::Compiler->cls.flagValueForArrayCheck(comp()));
945+
TR::Node *isArrayNode = TR::Node::createif(TR::ificmpeq, testIsArrayFlag, flagConstNode, NULL);
956946
isArrayTreeTop = TR::TreeTop::create(comp(), isArrayNode, NULL, NULL);
957947
isArrayBlock = TR::Block::createEmptyBlock(vftLoad, comp(), indirectAccessBlock->getFrequency());
958948
isArrayBlock->append(isArrayTreeTop);

0 commit comments

Comments
 (0)