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