Details
-
Bug
-
Resolution: Fixed
-
P3
-
17, 18
-
b11
Backports
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-8274012 | 17.0.2 | Aleksey Shipilev | P3 | Resolved | Fixed | b01 |
Description
While fixing JDK-8270626 it was discovered that the C2 intrinsic for Reference.refersTo() is not used as often as one would think. Instead C2 often prefers using the native implementation, which is much slower which defeats the purpose of having an intrinsic in the first place.
The problem seem to arise from having refersTo0() being virtual, native and @IntrinsicCandidate. This can be easily worked around by making refersTo0() final, like this:
diff --git a/src/java.base/share/classes/java/lang/ref/PhantomReference.java b/src/java.base/share/classes/java/lang/ref/PhantomReference.java
index 9aba41feb02..36ff6299ffd 100644
--- a/src/java.base/share/classes/java/lang/ref/PhantomReference.java
+++ b/src/java.base/share/classes/java/lang/ref/PhantomReference.java
@@ -69,8 +69,12 @@ public class PhantomReference<T> extends Reference<T> {
* do reference processing concurrently.
*/
@Override
+ boolean refersToImpl(T obj) {
+ return refersTo0(obj);
+ }
+
@IntrinsicCandidate
- native final boolean refersTo0(Object o);
+ private native final boolean refersTo0(Object o);
/**
* Creates a new phantom reference that refers to the given object and
diff --git a/src/java.base/share/classes/java/lang/ref/Reference.java b/src/java.base/share/classes/java/lang/ref/Reference.java
index 0a312f97422..7f42daebb40 100644
--- a/src/java.base/share/classes/java/lang/ref/Reference.java
+++ b/src/java.base/share/classes/java/lang/ref/Reference.java
@@ -363,13 +363,20 @@ public abstract class Reference<T> {
* @since 16
*/
public final boolean refersTo(T obj) {
- return refersTo0(obj);
+ return refersToImpl(obj);
}
/* Implementation of refersTo(), overridden for phantom references.
+ * This method exists only to avoid making refersTo0() virtual. Making
+ * refersTo0() virtual has the undesirable effect of C2 often preferring
+ * to call the native implementation over the intrinsic.
*/
+ boolean refersToImpl(T obj) {
+ return refersTo0(obj);
+ }
+
@IntrinsicCandidate
- native boolean refersTo0(Object o);
+ private native final boolean refersTo0(Object o);
/**
* Clears this reference object. Invoking this method will not cause this
However, Object.clone() and Object.hashCode() are also virtual, native and @IntrinsicCandidate, and these get special treatment by C2 to get the intrinsic generated more optimally. It's not clear to me if we should do something similar with refersTo0() or if the above workaround should be considered good enough.
The problem seem to arise from having refersTo0() being virtual, native and @IntrinsicCandidate. This can be easily worked around by making refersTo0() final, like this:
diff --git a/src/java.base/share/classes/java/lang/ref/PhantomReference.java b/src/java.base/share/classes/java/lang/ref/PhantomReference.java
index 9aba41feb02..36ff6299ffd 100644
--- a/src/java.base/share/classes/java/lang/ref/PhantomReference.java
+++ b/src/java.base/share/classes/java/lang/ref/PhantomReference.java
@@ -69,8 +69,12 @@ public class PhantomReference<T> extends Reference<T> {
* do reference processing concurrently.
*/
@Override
+ boolean refersToImpl(T obj) {
+ return refersTo0(obj);
+ }
+
@IntrinsicCandidate
- native final boolean refersTo0(Object o);
+ private native final boolean refersTo0(Object o);
/**
* Creates a new phantom reference that refers to the given object and
diff --git a/src/java.base/share/classes/java/lang/ref/Reference.java b/src/java.base/share/classes/java/lang/ref/Reference.java
index 0a312f97422..7f42daebb40 100644
--- a/src/java.base/share/classes/java/lang/ref/Reference.java
+++ b/src/java.base/share/classes/java/lang/ref/Reference.java
@@ -363,13 +363,20 @@ public abstract class Reference<T> {
* @since 16
*/
public final boolean refersTo(T obj) {
- return refersTo0(obj);
+ return refersToImpl(obj);
}
/* Implementation of refersTo(), overridden for phantom references.
+ * This method exists only to avoid making refersTo0() virtual. Making
+ * refersTo0() virtual has the undesirable effect of C2 often preferring
+ * to call the native implementation over the intrinsic.
*/
+ boolean refersToImpl(T obj) {
+ return refersTo0(obj);
+ }
+
@IntrinsicCandidate
- native boolean refersTo0(Object o);
+ private native final boolean refersTo0(Object o);
/**
* Clears this reference object. Invoking this method will not cause this
However, Object.clone() and Object.hashCode() are also virtual, native and @IntrinsicCandidate, and these get special treatment by C2 to get the intrinsic generated more optimally. It's not clear to me if we should do something similar with refersTo0() or if the above workaround should be considered good enough.
Attachments
Issue Links
- backported by
-
JDK-8274012 C2 intrinsic for Reference.refersTo() is often not used
- Resolved
- relates to
-
JDK-8272140 C2: investigate alternative intrinsic selection for Reference.refersTo
- Open
-
JDK-8256999 Add C2 intrinsic for Reference.refersTo and PhantomReference::refersTo
- Resolved
- links to
-
Commit openjdk/jdk17u/bf788eee
-
Commit openjdk/jdk/3f723ca4
-
Review openjdk/jdk17u/62
-
Review openjdk/jdk/5052
(2 links to)