Skip to content
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
2 changes: 1 addition & 1 deletion substratevm/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ This changelog summarizes major changes to GraalVM Native Image.
* (GR-42964) Deprecate `--enable-monitoring` without an argument. The option will no longer default to `all` in a future release. Instead, please always explicitly specify the list of monitoring features to be enabled (for example, `--enable-monitoring=heapdump,jfr,jvmstat`").
* (GR-19890) Native Image now sets up build environments for Windows users automatically. Running in an x64 Native Tools Command Prompt is no longer a requirement.
* (GR-43410) Added support for the JFR event `ExecutionSample`.
* (GR-44058) Red Hat added support for the JFR event `ObjectAllocationInNewTLAB`.
* (GR-44058) (GR-44087) Red Hat added support for the JFR events `ObjectAllocationInNewTLAB` and `JavaMonitorInflate`.
* (GR-42467) The search path for `System.loadLibrary()` by default includes the directory containing the native image.

## Version 22.3.0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ public final class JfrEvent {
public static final JfrEvent JavaMonitorEnter = create("jdk.JavaMonitorEnter");
public static final JfrEvent ThreadPark = create("jdk.ThreadPark");
public static final JfrEvent JavaMonitorWait = create("jdk.JavaMonitorWait");
public static final JfrEvent JavaMonitorInflate = create("jdk.JavaMonitorInflate");
public static final JfrEvent ObjectAllocationInNewTLAB = create("jdk.ObjectAllocationInNewTLAB");

private final long id;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ public void afterRegistration(AfterRegistrationAccess access) {

JfrSerializerSupport.get().register(new JfrFrameTypeSerializer());
JfrSerializerSupport.get().register(new JfrThreadStateSerializer());
JfrSerializerSupport.get().register(new JfrMonitorInflationCauseSerializer());
JfrSerializerSupport.get().register(new JfrGCCauseSerializer());
JfrSerializerSupport.get().register(new JfrGCNameSerializer());
JfrSerializerSupport.get().register(new JfrVMOperationNameSerializer());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* Copyright (c) 2023, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2023, 2023, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/

package com.oracle.svm.core.jfr;

import org.graalvm.nativeimage.Platform;
import org.graalvm.nativeimage.Platforms;

import com.oracle.svm.core.monitor.MonitorInflationCause;

public class JfrMonitorInflationCauseSerializer implements JfrConstantPool {
@Platforms(Platform.HOSTED_ONLY.class)
public JfrMonitorInflationCauseSerializer() {
}

@Override
public int write(JfrChunkWriter writer) {
writer.writeCompressedLong(JfrType.MonitorInflationCause.getId());

MonitorInflationCause[] inflationCauses = MonitorInflationCause.values();
writer.writeCompressedLong(inflationCauses.length);
for (int i = 0; i < inflationCauses.length; i++) {
writer.writeCompressedInt(i);
writer.writeString(inflationCauses[i].getText());
}

return NON_EMPTY;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ public enum JfrType {
FrameType("jdk.types.FrameType"),
GCCause("jdk.types.GCCause"),
GCName("jdk.types.GCName"),
VMOperation("jdk.types.VMOperationType");
VMOperation("jdk.types.VMOperationType"),
MonitorInflationCause("jdk.types.InflateCause");

private final long id;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
* Copyright (c) 2023, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2023, 2023, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/

package com.oracle.svm.core.jfr.events;

import org.graalvm.compiler.word.Word;
import org.graalvm.nativeimage.StackValue;

import com.oracle.svm.core.Uninterruptible;
import com.oracle.svm.core.jfr.HasJfrSupport;
import com.oracle.svm.core.jfr.JfrEvent;
import com.oracle.svm.core.jfr.JfrNativeEventWriter;
import com.oracle.svm.core.jfr.JfrNativeEventWriterData;
import com.oracle.svm.core.jfr.JfrNativeEventWriterDataAccess;
import com.oracle.svm.core.jfr.JfrTicks;
import com.oracle.svm.core.jfr.SubstrateJVM;
import com.oracle.svm.core.monitor.MonitorInflationCause;

public class JavaMonitorInflateEvent {
public static void emit(Object obj, long startTicks, MonitorInflationCause cause) {
if (HasJfrSupport.get()) {
emit0(obj, startTicks, cause);
}
}

@Uninterruptible(reason = "Accesses a JFR buffer.")
public static void emit0(Object obj, long startTicks, MonitorInflationCause cause) {
if (JfrEvent.JavaMonitorInflate.shouldEmit()) {
JfrNativeEventWriterData data = StackValue.get(JfrNativeEventWriterData.class);
JfrNativeEventWriterDataAccess.initializeThreadLocalNativeBuffer(data);

JfrNativeEventWriter.beginSmallEvent(data, JfrEvent.JavaMonitorInflate);
JfrNativeEventWriter.putLong(data, startTicks);
JfrNativeEventWriter.putLong(data, JfrTicks.elapsedTicks() - startTicks);
JfrNativeEventWriter.putEventThread(data);
JfrNativeEventWriter.putLong(data, SubstrateJVM.get().getStackTraceId(JfrEvent.JavaMonitorInflate, 0));
JfrNativeEventWriter.putClass(data, obj.getClass());
JfrNativeEventWriter.putLong(data, Word.objectToUntrackedPointer(obj).rawValue());
JfrNativeEventWriter.putLong(data, getId(cause));
JfrNativeEventWriter.endSmallEvent(data);
}
}

@Uninterruptible(reason = "Called from uninterruptible code", mayBeInlined = true)
private static long getId(MonitorInflationCause cause) {
/* First entry needs to have id 0. */
return cause.ordinal();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@
import com.oracle.svm.core.jni.headers.JNIVersion;
import com.oracle.svm.core.jni.headers.JNIVersionJDK19OrLater;
import com.oracle.svm.core.log.Log;
import com.oracle.svm.core.monitor.MonitorInflationCause;
import com.oracle.svm.core.monitor.MonitorSupport;
import com.oracle.svm.core.snippets.KnownIntrinsics;
import com.oracle.svm.core.stack.StackOverflowCheck;
Expand Down Expand Up @@ -1015,7 +1016,7 @@ static int MonitorEnter(JNIEnvironment env, JNIObjectHandle handle) {
}
boolean acquired = false;
try {
MonitorSupport.singleton().monitorEnter(obj);
MonitorSupport.singleton().monitorEnter(obj, MonitorInflationCause.JNI_ENTER);
assert Thread.holdsLock(obj);
acquired = true;

Expand All @@ -1024,7 +1025,8 @@ static int MonitorEnter(JNIEnvironment env, JNIObjectHandle handle) {
} catch (Throwable t) {
try {
if (acquired) {
MonitorSupport.singleton().monitorExit(obj);
/* The thread acquired the monitor, so monitor inflation can't happen here. */
MonitorSupport.singleton().monitorExit(obj, MonitorInflationCause.VM_INTERNAL);
}
if (pinned) {
VirtualThreads.singleton().unpinCurrent();
Expand All @@ -1049,7 +1051,7 @@ static int MonitorExit(JNIEnvironment env, JNIObjectHandle handle) {
if (!Thread.holdsLock(obj)) {
throw new IllegalMonitorStateException();
}
MonitorSupport.singleton().monitorExit(obj);
MonitorSupport.singleton().monitorExit(obj, MonitorInflationCause.JNI_EXIT);
JNIThreadOwnedMonitors.exited(obj);
if (VirtualThreads.isSupported() && JavaThreads.isCurrentThreadVirtual()) {
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@
import org.graalvm.word.WordFactory;

import com.oracle.svm.core.SubstrateOptions;
import com.oracle.svm.core.UnmanagedMemoryUtil;
import com.oracle.svm.core.Uninterruptible;
import com.oracle.svm.core.UnmanagedMemoryUtil;
import com.oracle.svm.core.c.CGlobalData;
import com.oracle.svm.core.c.CGlobalDataFactory;
import com.oracle.svm.core.c.function.CEntryPointActions;
Expand Down Expand Up @@ -73,6 +73,7 @@
import com.oracle.svm.core.jni.headers.JNIJavaVMPointer;
import com.oracle.svm.core.jni.headers.JNIVersion;
import com.oracle.svm.core.log.FunctionPointerLogHandler;
import com.oracle.svm.core.monitor.MonitorInflationCause;
import com.oracle.svm.core.monitor.MonitorSupport;
import com.oracle.svm.core.snippets.ImplicitExceptions;
import com.oracle.svm.core.thread.PlatformThreads;
Expand Down Expand Up @@ -265,11 +266,8 @@ static int AttachCurrentThreadAsDaemon(JNIJavaVM vm, JNIEnvironmentPointer penv,
*/
@CEntryPoint(include = CEntryPoint.NotIncludedAutomatically.class, publishAs = Publish.NotPublished)
@CEntryPointOptions(prologue = JNIJavaVMEnterAttachThreadEnsureJavaThreadPrologue.class, epilogue = LeaveDetachThreadEpilogue.class)
static int DetachCurrentThread(JNIJavaVM vm) {
static int DetachCurrentThread(@SuppressWarnings("unused") JNIJavaVM vm) {
int result = JNIErrors.JNI_OK();
if (!vm.equal(JNIFunctionTables.singleton().getGlobalJavaVM())) {
result = JNIErrors.JNI_ERR();
}
// JNI specification requires releasing all owned monitors
Support.releaseCurrentThreadOwnedMonitors();
return result;
Expand Down Expand Up @@ -353,7 +351,7 @@ static void attachCurrentThread(JNIJavaVM vm, JNIEnvironmentPointer penv, JNIJav
static void releaseCurrentThreadOwnedMonitors() {
JNIThreadOwnedMonitors.forEach((obj, depth) -> {
for (int i = 0; i < depth; i++) {
MonitorSupport.singleton().monitorExit(obj);
MonitorSupport.singleton().monitorExit(obj, MonitorInflationCause.VM_INTERNAL);
}
assert !Thread.holdsLock(obj);
});
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Copyright (c) 2023, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2023, 2023, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/

package com.oracle.svm.core.monitor;

import org.graalvm.nativeimage.Platform;
import org.graalvm.nativeimage.Platforms;

public enum MonitorInflationCause {
VM_INTERNAL("VM Internal"),
MONITOR_ENTER("Monitor Enter"),
WAIT("Monitor Wait"),
NOTIFY("Monitor Notify"),
JNI_ENTER("JNI Monitor Enter"),
JNI_EXIT("JNI Monitor Exit");

private final String text;

@Platforms(Platform.HOSTED_ONLY.class)
MonitorInflationCause(String text) {
this.text = text;
}

public String getText() {
return text;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,12 @@ public static MonitorSupport singleton() {
/**
* Implements the semantics of the monitorenter bytecode.
*/
public abstract void monitorEnter(Object obj);
public abstract void monitorEnter(Object obj, MonitorInflationCause cause);

/**
* Implements the semantics of the monitorexit bytecode.
*/
public abstract void monitorExit(Object obj);
public abstract void monitorExit(Object obj, MonitorInflationCause cause);

/*
* Support for objects that are re-locked during deoptimization. This method is called when
Expand Down
Loading