Skip to content

Commit

Permalink
Z: Use general constant helpers for unpatchable address constants
Browse files Browse the repository at this point in the history
When there is no assumption that an address constant can be patched,
it is safe to use the same instructions that are used to generate
non-address constants.

Signed-off-by: Spencer Comin <spencer.comin@ibm.com>
  • Loading branch information
Spencer-Comin committed Apr 23, 2024
1 parent e2d8e0f commit c454372
Showing 1 changed file with 52 additions and 25 deletions.
77 changes: 52 additions & 25 deletions compiler/z/codegen/OMRTreeEvaluator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2477,18 +2477,36 @@ TR::Instruction *
genLoadAddressConstant(TR::CodeGenerator * cg, TR::Node * node, uintptr_t value, TR::Register * targetRegister,
TR::Instruction * cursor, TR::RegisterDependencyConditions * cond, TR::Register * base)
{
TR_ExternalRelocationTargetKind reloKind = TR_NoRelocation;
if (cg->profiledPointersRequireRelocation() &&
node->getOpCodeValue() == TR::aconst &&
(node->isMethodPointerConstant() || node->isClassPointerConstant()))
TR::Compilation *comp = cg->comp();
bool isPicSite = false;
bool assumeUnload = false;
bool isMethodPointer = false;
if (node->getOpCodeValue() == TR::aconst)
{
TR_ResolvedMethod * method = comp->getCurrentMethod();
if (node->isMethodPointerConstant())
{
isPicSite = true;
isMethodPointer = true;
assumeUnload = cg->fe()->isUnloadAssumptionRequired(cg->fe()->createResolvedMethod(cg->trMemory(), reinterpret_cast<TR_OpaqueMethodBlock *>(value), method)->classOfMethod(), method);
}
else if (node->isClassPointerConstant())
{
isPicSite = true;
assumeUnload = cg->fe()->isUnloadAssumptionRequired(reinterpret_cast<TR_OpaqueClassBlock *>(value), method);
}
}

TR_ExternalRelocationTargetKind reloKind = TR_NoRelocation;
if (cg->profiledPointersRequireRelocation() && isPicSite)
{
if (isMethodPointer)
{
reloKind = TR_MethodPointer;
if (node->getInlinedSiteIndex() == -1)
reloKind = TR_RamMethod;
}
else if (node->isClassPointerConstant())
else
reloKind = TR_ClassPointer;

TR_ASSERT(reloKind != TR_NoRelocation, "relocation kind shouldn't be TR_NoRelocation");
Expand All @@ -2503,14 +2521,16 @@ genLoadAddressConstant(TR::CodeGenerator * cg, TR::Node * node, uintptr_t value,
return generateRegLitRefInstruction(cg, TR::InstOpCode::getLoadOpCode(), node, targetRegister, value, reloKind, cond, cursor, base);
}

TR::Compilation *comp = cg->comp();
cursor = generateRILInstruction(cg, comp->target().is64Bit() ? TR::InstOpCode::LLILF : TR::InstOpCode::IILF, node, targetRegister, static_cast<uint32_t>(value), cursor);

bool assumePatch = false;
bool isCompressedClassPointer = false;
if (node->isClassUnloadingConst())
if (assumeUnload)
{
if (node->isMethodPointerConstant())
// the address constant may need patched, must use a recognizable instruction sequence
// for TR_UnloadedClassPicSite::compensate and TR_RedefinedClassPicSite::compensate to
// be able to patch the address correctly
cursor = generateRILInstruction(cg, comp->target().is64Bit() ? TR::InstOpCode::LLILF : TR::InstOpCode::IILF, node, targetRegister, static_cast<uint32_t>(value), cursor);

bool isCompressedClassPointer = false;

if (isMethodPointer)
{
comp->getStaticMethodPICSites()->push_front(cursor);
}
Expand All @@ -2519,24 +2539,31 @@ genLoadAddressConstant(TR::CodeGenerator * cg, TR::Node * node, uintptr_t value,
comp->getStaticPICSites()->push_front(cursor);
isCompressedClassPointer = comp->useCompressedPointers();
}
assumePatch = true;

if (comp->getOption(TR_EnableHCR))
{
comp->getStaticHCRPICSites()->push_front(cursor);
}

TR_ASSERT(!isCompressedClassPointer || ((value & CONSTANT64(0xFFFFFFFF00000000)) == 0), "Compressed class pointers are assumed to fit in 32 bits");
// IIHF is only needed when addresses do not fit into 32 bits
if (comp->target().is64Bit() && !isCompressedClassPointer)
{
toS390RILInstruction(cursor)->setisFirstOfAddressPair();
uint32_t high32 = static_cast<uint32_t>(value >> 32);
cursor = generateRILInstruction(cg, TR::InstOpCode::IIHF, node, targetRegister, high32, cursor);
}

return cursor;
}
if (comp->getOption(TR_EnableHCR))
else if (comp->target().is64Bit())
{
comp->getStaticHCRPICSites()->push_front(cursor);
assumePatch = true;
return genLoadLongConstant(cg, node, static_cast<int64_t>(value), targetRegister, cursor, cond, base);
}

TR_ASSERT(!isCompressedClassPointer || ((value & CONSTANT64(0xFFFFFFFF00000000)) == 0), "Compressed class pointers are assumed to fit in 32 bits");
// IIHF is only needed when addresses (besides compressed class pointer) need to be patched or do not fit into 32 bits
if (comp->target().is64Bit() && !isCompressedClassPointer && (assumePatch || ((value & CONSTANT64(0xFFFFFFFF00000000)) != 0)))
else
{
toS390RILInstruction(cursor)->setisFirstOfAddressPair();
uint32_t high32 = static_cast<uint32_t>(value >> 32);
cursor = generateRILInstruction(cg, TR::InstOpCode::IIHF, node, targetRegister, high32, cursor);
return generateLoad32BitConstant(cg, node, static_cast<int32_t>(value), targetRegister, false, cursor, cond, base);
}

return cursor;
}

TR::Instruction *
Expand Down

0 comments on commit c454372

Please sign in to comment.