Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modify rememberClass to return the offset to the class chain identifying the class #18832

Merged
merged 8 commits into from
Jan 31, 2024

Conversation

cjjdespres
Copy link
Contributor

The rememberClass function now returns the offset to the class chain that it creates or finds in the local SCC, instead of returning the chain directly. Instead of returning NULL when class remembering fails, it now returns the value 0. The offset of a class chain can never be zero in the local SCC, because that offset is always encoded with encodeOffsetFromEnd by isPointerInSharedCache, which means that the resulting value will always be odd:

static inline uintptr_t encodeOffsetFromEnd(uintptr_t offset) { return ((offset << 1) | OFFSET_FROM_END); }
static inline uintptr_t decodeOffsetFromEnd(uintptr_t offset) { return (offset >> 1); }

Various structures that previously stored class chain pointers now instead store offsets instead.

@cjjdespres cjjdespres requested a review from dsouzai as a code owner January 26, 2024 20:22
@cjjdespres
Copy link
Contributor Author

Attn @mpirvu, @dsouzai. This is a fairly mechanical change that implements what I talked about in #18821 (comment), though I decided to have rememberClass return the offset directly (or 0) instead of going with a bool return with uintptr_t & input scheme.

@dsouzai
Copy link
Contributor

dsouzai commented Jan 26, 2024

I'll go through the code in more detail as well, but just from a high level overview, I don't think it's a good idea to compare the returned encoded offset against 0; it weakens the conceptual integrity of the API because it exposes the implementation details to the callers of the API.

That said, I do think taking advantage of the fact that the SCC offset is always an offset from the end, and therefore is low tagged, is a valid approach to take.

So, in keeping with the contract that a caller of this API should not directly interact with the offset (which conceptually is a token or key of sorts), it would be better to add another method to J9SharedCache along the lines of offsetOfPointerIntoSCCIsValid(uintptr_t offset). This both hides the implementation details from callers as well as facilitates taking advantage of the low tagging.

@cjjdespres
Copy link
Contributor Author

In a few places we (now) rely on the existence of a class chain offset that is not valid; before, we would just store a NULL pointer in those places. I've added a static const uintptr_t INVALID_CLASS_CHAIN_OFFSET = 0 to TR_SharedCache that we can compare with the return value of rememberClass and also use instead of a bare 0. Does that seem all right?

@cjjdespres cjjdespres force-pushed the rememberclass-change branch 2 times, most recently from 0903e6b to d0cfdd0 Compare January 27, 2024 16:23
@dsouzai
Copy link
Contributor

dsouzai commented Jan 29, 2024

In a few places we (now) rely on the existence of a class chain offset that is not valid; before, we would just store a NULL pointer in those places. I've added a static const uintptr_t INVALID_CLASS_CHAIN_OFFSET = 0 to TR_SharedCache that we can compare with the return value of rememberClass and also use instead of a bare 0. Does that seem all right?

Yeah that seems reasonable to me.

Copy link
Contributor

@dsouzai dsouzai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM; however, I'll let Marius be the final reviewer/committer.

Copy link
Contributor

@mpirvu mpirvu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall, it looks good I have a few inline comments though.

}

if (!create)
{
LOG(1, "\tnot asked to create but could create, returning non-null\n");
return (uintptr_t *)0x1;
return 1;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs a symbolic value. Can 1 be a valid offset?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that the only time create is false in a rememberClass call is when canRememberClass or one of its overloads is run:

virtual bool canRememberClass(TR_OpaqueClassBlock *classPtr)
{
return rememberClass((J9Class *)classPtr, NULL, false) != NULL;
}

In those cases we don't care about the offset at all, and the return 1 is just a method of communicating that the chain could have been created. It looks like the intent is to avoid duplicating the rememberClass code in canRememberClass.

I'm not sure if 1 could be a valid offset - judging from isPointerInSharedCache:

TR_J9SharedCache::isPointerInSharedCache(void *ptr, uintptr_t *cacheOffset)

that would happen only if a class chain started at exactly the metadataStartAddress of the first layer of an SCC.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll add a symbolic constant.

@@ -7227,6 +7227,19 @@ TR_J9VM::getClassFromSignature(const char * sig, int32_t sigLength, J9ConstantPo
return returnValue; // 0 means failure
}

uint32_t
TR_J9VMBase::numInterfacesImplemented(J9Class *clazz)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this need to be overridden for server fe?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like the cls.iTableOf() and cls.iTableNext() calls handle this properly:

J9ITable *
J9::ClassEnv::iTableOf(TR_OpaqueClassBlock * clazz)
{
#if defined(J9VM_OPT_JITSERVER)
if (auto stream = TR::CompilationInfo::getStream())
{
stream->write(JITServer::MessageType::ClassEnv_iTableOf, clazz);
return std::get<0>(stream->read<J9ITable*>());
}
#endif /* defined(J9VM_OPT_JITSERVER) */
return (J9ITable*) self()->convertClassOffsetToClassPtr(clazz)->iTable;
}
J9ITable *
J9::ClassEnv::iTableNext(J9ITable *current)
{
#if defined(J9VM_OPT_JITSERVER)
if (auto stream = TR::CompilationInfo::getStream())
{
stream->write(JITServer::MessageType::ClassEnv_iTableNext, current);
return std::get<0>(stream->read<J9ITable*>());
}
#endif /* defined(J9VM_OPT_JITSERVER) */
return current->next;
}

case MessageType::ClassEnv_iTableOf:
{
auto clazz = std::get<0>(client->getRecvData<TR_OpaqueClassBlock *>());
client->write(response, TR::Compiler->cls.iTableOf(clazz));
}
break;
case MessageType::ClassEnv_iTableNext:
{
auto clazz = std::get<0>(client->getRecvData<J9ITable *>());
client->write(response, TR::Compiler->cls.iTableNext(clazz));
}
break;

so it shouldn't need a server override.

@cjjdespres cjjdespres force-pushed the rememberclass-change branch 2 times, most recently from 642d05e to 16c7ebf Compare January 30, 2024 02:15
@cjjdespres
Copy link
Contributor Author

Rebasing to pull in the reversion in #18843, and to fix the JITServer version merge conflict. The review comments should all be addressed as well.

@mpirvu mpirvu self-assigned this Jan 30, 2024
The length of the class chain associated to a class is relevant to the
JITServer AOT cache, as this quantity is used to construct RAMClass
chains that are sent from the client to the server. To support the
operation of the JITServer AOT cache without a local SCC, this length
must always be available.
@cjjdespres cjjdespres force-pushed the rememberclass-change branch from 16c7ebf to 7e9e21b Compare January 30, 2024 16:09
@cjjdespres cjjdespres force-pushed the rememberclass-change branch from 7e9e21b to 32ad2f5 Compare January 30, 2024 18:48
@cjjdespres cjjdespres force-pushed the rememberclass-change branch from 32ad2f5 to 528739f Compare January 30, 2024 18:58
@cjjdespres
Copy link
Contributor Author

That should be all of the log messages fixed.

Copy link
Contributor

@mpirvu mpirvu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@mpirvu
Copy link
Contributor

mpirvu commented Jan 30, 2024

jenkins test sanity all jdk17

@mpirvu
Copy link
Contributor

mpirvu commented Jan 31, 2024

jenkins test sanity aix jdk17

@mpirvu
Copy link
Contributor

mpirvu commented Jan 31, 2024

jenkins test sanity plinuxjit,xlinuxjit,zlinuxjit,alinux64jit jdk17

@mpirvu mpirvu merged commit fe7f576 into eclipse-openj9:master Jan 31, 2024
21 checks passed
cjjdespres added a commit to cjjdespres/openj9 that referenced this pull request Feb 16, 2024
…berclass-change"

This reverts commit fe7f576, reversing
changes made to c0cbb3e.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants