From c16be679e2971998505d81cc50a821b27666f26d Mon Sep 17 00:00:00 2001 From: Annabelle Huo Date: Wed, 12 Feb 2020 13:45:33 -0800 Subject: [PATCH] Support Known Object Table at JITServer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add KnownObjectTable::updateKnownObjectTableAtServer() which is used to update KOT at the server. Remove getfPointerLocationAt() which is not used any where. Add Compilation::isOutOfProcessCompilation() which returns true only when it’s called at the server. Compilation::isOutOfProcessCompilation() is used to prevent KOT from being used in OMR code at the server where the object pointer needs to be dereferened. Replace the direct dereference of getPointerLocation() with getPointer(). When getPointer() is called at the server, it sends a message to the client to dereference it with the proper VM access. Although there are a few places the known object pointers are dereferenced directly, it shouldn't cause any issue if the critical section is created with VMAccessCriticalSection::tryToAcquireVMAccess, because at the server the VM access will not be granted. Signed-off-by: Annabelle Huo --- compiler/compile/OMRCompilation.hpp | 6 ++++++ compiler/env/OMRKnownObjectTable.cpp | 11 +++++++---- compiler/env/OMRKnownObjectTable.hpp | 9 +++++---- compiler/optimizer/Inliner.cpp | 4 ++-- compiler/optimizer/LocalOpts.cpp | 14 +++++++++++--- compiler/optimizer/VPConstraint.cpp | 6 +++--- compiler/optimizer/VPHandlers.cpp | 5 +++++ 7 files changed, 39 insertions(+), 16 deletions(-) diff --git a/compiler/compile/OMRCompilation.hpp b/compiler/compile/OMRCompilation.hpp index 7910a4f377c..dd0c17297f3 100644 --- a/compiler/compile/OMRCompilation.hpp +++ b/compiler/compile/OMRCompilation.hpp @@ -1052,6 +1052,12 @@ class OMR_EXTENSIBLE Compilation */ DebugCounterMap &getDebugCounterMap() { return _debugCounterMap; } + /** + * @brief Answers whether the compilation is an out of process compilation + * @return true if the compilation is an out of process compilation + */ + static bool isOutOfProcessCompilation() { return false; } + public: #ifdef J9_PROJECT_SPECIFIC // Access to this list must be performed with assumptionTableMutex in hand diff --git a/compiler/env/OMRKnownObjectTable.cpp b/compiler/env/OMRKnownObjectTable.cpp index a87e0a62f29..8b8e36d7401 100644 --- a/compiler/env/OMRKnownObjectTable.cpp +++ b/compiler/env/OMRKnownObjectTable.cpp @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2019 IBM Corp. and others + * Copyright (c) 2000, 2020 IBM Corp. and others * * This program and the accompanying materials are made available under * the terms of the Eclipse Public License 2.0 which accompanies this @@ -137,7 +137,10 @@ OMR::KnownObjectTable::getExistingIndexAt(uintptrj_t *objectReferenceLocation) for (Index i = 0; i < self()->getEndIndex() && (result == UNKNOWN); i++) { if (self()->getPointer(i) == objectPointer) + { result = i; + break; + } } return result; } @@ -152,8 +155,8 @@ OMR::KnownObjectTable::getPointer(Index index) return *self()->getPointerLocation(index); } -uintptrj_t * -OMR::KnownObjectTable::getfPointerLocationAt(uintptrj_t *objectReferenceLocation) +void +OMR::KnownObjectTable::updateKnownObjectTableAtServer(Index index, uintptrj_t *objectReferenceLocation) { - return self()->getPointerLocation(self()->getIndexAt(objectReferenceLocation)); + TR_UNIMPLEMENTED(); } diff --git a/compiler/env/OMRKnownObjectTable.hpp b/compiler/env/OMRKnownObjectTable.hpp index 8186a1e2cdf..57517feaad0 100644 --- a/compiler/env/OMRKnownObjectTable.hpp +++ b/compiler/env/OMRKnownObjectTable.hpp @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2019 IBM Corp. and others + * Copyright (c) 2000, 2020 IBM Corp. and others * * This program and the accompanying materials are made available under * the terms of the Eclipse Public License 2.0 which accompanies this @@ -68,10 +68,10 @@ class OMR_EXTENSIBLE KnownObjectTable typedef int32_t Index; static const Index UNKNOWN = -1; - TR_FrontEnd *fe() { return _fe; } + TR_FrontEnd *fe() const { return _fe; } void setFe(TR_FrontEnd *fe) { _fe = fe; } - TR::Compilation *comp() { return _comp; } + TR::Compilation *comp() const { return _comp; } void setComp(TR::Compilation *comp) { _comp = comp; } virtual Index getEndIndex(); // Highest index assigned so far + 1 @@ -92,7 +92,8 @@ class OMR_EXTENSIBLE KnownObjectTable Index getExistingIndexAt(uintptrj_t *objectReferenceLocation); uintptrj_t getPointer(Index index); - uintptrj_t *getfPointerLocationAt(uintptrj_t *objectReferenceLocation); + + void updateKnownObjectTableAtServer(Index index, uintptrj_t *objectReferenceLocation); protected: void addArrayWithConstantElements(Index index); diff --git a/compiler/optimizer/Inliner.cpp b/compiler/optimizer/Inliner.cpp index e653fcc3f61..a67f39a3749 100644 --- a/compiler/optimizer/Inliner.cpp +++ b/compiler/optimizer/Inliner.cpp @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2019 IBM Corp. and others + * Copyright (c) 2000, 2020 IBM Corp. and others * * This program and the accompanying materials are made available under * the terms of the Eclipse Public License 2.0 which accompanies this @@ -1512,7 +1512,7 @@ TR_InlinerBase::createVirtualGuard( { TR::KnownObjectTable *knot = comp()->getOrCreateKnownObjectTable(); if (knot) - heuristicTrace(tracer()," createVirtualGuard: MutableCallSite.epoch is %p.obj%d (%p.%p)", guard->_mutableCallSiteObject, guard->_mutableCallSiteEpoch, *guard->_mutableCallSiteObject, *knot->getPointerLocation(guard->_mutableCallSiteEpoch)); + heuristicTrace(tracer()," createVirtualGuard: MutableCallSite.epoch is %p.obj%d (%p.%p)", guard->_mutableCallSiteObject, guard->_mutableCallSiteEpoch, *guard->_mutableCallSiteObject, knot->getPointer(guard->_mutableCallSiteEpoch)); return TR_VirtualGuard::createMutableCallSiteTargetGuard(comp(), calleeIndex, callNode, destination, guard->_mutableCallSiteObject, guard->_mutableCallSiteEpoch); } diff --git a/compiler/optimizer/LocalOpts.cpp b/compiler/optimizer/LocalOpts.cpp index bbf9284dd75..12173b9e13d 100644 --- a/compiler/optimizer/LocalOpts.cpp +++ b/compiler/optimizer/LocalOpts.cpp @@ -6841,7 +6841,10 @@ int32_t TR_InvariantArgumentPreexistence::perform() parmInfo.setSymbol(p); TR::SymbolReference* symRef = methodSymbol->getParmSymRef(p->getSlot()); TR::KnownObjectTable::Index koi = symRef->getKnownObjectIndex(); - if (koi != TR::KnownObjectTable::UNKNOWN) + if ((koi != TR::KnownObjectTable::UNKNOWN) + && knot + && !comp()->isOutOfProcessCompilation() + ) { TR::VMAccessCriticalSection setClass(comp()); TR_OpaqueClassBlock *fixedClazz = TR::Compiler->cls.objectClass(comp(), knot->getPointer(koi)); @@ -6981,7 +6984,9 @@ int32_t TR_InvariantArgumentPreexistence::perform() if (enableTrace) traceMsg(comp(), "PREX: Parm %d is arg %p parmInfo %p\n", index, arg, &parmInfo); - if (arg->hasKnownObjectIndex()) + if (arg->hasKnownObjectIndex() + && !comp()->isOutOfProcessCompilation() + ) { if (enableTrace) traceMsg(comp(), "PREX: Parm %d is known object obj%d\n", index, arg->getKnownObjectIndex()); @@ -7281,7 +7286,10 @@ void TR_InvariantArgumentPreexistence::processIndirectCall(TR::Node *node, TR::T // Bonus goodies for known objects // - if (receiver->getSymbolReference() && receiver->getSymbolReference()->hasKnownObjectIndex()) + if (receiver->getSymbolReference() + && receiver->getSymbolReference()->hasKnownObjectIndex() + && !comp()->isOutOfProcessCompilation() + ) { if (trace()) traceMsg(comp(), "PREX: Receiver is obj%d\n", receiver->getSymbolReference()->getKnownObjectIndex()); diff --git a/compiler/optimizer/VPConstraint.cpp b/compiler/optimizer/VPConstraint.cpp index 0c66de538e8..bcb61057af1 100644 --- a/compiler/optimizer/VPConstraint.cpp +++ b/compiler/optimizer/VPConstraint.cpp @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2019 IBM Corp. and others + * Copyright (c) 2000, 2020 IBM Corp. and others * * This program and the accompanying materials are made available under * the terms of the Eclipse Public License 2.0 which accompanies this @@ -1313,12 +1313,12 @@ TR::VPKnownObject *TR::VPKnownObject::create(OMR::ValuePropagation *vp, TR::Know if (vpKnownObjectCriticalSection.hasVMAccess()) { - TR_OpaqueClassBlock *clazz = TR::Compiler->cls.objectClass(vp->comp(), *vp->comp()->getKnownObjectTable()->getPointerLocation(index)); + TR_OpaqueClassBlock *clazz = TR::Compiler->cls.objectClass(vp->comp(), knot->getPointer(index)); TR_OpaqueClassBlock *jlClass = vp->fe()->getClassClassPointer(clazz); if (isJavaLangClass) { TR_ASSERT(clazz == jlClass, "Use createForJavaLangClass only for instances of java/lang/Class"); - clazz = TR::Compiler->cls.classFromJavaLangClass(vp->comp(), *vp->comp()->getKnownObjectTable()->getPointerLocation(index)); + clazz = TR::Compiler->cls.classFromJavaLangClass(vp->comp(), knot->getPointer(index)); } else { diff --git a/compiler/optimizer/VPHandlers.cpp b/compiler/optimizer/VPHandlers.cpp index 3dfe40e9b41..7578b382fae 100644 --- a/compiler/optimizer/VPHandlers.cpp +++ b/compiler/optimizer/VPHandlers.cpp @@ -1529,6 +1529,11 @@ static const char *getFieldSignature(OMR::ValuePropagation *vp, TR::Node *node, */ static bool addKnownObjectConstraints(OMR::ValuePropagation *vp, TR::Node *node) { + // Access to VM for multiple operations including KnownObjectTable::getIndex() + // is not supported at the server for OMR. + if (vp->comp()->isOutOfProcessCompilation()) + return false; + TR::KnownObjectTable *knot = vp->comp()->getKnownObjectTable(); if (!knot) return false;