src/java.base/share/classes/jdk/internal/loader/AbstractClassLoaderValue.java
author mchung
Tue, 06 Nov 2018 10:01:16 -0800
changeset 52427 3c6aa484536c
parent 48373 f9152f462cbc
child 57956 e0b8b019d2f5
permissions -rw-r--r--
8211122: Reduce the number of internal classes made accessible to jdk.unsupported Reviewed-by: alanb, dfuchs, kvn
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
     1
/*
52427
3c6aa484536c 8211122: Reduce the number of internal classes made accessible to jdk.unsupported
mchung
parents: 48373
diff changeset
     2
 * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
     4
 *
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
48373
f9152f462cbc 8193758: Update copyright headers of files in src tree that are missing Classpath exception
alanb
parents: 47216
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
f9152f462cbc 8193758: Update copyright headers of files in src tree that are missing Classpath exception
alanb
parents: 47216
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
f9152f462cbc 8193758: Update copyright headers of files in src tree that are missing Classpath exception
alanb
parents: 47216
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    10
 *
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    15
 * accompanied this code).
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    16
 *
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    20
 *
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    23
 * questions.
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    24
 */
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    25
40459
88a91142b711 8164547: Make java.lang.reflect.ClassLoaderValue public for internal use
plevart
parents: 36972
diff changeset
    26
package jdk.internal.loader;
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    27
52427
3c6aa484536c 8211122: Reduce the number of internal classes made accessible to jdk.unsupported
mchung
parents: 48373
diff changeset
    28
import jdk.internal.access.JavaLangAccess;
3c6aa484536c 8211122: Reduce the number of internal classes made accessible to jdk.unsupported
mchung
parents: 48373
diff changeset
    29
import jdk.internal.access.SharedSecrets;
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    30
40459
88a91142b711 8164547: Make java.lang.reflect.ClassLoaderValue public for internal use
plevart
parents: 36972
diff changeset
    31
import java.lang.reflect.UndeclaredThrowableException;
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    32
import java.util.Iterator;
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    33
import java.util.Objects;
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    34
import java.util.concurrent.ConcurrentHashMap;
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    35
import java.util.function.BiFunction;
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    36
import java.util.function.Supplier;
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    37
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    38
/**
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    39
 * AbstractClassLoaderValue is a superclass of root-{@link ClassLoaderValue}
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    40
 * and {@link Sub sub}-ClassLoaderValue.
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    41
 *
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    42
 * @param <CLV> the type of concrete ClassLoaderValue (this type)
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    43
 * @param <V>   the type of values associated with ClassLoaderValue
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    44
 */
40459
88a91142b711 8164547: Make java.lang.reflect.ClassLoaderValue public for internal use
plevart
parents: 36972
diff changeset
    45
public abstract class AbstractClassLoaderValue<CLV extends AbstractClassLoaderValue<CLV, V>, V> {
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    46
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    47
    /**
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    48
     * Sole constructor.
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    49
     */
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    50
    AbstractClassLoaderValue() {}
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    51
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    52
    /**
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    53
     * Returns the key component of this ClassLoaderValue. The key component of
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    54
     * the root-{@link ClassLoaderValue} is the ClassLoaderValue itself,
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    55
     * while the key component of a {@link #sub(Object) sub}-ClassLoaderValue
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    56
     * is what was given to construct it.
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    57
     *
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    58
     * @return the key component of this ClassLoaderValue.
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    59
     */
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    60
    public abstract Object key();
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    61
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    62
    /**
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    63
     * Constructs new sub-ClassLoaderValue of this ClassLoaderValue with given
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    64
     * key component.
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    65
     *
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    66
     * @param key the key component of the sub-ClassLoaderValue.
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    67
     * @param <K> the type of the key component.
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    68
     * @return a sub-ClassLoaderValue of this ClassLoaderValue for given key
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    69
     */
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    70
    public <K> Sub<K> sub(K key) {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    71
        return new Sub<>(key);
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    72
    }
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    73
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    74
    /**
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    75
     * Returns {@code true} if this ClassLoaderValue is equal to given {@code clv}
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    76
     * or if this ClassLoaderValue was derived from given {@code clv} by a chain
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    77
     * of {@link #sub(Object)} invocations.
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    78
     *
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    79
     * @param clv the ClassLoaderValue to test this against
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    80
     * @return if this ClassLoaderValue is equal to given {@code clv} or
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    81
     * its descendant
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    82
     */
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    83
    public abstract boolean isEqualOrDescendantOf(AbstractClassLoaderValue<?, V> clv);
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    84
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    85
    /**
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    86
     * Returns the value associated with this ClassLoaderValue and given ClassLoader
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    87
     * or {@code null} if there is none.
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    88
     *
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    89
     * @param cl the ClassLoader for the associated value
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    90
     * @return the value associated with this ClassLoaderValue and given ClassLoader
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    91
     * or {@code null} if there is none.
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    92
     */
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    93
    public V get(ClassLoader cl) {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    94
        Object val = AbstractClassLoaderValue.<CLV>map(cl).get(this);
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    95
        try {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    96
            return extractValue(val);
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    97
        } catch (Memoizer.RecursiveInvocationException e) {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    98
            // propagate recursive get() for the same key that is just
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
    99
            // being calculated in computeIfAbsent()
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   100
            throw e;
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   101
        } catch (Throwable t) {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   102
            // don't propagate exceptions thrown from Memoizer - pretend
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   103
            // that there was no entry
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   104
            // (computeIfAbsent invocation will try to remove it anyway)
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   105
            return null;
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   106
        }
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   107
    }
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   108
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   109
    /**
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   110
     * Associates given value {@code v} with this ClassLoaderValue and given
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   111
     * ClassLoader and returns {@code null} if there was no previously associated
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   112
     * value or does nothing and returns previously associated value if there
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   113
     * was one.
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   114
     *
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   115
     * @param cl the ClassLoader for the associated value
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   116
     * @param v  the value to associate
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   117
     * @return previously associated value or null if there was none
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   118
     */
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   119
    public V putIfAbsent(ClassLoader cl, V v) {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   120
        ConcurrentHashMap<CLV, Object> map = map(cl);
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   121
        @SuppressWarnings("unchecked")
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   122
        CLV clv = (CLV) this;
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   123
        while (true) {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   124
            try {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   125
                Object val = map.putIfAbsent(clv, v);
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   126
                return extractValue(val);
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   127
            } catch (Memoizer.RecursiveInvocationException e) {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   128
                // propagate RecursiveInvocationException for the same key that
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   129
                // is just being calculated in computeIfAbsent
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   130
                throw e;
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   131
            } catch (Throwable t) {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   132
                // don't propagate exceptions thrown from foreign Memoizer -
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   133
                // pretend that there was no entry and retry
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   134
                // (foreign computeIfAbsent invocation will try to remove it anyway)
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   135
            }
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   136
            // TODO:
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   137
            // Thread.onSpinLoop(); // when available
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   138
        }
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   139
    }
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   140
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   141
    /**
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   142
     * Removes the value associated with this ClassLoaderValue and given
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   143
     * ClassLoader if the associated value is equal to given value {@code v} and
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   144
     * returns {@code true} or does nothing and returns {@code false} if there is
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   145
     * no currently associated value or it is not equal to given value {@code v}.
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   146
     *
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   147
     * @param cl the ClassLoader for the associated value
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   148
     * @param v  the value to compare with currently associated value
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   149
     * @return {@code true} if the association was removed or {@code false} if not
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   150
     */
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   151
    public boolean remove(ClassLoader cl, Object v) {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   152
        return AbstractClassLoaderValue.<CLV>map(cl).remove(this, v);
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   153
    }
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   154
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   155
    /**
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   156
     * Returns the value associated with this ClassLoaderValue and given
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   157
     * ClassLoader if there is one or computes the value by invoking given
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   158
     * {@code mappingFunction}, associates it and returns it.
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   159
     * <p>
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   160
     * Computation and association of the computed value is performed atomically
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   161
     * by the 1st thread that requests a particular association while holding a
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   162
     * lock associated with this ClassLoaderValue and given ClassLoader.
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   163
     * Nested calls from the {@code mappingFunction} to {@link #get},
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   164
     * {@link #putIfAbsent} or {@link #computeIfAbsent} for the same association
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   165
     * are not allowed and throw {@link IllegalStateException}. Nested call to
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   166
     * {@link #remove} for the same association is allowed but will always return
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   167
     * {@code false} regardless of passed-in comparison value. Nested calls for
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   168
     * other association(s) are allowed, but care should be taken to avoid
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   169
     * deadlocks. When two threads perform nested computations of the overlapping
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   170
     * set of associations they should always request them in the same order.
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   171
     *
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   172
     * @param cl              the ClassLoader for the associated value
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   173
     * @param mappingFunction the function to compute the value
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   174
     * @return the value associated with this ClassLoaderValue and given
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   175
     * ClassLoader.
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   176
     * @throws IllegalStateException if a direct or indirect invocation from
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   177
     *                               within given {@code mappingFunction} that
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   178
     *                               computes the value of a particular association
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   179
     *                               to {@link #get}, {@link #putIfAbsent} or
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   180
     *                               {@link #computeIfAbsent}
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   181
     *                               for the same association is attempted.
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   182
     */
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   183
    public V computeIfAbsent(ClassLoader cl,
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   184
                             BiFunction<
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   185
                                 ? super ClassLoader,
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   186
                                 ? super CLV,
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   187
                                 ? extends V
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   188
                                 > mappingFunction) throws IllegalStateException {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   189
        ConcurrentHashMap<CLV, Object> map = map(cl);
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   190
        @SuppressWarnings("unchecked")
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   191
        CLV clv = (CLV) this;
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   192
        Memoizer<CLV, V> mv = null;
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   193
        while (true) {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   194
            Object val = (mv == null) ? map.get(clv) : map.putIfAbsent(clv, mv);
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   195
            if (val == null) {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   196
                if (mv == null) {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   197
                    // create Memoizer lazily when 1st needed and restart loop
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   198
                    mv = new Memoizer<>(cl, clv, mappingFunction);
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   199
                    continue;
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   200
                }
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   201
                // mv != null, therefore sv == null was a result of successful
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   202
                // putIfAbsent
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   203
                try {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   204
                    // trigger Memoizer to compute the value
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   205
                    V v = mv.get();
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   206
                    // attempt to replace our Memoizer with the value
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   207
                    map.replace(clv, mv, v);
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   208
                    // return computed value
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   209
                    return v;
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   210
                } catch (Throwable t) {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   211
                    // our Memoizer has thrown, attempt to remove it
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   212
                    map.remove(clv, mv);
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   213
                    // propagate exception because it's from our Memoizer
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   214
                    throw t;
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   215
                }
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   216
            } else {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   217
                try {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   218
                    return extractValue(val);
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   219
                } catch (Memoizer.RecursiveInvocationException e) {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   220
                    // propagate recursive attempts to calculate the same
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   221
                    // value as being calculated at the moment
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   222
                    throw e;
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   223
                } catch (Throwable t) {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   224
                    // don't propagate exceptions thrown from foreign Memoizer -
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   225
                    // pretend that there was no entry and retry
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   226
                    // (foreign computeIfAbsent invocation will try to remove it anyway)
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   227
                }
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   228
            }
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   229
            // TODO:
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   230
            // Thread.onSpinLoop(); // when available
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   231
        }
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   232
    }
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   233
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   234
    /**
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   235
     * Removes all values associated with given ClassLoader {@code cl} and
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   236
     * {@link #isEqualOrDescendantOf(AbstractClassLoaderValue) this or descendants}
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   237
     * of this ClassLoaderValue.
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   238
     * This is not an atomic operation. Other threads may see some associations
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   239
     * be already removed and others still present while this method is executing.
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   240
     * <p>
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   241
     * The sole intention of this method is to cleanup after a unit test that
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   242
     * tests ClassLoaderValue directly. It is not intended for use in
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   243
     * actual algorithms.
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   244
     *
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   245
     * @param cl the associated ClassLoader of the values to be removed
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   246
     */
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   247
    public void removeAll(ClassLoader cl) {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   248
        ConcurrentHashMap<CLV, Object> map = map(cl);
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   249
        for (Iterator<CLV> i = map.keySet().iterator(); i.hasNext(); ) {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   250
            if (i.next().isEqualOrDescendantOf(this)) {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   251
                i.remove();
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   252
            }
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   253
        }
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   254
    }
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   255
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   256
    private static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess();
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   257
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   258
    /**
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   259
     * @return a ConcurrentHashMap for given ClassLoader
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   260
     */
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   261
    @SuppressWarnings("unchecked")
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   262
    private static <CLV extends AbstractClassLoaderValue<CLV, ?>>
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   263
    ConcurrentHashMap<CLV, Object> map(ClassLoader cl) {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   264
        return (ConcurrentHashMap<CLV, Object>)
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   265
            (cl == null ? BootLoader.getClassLoaderValueMap()
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   266
                        : JLA.createOrGetClassLoaderValueMap(cl));
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   267
    }
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   268
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   269
    /**
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   270
     * @return value extracted from the {@link Memoizer} if given
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   271
     * {@code memoizerOrValue} parameter is a {@code Memoizer} or
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   272
     * just return given parameter.
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   273
     */
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   274
    @SuppressWarnings("unchecked")
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   275
    private V extractValue(Object memoizerOrValue) {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   276
        if (memoizerOrValue instanceof Memoizer) {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   277
            return ((Memoizer<?, V>) memoizerOrValue).get();
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   278
        } else {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   279
            return (V) memoizerOrValue;
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   280
        }
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   281
    }
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   282
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   283
    /**
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   284
     * A memoized supplier that invokes given {@code mappingFunction} just once
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   285
     * and remembers the result or thrown exception for subsequent calls.
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   286
     * If given mappingFunction returns null, it is converted to NullPointerException,
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   287
     * thrown from the Memoizer's {@link #get()} method and remembered.
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   288
     * If the Memoizer is invoked recursively from the given {@code mappingFunction},
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   289
     * {@link RecursiveInvocationException} is thrown, but it is not remembered.
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   290
     * The in-flight call to the {@link #get()} can still complete successfully if
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   291
     * such exception is handled by the mappingFunction.
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   292
     */
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   293
    private static final class Memoizer<CLV extends AbstractClassLoaderValue<CLV, V>, V>
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   294
        implements Supplier<V> {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   295
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   296
        private final ClassLoader cl;
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   297
        private final CLV clv;
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   298
        private final BiFunction<? super ClassLoader, ? super CLV, ? extends V>
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   299
            mappingFunction;
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   300
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   301
        private volatile V v;
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   302
        private volatile Throwable t;
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   303
        private boolean inCall;
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   304
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   305
        Memoizer(ClassLoader cl,
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   306
                 CLV clv,
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   307
                 BiFunction<? super ClassLoader, ? super CLV, ? extends V>
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   308
                     mappingFunction
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   309
        ) {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   310
            this.cl = cl;
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   311
            this.clv = clv;
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   312
            this.mappingFunction = mappingFunction;
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   313
        }
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   314
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   315
        @Override
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   316
        public V get() throws RecursiveInvocationException {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   317
            V v = this.v;
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   318
            if (v != null) return v;
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   319
            Throwable t = this.t;
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   320
            if (t == null) {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   321
                synchronized (this) {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   322
                    if ((v = this.v) == null && (t = this.t) == null) {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   323
                        if (inCall) {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   324
                            throw new RecursiveInvocationException();
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   325
                        }
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   326
                        inCall = true;
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   327
                        try {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   328
                            this.v = v = Objects.requireNonNull(
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   329
                                mappingFunction.apply(cl, clv));
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   330
                        } catch (Throwable x) {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   331
                            this.t = t = x;
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   332
                        } finally {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   333
                            inCall = false;
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   334
                        }
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   335
                    }
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   336
                }
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   337
            }
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   338
            if (v != null) return v;
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   339
            if (t instanceof Error) {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   340
                throw (Error) t;
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   341
            } else if (t instanceof RuntimeException) {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   342
                throw (RuntimeException) t;
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   343
            } else {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   344
                throw new UndeclaredThrowableException(t);
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   345
            }
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   346
        }
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   347
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   348
        static class RecursiveInvocationException extends IllegalStateException {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   349
            private static final long serialVersionUID = 1L;
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   350
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   351
            RecursiveInvocationException() {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   352
                super("Recursive call");
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   353
            }
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   354
        }
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   355
    }
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   356
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   357
    /**
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   358
     * sub-ClassLoaderValue is an inner class of {@link AbstractClassLoaderValue}
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   359
     * and also a subclass of it. It can therefore be instantiated as an inner
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   360
     * class of either an instance of root-{@link ClassLoaderValue} or another
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   361
     * instance of itself. This enables composing type-safe compound keys of
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   362
     * arbitrary length:
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   363
     * <pre>{@code
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   364
     * ClassLoaderValue<V> clv = new ClassLoaderValue<>();
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   365
     * ClassLoaderValue<V>.Sub<K1>.Sub<K2>.Sub<K3> clv_k123 =
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   366
     *     clv.sub(k1).sub(k2).sub(k3);
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   367
     * }</pre>
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   368
     * From which individual components are accessible in a type-safe way:
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   369
     * <pre>{@code
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   370
     * K1 k1 = clv_k123.parent().parent().key();
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   371
     * K2 k2 = clv_k123.parent().key();
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   372
     * K3 k3 = clv_k123.key();
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   373
     * }</pre>
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   374
     * This allows specifying non-capturing lambdas for the mapping function of
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   375
     * {@link #computeIfAbsent(ClassLoader, BiFunction)} operation that can
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   376
     * access individual key components from passed-in
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   377
     * sub-[sub-...]ClassLoaderValue instance in a type-safe way.
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   378
     *
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   379
     * @param <K> the type of {@link #key()} component contained in the
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   380
     *            sub-ClassLoaderValue.
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   381
     */
40459
88a91142b711 8164547: Make java.lang.reflect.ClassLoaderValue public for internal use
plevart
parents: 36972
diff changeset
   382
    public final class Sub<K> extends AbstractClassLoaderValue<Sub<K>, V> {
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   383
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   384
        private final K key;
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   385
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   386
        Sub(K key) {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   387
            this.key = key;
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   388
        }
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   389
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   390
        /**
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   391
         * @return the parent ClassLoaderValue this sub-ClassLoaderValue
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   392
         * has been {@link #sub(Object) derived} from.
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   393
         */
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   394
        public AbstractClassLoaderValue<CLV, V> parent() {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   395
            return AbstractClassLoaderValue.this;
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   396
        }
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   397
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   398
        /**
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   399
         * @return the key component of this sub-ClassLoaderValue.
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   400
         */
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   401
        @Override
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   402
        public K key() {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   403
            return key;
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   404
        }
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   405
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   406
        /**
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   407
         * sub-ClassLoaderValue is a descendant of given {@code clv} if it is
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   408
         * either equal to it or if its {@link #parent() parent} is a
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   409
         * descendant of given {@code clv}.
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   410
         */
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   411
        @Override
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   412
        public boolean isEqualOrDescendantOf(AbstractClassLoaderValue<?, V> clv) {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   413
            return equals(Objects.requireNonNull(clv)) ||
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   414
                   parent().isEqualOrDescendantOf(clv);
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   415
        }
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   416
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   417
        @Override
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   418
        public boolean equals(Object o) {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   419
            if (this == o) return true;
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   420
            if (!(o instanceof Sub)) return false;
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   421
            @SuppressWarnings("unchecked")
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   422
            Sub<?> that = (Sub<?>) o;
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   423
            return this.parent().equals(that.parent()) &&
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   424
                   Objects.equals(this.key, that.key);
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   425
        }
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   426
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   427
        @Override
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   428
        public int hashCode() {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   429
            return 31 * parent().hashCode() +
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   430
                   Objects.hashCode(key);
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   431
        }
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   432
    }
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents:
diff changeset
   433
}