From e3f3e09d16f4c28d2572a601b8375b48d8d9fcb4 Mon Sep 17 00:00:00 2001 From: Irwin D'Souza Date: Wed, 5 Sep 2018 14:59:50 -0400 Subject: [PATCH 01/16] Fix Higher Method Counts for AOT If the user specifies higher method counts, don't delay relocation and make the scount the same as the count. Signed-off-by: Irwin D'Souza --- compiler/control/OMROptions.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/compiler/control/OMROptions.cpp b/compiler/control/OMROptions.cpp index e01e31f5671..2b4a5e622a7 100644 --- a/compiler/control/OMROptions.cpp +++ b/compiler/control/OMROptions.cpp @@ -2216,6 +2216,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 { From 6eaccdb0e9bb8f39da64ab6deb3d934d105b823d Mon Sep 17 00:00:00 2001 From: Irwin D'Souza Date: Wed, 15 Aug 2018 10:13:58 -0400 Subject: [PATCH 02/16] Check if KNOT is NULL If the user specifies disableKnownObjectTable, the KNOT does not get created. However, some parts of the code assume the KNOT always exist. Signed-off-by: Irwin D'Souza --- compiler/optimizer/VPConstraint.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/compiler/optimizer/VPConstraint.cpp b/compiler/optimizer/VPConstraint.cpp index cbdb181d79a..843849e56ba 100644 --- a/compiler/optimizer/VPConstraint.cpp +++ b/compiler/optimizer/VPConstraint.cpp @@ -1293,6 +1293,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; From 5e1590083b4bd07aa779f488b831f79bad5793e3 Mon Sep 17 00:00:00 2001 From: Irwin D'Souza Date: Thu, 4 Oct 2018 10:39:01 -0400 Subject: [PATCH 03/16] Add new External Relocation Types Add new external relocation types to enable the use of the Symbol Validation Manager which will be used to validate relocatable compilations. Signed-off-by: Irwin D'Souza --- compiler/codegen/Relocation.cpp | 37 +++++++++++++++++++++++++ compiler/runtime/Runtime.hpp | 48 ++++++++++++++++++++++++++++++++- 2 files changed, 84 insertions(+), 1 deletion(-) 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/runtime/Runtime.hpp b/compiler/runtime/Runtime.hpp index fa0f7f03130..19133978360 100644 --- a/compiler/runtime/Runtime.hpp +++ b/compiler/runtime/Runtime.hpp @@ -356,11 +356,57 @@ 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; From 5f2e1cc093614807a4fefea121d5614fed12fcf6 Mon Sep 17 00:00:00 2001 From: Irwin D'Souza Date: Thu, 4 Oct 2018 10:39:22 -0400 Subject: [PATCH 04/16] Add option to guard uses of Sym Validation Manager Signed-off-by: Irwin D'Souza --- compiler/control/OMROptions.cpp | 1 + compiler/control/OMROptions.hpp | 2 +- compiler/env/TRMemory.cpp | 4 +++- compiler/env/TRMemory.hpp | 4 ++-- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/compiler/control/OMROptions.cpp b/compiler/control/OMROptions.cpp index 2b4a5e622a7..352657eb414 100644 --- a/compiler/control/OMROptions.cpp +++ b/compiler/control/OMROptions.cpp @@ -1319,6 +1319,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"}, diff --git a/compiler/control/OMROptions.hpp b/compiler/control/OMROptions.hpp index ee2be16cbd1..78883c62703 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, 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, From 2347110d9559740fc3195d340e871898e3cb2d52 Mon Sep 17 00:00:00 2001 From: Irwin D'Souza Date: Thu, 4 Oct 2018 10:39:38 -0400 Subject: [PATCH 05/16] Relocatable abstract method inlining Enable the infrastructure to allow inlining of abstract methods inlining in relocatable compilations. Signed-off-by: Irwin D'Souza --- compiler/x/codegen/ControlFlowEvaluator.cpp | 1 + 1 file changed, 1 insertion(+) 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: From 7ba167cbe4f60f422d4cbdd5eab48db526ab3841 Mon Sep 17 00:00:00 2001 From: Irwin D'Souza Date: Wed, 5 Sep 2018 15:00:03 -0400 Subject: [PATCH 06/16] Add one more field for relodata This commit adds another field into relodata so that a downstream project can make use of it. These fields are generic data fields whose contents can vary based on the relocation record being generated. Signed-off-by: Irwin D'Souza --- compiler/runtime/Runtime.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/runtime/Runtime.hpp b/compiler/runtime/Runtime.hpp index 19133978360..4d790994193 100644 --- a/compiler/runtime/Runtime.hpp +++ b/compiler/runtime/Runtime.hpp @@ -413,6 +413,7 @@ typedef struct TR_RelocationRecordInformation { uintptr_t data2; uintptr_t data3; uintptr_t data4; + uintptr_t data5; } TR_RelocationRecordInformation; From 7df29e2760d2ffcf9f5f28fa195b84dfe3714385 Mon Sep 17 00:00:00 2001 From: Irwin D'Souza Date: Tue, 14 Aug 2018 22:32:28 -0400 Subject: [PATCH 07/16] Used resolved interpreter dispatch for AOT Previously, because almost everything was "unresolved" under AOT, all calls would use the unresolved dispatch. However, with the new validations, very few unresolved pointers are only unresolved because of AOT. Therefore, generating an unresolved dispatch is incorrect. The solution to this problem is to assume, during an AOT compile, that all methods are interpreted. Thus, if a method is resolved, the compiler will generate a resolved interpreter dispatch snippet, which can patch the caller if/when the method is compiled. Signed-off-by: Irwin D'Souza --- compiler/il/symbol/OMRResolvedMethodSymbol.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) 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()) { From bf3d1ec9d922241ae5296434ddb4be20dd8e73f5 Mon Sep 17 00:00:00 2001 From: Irwin D'Souza Date: Thu, 23 Aug 2018 15:16:30 -0400 Subject: [PATCH 08/16] Add Front End query for canDevirtualizeDispatch Sometimes, when devirtualizing, the compiler keeps the call virtual, but uses a cpIndex of -1, which causes a problem during relocation. Thus this commit adds a check to not devirtualize calls based on a Front End query. Signed-off-by: Irwin D'Souza --- compiler/codegen/FrontEnd.hpp | 2 ++ compiler/optimizer/VPHandlers.cpp | 3 +++ 2 files changed, 5 insertions(+) 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/optimizer/VPHandlers.cpp b/compiler/optimizer/VPHandlers.cpp index 874715fb5e8..a7aa1bb52bd 100644 --- a/compiler/optimizer/VPHandlers.cpp +++ b/compiler/optimizer/VPHandlers.cpp @@ -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); From a18a64aa5ee708cd9e3285ec73fc8f98b5263845 Mon Sep 17 00:00:00 2001 From: Irwin D'Souza Date: Thu, 6 Sep 2018 01:23:53 -0400 Subject: [PATCH 09/16] Add query to validate targets to be inlined Add a query to allow the validation of targets to be inlined for relocatable compiles. Signed-off-by: Irwin D'Souza --- compiler/compile/OMRCompilation.hpp | 6 ++++++ compiler/optimizer/Inliner.cpp | 2 ++ 2 files changed, 8 insertions(+) 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/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]; From 1520ed098d17ca76238e9a9fc0591f22d41f98cd Mon Sep 17 00:00:00 2001 From: Irwin D'Souza Date: Wed, 29 Aug 2018 12:19:51 -0400 Subject: [PATCH 10/16] Update relocation for class and method pointers Under the option to use the Symbol Validation Manager, the correct way to acquire the address for classes or methods, is to go through the manager, since it maintains consistency with all the validations as well as relocations. This commit transmutes the TR_ClassPointer, TR_MethodPointer, and TR_RamMethod into a TR_SymbolFromManager relocation record in order to maintain consistency with the rest of the validations. Signed-off-by: Irwin D'Souza --- compiler/x/codegen/X86BinaryEncoding.cpp | 104 ++++++++++++++++++----- 1 file changed, 82 insertions(+), 22 deletions(-) diff --git a/compiler/x/codegen/X86BinaryEncoding.cpp b/compiler/x/codegen/X86BinaryEncoding.cpp index d23245f158e..b7f947406a7 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()), @@ -1479,6 +1494,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 +1540,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 +1645,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: @@ -1665,13 +1696,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: { @@ -2571,6 +2616,7 @@ TR::AMD64RegImm64Instruction::addMetaDataForCodeAddress(uint8_t *cursor) } else { + TR::SymbolType symbolKind = TR::SymbolType::typeClass; switch (_reloKind) { case TR_ClassAddress: @@ -2589,13 +2635,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: From 34f7416180295904e6a0e3ec051eb0c713857b19 Mon Sep 17 00:00:00 2001 From: Irwin D'Souza Date: Wed, 29 Aug 2018 10:36:20 -0400 Subject: [PATCH 11/16] Update relocation for ClassAddress Under the option to use the Symbol Validation Manager, the correct way to acquire the address for classes is to go through the manager, since it maintains consistency with all the validations as well as relocations. This commit transmutes the TR_ClassAddress into a TR_SymbolFromManager relocation record in order to maintain consistency with the rest of the validations. Signed-off-by: Irwin D'Souza --- .../x/amd64/codegen/OMRMemoryReference.cpp | 24 +++- compiler/x/codegen/OMRMemoryReference.cpp | 18 ++- compiler/x/codegen/X86BinaryEncoding.cpp | 120 ++++++++++++++---- 3 files changed, 127 insertions(+), 35 deletions(-) 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/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 b7f947406a7..ec16c981d94 100644 --- a/compiler/x/codegen/X86BinaryEncoding.cpp +++ b/compiler/x/codegen/X86BinaryEncoding.cpp @@ -1127,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()) @@ -1668,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; @@ -1951,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()); + } } } @@ -2100,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()) @@ -2620,13 +2669,28 @@ TR::AMD64RegImm64Instruction::addMetaDataForCodeAddress(uint8_t *cursor) 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: From 482c102656379277aa7a75912b68dc297a166639 Mon Sep 17 00:00:00 2001 From: Irwin D'Souza Date: Thu, 30 Aug 2018 15:09:52 -0400 Subject: [PATCH 12/16] Improve classInfo queries under AOT This commit allows, under AOT and the option to use the Symbol Validation Manager, some findClassInfoAfterLocking queries in order to provide the optimizer with more information that was previously unavailable. Signed-off-by: Irwin D'Souza --- compiler/optimizer/VPConstraint.cpp | 3 ++- compiler/optimizer/VPHandlers.cpp | 18 ++++++++++-------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/compiler/optimizer/VPConstraint.cpp b/compiler/optimizer/VPConstraint.cpp index 843849e56ba..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) diff --git a/compiler/optimizer/VPHandlers.cpp b/compiler/optimizer/VPHandlers.cpp index a7aa1bb52bd..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(), @@ -9466,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() && @@ -9490,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", @@ -9528,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", From e5c1d423c4accd11e6a4a9fad890cd59ea8d0c18 Mon Sep 17 00:00:00 2001 From: Irwin D'Souza Date: Fri, 7 Sep 2018 15:16:19 -0400 Subject: [PATCH 13/16] Add relocation for class address in a data snippet If a data snippet contains a class address, this address needs to be relocated. This commit ensures that the necessary relocation record is created. Signed-off-by: Irwin D'souza --- compiler/x/codegen/DataSnippet.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) 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()); + } } } From ace92d2a223565974807e0fdf2f6b67231f81073 Mon Sep 17 00:00:00 2001 From: Irwin D'Souza Date: Tue, 11 Sep 2018 17:43:34 -0400 Subject: [PATCH 14/16] Improve cold block marker under AOT Under AOT, the compiler assumes some classes are unresolved, even if they actually aren't. This is because some queries will return NULL if the class can't be remembered in the SCC. Some optimizations, such as cold block marker, are affected by whether or not a block contains an unresolved reference. In AOT, many more blocks are incorrectly marked cold. This commit attempts to remedy that. Signed-off-by: Irwin D'Souza --- compiler/optimizer/LocalOpts.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) 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; From d96f3ba724d63f729bd321d8d680c0f43e2b3e8f Mon Sep 17 00:00:00 2001 From: Irwin D'Souza Date: Thu, 13 Sep 2018 14:40:08 -0400 Subject: [PATCH 15/16] Add isInterpretedForHeuristics Add query for when the compiler asks about whether a method is interpreted for heuristic reasons, and not for functional correctness reasons. Signed-off-by: Irwin D'Souzai --- compiler/compile/Method.cpp | 1 + compiler/compile/ResolvedMethod.hpp | 1 + 2 files changed, 2 insertions(+) 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/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(); From e0bc346110578f2112f76433a7554415d4a83c55 Mon Sep 17 00:00:00 2001 From: Irwin D'Souza Date: Mon, 24 Sep 2018 10:09:37 -0400 Subject: [PATCH 16/16] Add option to enable/disable sym validation manager Signed-off-by: Irwin D'Souza --- compiler/control/OMROptions.cpp | 2 ++ compiler/control/OMROptions.hpp | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/compiler/control/OMROptions.cpp b/compiler/control/OMROptions.cpp index 352657eb414..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"}, diff --git a/compiler/control/OMROptions.hpp b/compiler/control/OMROptions.hpp index 78883c62703..ef325710a20 100644 --- a/compiler/control/OMROptions.hpp +++ b/compiler/control/OMROptions.hpp @@ -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