From c4543727f35a549e4c56d1bd780301f7658a4758 Mon Sep 17 00:00:00 2001 From: Spencer Comin Date: Tue, 26 Mar 2024 13:50:59 -0400 Subject: [PATCH] Z: Use general constant helpers for unpatchable address constants 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 --- compiler/z/codegen/OMRTreeEvaluator.cpp | 77 +++++++++++++++++-------- 1 file changed, 52 insertions(+), 25 deletions(-) diff --git a/compiler/z/codegen/OMRTreeEvaluator.cpp b/compiler/z/codegen/OMRTreeEvaluator.cpp index 1e10511fe6d..09b2ae14f21 100644 --- a/compiler/z/codegen/OMRTreeEvaluator.cpp +++ b/compiler/z/codegen/OMRTreeEvaluator.cpp @@ -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(value), method)->classOfMethod(), method); + } + else if (node->isClassPointerConstant()) + { + isPicSite = true; + assumeUnload = cg->fe()->isUnloadAssumptionRequired(reinterpret_cast(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"); @@ -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(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(value), cursor); + + bool isCompressedClassPointer = false; + + if (isMethodPointer) { comp->getStaticMethodPICSites()->push_front(cursor); } @@ -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(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(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(value >> 32); - cursor = generateRILInstruction(cg, TR::InstOpCode::IIHF, node, targetRegister, high32, cursor); + return generateLoad32BitConstant(cg, node, static_cast(value), targetRegister, false, cursor, cond, base); } - - return cursor; } TR::Instruction *