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 }
|