|
23 | 23 |
|
24 | 24 | package com.oracle.truffle.espresso.substitutions; |
25 | 25 |
|
26 | | -import java.lang.reflect.InvocationTargetException; |
27 | 26 | import java.util.Arrays; |
| 27 | +import java.util.concurrent.atomic.AtomicLong; |
28 | 28 |
|
29 | 29 | import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; |
30 | 30 | import com.oracle.truffle.api.nodes.DirectCallNode; |
|
61 | 61 | // @formatter:on |
62 | 62 | @EspressoSubstitutions |
63 | 63 | public final class Target_java_lang_Thread { |
64 | | - private static final java.lang.reflect.Method isInterrupted; |
65 | | - static { |
66 | | - try { |
67 | | - isInterrupted = Thread.class.getDeclaredMethod("isInterrupted", boolean.class); |
68 | | - isInterrupted.setAccessible(true); |
69 | | - } catch (Throwable e) { |
70 | | - throw EspressoError.shouldNotReachHere(); |
71 | | - } |
72 | | - } |
73 | 64 |
|
74 | 65 | public static void incrementThreadCounter(StaticObject thread, Field hiddenField) { |
75 | 66 | assert hiddenField.isHidden(); |
76 | | - Long counter = (Long) hiddenField.getHiddenObject(thread); |
77 | | - if (counter == null) { |
78 | | - counter = 0L; |
| 67 | + AtomicLong atomicCounter = (AtomicLong) hiddenField.getHiddenObject(thread); |
| 68 | + if (atomicCounter == null) { |
| 69 | + hiddenField.setHiddenObject(thread, atomicCounter = new AtomicLong()); |
79 | 70 | } |
80 | | - ++counter; |
81 | | - hiddenField.setHiddenObject(thread, counter); |
| 71 | + atomicCounter.incrementAndGet(); |
82 | 72 | } |
83 | 73 |
|
84 | 74 | public static long getThreadCounter(StaticObject thread, Field hiddenField) { |
85 | 75 | assert hiddenField.isHidden(); |
86 | | - Long counter = (Long) hiddenField.getHiddenObject(thread); |
87 | | - if (counter == null) { |
88 | | - counter = 0L; |
| 76 | + AtomicLong atomicCounter = (AtomicLong) hiddenField.getHiddenObject(thread); |
| 77 | + if (atomicCounter == null) { |
| 78 | + return 0L; |
89 | 79 | } |
90 | | - return counter; |
| 80 | + return atomicCounter.get(); |
91 | 81 | } |
92 | 82 |
|
93 | 83 | public enum State { |
@@ -405,28 +395,21 @@ public static void interrupt0(@Host(Object.class) StaticObject self) { |
405 | 395 | hostThread.interrupt(); |
406 | 396 | } |
407 | 397 |
|
| 398 | + @TruffleBoundary |
408 | 399 | @Substitution(hasReceiver = true) |
409 | 400 | public static boolean isInterrupted(@Host(Thread.class) StaticObject self, boolean clear) { |
410 | 401 | boolean result = checkInterrupt(self); |
411 | 402 | if (clear) { |
412 | 403 | Thread hostThread = getHostFromGuestThread(self); |
| 404 | + EspressoError.guarantee(hostThread == Thread.currentThread(), "Thread#isInterrupted(true) is only supported for the current thread."); |
413 | 405 | if (hostThread != null && hostThread.isInterrupted()) { |
414 | | - try { |
415 | | - callHostThreadIsInterrupted(hostThread); |
416 | | - } catch (Throwable e) { |
417 | | - throw EspressoError.shouldNotReachHere(e); |
418 | | - } |
| 406 | + Thread.interrupted(); |
419 | 407 | } |
420 | 408 | setInterrupt(self, false); |
421 | 409 | } |
422 | 410 | return result; |
423 | 411 | } |
424 | 412 |
|
425 | | - @TruffleBoundary |
426 | | - private static void callHostThreadIsInterrupted(Thread hostThread) throws IllegalAccessException, InvocationTargetException { |
427 | | - isInterrupted.invoke(hostThread, true); |
428 | | - } |
429 | | - |
430 | 413 | @TruffleBoundary |
431 | 414 | @SuppressWarnings({"unused"}) |
432 | 415 | @Substitution(hasReceiver = true) |
|
0 commit comments