diff --git a/compiler/codegen/FrontEnd.hpp b/compiler/codegen/FrontEnd.hpp index bfd069bac4e..2b9f10783f4 100644 --- a/compiler/codegen/FrontEnd.hpp +++ b/compiler/codegen/FrontEnd.hpp @@ -157,6 +157,8 @@ class TR_FrontEnd : public TR_Uncopyable virtual int32_t getLineNumberForMethodAndByteCodeIndex(TR_OpaqueMethodBlock *, int32_t); + virtual bool canDevirtualizeDispatch() { return true; } + // -------------------------------------------------------------------------- // Codegen // -------------------------------------------------------------------------- diff --git a/compiler/codegen/Relocation.cpp b/compiler/codegen/Relocation.cpp index 02dd8ab5fab..5eb049f2af1 100644 --- a/compiler/codegen/Relocation.cpp +++ b/compiler/codegen/Relocation.cpp @@ -423,6 +423,43 @@ const char *TR::ExternalRelocation::_externalRelocationTargetKindNames[TR_NumExt "TR_DebugCounter (59)", "TR_ClassUnloadAssumption (60)", "TR_J2IVirtualThunkPointer (61)", + "TR_InlinedAbstractMethodWithNopGuard (62)", + "TR_ValidateRootClass (63)", + "TR_ValidateClassByName (64)", + "TR_ValidateProfiledClass (65)", + "TR_ValidateClassFromCP (66)", + "TR_ValidateDefiningClassFromCP (67)", + "TR_ValidateStaticClassFromCP (68)", + "TR_ValidateClassFromMethod (69)", + "TR_ValidateComponentClassFromArrayClass (70)", + "TR_ValidateArrayClassFromComponentClass (71)", + "TR_ValidateSuperClassFromClass (72)", + "TR_ValidateClassInstanceOfClass (73)", + "TR_ValidateSystemClassByName (74)", + "TR_ValidateClassFromITableIndexCP (75)", + "TR_ValidateDeclaringClassFromFieldOrStatic (76)", + "TR_ValidateClassClass (77)", + "TR_ValidateConcreteSubClassFromClass (78)", + "TR_ValidateClassChain (79)", + "TR_ValidateRomClass (80)", + "TR_ValidatePrimitiveClass (81)", + "TR_ValidateMethodFromInlinedSite (82)", + "TR_ValidateMethodByName (83)", + "TR_ValidateMethodFromClass (84)", + "TR_ValidateStaticMethodFromCP (85)", + "TR_ValidateSpecialMethodFromCP (86)", + "TR_ValidateVirtualMethodFromCP (87)", + "TR_ValidateVirtualMethodFromOffset (88)", + "TR_ValidateInterfaceMethodFromCP (89)", + "TR_ValidateMethodFromClassAndSig (90)", + "TR_ValidateStackWalkerMaySkipFramesRecord (91)", + "TR_ValidateArrayClassFromJavaVM (92)", + "TR_ValidateClassInfoIsInitialized (93)", + "TR_ValidateMethodFromSingleImplementer (94)", + "TR_ValidateMethodFromSingleInterfaceImplementer (95)", + "TR_ValidateMethodFromSingleAbstractImplementer (96)", + "TR_ValidateImproperInterfaceMethodFromCP (97)", + "TR_SymbolFromManager (98)", }; uintptr_t TR::ExternalRelocation::_globalValueList[TR_NumGlobalValueItems] = diff --git a/compiler/compile/Method.cpp b/compiler/compile/Method.cpp index b10d3521c34..cba4a9f8696 100644 --- a/compiler/compile/Method.cpp +++ b/compiler/compile/Method.cpp @@ -385,6 +385,7 @@ bool TR_ResolvedMethod::isPublic() { not bool TR_ResolvedMethod::isFinal() { notImplemented("isFinal"); return false; } bool TR_ResolvedMethod::isStrictFP() { notImplemented("isStrictFP"); return false; } bool TR_ResolvedMethod::isInterpreted() { notImplemented("isInterpreted"); return false; } +bool TR_ResolvedMethod::isInterpretedForHeuristics() { notImplemented("isInterpretedForHeuristics"); return false; } bool TR_ResolvedMethod::hasBackwardBranches() { notImplemented("hasBackwardBranches"); return false; } bool TR_ResolvedMethod::isObjectConstructor() { notImplemented("isObjectConstructor"); return false; } bool TR_ResolvedMethod::isNonEmptyObjectConstructor() { notImplemented("isNonEmptyObjectConstructor"); return false; } diff --git a/compiler/compile/OMRCompilation.hpp b/compiler/compile/OMRCompilation.hpp index 130ee68ccb5..5c29e8f4b9b 100644 --- a/compiler/compile/OMRCompilation.hpp +++ b/compiler/compile/OMRCompilation.hpp @@ -350,6 +350,12 @@ class OMR_EXTENSIBLE Compilation bool compilationShouldBeInterrupted(TR_CallingContext) { return false; } + /* Can be used to ensure that a implementer chosen for inlining is valid; + * for example, to ensure that the implementer can be used for inlining + * in a relocatable compilation + */ + bool validateTargetToBeInlined(TR_ResolvedMethod *implementer) { return true; } + // .......................................................................... // Optimizer mechanics int16_t getOptIndex() { return _currentOptIndex; } diff --git a/compiler/compile/ResolvedMethod.hpp b/compiler/compile/ResolvedMethod.hpp index cf04c79b8be..0378eb6620e 100644 --- a/compiler/compile/ResolvedMethod.hpp +++ b/compiler/compile/ResolvedMethod.hpp @@ -84,6 +84,7 @@ class TR_ResolvedMethod virtual bool isFinal(); virtual bool isInterpreted(); + virtual bool isInterpretedForHeuristics(); virtual bool hasBackwardBranches(); virtual bool isObjectConstructor(); virtual bool isNonEmptyObjectConstructor(); diff --git a/compiler/control/OMROptions.cpp b/compiler/control/OMROptions.cpp index e01e31f5671..b1330413c95 100644 --- a/compiler/control/OMROptions.cpp +++ b/compiler/control/OMROptions.cpp @@ -535,6 +535,7 @@ TR::OptionTable OMR::Options::_jitOptions[] = { {"disableSupportForCpuSpentInCompilation", "M\tdo not provide CPU spent in compilation", SET_OPTION_BIT(TR_DisableSupportForCpuSpentInCompilation), "F" }, {"disableSwitchAnalyzer", "O\tdisable switch analyzer", TR::Options::disableOptimization, switchAnalyzer, 0, "P"}, {"disableSwitchAwayFromProfilingForHotAndVeryhot", "O\tdisable switch away from profiling for hot and veryhot", SET_OPTION_BIT(TR_DisableSwitchAwayFromProfilingForHotAndVeryhot), "F"}, + {"disableSymbolValidationManager", "M\tEnable Symbol Validation Manager for Relocatable Compile Validations", RESET_OPTION_BIT(TR_EnableSymbolValidationManager), "F"}, {"disableSynchronizedFieldLoad", "O\tDisable the use of hardware optimized synchronized field load intrinsics", SET_OPTION_BIT(TR_DisableSynchronizedFieldLoad), "F"}, {"disableSyncMethodInlining", "O\tdisable inlining of synchronized methods", SET_OPTION_BIT(TR_DisableSyncMethodInlining), "F"}, {"disableTailRecursion", "O\tdisable tail recursion", SET_OPTION_BIT(TR_DisableTailRecursion), "F"}, @@ -754,6 +755,7 @@ TR::OptionTable OMR::Options::_jitOptions[] = { {"enableSharedCacheTiming", "M\tenable timing stats for accessing the shared cache", SET_OPTION_BIT(TR_EnableSharedCacheTiming), "F"}, {"enableSIMDLibrary", "M\tEnable recognized methods for SIMD library", SET_OPTION_BIT(TR_EnableSIMDLibrary), "F"}, {"enableSnapshotBlockOpts", "O\tenable block ordering/redirecting optimizations in the presences of snapshot nodes", SET_OPTION_BIT(TR_EnableSnapshotBlockOpts), "F"}, + {"enableSymbolValidationManager", "M\tEnable Symbol Validation Manager for Relocatable Compile Validations", SET_OPTION_BIT(TR_EnableSymbolValidationManager), "F"}, {"enableTailCallOpt", "R\tenable tall call optimization in peephole", SET_OPTION_BIT(TR_EnableTailCallOpt), "F"}, {"enableThisLiveRangeExtension", "R\tenable this live range extesion to the end of the method", SET_OPTION_BIT(TR_EnableThisLiveRangeExtension), "F"}, {"enableTraps", "C\tenable trap instructions", RESET_OPTION_BIT(TR_DisableTraps), "F"}, @@ -1319,6 +1321,7 @@ TR::OptionTable OMR::Options::_jitOptions[] = { {"useSamplingJProfilingForInterpSampledMethods","M\tHeuristic. Use samplingJProfiling for methods sampled by interpreter", SET_OPTION_BIT(TR_UseSamplingJProfilingForInterpSampledMethods), "F", NOT_IN_SUBSET }, {"useSamplingJProfilingForLPQ", "M\tHeuristic. Use samplingJProfiling for methods from low priority queue", SET_OPTION_BIT(TR_UseSamplingJProfilingForLPQ), "F", NOT_IN_SUBSET }, {"useStrictStartupHints", "M\tStartup hints from application obeyed strictly", SET_OPTION_BIT(TR_UseStrictStartupHints), "F", NOT_IN_SUBSET}, + {"useSymbolValidationManager", "M\tUse Symbol Validation Manager for Relocatable Compile Validations", SET_OPTION_BIT(TR_UseSymbolValidationManager), "F", NOT_IN_SUBSET}, {"useVmTotalCpuTimeAsAbstractTime", "M\tUse VmTotalCpuTime as abstractTime", SET_OPTION_BIT(TR_UseVmTotalCpuTimeAsAbstractTime), "F", NOT_IN_SUBSET }, {"varyInlinerAggressivenessWithTime", "M\tVary inliner aggressiveness with abstract time", SET_OPTION_BIT(TR_VaryInlinerAggressivenessWithTime), "F", NOT_IN_SUBSET }, {"verifyReferenceCounts", "I\tverify the sanity of object reference counts before manipulation", SET_OPTION_BIT(TR_VerifyReferenceCounts), "F"}, @@ -2216,6 +2219,19 @@ OMR::Options::jitLatePostProcess(TR::OptionSet *optionSet, void * jitConfig) if (_coldUpgradeSampleThreshold == TR_DEFAULT_COLD_UPGRADE_SAMPLE_THRESHOLD) _coldUpgradeSampleThreshold = 2; } + + // disable DelayRelocationForAOTCompilations feature because with higher + // method counts, the JIT collects enough IProfiler info prior to + // compilation that it doesn't need to wait any longer before running the + + if (self()->getOption(TR_UseHigherMethodCounts)) + { + self()->setOption(TR_DisableDelayRelocationForAOTCompilations, true);// If scount has not been changed on the command line, adjust it here + if (self()->getInitialSCount() == TR_INITIAL_SCOUNT) + { + _initialSCount = _initialCount; + } + } } else // No AOT { diff --git a/compiler/control/OMROptions.hpp b/compiler/control/OMROptions.hpp index ee2be16cbd1..ef325710a20 100644 --- a/compiler/control/OMROptions.hpp +++ b/compiler/control/OMROptions.hpp @@ -234,7 +234,7 @@ enum TR_CompilationOptions TR_TraceMarkingOfHotFields = 0x00001000 + 4, TR_EnableAnnotations = 0x00002000 + 4, // change to disable when on by default TR_UnresolvedAreNotColdAtCold = 0x00004000 + 4, // cold block marker marks unresolved blocks as cold at hotness cold or less - // AVAILABLE = 0x00008000 + 4, + TR_UseSymbolValidationManager = 0x00008000 + 4, TR_EnablePIDExtension = 0x00010000 + 4, TR_GenerateCompleteInlineRanges = 0x00020000 + 4, TR_DisableInliningOfNatives = 0x00040000 + 4, @@ -264,7 +264,7 @@ enum TR_CompilationOptions TR_enableProfiledDevirtualization = 0x00001000 + 5, TR_EnableValueTracing = 0x00002000 + 5, // run-time value tracing TR_IgnoreAssert = 0x00004000 + 5, // ignore failing assertions - // AVAILABLE = 0x00008000 + 5, + TR_EnableSymbolValidationManager = 0x00008000 + 5, TR_EnableNewAllocationProfiling = 0x00010000 + 5, // enable tracing of fields load and store TR_IgnoreIEEERestrictions = 0x00020000 + 5, // enable more aggressive, nonIEEE compliant xforms TR_ProcessHugeMethods = 0x00040000 + 5, // allow processing of huge methods diff --git a/compiler/env/TRMemory.cpp b/compiler/env/TRMemory.cpp index 2eda766f754..cc77f560c3a 100644 --- a/compiler/env/TRMemory.cpp +++ b/compiler/env/TRMemory.cpp @@ -301,7 +301,9 @@ const char * objectName[] = "Debug", "ClientSessionData", - "ROMClass" + "ROMClass", + + "SymbolValidationManager" }; diff --git a/compiler/env/TRMemory.hpp b/compiler/env/TRMemory.hpp index cda3787d41a..351145810e6 100644 --- a/compiler/env/TRMemory.hpp +++ b/compiler/env/TRMemory.hpp @@ -449,6 +449,8 @@ class TR_MemoryBase ClientSessionData, ROMClass, + SymbolValidationManager, + NumObjectTypes, // If adding new object types above, add the corresponding names // to objectName[] array defined in TRMemory.cpp @@ -682,8 +684,6 @@ inline void * operator new[](size_t size, PERSISTENT_NEW_DECLARE) { return TR_Memory::jitPersistentAlloc(size, TR_MemoryBase::UnknownType); } - - /* * TR_ByteCodeInfo exists in an awkward situation where it seems TR_ALLOC() * would be inappropriate for the structure, despite things needing to allocate them, diff --git a/compiler/il/symbol/OMRResolvedMethodSymbol.cpp b/compiler/il/symbol/OMRResolvedMethodSymbol.cpp index 1b3f25f6f40..23899e01c4b 100644 --- a/compiler/il/symbol/OMRResolvedMethodSymbol.cpp +++ b/compiler/il/symbol/OMRResolvedMethodSymbol.cpp @@ -160,7 +160,9 @@ OMR::ResolvedMethodSymbol::ResolvedMethodSymbol(TR_ResolvedMethod * method, TR:: // Set the interpreted flag for an interpreted method unless we're calling // the method that's being jitted // - if ((_methodIndex > JITTED_METHOD_INDEX && !_resolvedMethod->isSameMethod(comp->getJittedMethodSymbol()->getResolvedMethod())) || comp->isDLT()) + if ((_methodIndex > JITTED_METHOD_INDEX && !_resolvedMethod->isSameMethod(comp->getJittedMethodSymbol()->getResolvedMethod())) + || comp->isDLT() + || (comp->getOption(TR_UseSymbolValidationManager) && comp->compileRelocatableCode())) { if (_resolvedMethod->isInterpreted()) { diff --git a/compiler/optimizer/Inliner.cpp b/compiler/optimizer/Inliner.cpp index a7f01469fff..d7ebdd61def 100644 --- a/compiler/optimizer/Inliner.cpp +++ b/compiler/optimizer/Inliner.cpp @@ -5689,6 +5689,8 @@ TR_CallSite::addTarget(TR_Memory* mem, TR_InlinerBase *inliner, TR_VirtualGuardS addTarget(result); + _comp->validateTargetToBeInlined(implementer); + if(inliner->tracer()->heuristicLevel()) { char name[1024]; diff --git a/compiler/optimizer/LocalOpts.cpp b/compiler/optimizer/LocalOpts.cpp index 5a092720d8c..46dafff88c8 100644 --- a/compiler/optimizer/LocalOpts.cpp +++ b/compiler/optimizer/LocalOpts.cpp @@ -8058,7 +8058,9 @@ TR_ColdBlockMarker::hasNotYetRun(TR::Node *node) TR::SymbolReference *symRef = node->getSymbolReference(); bool isUnresolved; - if (comp()->compileRelocatableCode() && !comp()->getOption(TR_DisablePeekAOTResolutions)) + if (comp()->compileRelocatableCode() && + !comp()->getOption(TR_UseSymbolValidationManager) && + !comp()->getOption(TR_DisablePeekAOTResolutions)) isUnresolved = symRef->isUnresolvedMethodInCP(comp()); else isUnresolved = symRef->isUnresolved(); @@ -8090,7 +8092,9 @@ TR_ColdBlockMarker::hasNotYetRun(TR::Node *node) } else { - if (comp()->compileRelocatableCode() && !comp()->getOption(TR_DisablePeekAOTResolutions)) + if (comp()->compileRelocatableCode() && + !comp()->getOption(TR_UseSymbolValidationManager) && + !comp()->getOption(TR_DisablePeekAOTResolutions)) { bool isUnresolved = node->getSymbolReference()->isUnresolvedFieldInCP(comp()); //currentely node->hasUnresolvedSymbolReference() returns true more often for AOT than non-AOT beacause of @@ -8104,7 +8108,15 @@ TR_ColdBlockMarker::hasNotYetRun(TR::Node *node) return isUnresolved; } else + { + if (comp()->compileRelocatableCode() + && comp()->getOption(TR_UseSymbolValidationManager) + && node->getSymbol()->isConstString()) + { + return false; + } return true; + } } } return false; diff --git a/compiler/optimizer/VPConstraint.cpp b/compiler/optimizer/VPConstraint.cpp index cbdb181d79a..e2ca13a00ca 100644 --- a/compiler/optimizer/VPConstraint.cpp +++ b/compiler/optimizer/VPConstraint.cpp @@ -1215,8 +1215,9 @@ TR::VPClassType *TR::VPClassType::create(OMR::ValuePropagation *vp, const char * if (classObject) { bool isClassInitialized = false; + bool allowForAOT = vp->comp()->getOption(TR_UseSymbolValidationManager); TR_PersistentClassInfo * classInfo = - vp->comp()->getPersistentInfo()->getPersistentCHTable()->findClassInfoAfterLocking(classObject, vp->comp()); + vp->comp()->getPersistentInfo()->getPersistentCHTable()->findClassInfoAfterLocking(classObject, vp->comp(), allowForAOT); if (classInfo && classInfo->isInitialized()) { if (isFixed) @@ -1293,6 +1294,8 @@ TR::VPKnownObject *TR::VPKnownObject::create(OMR::ValuePropagation *vp, TR::Know { TR::KnownObjectTable *knot = vp->comp()->getKnownObjectTable(); TR_ASSERT(knot, "Can't create a TR::VPKnownObject without a known-object table"); + if (!knot) + return NULL; if (knot->isNull(index)) // No point in worrying about the NULL case because existing constraints handle that optimally return NULL; diff --git a/compiler/optimizer/VPHandlers.cpp b/compiler/optimizer/VPHandlers.cpp index 874715fb5e8..ad6d489efb9 100644 --- a/compiler/optimizer/VPHandlers.cpp +++ b/compiler/optimizer/VPHandlers.cpp @@ -1599,6 +1599,7 @@ TR::Node *constrainAload(OMR::ValuePropagation *vp, TR::Node *node) sym->isFinal())) haveClassLookaheadInfo = true; + bool allowForAOT = vp->comp()->getOption(TR_UseSymbolValidationManager); if (haveClassLookaheadInfo) { bool foundInfo = false; @@ -1623,13 +1624,12 @@ TR::Node *constrainAload(OMR::ValuePropagation *vp, TR::Node *node) } bool isClassInitialized = false; TR_PersistentClassInfo * classInfo = - vp->comp()->getPersistentInfo()->getPersistentCHTable()->findClassInfoAfterLocking(classOfStatic, vp->comp()); + vp->comp()->getPersistentInfo()->getPersistentCHTable()->findClassInfoAfterLocking(classOfStatic, vp->comp(), allowForAOT); if (classInfo && classInfo->isInitialized()) isClassInitialized = true; if (classOfStatic != vp->comp()->getSystemClassPointer() && isClassInitialized && - !vp->comp()->getOption(TR_AOT) && (type == TR::Address)) { TR::VMAccessCriticalSection constrainAloadCriticalSection(vp->comp(), @@ -1663,7 +1663,7 @@ TR::Node *constrainAload(OMR::ValuePropagation *vp, TR::Node *node) if (!foundInfo) { TR_PersistentClassInfo * classInfo = - vp->comp()->getPersistentInfo()->getPersistentCHTable()->findClassInfoAfterLocking(symRef->getOwningMethod(vp->comp())->classOfStatic(symRef->getCPIndex()), vp->comp()); + vp->comp()->getPersistentInfo()->getPersistentCHTable()->findClassInfoAfterLocking(symRef->getOwningMethod(vp->comp())->classOfStatic(symRef->getCPIndex()), vp->comp(), allowForAOT); if (classInfo && classInfo->getFieldInfo()) { TR_PersistentFieldInfo * fieldInfo = classInfo->getFieldInfo()->findFieldInfo(vp->comp(), node, false); @@ -2366,6 +2366,7 @@ TR::Node *constrainIaload(OMR::ValuePropagation *vp, TR::Node *node) sym->isFinal())) haveClassLookaheadInfo = true; + bool allowForAOT = vp->comp()->getOption(TR_UseSymbolValidationManager); if (haveClassLookaheadInfo) { if (sym->isStatic() && sym->isFinal()) @@ -2375,13 +2376,12 @@ TR::Node *constrainIaload(OMR::ValuePropagation *vp, TR::Node *node) TR_OpaqueClassBlock * classOfStatic = symRef->getOwningMethod(vp->comp())->classOfStatic(symRef->getCPIndex()); bool isClassInitialized = false; TR_PersistentClassInfo * classInfo = - vp->comp()->getPersistentInfo()->getPersistentCHTable()->findClassInfoAfterLocking(classOfStatic, vp->comp()); + vp->comp()->getPersistentInfo()->getPersistentCHTable()->findClassInfoAfterLocking(classOfStatic, vp->comp(), allowForAOT); if (classInfo && classInfo->isInitialized()) isClassInitialized = true; if ((classOfStatic != vp->comp()->getSystemClassPointer() && isClassInitialized && - !vp->comp()->getOption(TR_AOT) && (type == TR::Address))) { TR::VMAccessCriticalSection constrainIaloadCriticalSection(vp->comp(), @@ -4870,6 +4870,9 @@ static void devirtualizeCall(OMR::ValuePropagation *vp, TR::Node *node) return; } + if (!vp->comp()->fe()->canDevirtualizeDispatch()) + return; + int32_t firstArgIndex = node->getFirstArgumentIndex(); bool isGlobal; TR::VPConstraint *constraint = vp->getConstraint(node->getChild(firstArgIndex), isGlobal); @@ -9463,7 +9466,8 @@ static TR::Node *constrainIfcmpeqne(OMR::ValuePropagation *vp, TR::Node *node, b } #ifdef J9_PROJECT_SPECIFIC - if (!vp->comp()->compileRelocatableCode() && + + if ((!vp->comp()->compileRelocatableCode() || vp->comp()->getOption(TR_UseSymbolValidationManager)) && vp->lastTimeThrough() && vp->comp()->performVirtualGuardNOPing() && !vp->_curBlock->isCold() && @@ -9487,12 +9491,13 @@ static TR::Node *constrainIfcmpeqne(OMR::ValuePropagation *vp, TR::Node *node, b if (typeConstraint) { TR::VPConstraint *resolvedTypeConstraint = typeConstraint->asResolvedClass(); + bool allowForAOT = vp->comp()->getOption(TR_UseSymbolValidationManager); if (resolvedTypeConstraint) { TR_OpaqueClassBlock *clazz = resolvedTypeConstraint->getClass(); TR_PersistentClassInfo * classInfo = - vp->comp()->getPersistentInfo()->getPersistentCHTable()->findClassInfoAfterLocking(clazz, vp->comp()); + vp->comp()->getPersistentInfo()->getPersistentCHTable()->findClassInfoAfterLocking(clazz, vp->comp(), allowForAOT); if (vp->trace()) traceMsg(vp->comp(), "MyDebug: clazz %p classInfo %p classInfo->isInitialized() %d\n", @@ -9525,7 +9530,7 @@ static TR::Node *constrainIfcmpeqne(OMR::ValuePropagation *vp, TR::Node *node, b else { TR_PersistentClassInfo * classInfo = - vp->comp()->getPersistentInfo()->getPersistentCHTable()->findClassInfoAfterLocking(clazz, vp->comp()); + vp->comp()->getPersistentInfo()->getPersistentCHTable()->findClassInfoAfterLocking(clazz, vp->comp(), allowForAOT); if (vp->trace()) traceMsg(vp->comp(), "MyDebug: clazz %p classInfo %p classInfo->isInitialized() %d\n", diff --git a/compiler/runtime/Runtime.hpp b/compiler/runtime/Runtime.hpp index fa0f7f03130..4d790994193 100644 --- a/compiler/runtime/Runtime.hpp +++ b/compiler/runtime/Runtime.hpp @@ -356,17 +356,64 @@ typedef enum TR_DebugCounter = 59, TR_ClassUnloadAssumption = 60, // this should not be used in AOT relocations TR_J2IVirtualThunkPointer = 61, - TR_NumExternalRelocationKinds = 62, + TR_InlinedAbstractMethodWithNopGuard = 62, + TR_ValidateRootClass = 63, + TR_ValidateClassByName = 64, + TR_ValidateProfiledClass = 65, + TR_ValidateClassFromCP = 66, + TR_ValidateDefiningClassFromCP = 67, + TR_ValidateStaticClassFromCP = 68, + TR_ValidateClassFromMethod = 69, + TR_ValidateComponentClassFromArrayClass= 70, + TR_ValidateArrayClassFromComponentClass= 71, + TR_ValidateSuperClassFromClass = 72, + TR_ValidateClassInstanceOfClass = 73, + TR_ValidateSystemClassByName = 74, + TR_ValidateClassFromITableIndexCP = 75, + TR_ValidateDeclaringClassFromFieldOrStatic=76, + TR_ValidateClassClass = 77, + TR_ValidateConcreteSubClassFromClass = 78, + TR_ValidateClassChain = 79, + TR_ValidateRomClass = 80, + TR_ValidatePrimitiveClass = 81, + TR_ValidateMethodFromInlinedSite = 82, + TR_ValidateMethodByName = 83, + TR_ValidateMethodFromClass = 84, + TR_ValidateStaticMethodFromCP = 85, + TR_ValidateSpecialMethodFromCP = 86, + TR_ValidateVirtualMethodFromCP = 87, + TR_ValidateVirtualMethodFromOffset = 88, + TR_ValidateInterfaceMethodFromCP = 89, + TR_ValidateMethodFromClassAndSig = 90, + TR_ValidateStackWalkerMaySkipFramesRecord=91, + TR_ValidateArrayClassFromJavaVM = 92, + TR_ValidateClassInfoIsInitialized = 93, + TR_ValidateMethodFromSingleImplementer = 94, + TR_ValidateMethodFromSingleInterfaceImplementer = 95, + TR_ValidateMethodFromSingleAbstractImplementer = 96, + TR_ValidateImproperInterfaceMethodFromCP=97, + TR_SymbolFromManager = 98, + TR_NumExternalRelocationKinds = 99, TR_ExternalRelocationTargetKindMask = 0xff, } TR_ExternalRelocationTargetKind; +namespace TR { +enum SymbolType + { + typeOpaque, + typeClass, + typeMethod, + }; + +} typedef struct TR_RelocationRecordInformation { uintptr_t data1; uintptr_t data2; uintptr_t data3; uintptr_t data4; + uintptr_t data5; } TR_RelocationRecordInformation; diff --git a/compiler/x/amd64/codegen/OMRMemoryReference.cpp b/compiler/x/amd64/codegen/OMRMemoryReference.cpp index 25a07299183..ccf00257d28 100644 --- a/compiler/x/amd64/codegen/OMRMemoryReference.cpp +++ b/compiler/x/amd64/codegen/OMRMemoryReference.cpp @@ -400,10 +400,26 @@ OMR::X86::AMD64::MemoryReference::addMetaDataForCodeAddressWithLoad( if (sr.getSymbol()->isStatic()) { if (cg->needClassAndMethodPointerRelocations()) - cg->addExternalRelocation(new (cg->trHeapMemory()) TR::ExternalRelocation(displacementLocation, (uint8_t *)srCopy, - (uint8_t *)(uintptr_t)containingInstruction->getNode()->getInlinedSiteIndex(), - TR_ClassAddress, cg),__FILE__, __LINE__, - containingInstruction->getNode()); + { + if (cg->comp()->getOption(TR_UseSymbolValidationManager)) + { + cg->addExternalRelocation(new (cg->trHeapMemory()) TR::ExternalRelocation(displacementLocation, + (uint8_t *)sr.getSymbol()->castToStaticSymbol()->getStaticAddress(), + (uint8_t *)TR::SymbolType::typeClass, + TR_SymbolFromManager, + cg), + __FILE__, __LINE__, + containingInstruction->getNode()); + } + else + { + cg->addExternalRelocation(new (cg->trHeapMemory()) TR::ExternalRelocation(displacementLocation, (uint8_t *)srCopy, + (uint8_t *)(uintptr_t)containingInstruction->getNode()->getInlinedSiteIndex(), + TR_ClassAddress, cg),__FILE__, __LINE__, + containingInstruction->getNode()); + } + } + if (cg->wantToPatchClassPointer(NULL, displacementLocation)) // may not point to beginning of class { cg->jitAddPicToPatchOnClassRedefinition(((void *)displacement), displacementLocation); diff --git a/compiler/x/codegen/ControlFlowEvaluator.cpp b/compiler/x/codegen/ControlFlowEvaluator.cpp index 635d5e9d75e..ecc1fc66a83 100644 --- a/compiler/x/codegen/ControlFlowEvaluator.cpp +++ b/compiler/x/codegen/ControlFlowEvaluator.cpp @@ -2280,6 +2280,7 @@ static bool virtualGuardHelper(TR::Node *node, TR::CodeGenerator *cg) case TR_DirectMethodGuard: case TR_NonoverriddenGuard: case TR_InterfaceGuard: + case TR_AbstractGuard: case TR_MethodEnterExitGuard: case TR_HCRGuard: //case TR_AbstractGuard: diff --git a/compiler/x/codegen/DataSnippet.cpp b/compiler/x/codegen/DataSnippet.cpp index 6d122006d8d..6615e0f4fbb 100644 --- a/compiler/x/codegen/DataSnippet.cpp +++ b/compiler/x/codegen/DataSnippet.cpp @@ -54,9 +54,8 @@ TR::X86DataSnippet::addMetaDataForCodeAddress(uint8_t *cursor) if (_isClassAddress) { bool needRelocation = TR::Compiler->cls.classUnloadAssumptionNeedsRelocation(cg()->comp()); - if (needRelocation) + if (needRelocation && !cg()->comp()->compileRelocatableCode()) { - TR_ASSERT(!cg()->comp()->compileRelocatableCode(), "ClassUnloadAssumption relocation should not be used during AOT compilation"); cg()->addExternalRelocation(new (TR::comp()->trHeapMemory()) TR::ExternalRelocation(cursor, NULL, TR_ClassUnloadAssumption, cg()), __FILE__, __LINE__, self()->getNode()); @@ -80,6 +79,16 @@ TR::X86DataSnippet::addMetaDataForCodeAddress(uint8_t *cursor) cg()->jitAdd32BitPicToPatchOnClassRedefinition(((void *) -1), (void *) cursor, true); } } + + TR_OpaqueClassBlock *clazz = getData(); + if (clazz && cg()->comp()->compileRelocatableCode() && cg()->comp()->getOption(TR_UseSymbolValidationManager)) + { + cg()->addExternalRelocation(new (cg()->trHeapMemory()) TR::ExternalRelocation(cursor, + (uint8_t *)clazz, + (uint8_t *)TR::SymbolType::typeClass, + TR_SymbolFromManager, + cg()), __FILE__, __LINE__, getNode()); + } } } diff --git a/compiler/x/codegen/OMRMemoryReference.cpp b/compiler/x/codegen/OMRMemoryReference.cpp index 6aa9b6ebd46..3b046508787 100644 --- a/compiler/x/codegen/OMRMemoryReference.cpp +++ b/compiler/x/codegen/OMRMemoryReference.cpp @@ -1228,9 +1228,21 @@ OMR::X86::MemoryReference::addMetaDataForCodeAddress( if (cg->needClassAndMethodPointerRelocations()) { *(int32_t *)cursor = (int32_t)(TR::Compiler->cls.persistentClassPointerFromClassPointer(cg->comp(), (TR_OpaqueClassBlock*)(self()->getSymbolReference().getOffset() + (intptrj_t)staticSym->getStaticAddress()))); - cg->addExternalRelocation(new (cg->trHeapMemory()) TR::ExternalRelocation(cursor, (uint8_t *)&self()->getSymbolReference(), - node ? (uint8_t *)(intptrj_t)node->getInlinedSiteIndex() : (uint8_t *)-1, - TR_ClassAddress, cg), __FILE__, __LINE__, node); + if (cg->comp()->getOption(TR_UseSymbolValidationManager)) + { + cg->addExternalRelocation(new (cg->trHeapMemory()) TR::ExternalRelocation(cursor, + (uint8_t *)(self()->getSymbolReference().getOffset() + (intptrj_t)staticSym->getStaticAddress()), + (uint8_t *)TR::SymbolType::typeClass, + TR_SymbolFromManager, + cg), + __FILE__, __LINE__, node); + } + else + { + cg->addExternalRelocation(new (cg->trHeapMemory()) TR::ExternalRelocation(cursor, (uint8_t *)&self()->getSymbolReference(), + node ? (uint8_t *)(intptrj_t)node->getInlinedSiteIndex() : (uint8_t *)-1, + TR_ClassAddress, cg), __FILE__, __LINE__, node); + } } if (cg->wantToPatchClassPointer(NULL, cursor)) // might not point to beginning of class diff --git a/compiler/x/codegen/X86BinaryEncoding.cpp b/compiler/x/codegen/X86BinaryEncoding.cpp index d23245f158e..ec16c981d94 100644 --- a/compiler/x/codegen/X86BinaryEncoding.cpp +++ b/compiler/x/codegen/X86BinaryEncoding.cpp @@ -868,6 +868,7 @@ TR::X86ImmInstruction::addMetaDataForCodeAddress(uint8_t *cursor) if (getReloKind() != -1) // TODO: need to change Body info one to use this { + TR::SymbolType symbolKind = TR::SymbolType::typeClass; switch (getReloKind()) { case TR_StaticRamMethodConst: @@ -883,15 +884,29 @@ TR::X86ImmInstruction::addMetaDataForCodeAddress(uint8_t *cursor) setReloKind(TR_RamMethod); // intentional fall-through case TR_RamMethod: + symbolKind = TR::SymbolType::typeMethod; // intentional fall-through case TR_ClassPointer: - cg()->addExternalRelocation(new (cg()->trHeapMemory()) TR::ExternalRelocation(cursor, - (uint8_t*)getNode(), - (TR_ExternalRelocationTargetKind) _reloKind, - cg()), - __FILE__, - __LINE__, - getNode()); + if (cg()->comp()->getOption(TR_UseSymbolValidationManager)) + { + cg()->addExternalRelocation(new (cg()->trHeapMemory()) TR::ExternalRelocation(cursor, + (uint8_t *)getSourceImmediate(), + (uint8_t *)symbolKind, + TR_SymbolFromManager, + cg()), + __FILE__, __LINE__, + getNode()); + } + else + { + cg()->addExternalRelocation(new (cg()->trHeapMemory()) TR::ExternalRelocation(cursor, + (uint8_t*)getNode(), + (TR_ExternalRelocationTargetKind) _reloKind, + cg()), + __FILE__, + __LINE__, + getNode()); + } break; default: cg()->addExternalRelocation(new (cg()->trHeapMemory()) TR::ExternalRelocation(cursor, 0, (TR_ExternalRelocationTargetKind)getReloKind(), cg()), @@ -1112,11 +1127,23 @@ TR::X86ImmSymInstruction::addMetaDataForCodeAddress(uint8_t *cursor) { if (cg()->needClassAndMethodPointerRelocations()) { - cg()->addExternalRelocation(new (cg()->trHeapMemory()) TR::ExternalRelocation(cursor, - (uint8_t *)getSymbolReference(), - getNode() ? (uint8_t *)(uintptr_t)getNode()->getInlinedSiteIndex() : (uint8_t *)-1, - TR_ClassAddress, - cg()), __FILE__,__LINE__, getNode()); + if (cg()->comp()->getOption(TR_UseSymbolValidationManager)) + { + cg()->addExternalRelocation(new (cg()->trHeapMemory()) TR::ExternalRelocation(cursor, + (uint8_t *)getSourceImmediate(), + (uint8_t *)TR::SymbolType::typeClass, + TR_SymbolFromManager, + cg()), + __FILE__, __LINE__, getNode()); + } + else + { + cg()->addExternalRelocation(new (cg()->trHeapMemory()) TR::ExternalRelocation(cursor, + (uint8_t *)getSymbolReference(), + getNode() ? (uint8_t *)(uintptr_t)getNode()->getInlinedSiteIndex() : (uint8_t *)-1, + TR_ClassAddress, + cg()), __FILE__,__LINE__, getNode()); + } } } else if (symbol->isMethod()) @@ -1479,6 +1506,7 @@ TR::X86RegImmInstruction::addMetaDataForCodeAddress(uint8_t *cursor) cg()->jitAdd32BitPicToPatchOnClassUnload(classPointer, (void *) cursor); } + TR::SymbolType symbolKind = TR::SymbolType::typeClass; switch (_reloKind) { case TR_HEAP_BASE: @@ -1524,13 +1552,27 @@ TR::X86RegImmInstruction::addMetaDataForCodeAddress(uint8_t *cursor) setReloKind(TR_RamMethod); // intentional fall-through case TR_RamMethod: + symbolKind = TR::SymbolType::typeMethod; // intentional fall-through case TR_ClassPointer: - cg()->addExternalRelocation(new (cg()->trHeapMemory()) TR::ExternalRelocation(cursor, - (uint8_t*)getNode(), - (TR_ExternalRelocationTargetKind) _reloKind, - cg()), - __FILE__, __LINE__, getNode()); + if (cg()->comp()->getOption(TR_UseSymbolValidationManager)) + { + cg()->addExternalRelocation(new (cg()->trHeapMemory()) TR::ExternalRelocation(cursor, + (uint8_t *)getSourceImmediate(), + (uint8_t *)symbolKind, + TR_SymbolFromManager, + cg()), + __FILE__, __LINE__, + getNode()); + } + else + { + cg()->addExternalRelocation(new (cg()->trHeapMemory()) TR::ExternalRelocation(cursor, + (uint8_t*)getNode(), + (TR_ExternalRelocationTargetKind) _reloKind, + cg()), + __FILE__, __LINE__, getNode()); + } break; default: @@ -1615,6 +1657,7 @@ TR::X86RegImmSymInstruction::addMetaDataForCodeAddress(uint8_t *cursor) TR::Symbol *symbol = getSymbolReference()->getSymbol(); TR_RelocationRecordInformation *recordInfo; + TR::SymbolType symbolKind = TR::SymbolType::typeClass; switch (getReloKind()) { case TR_ConstantPool: @@ -1637,14 +1680,26 @@ TR::X86RegImmSymInstruction::addMetaDataForCodeAddress(uint8_t *cursor) TR_ASSERT(!(getSymbolReference()->isUnresolved() && !symbol->isClassObject()), "expecting a resolved symbol for this instruction class!\n"); *(int32_t *)cursor = (int32_t)TR::Compiler->cls.persistentClassPointerFromClassPointer(cg()->comp(), (TR_OpaqueClassBlock*)(uintptr_t)getSourceImmediate()); - cg()->addExternalRelocation(new (cg()->trHeapMemory()) TR::ExternalRelocation(cursor, - (uint8_t *)getSymbolReference(), - getNode() ? (uint8_t *)(uintptr_t)getNode()->getInlinedSiteIndex() : (uint8_t *)-1, - (TR_ExternalRelocationTargetKind)getReloKind(), - cg()), - __FILE__, - __LINE__, - getNode()); + if (cg()->comp()->getOption(TR_UseSymbolValidationManager)) + { + cg()->addExternalRelocation(new (cg()->trHeapMemory()) TR::ExternalRelocation(cursor, + (uint8_t *)getSourceImmediate(), + (uint8_t *)TR::SymbolType::typeClass, + TR_SymbolFromManager, + cg()), + __FILE__, __LINE__, getNode()); + } + else + { + cg()->addExternalRelocation(new (cg()->trHeapMemory()) TR::ExternalRelocation(cursor, + (uint8_t *)getSymbolReference(), + getNode() ? (uint8_t *)(uintptr_t)getNode()->getInlinedSiteIndex() : (uint8_t *)-1, + (TR_ExternalRelocationTargetKind)getReloKind(), + cg()), + __FILE__, + __LINE__, + getNode()); + } } } break; @@ -1665,13 +1720,27 @@ TR::X86RegImmSymInstruction::addMetaDataForCodeAddress(uint8_t *cursor) if (getNode() && getNode()->getInlinedSiteIndex() == -1 && (void *)(uintptr_t) getSourceImmediate() == cg()->comp()->getCurrentMethod()->resolvedMethodAddress()) setReloKind(TR_RamMethod); + symbolKind = TR::SymbolType::typeMethod; // intentional fall-through case TR_ClassPointer: - cg()->addExternalRelocation(new (cg()->trHeapMemory()) TR::ExternalRelocation(cursor, - (uint8_t*)getNode(), - (TR_ExternalRelocationTargetKind)getReloKind(), - cg()), - __FILE__, __LINE__, getNode()); + if (cg()->comp()->getOption(TR_UseSymbolValidationManager)) + { + cg()->addExternalRelocation(new (cg()->trHeapMemory()) TR::ExternalRelocation(cursor, + (uint8_t *)getSourceImmediate(), + (uint8_t *)symbolKind, + TR_SymbolFromManager, + cg()), + __FILE__, __LINE__, + getNode()); + } + else + { + cg()->addExternalRelocation(new (cg()->trHeapMemory()) TR::ExternalRelocation(cursor, + (uint8_t*)getNode(), + (TR_ExternalRelocationTargetKind)getReloKind(), + cg()), + __FILE__, __LINE__, getNode()); + } break; case TR_DebugCounter: { @@ -1906,12 +1975,25 @@ TR::X86MemImmInstruction::addMetaDataForCodeAddress(uint8_t *cursor) if (_reloKind == TR_ClassAddress && cg()->needClassAndMethodPointerRelocations()) { TR_ASSERT(getNode(), "node expected to be non-NULL here"); - cg()->addExternalRelocation(new (cg()->trHeapMemory()) TR::ExternalRelocation(cursor, - (uint8_t *)getNode()->getSymbolReference(), - (uint8_t *)(uintptr_t)getNode()->getInlinedSiteIndex(), - TR_ClassAddress, - cg()), - __FILE__,__LINE__, getNode()); + if (cg()->comp()->getOption(TR_UseSymbolValidationManager)) + { + cg()->addExternalRelocation(new (cg()->trHeapMemory()) TR::ExternalRelocation(cursor, + (uint8_t *)getSourceImmediate(), + (uint8_t *)TR::SymbolType::typeClass, + TR_SymbolFromManager, + cg()), + __FILE__, __LINE__, + getNode()); + } + else + { + cg()->addExternalRelocation(new (cg()->trHeapMemory()) TR::ExternalRelocation(cursor, + (uint8_t *)getNode()->getSymbolReference(), + (uint8_t *)(uintptr_t)getNode()->getInlinedSiteIndex(), + TR_ClassAddress, + cg()), + __FILE__,__LINE__, getNode()); + } } } @@ -2055,9 +2137,21 @@ TR::X86MemImmSymInstruction::addMetaDataForCodeAddress(uint8_t *cursor) if (cg()->needClassAndMethodPointerRelocations()) { *(int32_t *)cursor = (int32_t)TR::Compiler->cls.persistentClassPointerFromClassPointer(cg()->comp(), (TR_OpaqueClassBlock*)(uintptr_t)getSourceImmediate()); - cg()->addExternalRelocation(new (cg()->trHeapMemory()) TR::ExternalRelocation(cursor, (uint8_t *)getSymbolReference(), getNode() ? (uint8_t *)(uintptr_t)getNode()->getInlinedSiteIndex() : (uint8_t *)-1, TR_ClassAddress, cg()), - __FILE__, __LINE__, getNode()); - + if (cg()->comp()->getOption(TR_UseSymbolValidationManager)) + { + cg()->addExternalRelocation(new (cg()->trHeapMemory()) TR::ExternalRelocation(cursor, + (uint8_t *)getSourceImmediate(), + (uint8_t *)TR::SymbolType::typeClass, + TR_SymbolFromManager, + cg()), + __FILE__, __LINE__, + getNode()); + } + else + { + cg()->addExternalRelocation(new (cg()->trHeapMemory()) TR::ExternalRelocation(cursor, (uint8_t *)getSymbolReference(), getNode() ? (uint8_t *)(uintptr_t)getNode()->getInlinedSiteIndex() : (uint8_t *)-1, TR_ClassAddress, cg()), + __FILE__, __LINE__, getNode()); + } } } else if (symbol->isMethod()) @@ -2571,16 +2665,32 @@ TR::AMD64RegImm64Instruction::addMetaDataForCodeAddress(uint8_t *cursor) } else { + TR::SymbolType symbolKind = TR::SymbolType::typeClass; switch (_reloKind) { case TR_ClassAddress: + { TR_ASSERT(getNode(), "node assumed to be non-NULL here"); - cg()->addExternalRelocation(new (cg()->trHeapMemory()) TR::ExternalRelocation(cursor, - (uint8_t *)methodSymRef, - (uint8_t *)getNode()->getInlinedSiteIndex(), - TR_ClassAddress, - cg()), - __FILE__,__LINE__, getNode()); + if (cg()->comp()->getOption(TR_UseSymbolValidationManager)) + { + cg()->addExternalRelocation(new (cg()->trHeapMemory()) TR::ExternalRelocation(cursor, + (uint8_t *)getSourceImmediate(), + (uint8_t *)TR::SymbolType::typeClass, + TR_SymbolFromManager, + cg()), + __FILE__, __LINE__, + getNode()); + } + else + { + cg()->addExternalRelocation(new (cg()->trHeapMemory()) TR::ExternalRelocation(cursor, + (uint8_t *)methodSymRef, + (uint8_t *)getNode()->getInlinedSiteIndex(), + TR_ClassAddress, + cg()), + __FILE__,__LINE__, getNode()); + } + } break; case TR_MethodPointer: @@ -2589,13 +2699,27 @@ TR::AMD64RegImm64Instruction::addMetaDataForCodeAddress(uint8_t *cursor) setReloKind(TR_RamMethod); // intentional fall-through case TR_RamMethod: + symbolKind = TR::SymbolType::typeMethod; // intentional fall-through case TR_ClassPointer: - cg()->addExternalRelocation(new (cg()->trHeapMemory()) TR::ExternalRelocation(cursor, - (uint8_t*)getNode(), - (TR_ExternalRelocationTargetKind) _reloKind, - cg()), - __FILE__, __LINE__, getNode()); + if (cg()->comp()->getOption(TR_UseSymbolValidationManager)) + { + cg()->addExternalRelocation(new (cg()->trHeapMemory()) TR::ExternalRelocation(cursor, + (uint8_t *)getSourceImmediate(), + (uint8_t *)symbolKind, + TR_SymbolFromManager, + cg()), + __FILE__, __LINE__, + getNode()); + } + else + { + cg()->addExternalRelocation(new (cg()->trHeapMemory()) TR::ExternalRelocation(cursor, + (uint8_t*)getNode(), + (TR_ExternalRelocationTargetKind) _reloKind, + cg()), + __FILE__, __LINE__, getNode()); + } break; case TR_JNIStaticTargetAddress: case TR_JNISpecialTargetAddress: