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

Implementation of GC phase pause events #4272

Closed
wants to merge 1 commit into from

Conversation

zhengyu123
Copy link
Contributor

@zhengyu123 zhengyu123 commented Jan 28, 2022

Please review this patch that implements GC pause phase events.

GC pause phase events are emitted during GC phase changes at GC pause. To match hotspot implementation, there can be maximum 5 level (0 - 4) of nesting phases

The sample events:

jdk.GCPhasePause {
  startTime = 12:58:00.232
  duration = 78.384 ms
  gcId = 1
  name = "CollectOnAllocation"
  eventThread = "main" (javaThreadId = 1)
}

jdk.GCPhasePauseLevel1 {
  startTime = 12:58:00.283
  duration = 27.470 ms
  gcId = 1
  name = "Full GC"
  eventThread = "main" (javaThreadId = 1)
}

jdk.GCPhasePauseLevel2 {
  startTime = 12:58:00.311
  duration = 5.775 us
  gcId = 1
  name = "Release Spaces"
  eventThread = "main" (javaThreadId = 1)
}

@zhengyu123 zhengyu123 marked this pull request as draft January 28, 2022 18:49
@jiekang jiekang requested review from christianhaeubl and removed request for christianhaeubl January 28, 2022 20:35
JfrNativeEventWriter.putEventThread(data);
JfrNativeEventWriter.putLong(data, phase.getGCEpoch().rawValue());

int len = phase.getName().getLength();
Copy link
Member

Choose a reason for hiding this comment

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

The code below can be replaced with JfrNativeEventWriter.putString.

import static jdk.internal.misc.Unsafe.ARRAY_BYTE_BASE_OFFSET;
import static jdk.internal.misc.Unsafe.ARRAY_BYTE_INDEX_SCALE;

final class NativeStringConversion {
Copy link
Member

Choose a reason for hiding this comment

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

This class should be unnecessary.

* NativeString stores java.lang.String content in native memory
*/
@RawStructure
interface NativeString extends PointerBase {
Copy link
Member

Choose a reason for hiding this comment

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

This interface should be unnecessary.

case 4:
return JfrEvents.GCPhasePauseLevel4Event;
default:
VMError.shouldNotReachHere("At most " + MAX_PHASE_LEVEL + " levels");
Copy link
Member

Choose a reason for hiding this comment

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

throw VMError... avoids the unnecessary return.

* Therefore, we need to keep the states on stack or in native memory.
*/
@RawStructure
public interface JfrGCPausePhase extends PointerBase {
Copy link
Member

Choose a reason for hiding this comment

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

This interface should be unnecessary.

@@ -207,6 +209,9 @@ private boolean collectImpl(GCCause cause, long requestingNanoTime, boolean forc
precondition();

NoAllocationVerifier nav = noAllocationVerifier.open();

JfrGCPausePhase phase = StackValue.get(JfrGCPausePhase.class);
Copy link
Member

Choose a reason for hiding this comment

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

I think that a large portion of this PR is unnecessary. I don't think that there is any need for extra data structures:

  • the GC epoch can be queried at any time via getCollectionEpoch()
  • the start ticks can be stored in a local
  • the level can be a constant
  • the phase name can be a String constant

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Question: Are constant strings guaranteed in unmovable partition of heap in binary image? I introduced NativeString, not because of this PR, but if I want to generate per-worker events during, e.g. object evacuation phase, I am not sure, but unlikely, there are barriers for accessing the phase names on GC path.

Copy link
Member

Choose a reason for hiding this comment

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

Constant strings are located the image heap and won't be touched by the GC, so they can be used safely. Per-worker events would still use the same constant Strings (only the data in the eventThread field of the JFR events would be different).

@zhengyu123 zhengyu123 marked this pull request as ready for review January 31, 2022 20:29
@@ -137,6 +142,21 @@ public void afterThreadExit(IsolateThread isolateThread, Thread javaThread) {
nativeBuffer.set(isolateThread, WordFactory.nullPointer());
}

public void pushPausePhaseLevel() {
Copy link
Member

Choose a reason for hiding this comment

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

In GCImpl, it should be possible to directly use constant instead of a counter for the levels. If that is not feasible for some reason, please add the level as a field to JfrGCEventSupport and use that instead of the thread local.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Okay

import com.oracle.svm.core.jfr.SubstrateJVM;
import com.oracle.svm.core.util.VMError;

public abstract class JfrGCEventSupport {
Copy link
Member

Choose a reason for hiding this comment

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

Please move this class to the GC project as only that GC will use this file. There shouldn't be any need to register this class as an ImageSingleton (you can add a new field to GCImpl instead).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You mean moving it to com.oracle.svm.core.genscavenge? Is it the only GC that graal plans to support?

Copy link
Member

Choose a reason for hiding this comment

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

Yes, com.oracle.svm.core.genscavenge.
For now, this is the only GC that will use this particular implementation to trigger JFR events.


public abstract void emitGCPausePhaseEvent(UnsignedWord gcEpoch, String name, long startTicks);

public static class Unsupported extends JfrGCEventSupport {
Copy link
Member

Choose a reason for hiding this comment

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

This extra dummy implementation shouldn't be necessary. You can directly check in each relevant methods if the JFR support is enabled or not (see JfrEnabled.get()). This will get optimized at image build time.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nice! I thought it is a runtime flag.

Copy link
Member

Choose a reason for hiding this comment

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

JfrEnabled.get() is annotated with @Fold and this annotation ensures that the method is optimized away and replaced with a constant during the image build.

@zhengyu123 zhengyu123 changed the title Implementation of GC pause phase events Implementation of GC phase pause events Feb 2, 2022
Copy link
Member

@christianhaeubl christianhaeubl left a comment

Choose a reason for hiding this comment

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

The changes look good, please squash your commits if possible. I will then integrate them into master.

@zhengyu123 zhengyu123 force-pushed the gc_event_impl branch 2 times, most recently from 870990e to 23192ad Compare February 3, 2022 13:31
@zhengyu123
Copy link
Contributor Author

The changes look good, please squash your commits if possible. I will then integrate them into master.

Done. The failed tests do not seem to relate to this PR.

Thanks!

@zhengyu123
Copy link
Contributor Author

All clean now.

@christianhaeubl
Copy link
Member

This PR was already merged to master - seems that the graalvmbot didn't realize that.

@jerboaa
Copy link
Collaborator

jerboaa commented Feb 11, 2022

870990e was the commit I believe.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants