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