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

Loom: GC Thread scanning #15612

Merged
merged 1 commit into from
Sep 28, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion runtime/gc_base/RootScanner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -536,7 +536,19 @@ MM_RootScanner::scanOneThread(MM_EnvironmentBase *env, J9VMThread* walkThread, v
doVMThreadSlot(slot, &vmThreadIterator);
}

GC_VMThreadStackSlotIterator::scanSlots((J9VMThread *)env->getOmrVMThread()->_language_vmthread, walkThread, localData, stackSlotIterator, isStackFrameClassWalkNeeded(), _trackVisibleStackFrameDepth);
J9VMThread *currentThread = (J9VMThread *)env->getOmrVMThread()->_language_vmthread;
/* In a case this thread is a carrier thread, and a virtual thread is mounted, we will scan virtual thread's stack.
* If virtual thread is not mounted, or this is just a regular thread, this will scan its own stack. */
GC_VMThreadStackSlotIterator::scanSlots(currentThread, walkThread, localData, stackSlotIterator, isStackFrameClassWalkNeeded(), _trackVisibleStackFrameDepth);
Copy link
Contributor

@amicic amicic Sep 16, 2022

Choose a reason for hiding this comment

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

You should probably put a comment above, something like this:
In a case this thread is a carrier thread, and a virtual thread is mounted, we will scan virtual thread's stack.

Copy link
Contributor

Choose a reason for hiding this comment

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

You can append this comment by another sentence.
... If virtual thread is not mounted, or this is just a regular thread, this will scan its own stack.


#if JAVA_SPEC_VERSION >= 19
if (NULL != walkThread->currentContinuation)
{
/* At this point we know that a virtual thread is mounted. We previously scanned its stack,
* and now we will scan carrier's stack, that continuation struct is currently pointing to. */
GC_VMThreadStackSlotIterator::scanSlots(currentThread, walkThread->currentContinuation, localData, stackSlotIterator, isStackFrameClassWalkNeeded(), _trackVisibleStackFrameDepth);
}
#endif /* JAVA_SPEC_VERSION >= 19 */
return false;
}

Expand Down
7 changes: 7 additions & 0 deletions runtime/gc_glue_java/ConcurrentMarkingDelegate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,15 @@ MM_ConcurrentMarkingDelegate::scanThreadRoots(MM_EnvironmentBase *env)
markSchemeStackIteratorData localData;
localData.markingScheme = _markingScheme;
localData.env = env;
/* In a case this thread is a carrier thread, and a virtual thread is mounted, we will scan virtual thread's stack. */
GC_VMThreadStackSlotIterator::scanSlots(vmThread, vmThread, (void *)&localData, concurrentStackSlotIterator, true, false);

#if JAVA_SPEC_VERSION >= 19
if (NULL != vmThread->currentContinuation) {
GC_VMThreadStackSlotIterator::scanSlots(vmThread, vmThread->currentContinuation, (void *)&localData, concurrentStackSlotIterator, true, false);
}
#endif /* JAVA_SPEC_VERSION >= 19 */

return true;
}

Expand Down
102 changes: 56 additions & 46 deletions runtime/gc_structs/VMThreadStackSlotIterator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,42 @@ vmThreadStackFrameIterator(J9VMThread * currentThread, J9StackWalkState * walkSt

} /* extern "C" */

void
Copy link
Contributor

Choose a reason for hiding this comment

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

Either make this is a static method or make the name of the method more specific for GC purposes. In theory there could be a same/similar method somewhere in core VM code.

Copy link
Contributor

Choose a reason for hiding this comment

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

as I said in hpp comment, make this method a class member and remove 'forGC'

GC_VMThreadStackSlotIterator::initializeStackWalkState(
J9StackWalkState *stackWalkState,
J9VMThread *vmThread,
void *userData,
J9MODRON_OSLOTITERATOR *oSlotIterator,
bool includeStackFrameClassReferences,
bool trackVisibleFrameDepth
)
{
J9JavaVM *vm = vmThread->javaVM;

stackWalkState->objectSlotWalkFunction = vmThreadStackDoOSlotIterator;
stackWalkState->userData1 = (void *)oSlotIterator;
stackWalkState->userData2 = (void *)vm;
stackWalkState->userData3 = userData;

stackWalkState->flags = J9_STACKWALK_ITERATE_O_SLOTS | J9_STACKWALK_DO_NOT_SNIFF_AND_WHACK;
stackWalkState->walkThread = NULL;

if (trackVisibleFrameDepth) {
stackWalkState->skipCount = 0;
stackWalkState->flags |= J9_STACKWALK_VISIBLE_ONLY;
} else {
if (NULL != vm->collectJitPrivateThreadData) {
stackWalkState->frameWalkFunction = vmThreadStackFrameIterator;
stackWalkState->flags |= J9_STACKWALK_ITERATE_FRAMES;
}
stackWalkState->flags |= J9_STACKWALK_SKIP_INLINES;
}

if (includeStackFrameClassReferences) {
stackWalkState->flags |= J9_STACKWALK_ITERATE_METHOD_CLASS_SLOTS;
}

}
/**
* Walk all slots of the walk thread which contain object references.
* For every object slot found in <code>walkThread</code> call the <code>oSlotIterator</code> function.
Expand All @@ -87,32 +123,10 @@ GC_VMThreadStackSlotIterator::scanSlots(
)
{
J9StackWalkState stackWalkState;
J9JavaVM *vm = vmThread->javaVM;

stackWalkState.objectSlotWalkFunction = vmThreadStackDoOSlotIterator;
stackWalkState.userData1 = (void *)oSlotIterator;
stackWalkState.userData2 = (void *)vm;
stackWalkState.userData3 = userData;

stackWalkState.flags = J9_STACKWALK_ITERATE_O_SLOTS | J9_STACKWALK_DO_NOT_SNIFF_AND_WHACK;
initializeStackWalkState(&stackWalkState, vmThread, userData, oSlotIterator, includeStackFrameClassReferences, trackVisibleFrameDepth);
stackWalkState.walkThread = walkThread;
Copy link
Contributor

Choose a reason for hiding this comment

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

should we set this explicitely to NULL in other cases?


if (trackVisibleFrameDepth) {
stackWalkState.skipCount = 0;
stackWalkState.flags |= J9_STACKWALK_VISIBLE_ONLY;
} else {
if (NULL != vm->collectJitPrivateThreadData) {
stackWalkState.frameWalkFunction = vmThreadStackFrameIterator;
stackWalkState.flags |= J9_STACKWALK_ITERATE_FRAMES;
}
stackWalkState.flags |= J9_STACKWALK_SKIP_INLINES;
}

if (includeStackFrameClassReferences) {
stackWalkState.flags |= J9_STACKWALK_ITERATE_METHOD_CLASS_SLOTS;
}

vm->walkStackFrames(vmThread, &stackWalkState);
vmThread->javaVM->walkStackFrames(vmThread, &stackWalkState);
}

void
Expand All @@ -126,29 +140,25 @@ GC_VMThreadStackSlotIterator::scanSlots(
)
{
J9StackWalkState stackWalkState;
J9JavaVM *vm = vmThread->javaVM;
initializeStackWalkState(&stackWalkState, vmThread, userData, oSlotIterator, includeStackFrameClassReferences, trackVisibleFrameDepth);

stackWalkState.objectSlotWalkFunction = vmThreadStackDoOSlotIterator;
stackWalkState.userData1 = (void *)oSlotIterator;
stackWalkState.userData2 = (void *)vm;
stackWalkState.userData3 = userData;

stackWalkState.flags = J9_STACKWALK_ITERATE_O_SLOTS | J9_STACKWALK_DO_NOT_SNIFF_AND_WHACK;

if (trackVisibleFrameDepth) {
stackWalkState.skipCount = 0;
stackWalkState.flags |= J9_STACKWALK_VISIBLE_ONLY;
} else {
if (NULL != vm->collectJitPrivateThreadData) {
stackWalkState.frameWalkFunction = vmThreadStackFrameIterator;
stackWalkState.flags |= J9_STACKWALK_ITERATE_FRAMES;
}
stackWalkState.flags |= J9_STACKWALK_SKIP_INLINES;
}
VM_VMHelpers::walkContinuationStackFramesWrapper(vmThread, continuationObjectPtr, &stackWalkState);
}

if (includeStackFrameClassReferences) {
stackWalkState.flags |= J9_STACKWALK_ITERATE_METHOD_CLASS_SLOTS;
}
#if JAVA_SPEC_VERSION >= 19
void
GC_VMThreadStackSlotIterator::scanSlots(
J9VMThread *vmThread,
J9VMContinuation *continuation,
void *userData,
J9MODRON_OSLOTITERATOR *oSlotIterator,
bool includeStackFrameClassReferences,
bool trackVisibleFrameDepth
)
{
J9StackWalkState stackWalkState;
initializeStackWalkState(&stackWalkState, vmThread, userData, oSlotIterator, includeStackFrameClassReferences, trackVisibleFrameDepth);

VM_VMHelpers::walkContinuationStackFramesWrapper(vmThread, continuationObjectPtr, &stackWalkState);
vmThread->javaVM->internalVMFunctions->walkContinuationStackFrames(vmThread, continuation, &stackWalkState);
}
#endif /* JAVA_SPEC_VERSION >= 19 */
18 changes: 18 additions & 0 deletions runtime/gc_structs/VMThreadStackSlotIterator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,14 @@ typedef void J9MODRON_OSLOTITERATOR(J9JavaVM *javaVM, J9Object **objectIndirect,
*/
class GC_VMThreadStackSlotIterator
{
private:
static void initializeStackWalkState(
J9StackWalkState *stackWalkState,
J9VMThread *vmThread,
void *userData,
J9MODRON_OSLOTITERATOR *oSlotIterator,
bool includeStackFrameClassReferences,
bool trackVisibleFrameDepth);
public:
static void scanSlots(
J9VMThread *vmThread,
Expand All @@ -59,6 +67,16 @@ class GC_VMThreadStackSlotIterator
J9MODRON_OSLOTITERATOR *oSlotIterator,
bool includeStackFrameClassReferences,
bool trackVisibleFrameDepth);

#if JAVA_SPEC_VERSION >= 19
static void scanSlots(
J9VMThread *vmThread,
J9VMContinuation *continuation,
void *userData,
J9MODRON_OSLOTITERATOR *oSlotIterator,
bool includeStackFrameClassReferences,
bool trackVisibleFrameDepth);
#endif /* JAVA_SPEC_VERSION >= 19 */
};

#endif /* VMTHREADSTACKSLOTITERATOR_HPP_ */
Expand Down