Skip to content
Permalink
Browse files
8278065: Refactor subclassAudits to use ClassValue
Backport-of: 8fed8ab29cae4f189f44609c23f116967eef6bdf
  • Loading branch information
rkennke committed Mar 25, 2022
1 parent 9923714 commit 8d7f26b7ad4d1cf5750ac807b4f935fa63d3b047
Showing 3 changed files with 16 additions and 103 deletions.
@@ -26,11 +26,9 @@
package java.io;

import java.io.ObjectInputFilter.Config;
import java.io.ObjectStreamClass.WeakClassKey;
import java.io.ObjectStreamClass.RecordSupport;
import java.lang.System.Logger;
import java.lang.invoke.MethodHandle;
import java.lang.ref.ReferenceQueue;
import java.lang.reflect.Array;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Modifier;
@@ -43,10 +41,6 @@
import java.util.Arrays;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import static java.io.ObjectStreamClass.processQueue;

import jdk.internal.access.SharedSecrets;
import jdk.internal.event.DeserializationEvent;
@@ -276,12 +270,13 @@

private static class Caches {
/** cache of subclass security audit results */
static final ConcurrentMap<WeakClassKey,Boolean> subclassAudits =
new ConcurrentHashMap<>();

/** queue for WeakReferences to audited subclasses */
static final ReferenceQueue<Class<?>> subclassAuditsQueue =
new ReferenceQueue<>();
static final ClassValue<Boolean> subclassAudits =
new ClassValue<>() {
@Override
protected Boolean computeValue(Class<?> type) {
return auditSubclass(type);
}
};

/**
* Property to permit setting a filter after objects
@@ -1616,13 +1611,7 @@ private void verifySubclass() {
if (sm == null) {
return;
}
processQueue(Caches.subclassAuditsQueue, Caches.subclassAudits);
WeakClassKey key = new WeakClassKey(cl, Caches.subclassAuditsQueue);
Boolean result = Caches.subclassAudits.get(key);
if (result == null) {
result = auditSubclass(cl);
Caches.subclassAudits.putIfAbsent(key, result);
}
boolean result = Caches.subclassAudits.get(cl);
if (!result) {
sm.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
}
@@ -25,17 +25,12 @@

package java.io;

import java.io.ObjectStreamClass.WeakClassKey;
import java.lang.ref.ReferenceQueue;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.StringJoiner;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import static java.io.ObjectStreamClass.processQueue;
import sun.reflect.misc.ReflectUtil;

/**
@@ -169,12 +164,13 @@

private static class Caches {
/** cache of subclass security audit results */
static final ConcurrentMap<WeakClassKey,Boolean> subclassAudits =
new ConcurrentHashMap<>();

/** queue for WeakReferences to audited subclasses */
static final ReferenceQueue<Class<?>> subclassAuditsQueue =
new ReferenceQueue<>();
static final ClassValue<Boolean> subclassAudits =
new ClassValue<>() {
@Override
protected Boolean computeValue(Class<?> type) {
return auditSubclass(type);
}
};
}

/** filter stream for handling block data conversion */
@@ -1060,13 +1056,7 @@ private void verifySubclass() {
if (sm == null) {
return;
}
processQueue(Caches.subclassAuditsQueue, Caches.subclassAudits);
WeakClassKey key = new WeakClassKey(cl, Caches.subclassAuditsQueue);
Boolean result = Caches.subclassAudits.get(key);
if (result == null) {
result = auditSubclass(cl);
Caches.subclassAudits.putIfAbsent(key, result);
}
boolean result = Caches.subclassAudits.get(cl);
if (!result) {
sm.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
}
@@ -28,9 +28,6 @@
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
@@ -58,7 +55,6 @@
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import jdk.internal.misc.Unsafe;
import jdk.internal.reflect.CallerSensitive;
import jdk.internal.reflect.Reflection;
@@ -2229,68 +2225,6 @@ private static ObjectStreamField[] matchFields(ObjectStreamField[] fields,
return matches;
}

/**
* Removes from the specified map any keys that have been enqueued
* on the specified reference queue.
*/
static void processQueue(ReferenceQueue<Class<?>> queue,
ConcurrentMap<? extends
WeakReference<Class<?>>, ?> map)
{
Reference<? extends Class<?>> ref;
while((ref = queue.poll()) != null) {
map.remove(ref);
}
}

/**
* Weak key for Class objects.
*
**/
static class WeakClassKey extends WeakReference<Class<?>> {
/**
* saved value of the referent's identity hash code, to maintain
* a consistent hash code after the referent has been cleared
*/
private final int hash;

/**
* Create a new WeakClassKey to the given object, registered
* with a queue.
*/
WeakClassKey(Class<?> cl, ReferenceQueue<Class<?>> refQueue) {
super(cl, refQueue);
hash = System.identityHashCode(cl);
}

/**
* Returns the identity hash code of the original referent.
*/
public int hashCode() {
return hash;
}

/**
* Returns true if the given object is this identical
* WeakClassKey instance, or, if this object's referent has not
* been cleared, if the given object is another WeakClassKey
* instance with the identical non-null referent as this one.
*/
public boolean equals(Object obj) {
if (obj == this) {
return true;
}

if (obj instanceof WeakClassKey) {
Class<?> referent = get();
return (referent != null) &&
(((WeakClassKey) obj).refersTo(referent));
} else {
return false;
}
}
}

/**
* A LRA cache of record deserialization constructors.
*/

1 comment on commit 8d7f26b

@openjdk-notifier
Copy link

@openjdk-notifier openjdk-notifier bot commented on 8d7f26b Mar 25, 2022

Choose a reason for hiding this comment

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

Please sign in to comment.