< prev index next >

src/java.base/share/classes/jdk/internal/vm/ScopedValueContainer.java

Print this page

  8  * particular file as subject to the "Classpath" exception as provided
  9  * by Oracle in the LICENSE file that accompanied this code.
 10  *
 11  * This code is distributed in the hope that it will be useful, but WITHOUT
 12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 14  * version 2 for more details (a copy is included in the LICENSE file that
 15  * accompanied this code).
 16  *
 17  * You should have received a copy of the GNU General Public License version
 18  * 2 along with this work; if not, write to the Free Software Foundation,
 19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 20  *
 21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 22  * or visit www.oracle.com if you need additional information or have any
 23  * questions.
 24  */
 25 package jdk.internal.vm;
 26 
 27 import java.util.concurrent.Callable;

 28 import jdk.internal.access.JavaLangAccess;
 29 import jdk.internal.access.SharedSecrets;
 30 import jdk.internal.misc.StructureViolationExceptions;
 31 import jdk.internal.misc.Unsafe;
 32 import jdk.internal.vm.annotation.DontInline;
 33 import jdk.internal.vm.annotation.ReservedStackAccess;
 34 
 35 /**
 36  * A StackableScope to represent scoped-value bindings.
 37  *
 38  * This class defines static methods to run an operation with a ScopedValueContainer
 39  * on the scope stack. It also defines a method to get the latest ScopedValueContainer
 40  * and a method to return a snapshot of the scoped value bindings.
 41  */
 42 public class ScopedValueContainer extends StackableScope {
 43     private static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess();
 44     static {
 45         Unsafe.getUnsafe().ensureClassInitialized(StructureViolationExceptions.class);
 46     }
 47 
 48     private ScopedValueContainer() {
 49     }
 50 
 51     /**
 52      * Returns the "latest" ScopedValueContainer for the current Thread. This may be on
 53      * the current thread's scope task or may require walking up the tree to find it.
 54      */
 55     public static <T extends ScopedValueContainer> T latest(Class<T> containerClass) {
 56         StackableScope scope = head();
 57         if (scope == null) {
 58             scope = JLA.threadContainer(Thread.currentThread());
 59             if (scope == null || scope.owner() == null)
 60                 return null;
 61         }
 62         if (containerClass.isInstance(scope)) {
 63             @SuppressWarnings("unchecked")
 64             T tmp = (T) scope;
 65             return tmp;

126      * Run an operation with this scope on the stack.
127      */
128     private void doRun(Runnable op) {
129         Throwable ex;
130         boolean atTop;
131         push();
132         try {
133             op.run();
134             ex = null;
135         } catch (Throwable e) {
136             ex = e;
137         } finally {
138             atTop = popForcefully();  // may block
139         }
140         throwIfFailed(ex, atTop);
141     }
142 
143     /**
144      * For use by ScopedValue to call a value returning operation in a structured context.
145      */
146     public static <V> V call(Callable<V> op) throws Exception {
147         if (head() == null) {
148             // no need to push scope when stack is empty
149             return callWithoutScope(op);
150         } else {
151             return new ScopedValueContainer().doCall(op);
152         }
153     }
154 
155     /**
156      * Call an operation without a scope on the stack.
157      */
158     private static <V> V callWithoutScope(Callable<V> op) {
159         assert head() == null;
160         Throwable ex;
161         boolean atTop;
162         V result;
163         try {
164             result = op.call();
165             ex = null;
166         } catch (Throwable e) {

185         try {
186             result = op.call();
187             ex = null;
188         } catch (Throwable e) {
189             result = null;
190             ex = e;
191         } finally {
192             atTop = popForcefully();  // may block
193         }
194         throwIfFailed(ex, atTop);
195         return result;
196     }
197 
198     /**
199      * Throws {@code ex} if not null. StructureViolationException is thrown or added
200      * as a suppressed exception when {@code atTop} is false.
201      */
202     private static void throwIfFailed(Throwable ex, boolean atTop) {
203         if (ex != null || !atTop) {
204             if (!atTop) {
205                 var sve = StructureViolationExceptions.newException();
206                 if (ex == null) {
207                     ex = sve;
208                 } else {
209                     ex.addSuppressed(sve);
210                 }
211             }
212             Unsafe.getUnsafe().throwException(ex);
213         }
214     }
215 }

  8  * particular file as subject to the "Classpath" exception as provided
  9  * by Oracle in the LICENSE file that accompanied this code.
 10  *
 11  * This code is distributed in the hope that it will be useful, but WITHOUT
 12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 14  * version 2 for more details (a copy is included in the LICENSE file that
 15  * accompanied this code).
 16  *
 17  * You should have received a copy of the GNU General Public License version
 18  * 2 along with this work; if not, write to the Free Software Foundation,
 19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 20  *
 21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 22  * or visit www.oracle.com if you need additional information or have any
 23  * questions.
 24  */
 25 package jdk.internal.vm;
 26 
 27 import java.util.concurrent.Callable;
 28 import java.util.concurrent.StructureViolationException;
 29 import jdk.internal.access.JavaLangAccess;
 30 import jdk.internal.access.SharedSecrets;

 31 import jdk.internal.misc.Unsafe;


 32 
 33 /**
 34  * A StackableScope to represent scoped-value bindings.
 35  *
 36  * This class defines static methods to run an operation with a ScopedValueContainer
 37  * on the scope stack. It also defines a method to get the latest ScopedValueContainer
 38  * and a method to return a snapshot of the scoped value bindings.
 39  */
 40 public class ScopedValueContainer extends StackableScope {
 41     private static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess();
 42     static {
 43         Unsafe.getUnsafe().ensureClassInitialized(StructureViolationException.class);
 44     }
 45 
 46     private ScopedValueContainer() {
 47     }
 48 
 49     /**
 50      * Returns the "latest" ScopedValueContainer for the current Thread. This may be on
 51      * the current thread's scope task or may require walking up the tree to find it.
 52      */
 53     public static <T extends ScopedValueContainer> T latest(Class<T> containerClass) {
 54         StackableScope scope = head();
 55         if (scope == null) {
 56             scope = JLA.threadContainer(Thread.currentThread());
 57             if (scope == null || scope.owner() == null)
 58                 return null;
 59         }
 60         if (containerClass.isInstance(scope)) {
 61             @SuppressWarnings("unchecked")
 62             T tmp = (T) scope;
 63             return tmp;

124      * Run an operation with this scope on the stack.
125      */
126     private void doRun(Runnable op) {
127         Throwable ex;
128         boolean atTop;
129         push();
130         try {
131             op.run();
132             ex = null;
133         } catch (Throwable e) {
134             ex = e;
135         } finally {
136             atTop = popForcefully();  // may block
137         }
138         throwIfFailed(ex, atTop);
139     }
140 
141     /**
142      * For use by ScopedValue to call a value returning operation in a structured context.
143      */
144     public static <V> V call(Callable<V> op) {
145         if (head() == null) {
146             // no need to push scope when stack is empty
147             return callWithoutScope(op);
148         } else {
149             return new ScopedValueContainer().doCall(op);
150         }
151     }
152 
153     /**
154      * Call an operation without a scope on the stack.
155      */
156     private static <V> V callWithoutScope(Callable<V> op) {
157         assert head() == null;
158         Throwable ex;
159         boolean atTop;
160         V result;
161         try {
162             result = op.call();
163             ex = null;
164         } catch (Throwable e) {

183         try {
184             result = op.call();
185             ex = null;
186         } catch (Throwable e) {
187             result = null;
188             ex = e;
189         } finally {
190             atTop = popForcefully();  // may block
191         }
192         throwIfFailed(ex, atTop);
193         return result;
194     }
195 
196     /**
197      * Throws {@code ex} if not null. StructureViolationException is thrown or added
198      * as a suppressed exception when {@code atTop} is false.
199      */
200     private static void throwIfFailed(Throwable ex, boolean atTop) {
201         if (ex != null || !atTop) {
202             if (!atTop) {
203                 var sve = new StructureViolationException();
204                 if (ex == null) {
205                     ex = sve;
206                 } else {
207                     ex.addSuppressed(sve);
208                 }
209             }
210             Unsafe.getUnsafe().throwException(ex);
211         }
212     }
213 }
< prev index next >