diff --git a/runtime/compiler/control/JITClientCompilationThread.cpp b/runtime/compiler/control/JITClientCompilationThread.cpp index 5fa28edf825..fa9460547a5 100644 --- a/runtime/compiler/control/JITClientCompilationThread.cpp +++ b/runtime/compiler/control/JITClientCompilationThread.cpp @@ -586,6 +586,24 @@ handleServerMessage(JITServer::ClientStream *client, TR_J9VM *fe, JITServer::Mes client->write(response, fe->getObjectClassFromKnownObjectIndex(comp, idx)); } break; + case MessageType::VM_getObjectClassFromKnownObjectIndexJLClass: + { + auto recv = client->getRecvData(); + auto idx = std::get<0>(recv); + bool isJL; + client->write(response, fe->getObjectClassFromKnownObjectIndex(comp, idx, &isJL), isJL); + } + break; + case MessageType::VM_getObjectClassInfoFromObjectReferenceLocation: + { + auto recv = client->getRecvData(); + uintptr_t objectReferenceLocation = std::get<0>(recv); + auto ci = fe->getObjectClassInfoFromObjectReferenceLocation(comp, objectReferenceLocation); + client->write(response, + ci, + knot->getPointerLocation(ci.knownObjectIndex)); + } + break; case MessageType::VM_stackWalkerMaySkipFrames: { client->getRecvData(); diff --git a/runtime/compiler/env/VMJ9.cpp b/runtime/compiler/env/VMJ9.cpp index bcaea0128ab..1aed8150c53 100644 --- a/runtime/compiler/env/VMJ9.cpp +++ b/runtime/compiler/env/VMJ9.cpp @@ -1213,6 +1213,26 @@ TR_J9VMBase::getObjectClassFromKnownObjectIndex(TR::Compilation *comp, TR::Known return clazz; } +TR_OpaqueClassBlock * +TR_J9VMBase::getObjectClassFromKnownObjectIndex(TR::Compilation *comp, + TR::KnownObjectTable::Index idx, + bool *isJavaLangClass) + { + TR::VMAccessCriticalSection vpKnownObjectCriticalSection(comp); + + TR::KnownObjectTable *knot = comp->getKnownObjectTable(); + if (!knot) + return NULL; + + TR_OpaqueClassBlock *clazz = getObjectClass(knot->getPointer(idx)); + TR_OpaqueClassBlock *jlClass = getClassClassPointer(clazz); + *isJavaLangClass = (clazz == jlClass); + if (*isJavaLangClass) + { + clazz = getClassFromJavaLangClass(knot->getPointer(idx)); + } + return clazz; + } uintptr_t TR_J9VMBase::getStaticReferenceFieldAtAddress(uintptr_t fieldAddress) { @@ -1220,6 +1240,34 @@ TR_J9VMBase::getStaticReferenceFieldAtAddress(uintptr_t fieldAddress) return (uintptr_t)J9STATIC_OBJECT_LOAD(vmThread(), NULL, fieldAddress); } +TR_J9VMBase::ObjectClassInfo +TR_J9VMBase::getObjectClassInfoFromObjectReferenceLocation(TR::Compilation *comp, + uintptr_t objectReferenceLocation) + { + TR_J9VMBase::ObjectClassInfo ci = {}; + TR::KnownObjectTable *knot = comp->getKnownObjectTable(); + if (knot) + { + TR::VMAccessCriticalSection getObjectReferenceLocation(comp); + uintptr_t objectReference = getStaticReferenceFieldAtAddress + (objectReferenceLocation); + ci.clazz = getObjectClass(objectReference); + ci.isString = isString(ci.clazz); + ci.jlClass = getClassClassPointer(ci.clazz); + ci.isFixedJavaLangClass = (ci.jlClass == ci.clazz); + if (ci.isFixedJavaLangClass) + { + // A FixedClass constraint means something different + // when the class happens to be java/lang/Class. + // Must add constraints pertaining to the class that + // the java/lang/Class object represents. + ci.clazz = getClassFromJavaLangClass(objectReference); + } + ci.knownObjectIndex = knot->getOrCreateIndex(objectReference); + } + return ci; + } + uintptr_t TR_J9VMBase::getReferenceFieldAtAddress(uintptr_t fieldAddress) { diff --git a/runtime/compiler/env/VMJ9.h b/runtime/compiler/env/VMJ9.h index a7b57e42501..b3e2fc6e378 100644 --- a/runtime/compiler/env/VMJ9.h +++ b/runtime/compiler/env/VMJ9.h @@ -635,6 +635,7 @@ class TR_J9VMBase : public TR_FrontEnd virtual TR_OpaqueClassBlock *getObjectClass(uintptr_t objectPointer); virtual TR_OpaqueClassBlock *getObjectClassAt(uintptr_t objectAddress); virtual TR_OpaqueClassBlock *getObjectClassFromKnownObjectIndex(TR::Compilation *comp, TR::KnownObjectTable::Index idx); + virtual TR_OpaqueClassBlock *getObjectClassFromKnownObjectIndex(TR::Compilation *comp, TR::KnownObjectTable::Index idx, bool *isJavaLangClass); virtual uintptr_t getReferenceFieldAt(uintptr_t objectPointer, uintptr_t offsetFromHeader); virtual uintptr_t getVolatileReferenceFieldAt(uintptr_t objectPointer, uintptr_t offsetFromHeader); virtual uintptr_t getReferenceFieldAtAddress(uintptr_t fieldAddress); @@ -642,6 +643,20 @@ class TR_J9VMBase : public TR_FrontEnd virtual uintptr_t getStaticReferenceFieldAtAddress(uintptr_t fieldAddress); virtual int32_t getInt32FieldAt(uintptr_t objectPointer, uintptr_t fieldOffset); + /* Used to contain all information needed for getObjectClassInfoFromObjectReferenceLocation + * to create a VPKnownObject constraint. + */ + struct ObjectClassInfo + { + TR_OpaqueClassBlock *clazz; + TR_OpaqueClassBlock *jlClass; + bool isFixedJavaLangClass; + bool isString; + TR::KnownObjectTable::Index knownObjectIndex; + }; + virtual ObjectClassInfo getObjectClassInfoFromObjectReferenceLocation + (TR::Compilation *comp, uintptr_t objectReferenceLocation); + int32_t getInt32Field(uintptr_t objectPointer, const char *fieldName) { return getInt32FieldAt(objectPointer, getInstanceFieldOffset(getObjectClass(objectPointer), fieldName, "I")); diff --git a/runtime/compiler/env/VMJ9Server.cpp b/runtime/compiler/env/VMJ9Server.cpp index 3c1b7379904..7e802b0b967 100644 --- a/runtime/compiler/env/VMJ9Server.cpp +++ b/runtime/compiler/env/VMJ9Server.cpp @@ -937,12 +937,37 @@ TR_J9ServerVM::getObjectClassFromKnownObjectIndex(TR::Compilation *comp, TR::Kno return std::get<0>(stream->read()); } +TR_OpaqueClassBlock * +TR_J9ServerVM::getObjectClassFromKnownObjectIndex(TR::Compilation *comp, + TR::KnownObjectTable::Index idx, + bool *isJavaLangClass) + { + JITServer::ServerStream *stream = _compInfoPT->getMethodBeingCompiled()->_stream; + stream->write(JITServer::MessageType::VM_getObjectClassFromKnownObjectIndexJLClass, idx); + auto recv = stream->read(); + *isJavaLangClass = std::get<1>(recv); + return std::get<0>(recv); + } + uintptr_t TR_J9ServerVM::getStaticReferenceFieldAtAddress(uintptr_t fieldAddress) { TR_ASSERT_FATAL(false, "getStaticReferenceFieldAtAddress() should not be called by JITServer"); } +TR_J9VMBase::ObjectClassInfo +TR_J9ServerVM::getObjectClassInfoFromObjectReferenceLocation(TR::Compilation *comp, uintptr_t objectReferenceLocation) + { + JITServer::ServerStream *stream = _compInfoPT->getMethodBeingCompiled()->_stream; + stream->write(JITServer::MessageType::VM_getObjectClassInfoFromObjectReferenceLocation, + objectReferenceLocation); + auto recv = stream->read(); + TR_J9VMBase::ObjectClassInfo result = std::get<0>(recv); + uintptr_t *objectReferenceLocationClient = std::get<1>(recv); + comp->getKnownObjectTable()->updateKnownObjectTableAtServer(result.knownObjectIndex, objectReferenceLocationClient); + return result; + } + bool TR_J9ServerVM::stackWalkerMaySkipFrames(TR_OpaqueMethodBlock *method, TR_OpaqueClassBlock *clazz) { diff --git a/runtime/compiler/env/VMJ9Server.hpp b/runtime/compiler/env/VMJ9Server.hpp index 6d5f432bfb8..3d20990a165 100644 --- a/runtime/compiler/env/VMJ9Server.hpp +++ b/runtime/compiler/env/VMJ9Server.hpp @@ -111,8 +111,12 @@ class TR_J9ServerVM: public TR_J9VM virtual TR_OpaqueClassBlock * getObjectClass(uintptr_t objectPointer) override; virtual TR_OpaqueClassBlock * getObjectClassAt(uintptr_t objectAddress) override; virtual TR_OpaqueClassBlock *getObjectClassFromKnownObjectIndex(TR::Compilation *comp, TR::KnownObjectTable::Index idx) override; + virtual TR_OpaqueClassBlock *getObjectClassFromKnownObjectIndex(TR::Compilation *comp, TR::KnownObjectTable::Index idx, bool *isJavaLangClass) override; virtual uintptr_t getStaticReferenceFieldAtAddress(uintptr_t fieldAddress) override; + virtual ObjectClassInfo getObjectClassInfoFromObjectReferenceLocation + (TR::Compilation *comp, uintptr_t objectReferenceLocation) override; + virtual bool stackWalkerMaySkipFrames(TR_OpaqueMethodBlock *method, TR_OpaqueClassBlock *clazz) override; virtual bool hasFinalFieldsInClass(TR_OpaqueClassBlock *clazz) override; virtual const char *sampleSignature(TR_OpaqueMethodBlock * aMethod, char *buf, int32_t bufLen, TR_Memory *memory) override; diff --git a/runtime/compiler/net/CommunicationStream.hpp b/runtime/compiler/net/CommunicationStream.hpp index 7e953aa5512..b637e190665 100644 --- a/runtime/compiler/net/CommunicationStream.hpp +++ b/runtime/compiler/net/CommunicationStream.hpp @@ -129,7 +129,7 @@ class CommunicationStream // likely to lose an increment when merging/rebasing/etc. // static const uint8_t MAJOR_NUMBER = 1; - static const uint16_t MINOR_NUMBER = 74; // ID: Qi304qaThEQ4NoZZkw1O + static const uint16_t MINOR_NUMBER = 75; // ID: kzkyjklaOnYjEzzJyIl7 static const uint8_t PATCH_NUMBER = 0; static uint32_t CONFIGURATION_FLAGS; diff --git a/runtime/compiler/net/MessageTypes.cpp b/runtime/compiler/net/MessageTypes.cpp index 35a0629603a..36cb325a2ef 100644 --- a/runtime/compiler/net/MessageTypes.cpp +++ b/runtime/compiler/net/MessageTypes.cpp @@ -118,6 +118,8 @@ const char *messageNames[] = "VM_getObjectClass", "VM_getObjectClassAt", "VM_getObjectClassFromKnownObjectIndex", + "VM_getObjectClassFromKnownObjectIndexJLClass", + "VM_getObjectClassInfoFromObjectReferenceLocation", "VM_stackWalkerMaySkipFrames", "VM_getStringUTF8Length", "VM_classInitIsFinished", diff --git a/runtime/compiler/net/MessageTypes.hpp b/runtime/compiler/net/MessageTypes.hpp index e6d42d0686d..8cdceb317b1 100644 --- a/runtime/compiler/net/MessageTypes.hpp +++ b/runtime/compiler/net/MessageTypes.hpp @@ -127,6 +127,8 @@ enum MessageType : uint16_t VM_getObjectClass, VM_getObjectClassAt, VM_getObjectClassFromKnownObjectIndex, + VM_getObjectClassFromKnownObjectIndexJLClass, + VM_getObjectClassInfoFromObjectReferenceLocation, VM_stackWalkerMaySkipFrames, VM_getStringUTF8Length, VM_classInitIsFinished,