Skip to content

Commit

Permalink
Merge pull request #20112 from a7ehuo/PR-valuetypes-null-restricted-a…
Browse files Browse the repository at this point in the history
…rray

Fix null restricted array related issues for value types
  • Loading branch information
hzongaro authored Oct 21, 2024
2 parents abe8b1b + f2c432a commit f165fd4
Show file tree
Hide file tree
Showing 19 changed files with 308 additions and 71 deletions.
3 changes: 3 additions & 0 deletions runtime/compiler/codegen/J9RecognizedMethodsEnum.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,9 @@
LastVectorMethod = LastVectorIntrinsicMethod,

java_lang_reflect_Array_getLength,
jdk_internal_value_ValueClass_newArrayInstance,
jdk_internal_value_ValueClass_newNullRestrictedArray,
jdk_internal_value_NullRestrictedCheckedType_of,
java_lang_reflect_Method_invoke,
java_util_Arrays_fill,
java_util_Arrays_equals,
Expand Down
6 changes: 6 additions & 0 deletions runtime/compiler/control/JITClientCompilationThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -617,6 +617,12 @@ handleServerMessage(JITServer::ClientStream *client, TR_J9VM *fe, JITServer::Mes
client->write(response, fe->getArrayClassFromComponentClass(clazz));
}
break;
case MessageType::VM_getNullRestrictedArrayClassFromComponentClass:
{
auto clazz = std::get<0>(client->getRecvData<TR_OpaqueClassBlock *>());
client->write(response, fe->getNullRestrictedArrayClassFromComponentClass(clazz));
}
break;
case MessageType::VM_matchRAMclassFromROMclass:
{
J9ROMClass *clazz = std::get<0>(client->getRecvData<J9ROMClass *>());
Expand Down
7 changes: 6 additions & 1 deletion runtime/compiler/control/JITServerHelpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -969,6 +969,7 @@ JITServerHelpers::cacheRemoteROMClass(ClientSessionData *clientSessionData, J9Cl
classInfoStruct._classNameIdentifyingLoader = std::get<22>(classInfoTuple);
classInfoStruct._arrayElementSize = std::get<23>(classInfoTuple);
classInfoStruct._defaultValueSlotAddress = std::get<24>(classInfoTuple);
classInfoStruct._nullRestrictedArrayClass = std::get<26>(classInfoTuple);

auto result = clientSessionData->getROMClassMap().insert({ clazz, classInfoStruct });

Expand Down Expand Up @@ -1031,6 +1032,7 @@ JITServerHelpers::packRemoteROMClassInfo(J9Class *clazz, J9VMThread *vmThread, T
TR_OpaqueClassBlock *hostClass = fe->convertClassPtrToClassOffset(clazz->hostClass);
TR_OpaqueClassBlock *componentClass = fe->getComponentClassFromArrayClass((TR_OpaqueClassBlock *)clazz);
TR_OpaqueClassBlock *arrayClass = fe->getArrayClassFromComponentClass((TR_OpaqueClassBlock *)clazz);
TR_OpaqueClassBlock *nullRestrictedArrayClass = fe->getNullRestrictedArrayClassFromComponentClass((TR_OpaqueClassBlock *)clazz);
uintptr_t totalInstanceSize = clazz->totalInstanceSize;
uintptr_t cp = fe->getConstantPoolFromClass((TR_OpaqueClassBlock *)clazz);
uintptr_t classFlags = fe->getClassFlagsValue((TR_OpaqueClassBlock *)clazz);
Expand Down Expand Up @@ -1082,7 +1084,7 @@ JITServerHelpers::packRemoteROMClassInfo(J9Class *clazz, J9VMThread *vmThread, T
classHasFinalFields, classDepthAndFlags, classInitialized, byteOffsetToLockword, leafComponentClass,
classLoader, hostClass, componentClass, arrayClass, totalInstanceSize, clazz->romClass,
cp, classFlags, classChainOffsetIdentifyingLoader, origROMMethods, classNameIdentifyingLoader, arrayElementSize,
defaultValueSlotAddress, romClassHash
defaultValueSlotAddress, romClassHash, nullRestrictedArrayClass
);
}

Expand Down Expand Up @@ -1261,6 +1263,9 @@ JITServerHelpers::getROMClassData(const ClientSessionData::ClassInfo &classInfo,
case CLASSINFO_DEFAULT_VALUE_SLOT_ADDRESS:
*(j9object_t **)data = classInfo._defaultValueSlotAddress;
break;
case CLASSINFO_NULLRESTRICTED_ARRAY_CLASS :
*(TR_OpaqueClassBlock **)data = classInfo._nullRestrictedArrayClass;
break;
default:
TR_ASSERT(false, "Class Info not supported %u\n", dataType);
break;
Expand Down
4 changes: 3 additions & 1 deletion runtime/compiler/control/JITServerHelpers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ class JITServerHelpers
CLASSINFO_CLASS_CHAIN_OFFSET_IDENTIFYING_LOADER,
CLASSINFO_ARRAY_ELEMENT_SIZE,
CLASSINFO_DEFAULT_VALUE_SLOT_ADDRESS,
CLASSINFO_NULLRESTRICTED_ARRAY_CLASS,
};

// NOTE: when adding new elements to this tuple, add them to the end,
Expand Down Expand Up @@ -88,7 +89,8 @@ class JITServerHelpers
std::string, // 22: _classNameIdentifyingLoader
int32_t, // 23: _arrayElementSize
j9object_t *, // 24: _defaultValueSlotAddress
std::string // 25: optional hash of packedROMClass
std::string, // 25: optional hash of packedROMClass
TR_OpaqueClassBlock * // 26: _nullRestrictedArrayClass
>;

// Packs a ROMClass to be transferred to the server.
Expand Down
23 changes: 23 additions & 0 deletions runtime/compiler/env/J9ClassEnv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -902,6 +902,29 @@ J9::ClassEnv::isValueBasedOrValueTypeClass(TR_OpaqueClassBlock *clazz)
return J9_ARE_ANY_BITS_SET(j9class->classFlags, J9_CLASS_DISALLOWS_LOCKING_FLAGS);
}

bool
J9::ClassEnv::isArrayNullRestricted(TR::Compilation *comp,TR_OpaqueClassBlock *arrayClass)
{
#if defined(J9VM_OPT_JITSERVER)
if (auto stream = comp->getStream())
{
uintptr_t classFlags = 0;
JITServerHelpers::getAndCacheRAMClassInfo((J9Class *)arrayClass, TR::compInfoPT->getClientData(), stream, JITServerHelpers::CLASSINFO_CLASS_FLAGS, (void *)&classFlags);
#ifdef DEBUG
stream->write(JITServer::MessageType::ClassEnv_classFlagsValue, clazz);
uintptr_t classFlagsRemote = std::get<0>(stream->read<uintptr_t>());
// Check that class flags from remote call is equal to the cached ones
classFlags = classFlags & J9ClassArrayIsNullRestricted;
classFlagsRemote = classFlagsRemote & J9ClassArrayIsNullRestricted;
TR_ASSERT_FATAL(classFlags == classFlagsRemote, "remote call class flags is not equal to cached class flags");
#endif
return J9_ARE_ALL_BITS_SET(classFlags, J9ClassArrayIsNullRestricted);
}
#endif /* defined(J9VM_OPT_JITSERVER) */
J9ArrayClass *j9class = reinterpret_cast<J9ArrayClass*>(arrayClass);
return J9_IS_J9ARRAYCLASS_NULL_RESTRICTED(j9class);
}

bool
J9::ClassEnv::classHasIdentity(TR_OpaqueClassBlock *clazz)
{
Expand Down
1 change: 1 addition & 0 deletions runtime/compiler/env/J9ClassEnv.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ class OMR_EXTENSIBLE ClassEnv : public OMR::ClassEnvConnector
bool isPrimitiveValueTypeClass(TR_OpaqueClassBlock *);
bool isValueTypeClassFlattened(TR_OpaqueClassBlock *clazz);
bool isValueBasedOrValueTypeClass(TR_OpaqueClassBlock *);
bool isArrayNullRestricted(TR::Compilation *comp, TR_OpaqueClassBlock *arrayClass);

/** \brief
* Returns the size of the flattened array element
Expand Down
28 changes: 28 additions & 0 deletions runtime/compiler/env/VMJ9.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7107,6 +7107,13 @@ TR_J9VM::getArrayClassFromComponentClass(TR_OpaqueClassBlock * componentClass)
return convertClassPtrToClassOffset(TR::Compiler->cls.convertClassOffsetToClassPtr(componentClass)->arrayClass);
}

TR_OpaqueClassBlock *
TR_J9VM::getNullRestrictedArrayClassFromComponentClass(TR_OpaqueClassBlock * componentClass)
{
J9Class *clazz = TR::Compiler->cls.convertClassOffsetToClassPtr(componentClass);
return convertClassPtrToClassOffset(J9CLASS_GET_NULLRESTRICTED_ARRAY(clazz));
}

TR_OpaqueClassBlock *
TR_J9VM::getLeafComponentClassFromArrayClass(TR_OpaqueClassBlock * arrayClass)
{
Expand Down Expand Up @@ -9285,6 +9292,27 @@ TR_J9SharedCacheVM::getArrayClassFromComponentClass(TR_OpaqueClassBlock * compon
return NULL;
}

TR_OpaqueClassBlock *
TR_J9SharedCacheVM::getNullRestrictedArrayClassFromComponentClass(TR_OpaqueClassBlock * componentClass)
{
TR::Compilation* comp = _compInfoPT->getCompilation();
TR_ASSERT(comp, "Should be called only within a compilation");

bool validated = false;
TR_OpaqueClassBlock *nullRestrictedArrayClass = TR_J9VM::getNullRestrictedArrayClassFromComponentClass(componentClass);

if (comp->getOption(TR_UseSymbolValidationManager))
{
validated = comp->getSymbolValidationManager()->addArrayClassFromComponentClassRecord(nullRestrictedArrayClass, componentClass);
}
else
{
validated = ((TR_ResolvedRelocatableJ9Method *) comp->getCurrentMethod())->validateArbitraryClass(comp, (J9Class *) componentClass);
}

return validated ? nullRestrictedArrayClass : NULL;
}

TR_OpaqueClassBlock *
TR_J9SharedCacheVM::getLeafComponentClassFromArrayClass(TR_OpaqueClassBlock * arrayClass)
{
Expand Down
20 changes: 20 additions & 0 deletions runtime/compiler/env/VMJ9.h
Original file line number Diff line number Diff line change
Expand Up @@ -1559,6 +1559,16 @@ class TR_J9VM : public TR_J9VMBase

virtual TR_OpaqueClassBlock * getComponentClassFromArrayClass(TR_OpaqueClassBlock * arrayClass);
virtual TR_OpaqueClassBlock * getArrayClassFromComponentClass(TR_OpaqueClassBlock *componentClass);
/** \brief
* Retrieves the nullRestrictedArrayClass from the array component class.
*
* \param componentClass
* The array component class
*
* \return
* A pointer to nullRestrictedArrayClass if it exists, otherwise NULL
*/
virtual TR_OpaqueClassBlock * getNullRestrictedArrayClassFromComponentClass(TR_OpaqueClassBlock *componentClass);
virtual TR_OpaqueClassBlock * getLeafComponentClassFromArrayClass(TR_OpaqueClassBlock * arrayClass);
virtual int32_t getNewArrayTypeFromClass(TR_OpaqueClassBlock *clazz);
virtual TR_OpaqueClassBlock * getClassFromSignature(const char * sig, int32_t length, TR_ResolvedMethod *method, bool isVettedForAOT=false);
Expand Down Expand Up @@ -1685,6 +1695,16 @@ class TR_J9SharedCacheVM : public TR_J9VM
virtual bool isPrimitiveClass(TR_OpaqueClassBlock *clazz);
virtual TR_OpaqueClassBlock * getComponentClassFromArrayClass(TR_OpaqueClassBlock * arrayClass);
virtual TR_OpaqueClassBlock * getArrayClassFromComponentClass(TR_OpaqueClassBlock *componentClass);
/** \brief
* Retrieves the nullRestrictedArrayClass from the array component class.
*
* \param componentClass
* The array component class
*
* \return
* A pointer to nullRestrictedArrayClass if it exists, otherwise NULL
*/
virtual TR_OpaqueClassBlock * getNullRestrictedArrayClassFromComponentClass(TR_OpaqueClassBlock *componentClass);
virtual TR_OpaqueClassBlock * getLeafComponentClassFromArrayClass(TR_OpaqueClassBlock * arrayClass);
virtual TR_OpaqueClassBlock * getBaseComponentClass(TR_OpaqueClassBlock * clazz, int32_t & numDims);
virtual TR_OpaqueClassBlock * getClassFromNewArrayType(int32_t arrayType);
Expand Down
44 changes: 44 additions & 0 deletions runtime/compiler/env/VMJ9Server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1171,6 +1171,30 @@ TR_J9ServerVM::getArrayClassFromComponentClass(TR_OpaqueClassBlock *componentCla
return arrayClass;
}

TR_OpaqueClassBlock *
TR_J9ServerVM::getNullRestrictedArrayClassFromComponentClass(TR_OpaqueClassBlock *componentClass)
{
JITServer::ServerStream *stream = _compInfoPT->getMethodBeingCompiled()->_stream;
TR_OpaqueClassBlock *nullRestrictedArrayClass = NULL;
JITServerHelpers::getAndCacheRAMClassInfo((J9Class *)componentClass, _compInfoPT->getClientData(), stream, JITServerHelpers::CLASSINFO_NULLRESTRICTED_ARRAY_CLASS, (void *)&nullRestrictedArrayClass);
if (!nullRestrictedArrayClass)
{
stream->write(JITServer::MessageType::VM_getNullRestrictedArrayClassFromComponentClass, componentClass);
nullRestrictedArrayClass = std::get<0>(stream->read<TR_OpaqueClassBlock *>());
if (nullRestrictedArrayClass)
{
// if client initialized nullRestrictedArrayClass, cache the new value
OMR::CriticalSection getRemoteROMClass(_compInfoPT->getClientData()->getROMMapMonitor());
auto it = _compInfoPT->getClientData()->getROMClassMap().find((J9Class*) componentClass);
if (it != _compInfoPT->getClientData()->getROMClassMap().end())
{
it->second._nullRestrictedArrayClass = nullRestrictedArrayClass;
}
}
}
return nullRestrictedArrayClass;
}

J9Class *
TR_J9ServerVM::matchRAMclassFromROMclass(J9ROMClass *clazz, TR::Compilation *comp)
{
Expand Down Expand Up @@ -3292,6 +3316,26 @@ TR_J9SharedCacheServerVM::getArrayClassFromComponentClass(TR_OpaqueClassBlock *
return validated ? arrayClass : NULL;
}

TR_OpaqueClassBlock *
TR_J9SharedCacheServerVM::getNullRestrictedArrayClassFromComponentClass(TR_OpaqueClassBlock * componentClass)
{
TR::Compilation* comp = _compInfoPT->getCompilation();
TR_ASSERT(comp, "Should be called only within a compilation");

bool validated = false;
TR_OpaqueClassBlock *nullRestrictedArrayClass = TR_J9ServerVM::getNullRestrictedArrayClassFromComponentClass(componentClass);

if (comp->getOption(TR_UseSymbolValidationManager))
{
validated = comp->getSymbolValidationManager()->addArrayClassFromComponentClassRecord(nullRestrictedArrayClass, componentClass);
}
else
{
validated = ((TR_ResolvedRelocatableJ9JITServerMethod *) comp->getCurrentMethod())->validateArbitraryClass(comp, (J9Class *) componentClass);
}
return validated ? nullRestrictedArrayClass : NULL;
}

TR_OpaqueClassBlock *
TR_J9SharedCacheServerVM::getLeafComponentClassFromArrayClass(TR_OpaqueClassBlock * arrayClass)
{
Expand Down
20 changes: 20 additions & 0 deletions runtime/compiler/env/VMJ9Server.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,16 @@ class TR_J9ServerVM: public TR_J9VM
virtual bool isCloneable(TR_OpaqueClassBlock *clazzPointer) override;
virtual bool canAllocateInlineClass(TR_OpaqueClassBlock *clazz) override;
virtual TR_OpaqueClassBlock * getArrayClassFromComponentClass(TR_OpaqueClassBlock *componentClass) override;
/** \brief
* Retrieves the nullRestrictedArrayClass from the array component class.
*
* \param componentClass
* The array component class
*
* \return
* A pointer to nullRestrictedArrayClass if it exists, otherwise NULL
*/
virtual TR_OpaqueClassBlock * getNullRestrictedArrayClassFromComponentClass(TR_OpaqueClassBlock *componentClass) override;
virtual J9Class * matchRAMclassFromROMclass(J9ROMClass *clazz, TR::Compilation *comp) override;
virtual int32_t * getCurrentLocalsMapForDLT(TR::Compilation *comp) override;
virtual uintptr_t getReferenceFieldAt(uintptr_t objectPointer, uintptr_t offsetFromHeader) override;
Expand Down Expand Up @@ -345,6 +355,16 @@ class TR_J9SharedCacheServerVM: public TR_J9ServerVM
virtual bool isPrimitiveClass(TR_OpaqueClassBlock *clazzPointer) override;
virtual TR_OpaqueClassBlock *getComponentClassFromArrayClass(TR_OpaqueClassBlock *arrayClass) override;
virtual TR_OpaqueClassBlock *getArrayClassFromComponentClass(TR_OpaqueClassBlock *componentClass) override;
/** \brief
* Retrieves the nullRestrictedArrayClass from the array component class.
*
* \param componentClass
* The array component class
*
* \return
* A pointer to nullRestrictedArrayClass if it exists, otherwise NULL
*/
virtual TR_OpaqueClassBlock * getNullRestrictedArrayClassFromComponentClass(TR_OpaqueClassBlock *componentClass) override;
virtual TR_OpaqueClassBlock *getLeafComponentClassFromArrayClass(TR_OpaqueClassBlock *arrayClass) override;
virtual TR_OpaqueClassBlock *getBaseComponentClass(TR_OpaqueClassBlock *clazz, int32_t & numDims) override;
virtual TR_OpaqueClassBlock *getClassFromNewArrayType(int32_t arrayType) override;
Expand Down
15 changes: 15 additions & 0 deletions runtime/compiler/env/j9method.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3847,6 +3847,19 @@ void TR_ResolvedJ9Method::construct()
{ TR::unknownMethod}
};

static X ValueClassMethods[] =
{
{x(TR::jdk_internal_value_ValueClass_newArrayInstance, "newArrayInstance", "(Ljdk/internal/value/CheckedType;I)[Ljava/lang/Object;")},
{x(TR::jdk_internal_value_ValueClass_newNullRestrictedArray, "newNullRestrictedArray", "(Ljava/lang/Class;I)[Ljava/lang/Object;")},
{ TR::unknownMethod}
};

static X NullRestrictedCheckedTypeMethods[] =
{
{x(TR::jdk_internal_value_NullRestrictedCheckedType_of, "of", "(Ljava/lang/Class;)Ljdk/internal/value/NullRestrictedCheckedType;")},
{ TR::unknownMethod}
};

static X SpreadHandleMethods[] =
{
{x(TR::java_lang_invoke_SpreadHandle_numArgsToPassThrough, "numArgsToPassThrough", "()I")},
Expand Down Expand Up @@ -4183,6 +4196,7 @@ void TR_ResolvedJ9Method::construct()
{ "sun/nio/cs/ISO_8859_1$Decoder", EncodeMethods },
{ "java/io/ByteArrayOutputStream", ByteArrayOutputStreamMethods },
{ "java/lang/ScopedValue$Carrier", ScopedValueMethods },
{ "jdk/internal/value/ValueClass", ValueClassMethods },
{ 0 }
};

Expand Down Expand Up @@ -4311,6 +4325,7 @@ void TR_ResolvedJ9Method::construct()
{
{ "java/lang/invoke/ConvertHandle$FilterHelpers", ConvertHandleFilterHelpersMethods },
{ "java/lang/invoke/DirectMethodHandle$Accessor", DirectMethodHandleAccessorMethods },
{ "jdk/internal/value/NullRestrictedCheckedType", NullRestrictedCheckedTypeMethods },
{ 0 }
};

Expand Down
2 changes: 1 addition & 1 deletion runtime/compiler/net/CommunicationStream.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,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 = 68; // ID: +/QzEedP8cjGovxgYECy
static const uint16_t MINOR_NUMBER = 69; // ID: SMN6DXY0b2X1Z76N9825
static const uint8_t PATCH_NUMBER = 0;
static uint32_t CONFIGURATION_FLAGS;

Expand Down
1 change: 1 addition & 0 deletions runtime/compiler/net/MessageTypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ const char *messageNames[] =
"VM_classInitIsFinished",
"VM_getClassFromNewArrayType",
"VM_getArrayClassFromComponentClass",
"VM_getNullRestrictedArrayClassFromComponentClass",
"VM_matchRAMclassFromROMclass",
"VM_getInt32FieldAt",
"VM_getInt64FieldAt",
Expand Down
1 change: 1 addition & 0 deletions runtime/compiler/net/MessageTypes.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ enum MessageType : uint16_t
VM_classInitIsFinished,
VM_getClassFromNewArrayType,
VM_getArrayClassFromComponentClass,
VM_getNullRestrictedArrayClassFromComponentClass,
VM_matchRAMclassFromROMclass,
VM_getInt32FieldAt,
VM_getInt64FieldAt,
Expand Down
Loading

0 comments on commit f165fd4

Please sign in to comment.