1 /*
  2  * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved.
  3  * Copyright (c) 2020, 2022, Red Hat Inc.
  4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  5  *
  6  * This code is free software; you can redistribute it and/or modify it
  7  * under the terms of the GNU General Public License version 2 only, as
  8  * published by the Free Software Foundation.  Oracle designates this
  9  * particular file as subject to the "Classpath" exception as provided
 10  * by Oracle in the LICENSE file that accompanied this code.
 11  *
 12  * This code is distributed in the hope that it will be useful, but WITHOUT
 13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 15  * version 2 for more details (a copy is included in the LICENSE file that
 16  * accompanied this code).
 17  *
 18  * You should have received a copy of the GNU General Public License version
 19  * 2 along with this work; if not, write to the Free Software Foundation,
 20  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 21  *
 22  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 23  * or visit www.oracle.com if you need additional information or have any
 24  * questions.
 25  */
 26 
 27 package java.lang;
 28 
 29 import java.util.NoSuchElementException;
 30 import java.util.Objects;
 31 import java.lang.ref.Reference;
 32 import java.util.concurrent.StructuredTaskScope;
 33 import java.util.concurrent.StructureViolationException;
 34 import java.util.function.Supplier;
 35 import jdk.internal.access.JavaUtilConcurrentTLRAccess;
 36 import jdk.internal.access.SharedSecrets;
 37 import jdk.internal.javac.PreviewFeature;
 38 import jdk.internal.vm.annotation.ForceInline;
 39 import jdk.internal.vm.annotation.Hidden;
 40 import jdk.internal.vm.ScopedValueContainer;
 41 
 42 /**
 43  * A value that may be safely and efficiently shared to methods without using method
 44  * parameters.
 45  *
 46  * <p> In the Java programming language, data is usually passed to a method by means of a
 47  * method parameter. The data may need to be passed through a sequence of many methods to
 48  * get to the method that makes use of the data. Every method in the sequence of calls
 49  * needs to declare the parameter and every method has access to the data.
 50  * {@code ScopedValue} provides a means to pass data to a faraway method (typically a
 51  * <em>callback</em>) without using method parameters. In effect, a {@code ScopedValue}
 52  * is an <em>implicit method parameter</em>. It is "as if" every method in a sequence of
 53  * calls has an additional parameter. None of the methods declare the parameter and only
 54  * the methods that have access to the {@code ScopedValue} object can access its value
 55  * (the data). {@code ScopedValue} makes it possible to securely pass data from a
 56  * <em>caller</em> to a faraway <em>callee</em> through a sequence of intermediate methods
 57  * that do not declare a parameter for the data and have no access to the data.
 58  *
 59  * <p> The {@code ScopedValue} API works by executing a method with a {@code ScopedValue}
 60  * object <em>bound</em> to some value for the bounded period of execution of a method.
 61  * The method may invoke another method, which in turn may invoke another. The unfolding
 62  * execution of the methods define a <em>dynamic scope</em>. Code in these methods with
 63  * access to the {@code ScopedValue} object may read its value. The {@code ScopedValue}
 64  * object reverts to being <em>unbound</em> when the original method completes normally or
 65  * with an exception. The {@code ScopedValue} API supports executing a {@link Runnable},
 66  * or {@link CallableOp} with a {@code ScopedValue} bound to a value.
 67  *
 68  * <p> Consider the following example with a scoped value "{@code NAME}" bound to the value
 69  * "{@code duke}" for the execution of a {@code Runnable}'s {@code run} method.
 70  * The {@code run} method, in turn, invokes a method {@code doSomething}.
 71  *
 72  *
 73  * {@snippet lang=java :
 74  *     // @link substring="newInstance" target="#newInstance" :
 75  *     private static final ScopedValue<String> NAME = ScopedValue.newInstance();
 76  *
 77  *     // @link substring="run" target="Carrier#run(Runnable)" :
 78  *     ScopedValue.where(NAME, "duke").run(() -> doSomething());
 79  * }
 80  * Code executed directly or indirectly by {@code doSomething}, with access to the field
 81  * {@code NAME}, can invoke {@code NAME.get()} to read the value "{@code duke}". {@code
 82  * NAME} is bound while executing the {@code run} method. It reverts to being unbound when
 83  * the {@code run} method completes.
 84  *
 85  * <p> The example using {@code run} invokes a method that does not return a result.
 86  * The {@link Carrier#call(CallableOp) call} method can be used
 87  * to invoke a method that returns a result.
 88  * {@code ScopedValue} defines the {@link #where(ScopedValue, Object)} method
 89  * for cases where multiple mappings (of {@code ScopedValue} to value) are accumulated
 90  * in advance of calling a method with all {@code ScopedValue}s bound to their value.
 91  *
 92  * <h2>Bindings are per-thread</h2>
 93  *
 94  * A {@code ScopedValue} binding to a value is per-thread. Invoking {@code run}
 95  * executes a method with a {@code ScopedValue} bound to a value for the current thread.
 96  * The {@link #get() get} method returns the value bound for the current thread.
 97  *
 98  * <p> In the example, if code executed by one thread invokes this:
 99  * {@snippet lang=java :
100  *     ScopedValue.where(NAME, "duke1").run(() -> doSomething());
101  * }
102  * and code executed by another thread invokes:
103  * {@snippet lang=java :
104  *     ScopedValue.where(NAME, "duke2").run(() -> doSomething());
105  * }
106  * then code in {@code doSomething} (or any method that it calls) invoking {@code NAME.get()}
107  * will read the value "{@code duke1}" or "{@code duke2}", depending on which thread is
108  * executing.
109  *
110  * <h2>Scoped values as capabilities</h2>
111  *
112  * A {@code ScopedValue} object should be treated as a <em>capability</em> or a key to
113  * access its value when the {@code ScopedValue} is bound. Secure usage depends on access
114  * control (see <cite>The Java Virtual Machine Specification</cite>, Section {@jvms 5.4.4})
115  * and taking care to not share the {@code ScopedValue} object. In many cases, a {@code
116  * ScopedValue} will be declared in a {@code final} and {@code static} field so that it
117  * is only accessible to code in a single class (or nest).
118  *
119  * <h2><a id="rebind">Rebinding</a></h2>
120  *
121  * The {@code ScopedValue} API allows a new binding to be established for <em>nested
122  * dynamic scopes</em>. This is known as <em>rebinding</em>. A {@code ScopedValue} that
123  * is bound to a value may be bound to a new value for the bounded execution of a new
124  * method. The unfolding execution of code executed by that method defines the nested
125  * dynamic scope. When the method completes, the value of the {@code ScopedValue} reverts
126  * to its previous value.
127  *
128  * <p> In the above example, suppose that code executed by {@code doSomething} binds
129  * {@code NAME} to a new value with:
130  * {@snippet lang=java :
131  *     ScopedValue.where(NAME, "duchess").run(() -> doMore());
132  * }
133  * Code executed directly or indirectly by {@code doMore()} that invokes {@code
134  * NAME.get()} will read the value "{@code duchess}". When {@code doMore()} completes
135  * then the value of {@code NAME} reverts to "{@code duke}".
136  *
137  * <h2><a id="inheritance">Inheritance</a></h2>
138  *
139  * {@code ScopedValue} supports sharing across threads. This sharing is limited to
140  * structured cases where child threads are started and terminate within the bounded
141  * period of execution by a parent thread. When using a {@link StructuredTaskScope},
142  * scoped value bindings are <em>captured</em> when creating a {@code StructuredTaskScope}
143  * and inherited by all threads started in that task scope with the
144  * {@link StructuredTaskScope#fork(java.util.concurrent.Callable) fork} method.
145  *
146  * <p> A {@code ScopedValue} that is shared across threads requires that the value be an
147  * immutable object or for all access to the value to be appropriately synchronized.
148  *
149  * <p> In the following example, the {@code ScopedValue} {@code NAME} is bound to the
150  * value "{@code duke}" for the execution of a runnable operation. The code in the {@code
151  * run} method creates a {@code StructuredTaskScope} that forks three tasks. Code executed
152  * directly or indirectly by these threads running {@code childTask1()}, {@code childTask2()},
153  * and {@code childTask3()} that invokes {@code NAME.get()} will read the value
154  * "{@code duke}".
155  *
156  * {@snippet lang=java :
157  *     private static final ScopedValue<String> NAME = ScopedValue.newInstance();
158 
159  *     ScopedValue.where(NAME, "duke").run(() -> {
160  *         try (var scope = new StructuredTaskScope<String>()) {
161  *
162  *              // @link substring="fork" target="StructuredTaskScope#fork(java.util.concurrent.Callable)" :
163  *              scope.fork(() -> childTask1());
164  *              scope.fork(() -> childTask2());
165  *              scope.fork(() -> childTask3());
166  *
167  *              // @link substring="join" target="StructuredTaskScope#join()" :
168  *              scope.join();
169  *
170  *              ..
171  *          }
172  *     });
173  * }
174  *
175  * <p> Unless otherwise specified, passing a {@code null} argument to a method in this
176  * class will cause a {@link NullPointerException} to be thrown.
177  *
178  * @apiNote
179  * A {@code ScopedValue} should be preferred over a {@link ThreadLocal} for cases where
180  * the goal is "one-way transmission" of data without using method parameters.  While a
181  * {@code ThreadLocal} can be used to pass data to a method without using method parameters,
182  * it does suffer from a number of issues:
183  * <ol>
184  *   <li> {@code ThreadLocal} does not prevent code in a faraway callee from {@linkplain
185  *   ThreadLocal#set(Object) setting} a new value.
186  *   <li> A {@code ThreadLocal} has an unbounded lifetime and thus continues to have a value
187  *   after a method completes, unless explicitly {@linkplain ThreadLocal#remove() removed}.
188  *   <li> {@linkplain InheritableThreadLocal Inheritance} is expensive - the map of
189  *   thread-locals to values must be copied when creating each child thread.
190  * </ol>
191  *
192  * @implNote
193  * Scoped values are designed to be used in fairly small
194  * numbers. {@link #get} initially performs a search through enclosing
195  * scopes to find a scoped value's innermost binding. It
196  * then caches the result of the search in a small thread-local
197  * cache. Subsequent invocations of {@link #get} for that scoped value
198  * will almost always be very fast. However, if a program has many
199  * scoped values that it uses cyclically, the cache hit rate
200  * will be low and performance will be poor. This design allows
201  * scoped-value inheritance by {@link StructuredTaskScope} threads to
202  * be very fast: in essence, no more than copying a pointer, and
203  * leaving a scoped-value binding also requires little more than
204  * updating a pointer.
205  *
206  * <p>Because the scoped-value per-thread cache is small, clients
207  * should minimize the number of bound scoped values in use. For
208  * example, if it is necessary to pass a number of values in this way,
209  * it makes sense to create a record class to hold those values, and
210  * then bind a single {@code ScopedValue} to an instance of that record.
211  *
212  * <p>For this release, the reference implementation
213  * provides some system properties to tune the performance of scoped
214  * values.
215  *
216  * <p>The system property {@code java.lang.ScopedValue.cacheSize}
217  * controls the size of the (per-thread) scoped-value cache. This cache is crucial
218  * for the performance of scoped values. If it is too small,
219  * the runtime library will repeatedly need to scan for each
220  * {@link #get}. If it is too large, memory will be unnecessarily
221  * consumed. The default scoped-value cache size is 16 entries. It may
222  * be varied from 2 to 16 entries in size. {@code ScopedValue.cacheSize}
223  * must be an integer power of 2.
224  *
225  * <p>For example, you could use {@code -Djava.lang.ScopedValue.cacheSize=8}.
226  *
227  * <p>The other system property is {@code jdk.preserveScopedValueCache}.
228  * This property determines whether the per-thread scoped-value
229  * cache is preserved when a virtual thread is blocked. By default
230  * this property is set to {@code true}, meaning that every virtual
231  * thread preserves its scoped-value cache when blocked. Like {@code
232  * ScopedValue.cacheSize}, this is a space versus speed trade-off: in
233  * situations where many virtual threads are blocked most of the time,
234  * setting this property to {@code false} might result in a useful
235  * memory saving, but each virtual thread's scoped-value cache would
236  * have to be regenerated after a blocking operation.
237  *
238  * @param <T> the type of the value
239  * @since 21
240  */
241 @PreviewFeature(feature = PreviewFeature.Feature.SCOPED_VALUES)
242 public final class ScopedValue<T> {
243     private final int hash;
244 
245     @Override
246     public int hashCode() { return hash; }
247 
248     /**
249      * An immutable map from {@code ScopedValue} to values.
250      *
251      * <p> Unless otherwise specified, passing a {@code null} argument to a constructor
252      * or method in this class will cause a {@link NullPointerException} to be thrown.
253      */
254     static final class Snapshot {
255         final Snapshot prev;
256         final Carrier bindings;
257         final int bitmask;
258 
259         private static final Object NIL = new Object();
260 
261         static final Snapshot EMPTY_SNAPSHOT = new Snapshot();
262 
263         Snapshot(Carrier bindings, Snapshot prev) {
264             this.prev = prev;
265             this.bindings = bindings;
266             this.bitmask = bindings.bitmask | prev.bitmask;
267         }
268 
269         protected Snapshot() {
270             this.prev = null;
271             this.bindings = null;
272             this.bitmask = 0;
273         }
274 
275         Object find(ScopedValue<?> key) {
276             int bits = key.bitmask();
277             for (Snapshot snapshot = this;
278                  containsAll(snapshot.bitmask, bits);
279                  snapshot = snapshot.prev) {
280                 for (Carrier carrier = snapshot.bindings;
281                      carrier != null && containsAll(carrier.bitmask, bits);
282                      carrier = carrier.prev) {
283                     if (carrier.getKey() == key) {
284                         Object value = carrier.get();
285                         return value;
286                     }
287                 }
288             }
289             return NIL;
290         }
291     }
292 
293     /**
294      * A mapping of scoped values, as <em>keys</em>, to values.
295      *
296      * <p> A {@code Carrier} is used to accumulate mappings so that an operation (a {@link
297      * Runnable} or {@link CallableOp}) can be executed with all scoped values in the
298      * mapping bound to values. The following example runs an operation with {@code k1}
299      * bound (or rebound) to {@code v1}, and {@code k2} bound (or rebound) to {@code v2}.
300      * {@snippet lang=java :
301      *     // @link substring="where" target="#where(ScopedValue, Object)" :
302      *     ScopedValue.where(k1, v1).where(k2, v2).run(() -> ... );
303      * }
304      *
305      * <p> A {@code Carrier} is immutable and thread-safe. The {@link
306      * #where(ScopedValue, Object) where} method returns a new {@code Carrier} object,
307      * it does not mutate an existing mapping.
308      *
309      * <p> Unless otherwise specified, passing a {@code null} argument to a method in
310      * this class will cause a {@link NullPointerException} to be thrown.
311      *
312      * @since 21
313      */
314     @PreviewFeature(feature = PreviewFeature.Feature.SCOPED_VALUES)
315     public static final class Carrier {
316         // Bit masks: a 1 in position n indicates that this set of bound values
317         // hits that slot in the cache.
318         final int bitmask;
319         final ScopedValue<?> key;
320         final Object value;
321         final Carrier prev;
322 
323         Carrier(ScopedValue<?> key, Object value, Carrier prev) {
324             this.key = key;
325             this.value = value;
326             this.prev = prev;
327             int bits = key.bitmask();
328             if (prev != null) {
329                 bits |= prev.bitmask;
330             }
331             this.bitmask = bits;
332         }
333 
334         /**
335          * Add a binding to this map, returning a new Carrier instance.
336          */
337         private static <T> Carrier where(ScopedValue<T> key, T value, Carrier prev) {
338             return new Carrier(key, value, prev);
339         }
340 
341         /**
342          * Returns a new {@code Carrier} with the mappings from this carrier plus a
343          * new mapping from {@code key} to {@code value}. If this carrier already has a
344          * mapping for the scoped value {@code key} then it will map to the new
345          * {@code value}. The current carrier is immutable, so it is not changed by this
346          * method.
347          *
348          * @param key the {@code ScopedValue} key
349          * @param value the value, can be {@code null}
350          * @param <T> the type of the value
351          * @return a new {@code Carrier} with the mappings from this carrier plus the new mapping
352          */
353         public <T> Carrier where(ScopedValue<T> key, T value) {
354             return where(key, value, this);
355         }
356 
357         /*
358          * Return a new set consisting of a single binding.
359          */
360         static <T> Carrier of(ScopedValue<T> key, T value) {
361             return where(key, value, null);
362         }
363 
364         Object get() {
365             return value;
366         }
367 
368         ScopedValue<?> getKey() {
369             return key;
370         }
371 
372         /**
373          * Returns the value of a {@link ScopedValue} in this mapping.
374          *
375          * @param key the {@code ScopedValue} key
376          * @param <T> the type of the value
377          * @return the value
378          * @throws NoSuchElementException if the key is not present in this mapping
379          */
380         @SuppressWarnings("unchecked")
381         public <T> T get(ScopedValue<T> key) {
382             var bits = key.bitmask();
383             for (Carrier carrier = this;
384                  carrier != null && containsAll(carrier.bitmask, bits);
385                  carrier = carrier.prev) {
386                 if (carrier.getKey() == key) {
387                     Object value = carrier.get();
388                     return (T) value;
389                 }
390             }
391             throw new NoSuchElementException("No mapping present");
392         }
393 
394         /**
395          * Calls a value-returning operation with each scoped value in this mapping bound
396          * to its value in the current thread.
397          * When the operation completes (normally or with an exception), each scoped value
398          * in the mapping will revert to being unbound, or revert to its previous value
399          * when previously bound, in the current thread. If {@code op} completes with an
400          * exception then it propagated by this method.
401          *
402          * <p> Scoped values are intended to be used in a <em>structured manner</em>. If code
403          * invoked directly or indirectly by the operation creates a {@link StructuredTaskScope}
404          * but does not {@linkplain StructuredTaskScope#close() close} it, then it is detected
405          * as a <em>structure violation</em> when the operation completes (normally or with an
406          * exception). In that case, the underlying construct of the {@code StructuredTaskScope}
407          * is closed and {@link StructureViolationException} is thrown.
408          *
409          * @param op the operation to run
410          * @param <R> the type of the result of the operation
411          * @param <X> type of the exception thrown by the operation
412          * @return the result
413          * @throws StructureViolationException if a structure violation is detected
414          * @throws X if {@code op} completes with an exception
415          * @since 23
416          */
417         public <R, X extends Throwable> R call(CallableOp<? extends R, X> op) throws X {
418             Objects.requireNonNull(op);
419             Cache.invalidate(bitmask);
420             var prevSnapshot = scopedValueBindings();
421             var newSnapshot = new Snapshot(this, prevSnapshot);
422             return runWith(newSnapshot, op);
423         }
424 
425         /**
426          * Execute the action with a set of ScopedValue bindings.
427          *
428          * The VM recognizes this method as special, so any changes to the
429          * name or signature require corresponding changes in
430          * JVM_FindScopedValueBindings().
431          */
432         @Hidden
433         @ForceInline
434         private <R, X extends Throwable> R runWith(Snapshot newSnapshot, CallableOp<R, X> op) {
435             try {
436                 Thread.setScopedValueBindings(newSnapshot);
437                 Thread.ensureMaterializedForStackWalk(newSnapshot);
438                 return ScopedValueContainer.call(op);
439             } finally {
440                 Reference.reachabilityFence(newSnapshot);
441                 Thread.setScopedValueBindings(newSnapshot.prev);
442                 Cache.invalidate(bitmask);
443             }
444         }
445 
446         /**
447          * Runs an operation with each scoped value in this mapping bound to its value
448          * in the current thread.
449          * When the operation completes (normally or with an exception), each scoped value
450          * in the mapping will revert to being unbound, or revert to its previous value
451          * when previously bound, in the current thread. If {@code op} completes with an
452          * exception then it propagated by this method.
453          *
454          * <p> Scoped values are intended to be used in a <em>structured manner</em>. If code
455          * invoked directly or indirectly by the operation creates a {@link StructuredTaskScope}
456          * but does not {@linkplain StructuredTaskScope#close() close} it, then it is detected
457          * as a <em>structure violation</em> when the operation completes (normally or with an
458          * exception). In that case, the underlying construct of the {@code StructuredTaskScope}
459          * is closed and {@link StructureViolationException} is thrown.
460          *
461          * @param op the operation to run
462          * @throws StructureViolationException if a structure violation is detected
463          */
464         public void run(Runnable op) {
465             Objects.requireNonNull(op);
466             Cache.invalidate(bitmask);
467             var prevSnapshot = scopedValueBindings();
468             var newSnapshot = new Snapshot(this, prevSnapshot);
469             runWith(newSnapshot, op);
470         }
471 
472         /**
473          * Execute the action with a set of {@code ScopedValue} bindings.
474          *
475          * The VM recognizes this method as special, so any changes to the
476          * name or signature require corresponding changes in
477          * JVM_FindScopedValueBindings().
478          */
479         @Hidden
480         @ForceInline
481         private void runWith(Snapshot newSnapshot, Runnable op) {
482             try {
483                 Thread.setScopedValueBindings(newSnapshot);
484                 Thread.ensureMaterializedForStackWalk(newSnapshot);
485                 ScopedValueContainer.run(op);
486             } finally {
487                 Reference.reachabilityFence(newSnapshot);
488                 Thread.setScopedValueBindings(newSnapshot.prev);
489                 Cache.invalidate(bitmask);
490             }
491         }
492     }
493 
494     /**
495      * An operation that returns a result and may throw an exception.
496      *
497      * @param <T> result type of the operation
498      * @param <X> type of the exception thrown by the operation
499      * @since 23
500      */
501     @PreviewFeature(feature = PreviewFeature.Feature.SCOPED_VALUES)
502     @FunctionalInterface
503     public interface CallableOp<T, X extends Throwable> {
504         /**
505          * Executes this operation.
506          * @return the result, can be null
507          * @throws X if the operation completes with an exception
508          */
509         T call() throws X;
510     }
511 
512     /**
513      * Creates a new {@code Carrier} with a single mapping of a {@code ScopedValue}
514      * <em>key</em> to a value. The {@code Carrier} can be used to accumulate mappings so
515      * that an operation can be executed with all scoped values in the mapping bound to
516      * values. The following example runs an operation with {@code k1} bound (or rebound)
517      * to {@code v1}, and {@code k2} bound (or rebound) to {@code v2}.
518      * {@snippet lang=java :
519      *     // @link substring="run" target="Carrier#run(Runnable)" :
520      *     ScopedValue.where(k1, v1).where(k2, v2).run(() -> ... );
521      * }
522      *
523      * @param key the {@code ScopedValue} key
524      * @param value the value, can be {@code null}
525      * @param <T> the type of the value
526      * @return a new {@code Carrier} with a single mapping
527      */
528     public static <T> Carrier where(ScopedValue<T> key, T value) {
529         return Carrier.of(key, value);
530     }
531 
532     private ScopedValue() {
533         this.hash = generateKey();
534     }
535 
536     /**
537      * Creates a scoped value that is initially unbound for all threads.
538      *
539      * @param <T> the type of the value
540      * @return a new {@code ScopedValue}
541      */
542     public static <T> ScopedValue<T> newInstance() {
543         return new ScopedValue<T>();
544     }
545 
546     /**
547      * {@return the value of the scoped value if bound in the current thread}
548      *
549      * @throws NoSuchElementException if the scoped value is not bound
550      */
551     @ForceInline
552     @SuppressWarnings("unchecked")
553     public T get() {
554         Object[] objects;
555         if ((objects = scopedValueCache()) != null) {
556             // This code should perhaps be in class Cache. We do it
557             // here because the generated code is small and fast and
558             // we really want it to be inlined in the caller.
559             int n = (hash & Cache.SLOT_MASK) * 2;
560             if (objects[n] == this) {
561                 return (T)objects[n + 1];
562             }
563             n = ((hash >>> Cache.INDEX_BITS) & Cache.SLOT_MASK) * 2;
564             if (objects[n] == this) {
565                 return (T)objects[n + 1];
566             }
567         }
568         return slowGet();
569     }
570 
571     @SuppressWarnings("unchecked")
572     private T slowGet() {
573         var value = findBinding();
574         if (value == Snapshot.NIL) {
575             throw new NoSuchElementException("ScopedValue not bound");
576         }
577         Cache.put(this, value);
578         return (T)value;
579     }
580 
581     /**
582      * {@return {@code true} if this scoped value is bound in the current thread}
583      */
584     public boolean isBound() {
585         Object[] objects = scopedValueCache();
586         if (objects != null) {
587             int n = (hash & Cache.SLOT_MASK) * 2;
588             if (objects[n] == this) {
589                 return true;
590             }
591             n = ((hash >>> Cache.INDEX_BITS) & Cache.SLOT_MASK) * 2;
592             if (objects[n] == this) {
593                 return true;
594             }
595         }
596         var value = findBinding();
597         boolean result = (value != Snapshot.NIL);
598         if (result)  Cache.put(this, value);
599         return result;
600     }
601 
602     /**
603      * Return the value of the scoped value or NIL if not bound.
604      */
605     private Object findBinding() {
606         Object value = scopedValueBindings().find(this);
607         return value;
608     }
609 
610     /**
611      * Returns the value of this scoped value if bound in the current thread, otherwise
612      * returns {@code other}.
613      *
614      * @param other the value to return if not bound, can be {@code null}
615      * @return the value of the scoped value if bound, otherwise {@code other}
616      */
617     public T orElse(T other) {
618         Object obj = findBinding();
619         if (obj != Snapshot.NIL) {
620             @SuppressWarnings("unchecked")
621             T value = (T) obj;
622             return value;
623         } else {
624             return other;
625         }
626     }
627 
628     /**
629      * Returns the value of this scoped value if bound in the current thread, otherwise
630      * throws an exception produced by the exception supplying function.
631      *
632      * @param <X> the type of the exception that may be thrown
633      * @param exceptionSupplier the supplying function that produces the exception to throw
634      * @return the value of the scoped value if bound in the current thread
635      * @throws X if the scoped value is not bound in the current thread
636      */
637     public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {
638         Objects.requireNonNull(exceptionSupplier);
639         Object obj = findBinding();
640         if (obj != Snapshot.NIL) {
641             @SuppressWarnings("unchecked")
642             T value = (T) obj;
643             return value;
644         } else {
645             throw exceptionSupplier.get();
646         }
647     }
648 
649     private static Object[] scopedValueCache() {
650         return Thread.scopedValueCache();
651     }
652 
653     private static void setScopedValueCache(Object[] cache) {
654         Thread.setScopedValueCache(cache);
655     }
656 
657     // Special value to indicate this is a newly-created Thread
658     // Note that his must match the declaration in j.l.Thread.
659     private static final Object NEW_THREAD_BINDINGS = Thread.class;
660 
661     private static Snapshot scopedValueBindings() {
662         // Bindings can be in one of four states:
663         //
664         // 1: class Thread: this is a new Thread instance, and no
665         // scoped values have ever been bound in this Thread, and neither
666         // have any scoped value bindings been inherited from a parent.
667         // 2: EmptySnapshot.SINGLETON: This is effectively an empty binding.
668         // 3: A Snapshot instance: this contains one or more scoped value
669         // bindings.
670         // 4: null: there may be some bindings in this Thread, but we don't know
671         // where they are. We must invoke Thread.findScopedValueBindings() to walk
672         // the stack to find them.
673 
674         Object bindings = Thread.scopedValueBindings();
675         if (bindings == NEW_THREAD_BINDINGS) {
676             // This must be a new thread
677             return Snapshot.EMPTY_SNAPSHOT;
678         }
679         if (bindings == null) {
680             // Search the stack
681             bindings = Thread.findScopedValueBindings();
682             if (bindings == NEW_THREAD_BINDINGS || bindings == null) {
683                 // We've walked the stack without finding anything.
684                 bindings = Snapshot.EMPTY_SNAPSHOT;
685             }
686             Thread.setScopedValueBindings(bindings);
687         }
688         assert (bindings != null);
689         return (Snapshot) bindings;
690     }
691 
692     private static int nextKey = 0xf0f0_f0f0;
693 
694     // A Marsaglia xor-shift generator used to generate hashes. This one has full period, so
695     // it generates 2**32 - 1 hashes before it repeats. We're going to use the lowest n bits
696     // and the next n bits as cache indexes, so we make sure that those indexes map
697     // to different slots in the cache.
698     private static synchronized int generateKey() {
699         int x = nextKey;
700         do {
701             x ^= x >>> 12;
702             x ^= x << 9;
703             x ^= x >>> 23;
704         } while (Cache.primarySlot(x) == Cache.secondarySlot(x));
705         return (nextKey = x);
706     }
707 
708     /**
709      * Return a bit mask that may be used to determine if this ScopedValue is
710      * bound in the current context. Each Carrier holds a bit mask which is
711      * the OR of all the bit masks of the bound ScopedValues.
712      * @return the bitmask
713      */
714     int bitmask() {
715         return (1 << Cache.primaryIndex(this)) | (1 << (Cache.secondaryIndex(this) + Cache.TABLE_SIZE));
716     }
717 
718     // Return true iff bitmask, considered as a set of bits, contains all
719     // of the bits in targetBits.
720     static boolean containsAll(int bitmask, int targetBits) {
721         return (bitmask & targetBits) == targetBits;
722     }
723 
724     // A small fixed-size key-value cache. When a scoped value's get() method
725     // is invoked, we record the result of the lookup in this per-thread cache
726     // for fast access in future.
727     private static final class Cache {
728         static final int INDEX_BITS = 4;  // Must be a power of 2
729         static final int TABLE_SIZE = 1 << INDEX_BITS;
730         static final int TABLE_MASK = TABLE_SIZE - 1;
731         static final int PRIMARY_MASK = (1 << TABLE_SIZE) - 1;
732 
733         // The number of elements in the cache array, and a bit mask used to
734         // select elements from it.
735         private static final int CACHE_TABLE_SIZE, SLOT_MASK;
736         // The largest cache we allow. Must be a power of 2 and greater than
737         // or equal to 2.
738         private static final int MAX_CACHE_SIZE = 16;
739 
740         static {
741             final String propertyName = "java.lang.ScopedValue.cacheSize";
742             var sizeString = System.getProperty(propertyName, "16");
743             var cacheSize = Integer.valueOf(sizeString);
744             if (cacheSize < 2 || cacheSize > MAX_CACHE_SIZE) {
745                 cacheSize = MAX_CACHE_SIZE;
746                 System.err.println(propertyName + " is out of range: is " + sizeString);
747             }
748             if ((cacheSize & (cacheSize - 1)) != 0) {  // a power of 2
749                 cacheSize = MAX_CACHE_SIZE;
750                 System.err.println(propertyName + " must be an integer power of 2: is " + sizeString);
751             }
752             CACHE_TABLE_SIZE = cacheSize;
753             SLOT_MASK = cacheSize - 1;
754         }
755 
756         static int primaryIndex(ScopedValue<?> key) {
757             return key.hash & TABLE_MASK;
758         }
759 
760         static int secondaryIndex(ScopedValue<?> key) {
761             return (key.hash >> INDEX_BITS) & TABLE_MASK;
762         }
763 
764         private static int primarySlot(ScopedValue<?> key) {
765             return key.hashCode() & SLOT_MASK;
766         }
767 
768         private static int secondarySlot(ScopedValue<?> key) {
769             return (key.hash >> INDEX_BITS) & SLOT_MASK;
770         }
771 
772         static int primarySlot(int hash) {
773             return hash & SLOT_MASK;
774         }
775 
776         static int secondarySlot(int hash) {
777             return (hash >> INDEX_BITS) & SLOT_MASK;
778         }
779 
780         static void put(ScopedValue<?> key, Object value) {
781             Object[] theCache = scopedValueCache();
782             if (theCache == null) {
783                 theCache = new Object[CACHE_TABLE_SIZE * 2];
784                 setScopedValueCache(theCache);
785             }
786             // Update the cache to replace one entry with the value we just looked up.
787             // Each value can be in one of two possible places in the cache.
788             // Pick a victim at (pseudo-)random.
789             int k1 = primarySlot(key);
790             int k2 = secondarySlot(key);
791             var usePrimaryIndex = chooseVictim();
792             int victim = usePrimaryIndex ? k1 : k2;
793             int other = usePrimaryIndex ? k2 : k1;
794             setKeyAndObjectAt(victim, key, value);
795             if (getKey(theCache, other) == key) {
796                 setKeyAndObjectAt(other, key, value);
797             }
798         }
799 
800         private static void setKeyAndObjectAt(int n, Object key, Object value) {
801             var cache = scopedValueCache();
802             cache[n * 2] = key;
803             cache[n * 2 + 1] = value;
804         }
805 
806         private static void setKeyAndObjectAt(Object[] cache, int n, Object key, Object value) {
807             cache[n * 2] = key;
808             cache[n * 2 + 1] = value;
809         }
810 
811         private static Object getKey(Object[] objs, int n) {
812             return objs[n * 2];
813         }
814 
815         private static void setKey(Object[] objs, int n, Object key) {
816             objs[n * 2] = key;
817         }
818 
819         private static final JavaUtilConcurrentTLRAccess THREAD_LOCAL_RANDOM_ACCESS
820                 = SharedSecrets.getJavaUtilConcurrentTLRAccess();
821 
822         // Return either true or false, at pseudo-random, with a bias towards true.
823         // This chooses either the primary or secondary cache slot, but the
824         // primary slot is approximately twice as likely to be chosen as the
825         // secondary one.
826         private static boolean chooseVictim() {
827             int r = THREAD_LOCAL_RANDOM_ACCESS.nextSecondaryThreadLocalRandomSeed();
828             return (r & 15) >= 5;
829         }
830 
831         // Null a set of cache entries, indicated by the 1-bits given
832         static void invalidate(int toClearBits) {
833             toClearBits = (toClearBits >>> TABLE_SIZE) | (toClearBits & PRIMARY_MASK);
834             Object[] objects;
835             if ((objects = scopedValueCache()) != null) {
836                 for (int bits = toClearBits; bits != 0; ) {
837                     int index = Integer.numberOfTrailingZeros(bits);
838                     setKeyAndObjectAt(objects, index & SLOT_MASK, null, null);
839                     bits &= ~1 << index;
840                 }
841             }
842         }
843     }
844 }