Skip to content

Commit

Permalink
Merge pull request #13884 from singh264/refactor_classesOnHeap
Browse files Browse the repository at this point in the history
Refactor classesOnHeap
  • Loading branch information
ymanton committed Nov 22, 2021
2 parents a178e38 + 6dd76c2 commit 644b652
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 143 deletions.
9 changes: 2 additions & 7 deletions runtime/compiler/arm/codegen/ARMPrivateLinkage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -956,13 +956,8 @@ void J9::ARM::PrivateLinkage::buildVirtualDispatch(TR::Node *callNode,
TR::Register * classReg;
if (methodSymRef == comp()->getSymRefTab()->findObjectNewInstanceImplSymbol())
{//In this case, methodSymRef is resolved and VTable index is small enough to fit in 12bit, so we can safely use gr11 for classReg.
if (TR::Compiler->cls.classesOnHeap())
{
classReg = gr11;
generateTrg1MemInstruction(codeGen, TR::InstOpCode::ldr, callNode, gr11, new (trHeapMemory()) TR::MemoryReference(gr0, fej9->getOffsetOfClassFromJavaLangClassField(), codeGen));
}
else
classReg = gr0;
classReg = gr11;
generateTrg1MemInstruction(codeGen, TR::InstOpCode::ldr, callNode, gr11, new (trHeapMemory()) TR::MemoryReference(gr0, fej9->getOffsetOfClassFromJavaLangClassField(), codeGen));
}
else
{
Expand Down
37 changes: 9 additions & 28 deletions runtime/compiler/env/VMJ9.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7468,16 +7468,8 @@ TR_J9VM::transformJavaLangClassIsArrayOrIsPrimitive(TR::Compilation * comp, TR::

TR::Node * vftFieldInd;

if (TR::Compiler->cls.classesOnHeap())
{
vftFieldInd = TR::Node::createWithSymRef(TR::aloadi, 1, 1, vftField, comp->getSymRefTab()->findOrCreateClassFromJavaLangClassSymbolRef());
isArrayField = TR::Node::createWithSymRef(TR::aloadi, 1, 1,vftFieldInd,symRefTab->findOrCreateClassRomPtrSymbolRef());
}
else
{
isArrayField = TR::Node::createWithSymRef(TR::aloadi, 1, 1,vftField,symRefTab->findOrCreateClassRomPtrSymbolRef());
vftFieldInd = isArrayField; //pkalle
}
vftFieldInd = TR::Node::createWithSymRef(TR::aloadi, 1, 1, vftField, comp->getSymRefTab()->findOrCreateClassFromJavaLangClassSymbolRef());
isArrayField = TR::Node::createWithSymRef(TR::aloadi, 1, 1,vftFieldInd,symRefTab->findOrCreateClassRomPtrSymbolRef());

if (treeTop->getNode()->getOpCode().isNullCheck())
{
Expand Down Expand Up @@ -7622,10 +7614,7 @@ TR_J9VM::inlineNativeCall(TR::Compilation * comp, TR::TreeTop * callNodeTreeTop,
case TR::java_lang_Object_getClass:
TR::Node::recreate(callNode, TR::aloadi);
callNode->setSymbolReference(comp->getSymRefTab()->findOrCreateVftSymbolRef());
if (TR::Compiler->cls.classesOnHeap())
{
callNode = TR::Node::createWithSymRef(TR::aloadi, 1, 1, callNode, comp->getSymRefTab()->findOrCreateJavaLangClassFromClassSymbolRef());
}
callNode = TR::Node::createWithSymRef(TR::aloadi, 1, 1, callNode, comp->getSymRefTab()->findOrCreateJavaLangClassFromClassSymbolRef());
return callNode;

// Note: these cases are not tested and thus are commented out:
Expand Down Expand Up @@ -7750,10 +7739,7 @@ TR_J9VM::inlineNativeCall(TR::Compilation * comp, TR::TreeTop * callNodeTreeTop,
callNode->removeAllChildren();
TR::SymbolReference *callerClassSymRef = comp->getSymRefTab()->findOrCreateClassSymbol(comp->getMethodSymbol(), -1, convertClassPtrToClassOffset(callerClass));
callNode->setSymbolReference(callerClassSymRef);
if (TR::Compiler->cls.classesOnHeap())
{
callNode = TR::Node::createWithSymRef(TR::aloadi, 1, 1, callNode, comp->getSymRefTab()->findOrCreateJavaLangClassFromClassSymbolRef());
}
callNode = TR::Node::createWithSymRef(TR::aloadi, 1, 1, callNode, comp->getSymRefTab()->findOrCreateJavaLangClassFromClassSymbolRef());
}
}
else
Expand Down Expand Up @@ -8398,18 +8384,13 @@ TR_J9VM::getClassClassPointer(TR_OpaqueClassBlock *objectClassPointer)
J9Class *j9class;
j9class = TR::Compiler->cls.convertClassOffsetToClassPtr(objectClassPointer);

if (TR::Compiler->cls.classesOnHeap())
{
void *javaLangClass = J9VM_J9CLASS_TO_HEAPCLASS(TR::Compiler->cls.convertClassOffsetToClassPtr(objectClassPointer));
void *javaLangClass = J9VM_J9CLASS_TO_HEAPCLASS(TR::Compiler->cls.convertClassOffsetToClassPtr(objectClassPointer));

// j9class points to the J9Class corresponding to java/lang/Object
if (TR::Compiler->om.generateCompressedObjectHeaders())
j9class = (J9Class *)(uintptr_t) *((uint32_t *) ((uintptr_t) javaLangClass + (uintptr_t) TR::Compiler->om.offsetOfObjectVftField()));
else
j9class = (J9Class *)(*((J9Class **) ((uintptr_t) javaLangClass + (uintptr_t) TR::Compiler->om.offsetOfObjectVftField())));
}
// j9class points to the J9Class corresponding to java/lang/Object
if (TR::Compiler->om.generateCompressedObjectHeaders())
j9class = (J9Class *)(uintptr_t) *((uint32_t *) ((uintptr_t) javaLangClass + (uintptr_t) TR::Compiler->om.offsetOfObjectVftField()));
else
j9class = (J9Class *)(*((J9Class **) ((uintptr_t)j9class + (uintptr_t) TR::Compiler->om.offsetOfObjectVftField())));
j9class = (J9Class *)(*((J9Class **) ((uintptr_t) javaLangClass + (uintptr_t) TR::Compiler->om.offsetOfObjectVftField())));

j9class = (J9Class *)((uintptr_t)j9class & TR::Compiler->om.maskOfObjectVftField());

Expand Down
54 changes: 15 additions & 39 deletions runtime/compiler/ilgen/IlGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1062,17 +1062,10 @@ TR_J9ByteCodeIlGenerator::prependEntryCode(TR::Block * firstBlock)
TR::Node * firstChild = pop();
TR::SymbolReference * monEnterSymRef = symRefTab()->findOrCreateMethodMonitorEntrySymbolRef(_methodSymbol);

if (TR::Compiler->cls.classesOnHeap())
if (firstChild->getOpCodeValue() == TR::loadaddr && firstChild->getSymbol()->isClassObject())
{
if (firstChild->getOpCodeValue() == TR::loadaddr && firstChild->getSymbol()->isClassObject())
{
monitorEnter = TR::Node::createWithSymRef(TR::aloadi, 1, 1, firstChild, symRefTab()->findOrCreateJavaLangClassFromClassSymbolRef());
monitorEnter = TR::Node::createWithSymRef(TR::monent, 1, 1, monitorEnter, monEnterSymRef);
}
else
{
monitorEnter = TR::Node::createWithSymRef(TR::monent, 1, 1, firstChild, monEnterSymRef);
}
monitorEnter = TR::Node::createWithSymRef(TR::aloadi, 1, 1, firstChild, symRefTab()->findOrCreateJavaLangClassFromClassSymbolRef());
monitorEnter = TR::Node::createWithSymRef(TR::monent, 1, 1, monitorEnter, monEnterSymRef);
}
else
{
Expand Down Expand Up @@ -1546,12 +1539,9 @@ TR_J9ByteCodeIlGenerator::genNewInstanceImplThunk()
//the call to findOrCreateClassSymbol is safe even though we pass CPI of -1 since it is guarded by !isAOT check in createResolvedMethodWithSignature
loadSymbol(TR::loadaddr, symRefTab()->findOrCreateClassSymbol(_methodSymbol, -1, classId)); // This Class

if (TR::Compiler->cls.classesOnHeap())
{
TR::Node* node = pop();
node = TR::Node::createWithSymRef(TR::aloadi, 1, 1, node, symRefTab()->findOrCreateJavaLangClassFromClassSymbolRef());
push(node);
}
TR::Node* node = pop();
node = TR::Node::createWithSymRef(TR::aloadi, 1, 1, node, symRefTab()->findOrCreateJavaLangClassFromClassSymbolRef());
push(node);

genTreeTop(genNodeAndPopChildren(TR::call, 3, accessCheckSymRef));
}
Expand Down Expand Up @@ -1583,30 +1573,16 @@ TR_J9ByteCodeIlGenerator::genNewInstanceImplCall(TR::Node *classNode)
TR_ResolvedMethod *caller = method()->owningMethod(); // the caller of Class.newInstance()
TR_ASSERT(caller, "should only be transforming newInstanceImpl call if newInstance is being inlined");

TR::Node *callNode;
if (TR::Compiler->cls.classesOnHeap())
{
TR::Node *classNodeAsClass = TR::Node::createWithSymRef(TR::aloadi, 1, 1, classNode, symRefTab()->findOrCreateClassFromJavaLangClassSymbolRef());
//the call to findOrCreateClassSymbol is safe even though we pass CPI of -1 since we check for !compileRelocatableCode() in the caller
TR::Node *node = TR::Node::createWithSymRef(TR::loadaddr, 0, symRefTab()->findOrCreateClassSymbol(_methodSymbol, -1, caller->classOfMethod()));
TR::Node *nodeAsObject = TR::Node::createWithSymRef(TR::aloadi, 1, 1, node, symRefTab()->findOrCreateJavaLangClassFromClassSymbolRef());
TR::Node *classNodeAsClass = TR::Node::createWithSymRef(TR::aloadi, 1, 1, classNode, symRefTab()->findOrCreateClassFromJavaLangClassSymbolRef());
//the call to findOrCreateClassSymbol is safe even though we pass CPI of -1 since we check for !compileRelocatableCode() in the caller
TR::Node *node = TR::Node::createWithSymRef(TR::loadaddr, 0, symRefTab()->findOrCreateClassSymbol(_methodSymbol, -1, caller->classOfMethod()));
TR::Node *nodeAsObject = TR::Node::createWithSymRef(TR::aloadi, 1, 1, node, symRefTab()->findOrCreateJavaLangClassFromClassSymbolRef());

callNode = TR::Node::createWithSymRef(TR::acalli, 3, 3,
classNodeAsClass,
classNode,
nodeAsObject,
symRefTab()->findOrCreateObjectNewInstanceImplSymbol(_methodSymbol));
}
else
{
//the call to findOrCreateClassSymbol is safe even though we pass CPI of -1 since we check for !compileRelocatableCode() in the caller
callNode = TR::Node::createWithSymRef(TR::acalli, 3, 3,
classNode,
classNode,
TR::Node::createWithSymRef(TR::loadaddr, 0,
symRefTab()->findOrCreateClassSymbol(_methodSymbol, -1, caller->classOfMethod())),
symRefTab()->findOrCreateObjectNewInstanceImplSymbol(_methodSymbol));
}
TR::Node *callNode = TR::Node::createWithSymRef(TR::acalli, 3, 3,
classNodeAsClass,
classNode,
nodeAsObject,
symRefTab()->findOrCreateObjectNewInstanceImplSymbol(_methodSymbol));

return callNode;
}
Expand Down
18 changes: 6 additions & 12 deletions runtime/compiler/ilgen/Walker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6006,10 +6006,7 @@ TR_J9ByteCodeIlGenerator::loadFromCP(TR::DataType type, int32_t cpIndex)
}
else if (method()->isClassConstant(cpIndex))
{
if (TR::Compiler->cls.classesOnHeap())
loadClassObjectAndIndirect(cpIndex);
else
loadClassObject(cpIndex);
loadClassObjectAndIndirect(cpIndex);
}
else if (method()->isStringConstant(cpIndex))
{
Expand Down Expand Up @@ -6191,7 +6188,7 @@ TR_J9ByteCodeIlGenerator::genMonitorEnter()

bool isStatic = (node->getOpCodeValue() == TR::loadaddr && node->getSymbol()->isClassObject());

if (isStatic && TR::Compiler->cls.classesOnHeap())
if (isStatic)
node = TR::Node::createWithSymRef(TR::aloadi, 1, 1, node, symRefTab()->findOrCreateJavaLangClassFromClassSymbolRef());

TR::Node *loadNode = node;
Expand Down Expand Up @@ -6240,7 +6237,7 @@ TR_J9ByteCodeIlGenerator::genMonitorExit(bool isReturn)
bool isStatic = (node->getOpCodeValue() == TR::loadaddr && node->getSymbol()->isClassObject());
///bool isStatic = _methodSymbol->isStatic();

if (isStatic && TR::Compiler->cls.classesOnHeap())
if (isStatic)
node = TR::Node::createWithSymRef(TR::aloadi, 1, 1, node, symRefTab()->findOrCreateJavaLangClassFromClassSymbolRef());

if (!comp()->getOption(TR_DisableLiveMonitorMetadata))
Expand Down Expand Up @@ -7340,12 +7337,9 @@ TR_J9ByteCodeIlGenerator::storeStatic(int32_t cpIndex)
void * staticClass = method()->classOfStatic(cpIndex);
loadSymbol(TR::loadaddr, symRefTab()->findOrCreateClassSymbol(_methodSymbol, cpIndex, staticClass, true /* cpIndexOfStatic */));

if (TR::Compiler->cls.classesOnHeap())
{
node = pop();
node = TR::Node::createWithSymRef(TR::aloadi, 1, 1, node, symRefTab()->findOrCreateJavaLangClassFromClassSymbolRef());
push(node);
}
node = pop();
node = TR::Node::createWithSymRef(TR::aloadi, 1, 1, node, symRefTab()->findOrCreateJavaLangClassFromClassSymbolRef());
push(node);

node = TR::Node::createWithSymRef(comp()->il.opCodeForDirectWriteBarrier(type), 2, 2, value, pop(), symRef);
}
Expand Down
23 changes: 6 additions & 17 deletions runtime/compiler/optimizer/InlinerTempForJ9.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1093,7 +1093,6 @@ TR_J9InlinerPolicy::createUnsafePutWithOffset(TR::ResolvedMethodSymbol *calleeSy
{
if (isVolatile && type == TR::Int64 && comp()->target().is32Bit() && !comp()->cg()->getSupportsInlinedAtomicLongVolatiles())
return false;
TR_ASSERT(TR::Compiler->cls.classesOnHeap(), "Unsafe inlining code assumes classes are on heap\n");
if (debug("traceUnsafe"))
printf("createUnsafePutWithOffset %d in %s\n", type.getDataType(), comp()->signature());

Expand Down Expand Up @@ -1427,7 +1426,6 @@ TR_J9InlinerPolicy::createUnsafeGetWithOffset(TR::ResolvedMethodSymbol *calleeSy
{
if (isVolatile && type == TR::Int64 && comp()->target().is32Bit() && !comp()->cg()->getSupportsInlinedAtomicLongVolatiles())
return false;
TR_ASSERT(TR::Compiler->cls.classesOnHeap(), "Unsafe inlining code assumes classes are on heap\n");

if (debug("traceUnsafe"))
printf("createUnsafeGetWithOffset %s in %s\n", type.toString(), comp()->signature());
Expand Down Expand Up @@ -1779,10 +1777,7 @@ TR_J9InlinerPolicy::inlineGetClassAccessFlags(TR::ResolvedMethodSymbol *calleeSy

TR::Node::recreate(j9cNode, TR::aload);

if (TR::Compiler->cls.classesOnHeap())
{
j9cNode = TR::Node::createWithSymRef(TR::aloadi, 1, 1, j9cNode, comp()->getSymRefTab()->findOrCreateClassFromJavaLangClassSymbolRef());
}
j9cNode = TR::Node::createWithSymRef(TR::aloadi, 1, 1, j9cNode, comp()->getSymRefTab()->findOrCreateClassFromJavaLangClassSymbolRef());

TR::Node *nullCheckNode = TR::Node::createWithSymRef(TR::NULLCHK, 1, 1, j9cNode, comp()->getSymRefTab()->findOrCreateNullCheckSymbolRef(callerSymbol));
TR::TreeTop *nullCheckTree = TR::TreeTop::create(comp(), nullCheckNode);
Expand Down Expand Up @@ -6296,17 +6291,11 @@ TR_J9TransformInlinedFunction::appendCatchBlockForInlinedSyncMethod(
//
TR::Node * monitorArg, *monitorArgHandle;
if (_calleeSymbol->isStatic())
if (TR::Compiler->cls.classesOnHeap())
{
monitorArgHandle = TR::Node::createWithSymRef(lastNode, TR::loadaddr, 0,
symRefTab->findOrCreateClassSymbol (_calleeSymbol, 0, _calleeSymbol->getResolvedMethod()->containingClass()));
monitorArgHandle = TR::Node::createWithSymRef(TR::aloadi, 1, 1, monitorArgHandle, symRefTab->findOrCreateJavaLangClassFromClassSymbolRef());
}
else
{
monitorArgHandle = TR::Node::createWithSymRef(lastNode, TR::loadaddr, 0,
symRefTab->findOrCreateClassSymbol (_calleeSymbol, 0, _calleeSymbol->getResolvedMethod()->containingClass()));
}
{
monitorArgHandle = TR::Node::createWithSymRef(lastNode, TR::loadaddr, 0,
symRefTab->findOrCreateClassSymbol (_calleeSymbol, 0, _calleeSymbol->getResolvedMethod()->containingClass()));
monitorArgHandle = TR::Node::createWithSymRef(TR::aloadi, 1, 1, monitorArgHandle, symRefTab->findOrCreateJavaLangClassFromClassSymbolRef());
}
else
monitorArgHandle = TR::Node::createWithSymRef(lastNode, TR::aload, 0, symRefTab->findOrCreateAutoSymbol(_calleeSymbol, 0, TR::Address));

Expand Down
62 changes: 22 additions & 40 deletions runtime/compiler/z/codegen/S390PrivateLinkage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1895,54 +1895,36 @@ J9::Z::PrivateLinkage::buildVirtualDispatch(TR::Node * callNode, TR::RegisterDep
}

// load class pointer
TR::Register *classReg;
if (!TR::Compiler->cls.classesOnHeap() && methodSymRef == comp()->getSymRefTab()->findObjectNewInstanceImplSymbol())
{
classReg = RegThis;
TR_ASSERT( offset >= 0,"J9::Z::PrivateLinkage::buildVirtualDispatch - Offset to instanceOf method is assumed positive\n");
}
else
TR::Register *classReg = vftReg;

// It should be impossible to have a offset that can't fit in 20bit given Java method table limitations.
// We assert here to insure limitation/assumption remains true. If this fires we need to fix this code
// and the _virtualUnresolvedHelper() code to deal with a new worst case scenario for patching.
TR_ASSERT_FATAL(offset>MINLONGDISP, "JIT VFT offset does not fit in 20bits");
TR_ASSERT_FATAL(offset!=0 || unresolvedSnippet, "Offset is 0 yet unresolvedSnippet is NULL");
TR_ASSERT_FATAL(offset<=MAX_IMMEDIATE_VAL, "Offset is larger then MAX_IMMEDIATE_VAL");

// If unresolved/AOT, this instruction will be patched by _virtualUnresolvedHelper() with the correct offset
cursor = generateRXInstruction(cg(), TR::InstOpCode::getExtendedLoadOpCode(), callNode, RegRA,
generateS390MemoryReference(classReg, offset, cg()));

if (unresolvedSnippet)
{
classReg = vftReg;
((TR::S390VirtualUnresolvedSnippet *)unresolvedSnippet)->setPatchVftInstruction(cursor);
}

if (!TR::Compiler->cls.classesOnHeap() && offset >= 0 && methodSymRef == comp()->getSymRefTab()->findObjectNewInstanceImplSymbol())
// A load immediate into R0 instruction (LHI/LGFI) MUST be generated here because the "LA" instruction used by
// the VM to find VFT table entries can't handle negative displacements. For unresolved/AOT targets we must assume
// the worse case (offset can't fit in 16bits). VFT offset 0 means unresolved/AOT, otherwise offset is negative.
// Some special cases have positive offsets i.e. java/lang/Object.newInstancePrototype()
if (!unresolvedSnippet && offset >= MIN_IMMEDIATE_VAL && offset <= MAX_IMMEDIATE_VAL) // Offset fits in 16bits
{
cursor =
generateRXInstruction(cg(), TR::InstOpCode::getLoadOpCode(), callNode, RegRA, generateS390MemoryReference(classReg, offset, cg()));
cursor = generateRIInstruction(cg(), TR::InstOpCode::getLoadHalfWordImmOpCode(), callNode, RegZero, offset);
}
else
else // if unresolved || offset can't fit in 16bits
{
// It should be impossible to have a offset that can't fit in 20bit given Java method table limitations.
// We assert here to insure limitation/assumption remains true. If this fires we need to fix this code
// and the _virtualUnresolvedHelper() code to deal with a new worst case scenario for patching.
TR_ASSERT_FATAL(offset>MINLONGDISP, "JIT VFT offset does not fit in 20bits");
TR_ASSERT_FATAL(offset!=0 || unresolvedSnippet, "Offset is 0 yet unresolvedSnippet is NULL");
TR_ASSERT_FATAL(offset<=MAX_IMMEDIATE_VAL, "Offset is larger then MAX_IMMEDIATE_VAL");

// If unresolved/AOT, this instruction will be patched by _virtualUnresolvedHelper() with the correct offset
cursor = generateRXInstruction(cg(), TR::InstOpCode::getExtendedLoadOpCode(), callNode, RegRA,
generateS390MemoryReference(classReg, offset, cg()));

if (unresolvedSnippet)
{
((TR::S390VirtualUnresolvedSnippet *)unresolvedSnippet)->setPatchVftInstruction(cursor);
}

// A load immediate into R0 instruction (LHI/LGFI) MUST be generated here because the "LA" instruction used by
// the VM to find VFT table entries can't handle negative displacements. For unresolved/AOT targets we must assume
// the worse case (offset can't fit in 16bits). VFT offset 0 means unresolved/AOT, otherwise offset is negative.
// Some special cases have positive offsets i.e. java/lang/Object.newInstancePrototype()
if (!unresolvedSnippet && offset >= MIN_IMMEDIATE_VAL && offset <= MAX_IMMEDIATE_VAL) // Offset fits in 16bits
{
cursor = generateRIInstruction(cg(), TR::InstOpCode::getLoadHalfWordImmOpCode(), callNode, RegZero, offset);
}
else // if unresolved || offset can't fit in 16bits
{
// If unresolved/AOT, this instruction will be patched by _virtualUnresolvedHelper() with the correct offset
cursor = generateRILInstruction(cg(), TR::InstOpCode::LGFI, callNode, RegZero, static_cast<int32_t>(offset));
}
cursor = generateRILInstruction(cg(), TR::InstOpCode::LGFI, callNode, RegZero, static_cast<int32_t>(offset));
}

gcPoint = new (trHeapMemory()) TR::S390RRInstruction(TR::InstOpCode::BASR, callNode, RegRA, RegRA, cg());
Expand Down

0 comments on commit 644b652

Please sign in to comment.