1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
|
/*
* Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef ART_RUNTIME_THREAD_H_
#define ART_RUNTIME_THREAD_H_
#include <atomic>
#include <bitset>
#include <deque>
#include <iosfwd>
#include <list>
#include <memory>
#include <string>
#include "base/atomic.h"
#include "base/bit_field.h"
#include "base/bit_utils.h"
#include "base/locks.h"
#include "base/macros.h"
#include "base/pointer_size.h"
#include "base/safe_map.h"
#include "base/value_object.h"
#include "entrypoints/jni/jni_entrypoints.h"
#include "entrypoints/quick/quick_entrypoints.h"
#include "handle.h"
#include "handle_scope.h"
#include "interpreter/interpreter_cache.h"
#include "interpreter/shadow_frame.h"
#include "javaheapprof/javaheapsampler.h"
#include "jvalue.h"
#include "managed_stack.h"
#include "offsets.h"
#include "read_barrier_config.h"
#include "reflective_handle_scope.h"
#include "runtime_globals.h"
#include "runtime_stats.h"
#include "suspend_reason.h"
#include "thread_state.h"
namespace unwindstack {
class AndroidLocalUnwinder;
} // namespace unwindstack
namespace art HIDDEN {
namespace gc {
namespace accounting {
template<class T> class AtomicStack;
} // namespace accounting
namespace collector {
class SemiSpace;
} // namespace collector
} // namespace gc
namespace instrumentation {
struct InstrumentationStackFrame;
} // namespace instrumentation
namespace mirror {
class Array;
class Class;
class ClassLoader;
class Object;
template<class T> class ObjectArray;
template<class T> class PrimitiveArray;
using IntArray = PrimitiveArray<int32_t>;
class StackTraceElement;
class String;
class Throwable;
} // namespace mirror
namespace verifier {
class VerifierDeps;
} // namespace verifier
class ArtMethod;
class BaseMutex;
class ClassLinker;
class Closure;
class Context;
class DeoptimizationContextRecord;
class DexFile;
class FrameIdToShadowFrame;
class IsMarkedVisitor;
class JavaVMExt;
class JNIEnvExt;
class Monitor;
class RootVisitor;
class ScopedObjectAccessAlreadyRunnable;
class ShadowFrame;
class StackedShadowFrameRecord;
class Thread;
class ThreadList;
enum VisitRootFlags : uint8_t;
enum class LowOverheadTraceType;
// A piece of data that can be held in the CustomTls. The destructor will be called during thread
// shutdown. The thread the destructor is called on is not necessarily the same thread it was stored
// on.
class TLSData {
public:
virtual ~TLSData() {}
};
// Thread priorities. These must match the Thread.MIN_PRIORITY,
// Thread.NORM_PRIORITY, and Thread.MAX_PRIORITY constants.
enum ThreadPriority {
kMinThreadPriority = 1,
kNormThreadPriority = 5,
kMaxThreadPriority = 10,
};
enum class ThreadFlag : uint32_t {
// If set, implies that suspend_count_ > 0 and the Thread should enter the safepoint handler.
kSuspendRequest = 1u << 0,
// Request that the thread do some checkpoint work and then continue.
// Only modified while holding thread_suspend_count_lock_ .
kCheckpointRequest = 1u << 1,
// Request that the thread do empty checkpoint and then continue.
kEmptyCheckpointRequest = 1u << 2,
// Register that at least 1 suspend barrier needs to be passed.
// Changes to this flag are guarded by suspend_count_lock_ .
kActiveSuspendBarrier = 1u << 3,
// Marks that a "flip function" needs to be executed on this thread.
// Set only while holding thread_list_lock_.
kPendingFlipFunction = 1u << 4,
// Marks that the "flip function" is being executed by another thread.
//
// This is used to guard against multiple threads trying to run the
// "flip function" for the same thread while the thread is suspended.
//
// Set when we have some way to ensure that the thread cannot disappear out from under us,
// Either:
// 1) Set by the thread itself,
// 2) by a thread holding thread_list_lock_, or
// 3) while the target has a pending suspension request.
// Once set, prevents a thread from exiting.
kRunningFlipFunction = 1u << 5,
// We are responsible for resuming all other threads. We ignore suspension requests,
// but not checkpoint requests, until a more opportune time. GC code should
// in any case not check for such requests; other clients of SuspendAll might.
// Prevents a situation in which we are asked to suspend just before we suspend all
// other threads, and then notice the suspension request and suspend ourselves,
// leading to deadlock. Guarded by thread_suspend_count_lock_ .
// Should not ever be set when we try to transition to kRunnable.
// TODO(b/296639267): Generalize use to prevent SuspendAll from blocking
// in-progress GC.
kSuspensionImmune = 1u << 6,
// Request that compiled JNI stubs do not transition to Native or Runnable with
// inlined code, but take a slow path for monitoring method entry and exit events.
kMonitorJniEntryExit = 1u << 7,
// Indicates the last flag. Used for checking that the flags do not overlap thread state.
kLastFlag = kMonitorJniEntryExit
};
enum class StackedShadowFrameType {
kShadowFrameUnderConstruction,
kDeoptimizationShadowFrame,
};
// The type of method that triggers deoptimization. It contains info on whether
// the deoptimized method should advance dex_pc.
enum class DeoptimizationMethodType {
kKeepDexPc, // dex pc is required to be kept upon deoptimization.
kDefault // dex pc may or may not advance depending on other conditions.
};
// For the CC colector, normal weak reference access can be disabled on a per-thread basis, while
// processing references. After finishing, the reference processor asynchronously sets the
// per-thread flags back to kEnabled with release memory ordering semantics. Each mutator thread
// should check its flag with acquire semantics before assuming that it is enabled. However,
// that is often too expensive, so the reading thread sets it to kVisiblyEnabled after seeing it
// kEnabled. The Reference.get() intrinsic can thus read it in relaxed mode, and reread (by
// resorting to the slow path) with acquire semantics if it sees a value of kEnabled rather than
// kVisiblyEnabled.
enum class WeakRefAccessState : int32_t {
kVisiblyEnabled = 0, // Enabled, and previously read with acquire load by this thread.
kEnabled,
kDisabled
};
// ART uses two types of ABI/code: quick and native.
//
// Quick code includes:
// - The code that ART compiles to, e.g: Java/dex code compiled to Arm64.
// - Quick assembly entrypoints.
//
// Native code includes:
// - Interpreter.
// - GC.
// - JNI.
// - Runtime methods, i.e.: all ART C++ code.
//
// In regular (non-simulator) mode, both native and quick code are of the same ISA and will operate
// on the hardware stack. The hardware stack is allocated by the kernel to ART and grows down in
// memory.
//
// In simulator mode, native and quick code use different ISA's and will use different stacks.
// Native code will use the hardware stack while quick code will use the simulated stack. The
// simulated stack is a simple buffer in the native heap owned by the Simulator class.
//
// The StackType enum reflects the underlying type of stack in use by any given function while two
// constexpr StackTypes (kNativeStackType and kQuickStackType) indicate which type of stack is used
// for native and quick code. Whenever possible kNativeStackType and kQuickStackType should be used
// instead of using the StackType directly.
enum class StackType {
kHardware,
kSimulated
};
// The type of stack used when executing native code, i.e.: runtime helpers, interpreter, JNI, etc.
// This stack is the native machine's call stack and so should be used when comparing against
// values returned from builtin functions such as __builtin_frame_address.
static constexpr StackType kNativeStackType = StackType::kHardware;
// The type of stack used when executing quick code, i.e.: compiled dex code and quick entrypoints.
// For simulator builds this is the kSimulated stack and for non-simulator builds this is the
// kHardware stack.
static constexpr StackType kQuickStackType = StackType::kHardware;
// See Thread.tlsPtr_.active_suspend1_barriers below for explanation.
struct WrappedSuspend1Barrier {
// TODO(b/323668816): At least weaken CHECKs to DCHECKs once the bug is fixed.
static constexpr int kMagic = 0xba8;
WrappedSuspend1Barrier() : magic_(kMagic), barrier_(1), next_(nullptr) {}
int magic_;
AtomicInteger barrier_;
struct WrappedSuspend1Barrier* next_ GUARDED_BY(Locks::thread_suspend_count_lock_);
};
// Mostly opaque structure allocated by the client of NotifyOnThreadExit. Allows a client to
// check whether the thread still exists after temporarily releasing thread_list_lock_, usually
// because we need to wait for something.
class ThreadExitFlag {
public:
ThreadExitFlag() : exited_(false) {}
bool HasExited() REQUIRES(Locks::thread_list_lock_) { return exited_; }
private:
// All ThreadExitFlags associated with a thread and with exited_ == false are in a doubly linked
// list. tlsPtr_.thread_exit_flags points to the first element. first.prev_ and last.next_ are
// null. This list contains no ThreadExitFlags with exited_ == true;
ThreadExitFlag* next_ GUARDED_BY(Locks::thread_list_lock_);
ThreadExitFlag* prev_ GUARDED_BY(Locks::thread_list_lock_);
bool exited_ GUARDED_BY(Locks::thread_list_lock_);
friend class Thread;
};
// This should match RosAlloc::kNumThreadLocalSizeBrackets.
static constexpr size_t kNumRosAllocThreadLocalSizeBracketsInThread = 16;
static constexpr size_t kSharedMethodHotnessThreshold = 0x1fff;
// Thread's stack layout for implicit stack overflow checks:
//
// +---------------------+ <- highest address of stack memory
// | |
// . . <- SP
// | |
// | |
// +---------------------+ <- stack_end
// | |
// | Gap |
// | |
// +---------------------+ <- stack_begin
// | |
// | Protected region |
// | |
// +---------------------+ <- lowest address of stack memory
//
// The stack always grows down in memory. At the lowest address is a region of memory
// that is set mprotect(PROT_NONE). Any attempt to read/write to this region will
// result in a segmentation fault signal. At any point, the thread's SP will be somewhere
// between the stack_end and the highest address in stack memory. An implicit stack
// overflow check is a read of memory at a certain offset below the current SP (8K typically).
// If the thread's SP is below the stack_end address this will be a read into the protected
// region. If the SP is above the stack_end address, the thread is guaranteed to have
// at least 8K of space. Because stack overflow checks are only performed in generated code,
// if the thread makes a call out to a native function (through JNI), that native function
// might only have 4K of memory (if the SP is adjacent to stack_end).
class EXPORT Thread {
public:
static const size_t kStackOverflowImplicitCheckSize;
static constexpr bool kVerifyStack = kIsDebugBuild;
// Creates a new native thread corresponding to the given managed peer.
// Used to implement Thread.start.
static void CreateNativeThread(JNIEnv* env, jobject peer, size_t stack_size, bool daemon);
// Attaches the calling native thread to the runtime, returning the new native peer.
// Used to implement JNI AttachCurrentThread and AttachCurrentThreadAsDaemon calls.
static Thread* Attach(const char* thread_name,
bool as_daemon,
jobject thread_group,
bool create_peer,
bool should_run_callbacks);
// Attaches the calling native thread to the runtime, returning the new native peer.
static Thread* Attach(const char* thread_name, bool as_daemon, jobject thread_peer);
// Reset internal state of child thread after fork.
void InitAfterFork();
// Get the currently executing thread, frequently referred to as 'self'. This call has reasonably
// high cost and so we favor passing self around when possible.
// TODO: mark as PURE so the compiler may coalesce and remove?
static Thread* Current();
// Get the thread from the JNI environment.
static Thread* ForEnv(JNIEnv* env);
// For implicit overflow checks we reserve an extra piece of memory at the bottom of the stack
// (lowest memory). The higher portion of the memory is protected against reads and the lower is
// available for use while throwing the StackOverflow exception.
ALWAYS_INLINE static size_t GetStackOverflowProtectedSize();
// On a runnable thread, check for pending thread suspension request and handle if pending.
void AllowThreadSuspension() REQUIRES_SHARED(Locks::mutator_lock_);
// Process pending thread suspension request and handle if pending.
void CheckSuspend(bool implicit = false) REQUIRES_SHARED(Locks::mutator_lock_);
// Process a pending empty checkpoint if pending.
void CheckEmptyCheckpointFromWeakRefAccess(BaseMutex* cond_var_mutex);
void CheckEmptyCheckpointFromMutex();
static Thread* FromManagedThread(Thread* self, ObjPtr<mirror::Object> thread_peer)
REQUIRES(Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_)
REQUIRES_SHARED(Locks::mutator_lock_);
static Thread* FromManagedThread(const ScopedObjectAccessAlreadyRunnable& ts, jobject thread)
REQUIRES(Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_)
REQUIRES_SHARED(Locks::mutator_lock_);
// Translates 172 to pAllocArrayFromCode and so on.
template<PointerSize size_of_pointers>
static void DumpThreadOffset(std::ostream& os, uint32_t offset);
// Dumps a one-line summary of thread state (used for operator<<).
void ShortDump(std::ostream& os) const;
// Order of threads for ANRs (ANRs can be trimmed, so we print important ones first).
enum class DumpOrder : uint8_t {
kMain, // Always print the main thread first (there might not be one).
kBlocked, // Then print all threads that are blocked due to waiting on lock.
kLocked, // Then print all threads that are holding some lock already.
kDefault, // Print all other threads which might not be interesting for ANR.
};
// Dumps the detailed thread state and the thread stack (used for SIGQUIT).
DumpOrder Dump(std::ostream& os,
bool dump_native_stack = true,
bool force_dump_stack = false) const
REQUIRES_SHARED(Locks::mutator_lock_);
DumpOrder Dump(std::ostream& os,
unwindstack::AndroidLocalUnwinder& unwinder,
bool dump_native_stack = true,
bool force_dump_stack = false) const
REQUIRES_SHARED(Locks::mutator_lock_);
DumpOrder DumpJavaStack(std::ostream& os,
bool check_suspended = true,
bool dump_locks = true) const
REQUIRES_SHARED(Locks::mutator_lock_);
// Dumps the SIGQUIT per-thread header. 'thread' can be null for a non-attached thread, in which
// case we use 'tid' to identify the thread, and we'll include as much information as we can.
static void DumpState(std::ostream& os, const Thread* thread, pid_t tid)
REQUIRES_SHARED(Locks::mutator_lock_);
ThreadState GetState() const {
return GetStateAndFlags(std::memory_order_relaxed).GetState();
}
ThreadState SetState(ThreadState new_state);
int GetSuspendCount() const REQUIRES(Locks::thread_suspend_count_lock_) {
return tls32_.suspend_count;
}
int GetUserCodeSuspendCount() const REQUIRES(Locks::thread_suspend_count_lock_,
Locks::user_code_suspension_lock_) {
return tls32_.user_code_suspend_count;
}
bool IsSuspended() const {
// We need to ensure that once we return true, all prior accesses to the Java data by "this"
// thread are complete. Hence we need "acquire" ordering here, and "release" when the flags
// are set.
StateAndFlags state_and_flags = GetStateAndFlags(std::memory_order_acquire);
return state_and_flags.GetState() != ThreadState::kRunnable &&
state_and_flags.IsFlagSet(ThreadFlag::kSuspendRequest);
}
void DecrDefineClassCount() {
tls32_.define_class_counter--;
}
void IncrDefineClassCount() {
tls32_.define_class_counter++;
}
uint32_t GetDefineClassCount() const {
return tls32_.define_class_counter;
}
// Increment suspend count and optionally install at most one suspend barrier.
// Must hold thread_list_lock, OR be called with self == this, so that the Thread cannot
// disappear while we're running. If it's known that this == self, and thread_list_lock_
// is not held, FakeMutexLock should be used to fake-acquire thread_list_lock_ for
// static checking purposes.
ALWAYS_INLINE
void IncrementSuspendCount(Thread* self,
AtomicInteger* suspendall_barrier,
WrappedSuspend1Barrier* suspend1_barrier,
SuspendReason reason) REQUIRES(Locks::thread_suspend_count_lock_)
REQUIRES(Locks::thread_list_lock_);
// The same, but default reason to kInternal, and barriers to nullptr.
ALWAYS_INLINE void IncrementSuspendCount(Thread* self) REQUIRES(Locks::thread_suspend_count_lock_)
REQUIRES(Locks::thread_list_lock_);
// Follows one of the above calls. For_user_code indicates if SuspendReason was kForUserCode.
// Generally will need to be closely followed by Thread::resume_cond_->Broadcast(self);
// since there may be waiters. DecrementSuspendCount() itself does not do this, since we often
// wake more than a single thread.
ALWAYS_INLINE void DecrementSuspendCount(Thread* self, bool for_user_code = false)
REQUIRES(Locks::thread_suspend_count_lock_);
private:
NO_RETURN static void UnsafeLogFatalForSuspendCount(Thread* self, Thread* thread);
public:
// Requests a checkpoint closure to run on another thread. The closure will be run when the
// thread notices the request, either in an explicit runtime CheckSuspend() call, or in a call
// originating from a compiler generated suspend point check. This returns true if the closure
// was added and will (eventually) be executed. It returns false if this was impossible
// because the thread was suspended, and we thus did nothing.
//
// Since multiple closures can be queued and some closures can delay other threads from running,
// no closure should attempt to suspend another thread while running.
// TODO We should add some debug option that verifies this.
//
// This guarantees that the RequestCheckpoint invocation happens-before the function invocation:
// RequestCheckpointFunction holds thread_suspend_count_lock_, and RunCheckpointFunction
// acquires it.
bool RequestCheckpoint(Closure* function)
REQUIRES(Locks::thread_suspend_count_lock_);
// RequestSynchronousCheckpoint releases the thread_list_lock_ as a part of its execution. This is
// due to the fact that Thread::Current() needs to go to sleep to allow the targeted thread to
// execute the checkpoint for us if it is Runnable. The wait_state is the state that the thread
// will go into while it is awaiting the checkpoint to be run.
// The closure may be run on Thread::Current() on behalf of "this" thread.
// Thus for lock ordering purposes, the closure should be runnable by the caller. This also
// sometimes makes it reasonable to pass ThreadState::kRunnable as wait_state: We may wait on
// a condition variable for the "this" thread to act, but for lock ordering purposes, this is
// exactly as though Thread::Current() had run the closure.
// NB Since multiple closures can be queued and some closures can delay other threads from running
// no closure should attempt to suspend another thread while running.
bool RequestSynchronousCheckpoint(Closure* function,
ThreadState wait_state = ThreadState::kWaiting)
REQUIRES_SHARED(Locks::mutator_lock_) RELEASE(Locks::thread_list_lock_)
REQUIRES(!Locks::thread_suspend_count_lock_);
bool RequestEmptyCheckpoint()
REQUIRES(Locks::thread_suspend_count_lock_);
Closure* GetFlipFunction() { return tlsPtr_.flip_function.load(std::memory_order_relaxed); }
// Set the flip function. This is done with all threads suspended, except for the calling thread.
void SetFlipFunction(Closure* function) REQUIRES(Locks::thread_suspend_count_lock_)
REQUIRES(Locks::thread_list_lock_);
// Wait for the flip function to complete if still running on another thread. Assumes the "this"
// thread remains live.
void WaitForFlipFunction(Thread* self) const REQUIRES(!Locks::thread_suspend_count_lock_);
// An enhanced version of the above that uses tef to safely return if the thread exited in the
// meantime.
void WaitForFlipFunctionTestingExited(Thread* self, ThreadExitFlag* tef)
REQUIRES(!Locks::thread_suspend_count_lock_, !Locks::thread_list_lock_);
gc::accounting::AtomicStack<mirror::Object>* GetThreadLocalMarkStack() {
CHECK(gUseReadBarrier);
return tlsPtr_.thread_local_mark_stack;
}
void SetThreadLocalMarkStack(gc::accounting::AtomicStack<mirror::Object>* stack) {
CHECK(gUseReadBarrier);
tlsPtr_.thread_local_mark_stack = stack;
}
uint8_t* GetThreadLocalGcBuffer() {
DCHECK(gUseUserfaultfd);
return tlsPtr_.thread_local_gc_buffer;
}
void SetThreadLocalGcBuffer(uint8_t* buf) {
DCHECK(gUseUserfaultfd);
tlsPtr_.thread_local_gc_buffer = buf;
}
// Called when thread detected that the thread_suspend_count_ was non-zero. Gives up share of
// mutator_lock_ and waits until it is resumed and thread_suspend_count_ is zero.
// Should be called only when the kSuspensionImmune flag is clear. Requires this == Current();
void FullSuspendCheck(bool implicit = false)
REQUIRES(!Locks::thread_suspend_count_lock_)
REQUIRES_SHARED(Locks::mutator_lock_);
// Transition from non-runnable to runnable state acquiring share on mutator_lock_. Returns the
// old state, or kInvalidState if we failed because allow_failure and kSuspensionImmune were set.
// Should not be called with an argument except by the next function below.
ALWAYS_INLINE ThreadState TransitionFromSuspendedToRunnable(bool fail_on_suspend_req = false)
REQUIRES(!Locks::thread_suspend_count_lock_) SHARED_LOCK_FUNCTION(Locks::mutator_lock_);
// A version that does not return the old ThreadState, and fails by returning false if it would
// have needed to handle a pending suspension request.
ALWAYS_INLINE bool TryTransitionFromSuspendedToRunnable()
REQUIRES(!Locks::thread_suspend_count_lock_)
SHARED_TRYLOCK_FUNCTION(true, Locks::mutator_lock_) NO_THREAD_SAFETY_ANALYSIS {
// The above function does not really acquire the lock when we pass true and it returns
// kInvalidState. We lie in both places, but clients see correct behavior.
return TransitionFromSuspendedToRunnable(true) != ThreadState::kInvalidState;
}
// Transition from runnable into a state where mutator privileges are denied. Releases share of
// mutator lock.
ALWAYS_INLINE void TransitionFromRunnableToSuspended(ThreadState new_state)
REQUIRES(!Locks::thread_suspend_count_lock_, !Roles::uninterruptible_)
UNLOCK_FUNCTION(Locks::mutator_lock_);
// Once called thread suspension will cause an assertion failure.
const char* StartAssertNoThreadSuspension(const char* cause) ACQUIRE(Roles::uninterruptible_) {
Roles::uninterruptible_.Acquire(); // No-op.
if (kIsDebugBuild) {
CHECK(cause != nullptr);
const char* previous_cause = tlsPtr_.last_no_thread_suspension_cause;
tls32_.no_thread_suspension++;
tlsPtr_.last_no_thread_suspension_cause = cause;
return previous_cause;
} else {
return nullptr;
}
}
// End region where no thread suspension is expected.
void EndAssertNoThreadSuspension(const char* old_cause) RELEASE(Roles::uninterruptible_) {
if (kIsDebugBuild) {
CHECK_IMPLIES(old_cause == nullptr, tls32_.no_thread_suspension == 1);
CHECK_GT(tls32_.no_thread_suspension, 0U);
tls32_.no_thread_suspension--;
tlsPtr_.last_no_thread_suspension_cause = old_cause;
}
Roles::uninterruptible_.Release(); // No-op.
}
// End region where no thread suspension is expected. Returns the current open region in case we
// want to reopen it. Used for ScopedAllowThreadSuspension. Not supported if no_thread_suspension
// is larger than one.
const char* EndAssertNoThreadSuspension() RELEASE(Roles::uninterruptible_) WARN_UNUSED {
const char* ret = nullptr;
if (kIsDebugBuild) {
CHECK_EQ(tls32_.no_thread_suspension, 1u);
tls32_.no_thread_suspension--;
ret = tlsPtr_.last_no_thread_suspension_cause;
tlsPtr_.last_no_thread_suspension_cause = nullptr;
}
Roles::uninterruptible_.Release(); // No-op.
return ret;
}
void AssertThreadSuspensionIsAllowable(bool check_locks = true) const;
void AssertNoTransactionCheckAllowed() const {
CHECK(tlsPtr_.last_no_transaction_checks_cause == nullptr)
<< tlsPtr_.last_no_transaction_checks_cause;
}
// Return true if thread suspension is allowable.
bool IsThreadSuspensionAllowable() const;
bool IsDaemon() const {
return tls32_.daemon;
}
size_t NumberOfHeldMutexes() const;
bool HoldsLock(ObjPtr<mirror::Object> object) const REQUIRES_SHARED(Locks::mutator_lock_);
/*
* Changes the priority of this thread to match that of the java.lang.Thread object.
*
* We map a priority value from 1-10 to Linux "nice" values, where lower
* numbers indicate higher priority.
*/
void SetNativePriority(int newPriority);
/*
* Returns the priority of this thread by querying the system.
* This is useful when attaching a thread through JNI.
*
* Returns a value from 1 to 10 (compatible with java.lang.Thread values).
*/
int GetNativePriority() const;
// Guaranteed to be non-zero.
uint32_t GetThreadId() const {
return tls32_.thin_lock_thread_id;
}
pid_t GetTid() const {
return tls32_.tid;
}
// Returns the java.lang.Thread's name, or null if this Thread* doesn't have a peer.
ObjPtr<mirror::String> GetThreadName() const REQUIRES_SHARED(Locks::mutator_lock_);
// Sets 'name' to the java.lang.Thread's name. This requires no transition to managed code,
// allocation, or locking.
void GetThreadName(std::string& name) const;
// Sets the thread's name.
void SetThreadName(const char* name) REQUIRES_SHARED(Locks::mutator_lock_);
// Returns the thread-specific CPU-time clock in microseconds or -1 if unavailable.
uint64_t GetCpuMicroTime() const;
// Returns the thread-specific CPU-time clock in nanoseconds or -1 if unavailable.
uint64_t GetCpuNanoTime() const;
mirror::Object* GetPeer() const REQUIRES_SHARED(Locks::mutator_lock_) {
DCHECK(Thread::Current() == this) << "Use GetPeerFromOtherThread instead";
CHECK(tlsPtr_.jpeer == nullptr);
return tlsPtr_.opeer;
}
// GetPeer is not safe if called on another thread in the middle of the thread flip and
// the thread's stack may have not been flipped yet and peer may be a from-space (stale) ref.
// This function will force a flip for the other thread if necessary.
// Since we hold a shared mutator lock, a new flip function cannot be concurrently installed.
// The target thread must be suspended, so that it cannot disappear during the call.
// We should ideally not hold thread_list_lock_ . GetReferenceKind in ti_heap.cc, currently does
// hold it, but in a context in which we do not invoke EnsureFlipFunctionStarted().
mirror::Object* GetPeerFromOtherThread() REQUIRES_SHARED(Locks::mutator_lock_);
// A version of the above that requires thread_list_lock_, but does not require the thread to
// be suspended. This may temporarily release thread_list_lock_. It thus needs a ThreadExitFlag
// describing the thread's status, so we can tell if it exited in the interim. Returns null if
// the thread exited.
mirror::Object* LockedGetPeerFromOtherThread(ThreadExitFlag* tef)
REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(Locks::thread_list_lock_);
// A convenience version of the above that creates the ThreadExitFlag locally. This is often
// unsafe if more than one thread is being processed. A prior call may have released
// thread_list_lock_, and thus the NotifyOnThreadExit() call here could see a deallocated
// Thread. We must hold the thread_list_lock continuously between obtaining the Thread*
// and calling NotifyOnThreadExit().
mirror::Object* LockedGetPeerFromOtherThread() REQUIRES_SHARED(Locks::mutator_lock_)
REQUIRES(Locks::thread_list_lock_) {
ThreadExitFlag tef;
NotifyOnThreadExit(&tef);
mirror::Object* result = LockedGetPeerFromOtherThread(&tef);
UnregisterThreadExitFlag(&tef);
return result;
}
bool HasPeer() const {
return tlsPtr_.jpeer != nullptr || tlsPtr_.opeer != nullptr;
}
RuntimeStats* GetStats() {
return &tls64_.stats;
}
bool IsStillStarting() const;
bool IsExceptionPending() const {
return tlsPtr_.exception != nullptr;
}
bool IsAsyncExceptionPending() const {
return tlsPtr_.async_exception != nullptr;
}
mirror::Throwable* GetException() const REQUIRES_SHARED(Locks::mutator_lock_) {
return tlsPtr_.exception;
}
void AssertPendingException() const;
void AssertPendingOOMException() const REQUIRES_SHARED(Locks::mutator_lock_);
void AssertNoPendingException() const;
void AssertNoPendingExceptionForNewException(const char* msg) const;
void SetException(ObjPtr<mirror::Throwable> new_exception) REQUIRES_SHARED(Locks::mutator_lock_);
// Set an exception that is asynchronously thrown from a different thread. This will be checked
// periodically and might overwrite the current 'Exception'. This can only be called from a
// checkpoint.
//
// The caller should also make sure that the thread has been deoptimized so that the exception
// could be detected on back-edges.
void SetAsyncException(ObjPtr<mirror::Throwable> new_exception)
REQUIRES_SHARED(Locks::mutator_lock_);
void ClearException() REQUIRES_SHARED(Locks::mutator_lock_) {
tlsPtr_.exception = nullptr;
}
// Move the current async-exception to the main exception. This should be called when the current
// thread is ready to deal with any async exceptions. Returns true if there is an async exception
// that needs to be dealt with, false otherwise.
bool ObserveAsyncException() REQUIRES_SHARED(Locks::mutator_lock_);
// Find catch block then prepare and return the long jump context to the appropriate exception
// handler. When is_method_exit_exception is true, the exception was thrown by the method exit
// callback and we should not send method unwind for the method on top of the stack since method
// exit callback was already called.
std::unique_ptr<Context> QuickDeliverException(bool is_method_exit_exception = false)
REQUIRES_SHARED(Locks::mutator_lock_);
// Perform deoptimization. Return a `Context` prepared for a long jump.
std::unique_ptr<Context> Deoptimize(DeoptimizationKind kind,
bool single_frame,
bool skip_method_exit_callbacks)
REQUIRES_SHARED(Locks::mutator_lock_);
// Get the current method and dex pc. If there are errors in retrieving the dex pc, this will
// abort the runtime iff abort_on_error is true.
ArtMethod* GetCurrentMethod(uint32_t* dex_pc,
bool check_suspended = true,
bool abort_on_error = true) const
REQUIRES_SHARED(Locks::mutator_lock_);
// Returns whether the given exception was thrown by the current Java method being executed
// (Note that this includes native Java methods).
bool IsExceptionThrownByCurrentMethod(ObjPtr<mirror::Throwable> exception) const
REQUIRES_SHARED(Locks::mutator_lock_);
void SetTopOfStack(ArtMethod** top_method) {
tlsPtr_.managed_stack.SetTopQuickFrame(top_method);
}
void SetTopOfStackGenericJniTagged(ArtMethod** top_method) {
tlsPtr_.managed_stack.SetTopQuickFrameGenericJniTagged(top_method);
}
void SetTopOfShadowStack(ShadowFrame* top) {
tlsPtr_.managed_stack.SetTopShadowFrame(top);
}
bool HasManagedStack() const {
return tlsPtr_.managed_stack.HasTopQuickFrame() || tlsPtr_.managed_stack.HasTopShadowFrame();
}
// If 'msg' is null, no detail message is set.
void ThrowNewException(const char* exception_class_descriptor, const char* msg)
REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_);
// If 'msg' is null, no detail message is set. An exception must be pending, and will be
// used as the new exception's cause.
void ThrowNewWrappedException(const char* exception_class_descriptor, const char* msg)
REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_);
void ThrowNewExceptionF(const char* exception_class_descriptor, const char* fmt, ...)
__attribute__((format(printf, 3, 4)))
REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_);
void ThrowNewExceptionV(const char* exception_class_descriptor, const char* fmt, va_list ap)
REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_);
// OutOfMemoryError is special, because we need to pre-allocate an instance.
// Only the GC should call this.
void ThrowOutOfMemoryError(const char* msg) REQUIRES_SHARED(Locks::mutator_lock_)
REQUIRES(!Roles::uninterruptible_);
static void Startup();
static void FinishStartup();
static void Shutdown();
// Notify this thread's thread-group that this thread has started.
// Note: the given thread-group is used as a fast path and verified in debug build. If the value
// is null, the thread's thread-group is loaded from the peer.
void NotifyThreadGroup(ScopedObjectAccessAlreadyRunnable& soa, jobject thread_group = nullptr)
REQUIRES_SHARED(Locks::mutator_lock_);
// Request notification when this thread is unregistered, typically because it has exited.
//
// The ThreadExitFlag status is only changed when we remove the thread from the thread list,
// which we only do once no suspend requests are outstanding, and no flip-functions are still
// running.
//
// The caller must allocate a fresh ThreadExitFlag, and pass it in. The caller is responsible
// for either waiting until the thread has exited, or unregistering the ThreadExitFlag, and
// then, and only then, deallocating the ThreadExitFlag. (This scheme avoids an allocation and
// questions about what to do if the allocation fails. Allows detection of thread exit after
// temporary release of thread_list_lock_)
void NotifyOnThreadExit(ThreadExitFlag* tef) REQUIRES(Locks::thread_list_lock_);
void UnregisterThreadExitFlag(ThreadExitFlag* tef) REQUIRES(Locks::thread_list_lock_);
// Is the ThreadExitFlag currently registered in this thread, which has not yet terminated?
// Intended only for testing.
bool IsRegistered(ThreadExitFlag* query_tef) REQUIRES(Locks::thread_list_lock_);
// For debuggable builds, CHECK that neither first nor last, nor any ThreadExitFlag with an
// address in-between, is currently registered with any thread.
static void DCheckUnregisteredEverywhere(ThreadExitFlag* first, ThreadExitFlag* last)
REQUIRES(!Locks::thread_list_lock_);
// Called when thread is unregistered. May be called repeatedly, in which case only newly
// registered clients are processed.
void SignalExitFlags() REQUIRES(Locks::thread_list_lock_);
// JNI methods
JNIEnvExt* GetJniEnv() const {
return tlsPtr_.jni_env;
}
// Convert a jobject into a Object*
ObjPtr<mirror::Object> DecodeJObject(jobject obj) const REQUIRES_SHARED(Locks::mutator_lock_);
// Checks if the weak global ref has been cleared by the GC without decoding it.
bool IsJWeakCleared(jweak obj) const REQUIRES_SHARED(Locks::mutator_lock_);
mirror::Object* GetMonitorEnterObject() const REQUIRES_SHARED(Locks::mutator_lock_) {
return tlsPtr_.monitor_enter_object;
}
void SetMonitorEnterObject(mirror::Object* obj) REQUIRES_SHARED(Locks::mutator_lock_) {
tlsPtr_.monitor_enter_object = obj;
}
// Implements java.lang.Thread.interrupted.
bool Interrupted();
// Implements java.lang.Thread.isInterrupted.
bool IsInterrupted();
void Interrupt(Thread* self) REQUIRES(!wait_mutex_);
void SetInterrupted(bool i) {
tls32_.interrupted.store(i, std::memory_order_seq_cst);
}
void Notify() REQUIRES(!wait_mutex_);
ALWAYS_INLINE void PoisonObjectPointers() {
++poison_object_cookie_;
}
ALWAYS_INLINE static void PoisonObjectPointersIfDebug();
ALWAYS_INLINE uintptr_t GetPoisonObjectCookie() const {
return poison_object_cookie_;
}
// Parking for 0ns of relative time means an untimed park, negative (though
// should be handled in java code) returns immediately
void Park(bool is_absolute, int64_t time) REQUIRES_SHARED(Locks::mutator_lock_);
void Unpark();
private:
void NotifyLocked(Thread* self) REQUIRES(wait_mutex_);
public:
Mutex* GetWaitMutex() const LOCK_RETURNED(wait_mutex_) {
return wait_mutex_;
}
ConditionVariable* GetWaitConditionVariable() const REQUIRES(wait_mutex_) {
return wait_cond_;
}
Monitor* GetWaitMonitor() const REQUIRES(wait_mutex_) {
return wait_monitor_;
}
void SetWaitMonitor(Monitor* mon) REQUIRES(wait_mutex_) {
wait_monitor_ = mon;
}
// Waiter link-list support.
Thread* GetWaitNext() const {
return tlsPtr_.wait_next;
}
void SetWaitNext(Thread* next) {
tlsPtr_.wait_next = next;
}
jobject GetClassLoaderOverride() {
return tlsPtr_.class_loader_override;
}
void SetClassLoaderOverride(jobject class_loader_override);
// Create the internal representation of a stack trace, that is more time
// and space efficient to compute than the StackTraceElement[].
ObjPtr<mirror::ObjectArray<mirror::Object>> CreateInternalStackTrace(
const ScopedObjectAccessAlreadyRunnable& soa) const
REQUIRES_SHARED(Locks::mutator_lock_);
// Convert an internal stack trace representation (returned by CreateInternalStackTrace) to a
// StackTraceElement[]. If output_array is null, a new array is created, otherwise as many
// frames as will fit are written into the given array. If stack_depth is non-null, it's updated
// with the number of valid frames in the returned array.
static jobjectArray InternalStackTraceToStackTraceElementArray(
const ScopedObjectAccessAlreadyRunnable& soa, jobject internal,
jobjectArray output_array = nullptr, int* stack_depth = nullptr)
REQUIRES_SHARED(Locks::mutator_lock_);
static jint InternalStackTraceToStackFrameInfoArray(
const ScopedObjectAccessAlreadyRunnable& soa,
jlong mode, // See java.lang.StackStreamFactory for the mode flags
jobject internal,
jint startLevel,
jint batchSize,
jint startIndex,
jobjectArray output_array) // java.lang.StackFrameInfo[]
REQUIRES_SHARED(Locks::mutator_lock_);
jobjectArray CreateAnnotatedStackTrace(const ScopedObjectAccessAlreadyRunnable& soa) const
REQUIRES_SHARED(Locks::mutator_lock_);
bool HasDebuggerShadowFrames() const {
return tlsPtr_.frame_id_to_shadow_frame != nullptr;
}
// This is done by GC using a checkpoint (or in a stop-the-world pause).
void SweepInterpreterCache(IsMarkedVisitor* visitor) REQUIRES_SHARED(Locks::mutator_lock_);
void VisitRoots(RootVisitor* visitor, VisitRootFlags flags)
REQUIRES_SHARED(Locks::mutator_lock_);
void VisitReflectiveTargets(ReflectiveValueVisitor* visitor)
REQUIRES(Locks::mutator_lock_);
// Check that the thread state is valid. Try to fail if the thread has erroneously terminated.
// Note that once the thread has been terminated, it can also be deallocated. But even if the
// thread state has been overwritten, the value is unlikely to be in the correct range.
void VerifyState() {
if (kIsDebugBuild) {
ThreadState state = GetState();
StateAndFlags::ValidateThreadState(state);
DCHECK_NE(state, ThreadState::kTerminated);
}
}
void VerifyStack() REQUIRES_SHARED(Locks::mutator_lock_) {
if (kVerifyStack) {
VerifyStackImpl();
}
}
//
// Offsets of various members of native Thread class, used by compiled code.
//
template<PointerSize pointer_size>
static constexpr ThreadOffset<pointer_size> ThinLockIdOffset() {
return ThreadOffset<pointer_size>(
OFFSETOF_MEMBER(Thread, tls32_) +
OFFSETOF_MEMBER(tls_32bit_sized_values, thin_lock_thread_id));
}
template<PointerSize pointer_size>
static constexpr ThreadOffset<pointer_size> TidOffset() {
return ThreadOffset<pointer_size>(
OFFSETOF_MEMBER(Thread, tls32_) +
OFFSETOF_MEMBER(tls_32bit_sized_values, tid));
}
template<PointerSize pointer_size>
static constexpr ThreadOffset<pointer_size> InterruptedOffset() {
return ThreadOffset<pointer_size>(
OFFSETOF_MEMBER(Thread, tls32_) +
OFFSETOF_MEMBER(tls_32bit_sized_values, interrupted));
}
template<PointerSize pointer_size>
static constexpr ThreadOffset<pointer_size> WeakRefAccessEnabledOffset() {
return ThreadOffset<pointer_size>(
OFFSETOF_MEMBER(Thread, tls32_) +
OFFSETOF_MEMBER(tls_32bit_sized_values, weak_ref_access_enabled));
}
template<PointerSize pointer_size>
static constexpr ThreadOffset<pointer_size> ThreadFlagsOffset() {
return ThreadOffset<pointer_size>(
OFFSETOF_MEMBER(Thread, tls32_) +
OFFSETOF_MEMBER(tls_32bit_sized_values, state_and_flags));
}
template<PointerSize pointer_size>
static constexpr ThreadOffset<pointer_size> IsGcMarkingOffset() {
return ThreadOffset<pointer_size>(
OFFSETOF_MEMBER(Thread, tls32_) +
OFFSETOF_MEMBER(tls_32bit_sized_values, is_gc_marking));
}
template <PointerSize pointer_size>
static constexpr ThreadOffset<pointer_size> DeoptCheckRequiredOffset() {
return ThreadOffset<pointer_size>(
OFFSETOF_MEMBER(Thread, tls32_) +
OFFSETOF_MEMBER(tls_32bit_sized_values, is_deopt_check_required));
}
static constexpr size_t IsGcMarkingSize() {
return sizeof(tls32_.is_gc_marking);
}
template<PointerSize pointer_size>
static constexpr ThreadOffset<pointer_size> SharedMethodHotnessOffset() {
return ThreadOffset<pointer_size>(
OFFSETOF_MEMBER(Thread, tls32_) +
OFFSETOF_MEMBER(tls_32bit_sized_values, shared_method_hotness));
}
// Deoptimize the Java stack.
void DeoptimizeWithDeoptimizationException(JValue* result) REQUIRES_SHARED(Locks::mutator_lock_);
private:
template<PointerSize pointer_size>
static constexpr ThreadOffset<pointer_size> ThreadOffsetFromTlsPtr(size_t tls_ptr_offset) {
size_t base = OFFSETOF_MEMBER(Thread, tlsPtr_);
size_t scale = (pointer_size > kRuntimePointerSize) ?
static_cast<size_t>(pointer_size) / static_cast<size_t>(kRuntimePointerSize) : 1;
size_t shrink = (kRuntimePointerSize > pointer_size) ?
static_cast<size_t>(kRuntimePointerSize) / static_cast<size_t>(pointer_size) : 1;
return ThreadOffset<pointer_size>(base + ((tls_ptr_offset * scale) / shrink));
}
public:
template<PointerSize pointer_size>
static constexpr ThreadOffset<pointer_size> QuickEntryPointOffset(
size_t quick_entrypoint_offset) {
return ThreadOffsetFromTlsPtr<pointer_size>(
OFFSETOF_MEMBER(tls_ptr_sized_values, quick_entrypoints) + quick_entrypoint_offset);
}
static constexpr uint32_t QuickEntryPointOffsetWithSize(size_t quick_entrypoint_offset,
PointerSize pointer_size) {
if (pointer_size == PointerSize::k32) {
return QuickEntryPointOffset<PointerSize::k32>(quick_entrypoint_offset).
Uint32Value();
} else {
return QuickEntryPointOffset<PointerSize::k64>(quick_entrypoint_offset).
Uint32Value();
}
}
template<PointerSize pointer_size>
static ThreadOffset<pointer_size> JniEntryPointOffset(size_t jni_entrypoint_offset) {
return ThreadOffsetFromTlsPtr<pointer_size>(
OFFSETOF_MEMBER(tls_ptr_sized_values, jni_entrypoints) + jni_entrypoint_offset);
}
// Return the entry point offset integer value for ReadBarrierMarkRegX, where X is `reg`.
template <PointerSize pointer_size>
static constexpr int32_t ReadBarrierMarkEntryPointsOffset(size_t reg) {
// The entry point list defines 30 ReadBarrierMarkRegX entry points.
DCHECK_LT(reg, 30u);
// The ReadBarrierMarkRegX entry points are ordered by increasing
// register number in Thread::tls_Ptr_.quick_entrypoints.
return QUICK_ENTRYPOINT_OFFSET(pointer_size, pReadBarrierMarkReg00).Int32Value()
+ static_cast<size_t>(pointer_size) * reg;
}
template<PointerSize pointer_size>
static constexpr ThreadOffset<pointer_size> SelfOffset() {
return ThreadOffsetFromTlsPtr<pointer_size>(OFFSETOF_MEMBER(tls_ptr_sized_values, self));
}
template<PointerSize pointer_size>
static constexpr ThreadOffset<pointer_size> ExceptionOffset() {
return ThreadOffsetFromTlsPtr<pointer_size>(OFFSETOF_MEMBER(tls_ptr_sized_values, exception));
}
template<PointerSize pointer_size>
static constexpr ThreadOffset<pointer_size> PeerOffset() {
return ThreadOffsetFromTlsPtr<pointer_size>(OFFSETOF_MEMBER(tls_ptr_sized_values, opeer));
}
template<PointerSize pointer_size>
static constexpr ThreadOffset<pointer_size> CardTableOffset() {
return ThreadOffsetFromTlsPtr<pointer_size>(OFFSETOF_MEMBER(tls_ptr_sized_values, card_table));
}
template<PointerSize pointer_size>
static constexpr ThreadOffset<pointer_size> ThreadSuspendTriggerOffset() {
return ThreadOffsetFromTlsPtr<pointer_size>(
OFFSETOF_MEMBER(tls_ptr_sized_values, suspend_trigger));
}
template<PointerSize pointer_size>
static constexpr ThreadOffset<pointer_size> ThreadLocalPosOffset() {
return ThreadOffsetFromTlsPtr<pointer_size>(OFFSETOF_MEMBER(tls_ptr_sized_values,
thread_local_pos));
}
template<PointerSize pointer_size>
static constexpr ThreadOffset<pointer_size> ThreadLocalEndOffset() {
return ThreadOffsetFromTlsPtr<pointer_size>(OFFSETOF_MEMBER(tls_ptr_sized_values,
thread_local_end));
}
template<PointerSize pointer_size>
static constexpr ThreadOffset<pointer_size> ThreadLocalObjectsOffset() {
return ThreadOffsetFromTlsPtr<pointer_size>(OFFSETOF_MEMBER(tls_ptr_sized_values,
thread_local_objects));
}
template<PointerSize pointer_size>
static constexpr ThreadOffset<pointer_size> RosAllocRunsOffset() {
return ThreadOffsetFromTlsPtr<pointer_size>(OFFSETOF_MEMBER(tls_ptr_sized_values,
rosalloc_runs));
}
template<PointerSize pointer_size>
static constexpr ThreadOffset<pointer_size> ThreadLocalAllocStackTopOffset() {
return ThreadOffsetFromTlsPtr<pointer_size>(OFFSETOF_MEMBER(tls_ptr_sized_values,
thread_local_alloc_stack_top));
}
template<PointerSize pointer_size>
static constexpr ThreadOffset<pointer_size> ThreadLocalAllocStackEndOffset() {
return ThreadOffsetFromTlsPtr<pointer_size>(OFFSETOF_MEMBER(tls_ptr_sized_values,
thread_local_alloc_stack_end));
}
template <PointerSize pointer_size>
static constexpr ThreadOffset<pointer_size> TraceBufferCurrPtrOffset() {
return ThreadOffsetFromTlsPtr<pointer_size>(
OFFSETOF_MEMBER(tls_ptr_sized_values, method_trace_buffer_curr_entry));
}
template <PointerSize pointer_size>
static constexpr ThreadOffset<pointer_size> TraceBufferPtrOffset() {
return ThreadOffsetFromTlsPtr<pointer_size>(
OFFSETOF_MEMBER(tls_ptr_sized_values, method_trace_buffer));
}
// Size of stack less any space reserved for stack overflow
template <StackType stack_type>
size_t GetUsableStackSize() const {
return GetStackSize<stack_type>() - static_cast<size_t>(
GetStackEnd<stack_type>() - GetStackBegin<stack_type>());
}
template <StackType stack_type>
ALWAYS_INLINE uint8_t* GetStackEnd() const;
ALWAYS_INLINE uint8_t* GetStackEndForInterpreter(bool implicit_overflow_check) const;
// Set the stack end to that to be used during a stack overflow
template <StackType stack_type>
ALWAYS_INLINE void SetStackEndForStackOverflow()
REQUIRES_SHARED(Locks::mutator_lock_);
// Set the stack end to that to be used during regular execution
template <StackType stack_type>
ALWAYS_INLINE void ResetDefaultStackEnd();
template <StackType stack_type>
bool IsHandlingStackOverflow() const {
return GetStackEnd<stack_type>() == GetStackBegin<stack_type>();
}
template<PointerSize pointer_size>
static constexpr ThreadOffset<pointer_size> StackEndOffset() {
return ThreadOffsetFromTlsPtr<pointer_size>(
OFFSETOF_MEMBER(tls_ptr_sized_values, stack_end));
}
template<PointerSize pointer_size>
static constexpr ThreadOffset<pointer_size> JniEnvOffset() {
return ThreadOffsetFromTlsPtr<pointer_size>(
OFFSETOF_MEMBER(tls_ptr_sized_values, jni_env));
}
template<PointerSize pointer_size>
static constexpr ThreadOffset<pointer_size> TopOfManagedStackOffset() {
return ThreadOffsetFromTlsPtr<pointer_size>(
OFFSETOF_MEMBER(tls_ptr_sized_values, managed_stack) +
ManagedStack::TaggedTopQuickFrameOffset());
}
const ManagedStack* GetManagedStack() const {
return &tlsPtr_.managed_stack;
}
// Linked list recording fragments of managed stack.
void PushManagedStackFragment(ManagedStack* fragment) {
tlsPtr_.managed_stack.PushManagedStackFragment(fragment);
}
void PopManagedStackFragment(const ManagedStack& fragment) {
tlsPtr_.managed_stack.PopManagedStackFragment(fragment);
}
ALWAYS_INLINE ShadowFrame* PushShadowFrame(ShadowFrame* new_top_frame);
ALWAYS_INLINE ShadowFrame* PopShadowFrame();
template<PointerSize pointer_size>
static constexpr ThreadOffset<pointer_size> TopShadowFrameOffset() {
return ThreadOffsetFromTlsPtr<pointer_size>(
OFFSETOF_MEMBER(tls_ptr_sized_values, managed_stack) +
ManagedStack::TopShadowFrameOffset());
}
// Is the given object on the quick stack?
bool IsRawObjOnQuickStack(uint8_t* raw_obj) const;
// Is the given obj in one of this thread's JNI transition frames?
bool IsJniTransitionReference(jobject obj) const REQUIRES_SHARED(Locks::mutator_lock_);
// Convert a global (or weak global) jobject into a Object*
ObjPtr<mirror::Object> DecodeGlobalJObject(jobject obj) const
REQUIRES_SHARED(Locks::mutator_lock_);
void HandleScopeVisitRoots(RootVisitor* visitor, uint32_t thread_id)
REQUIRES_SHARED(Locks::mutator_lock_);
BaseHandleScope* GetTopHandleScope() REQUIRES_SHARED(Locks::mutator_lock_) {
return tlsPtr_.top_handle_scope;
}
void PushHandleScope(BaseHandleScope* handle_scope) REQUIRES_SHARED(Locks::mutator_lock_) {
DCHECK_EQ(handle_scope->GetLink(), tlsPtr_.top_handle_scope);
tlsPtr_.top_handle_scope = handle_scope;
}
BaseHandleScope* PopHandleScope() REQUIRES_SHARED(Locks::mutator_lock_) {
BaseHandleScope* handle_scope = tlsPtr_.top_handle_scope;
DCHECK(handle_scope != nullptr);
tlsPtr_.top_handle_scope = tlsPtr_.top_handle_scope->GetLink();
return handle_scope;
}
template<PointerSize pointer_size>
static constexpr ThreadOffset<pointer_size> TopHandleScopeOffset() {
return ThreadOffsetFromTlsPtr<pointer_size>(OFFSETOF_MEMBER(tls_ptr_sized_values,
top_handle_scope));
}
template<PointerSize pointer_size>
static constexpr ThreadOffset<pointer_size> MutatorLockOffset() {
return ThreadOffsetFromTlsPtr<pointer_size>(OFFSETOF_MEMBER(tls_ptr_sized_values,
mutator_lock));
}
template<PointerSize pointer_size>
static constexpr ThreadOffset<pointer_size> HeldMutexOffset(LockLevel level) {
DCHECK_LT(enum_cast<size_t>(level), arraysize(tlsPtr_.held_mutexes));
return ThreadOffsetFromTlsPtr<pointer_size>(OFFSETOF_MEMBER(tls_ptr_sized_values,
held_mutexes[level]));
}
BaseReflectiveHandleScope* GetTopReflectiveHandleScope() {
return tlsPtr_.top_reflective_handle_scope;
}
void PushReflectiveHandleScope(BaseReflectiveHandleScope* scope) {
DCHECK_EQ(scope->GetLink(), tlsPtr_.top_reflective_handle_scope);
DCHECK_EQ(scope->GetThread(), this);
tlsPtr_.top_reflective_handle_scope = scope;
}
BaseReflectiveHandleScope* PopReflectiveHandleScope() {
BaseReflectiveHandleScope* handle_scope = tlsPtr_.top_reflective_handle_scope;
DCHECK(handle_scope != nullptr);
tlsPtr_.top_reflective_handle_scope = tlsPtr_.top_reflective_handle_scope->GetLink();
return handle_scope;
}
bool GetIsGcMarking() const {
DCHECK(gUseReadBarrier);
return tls32_.is_gc_marking;
}
void SetIsGcMarkingAndUpdateEntrypoints(bool is_marking);
bool IsDeoptCheckRequired() const { return tls32_.is_deopt_check_required; }
void SetDeoptCheckRequired(bool flag) { tls32_.is_deopt_check_required = flag; }
bool GetWeakRefAccessEnabled() const; // Only safe for current thread.
void SetWeakRefAccessEnabled(bool enabled) {
DCHECK(gUseReadBarrier);
WeakRefAccessState new_state = enabled ?
WeakRefAccessState::kEnabled : WeakRefAccessState::kDisabled;
tls32_.weak_ref_access_enabled.store(new_state, std::memory_order_release);
}
uint32_t GetDisableThreadFlipCount() const {
return tls32_.disable_thread_flip_count;
}
void IncrementDisableThreadFlipCount() {
++tls32_.disable_thread_flip_count;
}
void DecrementDisableThreadFlipCount() {
DCHECK_GT(tls32_.disable_thread_flip_count, 0U);
--tls32_.disable_thread_flip_count;
}
// Returns true if the thread is a runtime thread (eg from a ThreadPool).
bool IsRuntimeThread() const {
return is_runtime_thread_;
}
void SetIsRuntimeThread(bool is_runtime_thread) {
is_runtime_thread_ = is_runtime_thread;
}
uint32_t CorePlatformApiCookie() {
return core_platform_api_cookie_;
}
void SetCorePlatformApiCookie(uint32_t cookie) {
core_platform_api_cookie_ = cookie;
}
// Returns true if the thread is allowed to load java classes.
bool CanLoadClasses() const;
// Returns the fake exception used to activate deoptimization.
static mirror::Throwable* GetDeoptimizationException() {
// Note that the mirror::Throwable must be aligned to kObjectAlignment or else it cannot be
// represented by ObjPtr.
return reinterpret_cast<mirror::Throwable*>(0x100);
}
// Currently deoptimization invokes verifier which can trigger class loading
// and execute Java code, so there might be nested deoptimizations happening.
// We need to save the ongoing deoptimization shadow frames and return
// values on stacks.
// 'from_code' denotes whether the deoptimization was explicitly made from
// compiled code.
// 'method_type' contains info on whether deoptimization should advance
// dex_pc.
void PushDeoptimizationContext(const JValue& return_value,
bool is_reference,
ObjPtr<mirror::Throwable> exception,
bool from_code,
DeoptimizationMethodType method_type)
REQUIRES_SHARED(Locks::mutator_lock_);
void PopDeoptimizationContext(JValue* result,
ObjPtr<mirror::Throwable>* exception,
bool* from_code,
DeoptimizationMethodType* method_type)
REQUIRES_SHARED(Locks::mutator_lock_);
void AssertHasDeoptimizationContext()
REQUIRES_SHARED(Locks::mutator_lock_);
void PushStackedShadowFrame(ShadowFrame* sf, StackedShadowFrameType type);
ShadowFrame* PopStackedShadowFrame();
ShadowFrame* MaybePopDeoptimizedStackedShadowFrame();
// For debugger, find the shadow frame that corresponds to a frame id.
// Or return null if there is none.
ShadowFrame* FindDebuggerShadowFrame(size_t frame_id)
REQUIRES_SHARED(Locks::mutator_lock_);
// For debugger, find the bool array that keeps track of the updated vreg set
// for a frame id.
bool* GetUpdatedVRegFlags(size_t frame_id) REQUIRES_SHARED(Locks::mutator_lock_);
// For debugger, find the shadow frame that corresponds to a frame id. If
// one doesn't exist yet, create one and track it in frame_id_to_shadow_frame.
ShadowFrame* FindOrCreateDebuggerShadowFrame(size_t frame_id,
uint32_t num_vregs,
ArtMethod* method,
uint32_t dex_pc)
REQUIRES_SHARED(Locks::mutator_lock_);
// Delete the entry that maps from frame_id to shadow_frame.
void RemoveDebuggerShadowFrameMapping(size_t frame_id)
REQUIRES_SHARED(Locks::mutator_lock_);
std::vector<ArtMethod*>* GetStackTraceSample() const {
DCHECK(!IsAotCompiler());
return tlsPtr_.deps_or_stack_trace_sample.stack_trace_sample;
}
void SetStackTraceSample(std::vector<ArtMethod*>* sample) {
DCHECK(!IsAotCompiler());
tlsPtr_.deps_or_stack_trace_sample.stack_trace_sample = sample;
}
verifier::VerifierDeps* GetVerifierDeps() const {
DCHECK(IsAotCompiler());
return tlsPtr_.deps_or_stack_trace_sample.verifier_deps;
}
// It is the responsability of the caller to make sure the verifier_deps
// entry in the thread is cleared before destruction of the actual VerifierDeps
// object, or the thread.
void SetVerifierDeps(verifier::VerifierDeps* verifier_deps) {
DCHECK(IsAotCompiler());
DCHECK(verifier_deps == nullptr || tlsPtr_.deps_or_stack_trace_sample.verifier_deps == nullptr);
tlsPtr_.deps_or_stack_trace_sample.verifier_deps = verifier_deps;
}
uintptr_t* GetMethodTraceBuffer() { return tlsPtr_.method_trace_buffer; }
uintptr_t** GetTraceBufferCurrEntryPtr() { return &tlsPtr_.method_trace_buffer_curr_entry; }
void SetMethodTraceBuffer(uintptr_t* buffer, int init_index) {
tlsPtr_.method_trace_buffer = buffer;
SetMethodTraceBufferCurrentEntry(init_index);
}
void SetMethodTraceBufferCurrentEntry(int index) {
uintptr_t* buffer = tlsPtr_.method_trace_buffer;
if (buffer == nullptr) {
tlsPtr_.method_trace_buffer_curr_entry = nullptr;
} else {
DCHECK(buffer != nullptr);
tlsPtr_.method_trace_buffer_curr_entry = buffer + index;
}
}
void UpdateTlsLowOverheadTraceEntrypoints(LowOverheadTraceType type);
uint64_t GetTraceClockBase() const {
return tls64_.trace_clock_base;
}
void SetTraceClockBase(uint64_t clock_base) {
tls64_.trace_clock_base = clock_base;
}
BaseMutex* GetHeldMutex(LockLevel level) const {
return tlsPtr_.held_mutexes[level];
}
void SetHeldMutex(LockLevel level, BaseMutex* mutex) {
tlsPtr_.held_mutexes[level] = mutex;
}
// Possibly check that no mutexes at level kMonitorLock or above are subsequently acquired.
// Only invoked by the thread itself.
void DisallowPreMonitorMutexes();
// Undo the effect of the previous call. Again only invoked by the thread itself.
void AllowPreMonitorMutexes();
// Read a flag with the given memory order. See mutator_gc_coord.md for memory ordering
// considerations.
bool ReadFlag(ThreadFlag flag, std::memory_order order) const {
return GetStateAndFlags(order).IsFlagSet(flag);
}
void AtomicSetFlag(ThreadFlag flag, std::memory_order order = std::memory_order_seq_cst) {
// Since we discard the returned value, memory_order_release will often suffice.
tls32_.state_and_flags.fetch_or(enum_cast<uint32_t>(flag), order);
}
void AtomicClearFlag(ThreadFlag flag, std::memory_order order = std::memory_order_seq_cst) {
// Since we discard the returned value, memory_order_release will often suffice.
tls32_.state_and_flags.fetch_and(~enum_cast<uint32_t>(flag), order);
}
void ResetQuickAllocEntryPointsForThread();
// Returns the remaining space in the TLAB.
size_t TlabSize() const {
return tlsPtr_.thread_local_end - tlsPtr_.thread_local_pos;
}
// Returns pos offset from start.
size_t GetTlabPosOffset() const {
return tlsPtr_.thread_local_pos - tlsPtr_.thread_local_start;
}
// Returns the remaining space in the TLAB if we were to expand it to maximum capacity.
size_t TlabRemainingCapacity() const {
return tlsPtr_.thread_local_limit - tlsPtr_.thread_local_pos;
}
// Expand the TLAB by a fixed number of bytes. There must be enough capacity to do so.
void ExpandTlab(size_t bytes) {
tlsPtr_.thread_local_end += bytes;
DCHECK_LE(tlsPtr_.thread_local_end, tlsPtr_.thread_local_limit);
}
// Called from Concurrent mark-compact GC to slide the TLAB pointers backwards
// to adjust to post-compact addresses.
void AdjustTlab(size_t slide_bytes);
// Doesn't check that there is room.
mirror::Object* AllocTlab(size_t bytes);
void SetTlab(uint8_t* start, uint8_t* end, uint8_t* limit);
bool HasTlab() const;
void ResetTlab();
uint8_t* GetTlabStart() {
return tlsPtr_.thread_local_start;
}
uint8_t* GetTlabPos() {
return tlsPtr_.thread_local_pos;
}
uint8_t* GetTlabEnd() {
return tlsPtr_.thread_local_end;
}
// Remove the suspend trigger for this thread by making the suspend_trigger_ TLS value
// equal to a valid pointer.
void RemoveSuspendTrigger() {
tlsPtr_.suspend_trigger.store(reinterpret_cast<uintptr_t*>(&tlsPtr_.suspend_trigger),
std::memory_order_relaxed);
}
// Trigger a suspend check by making the suspend_trigger_ TLS value an invalid pointer.
// The next time a suspend check is done, it will load from the value at this address
// and trigger a SIGSEGV.
// Only needed if Runtime::implicit_suspend_checks_ is true. On some platforms, and in the
// interpreter, client code currently just looks at the thread flags directly to determine
// whether we should suspend, so this call is not always necessary.
void TriggerSuspend() { tlsPtr_.suspend_trigger.store(nullptr, std::memory_order_release); }
// Push an object onto the allocation stack.
bool PushOnThreadLocalAllocationStack(mirror::Object* obj)
REQUIRES_SHARED(Locks::mutator_lock_);
// Set the thread local allocation pointers to the given pointers.
void SetThreadLocalAllocationStack(StackReference<mirror::Object>* start,
StackReference<mirror::Object>* end);
// Resets the thread local allocation pointers.
void RevokeThreadLocalAllocationStack();
size_t GetThreadLocalBytesAllocated() const {
return tlsPtr_.thread_local_end - tlsPtr_.thread_local_start;
}
size_t GetThreadLocalObjectsAllocated() const {
return tlsPtr_.thread_local_objects;
}
void* GetRosAllocRun(size_t index) const {
return tlsPtr_.rosalloc_runs[index];
}
void SetRosAllocRun(size_t index, void* run) {
tlsPtr_.rosalloc_runs[index] = run;
}
template <StackType stack_type>
bool ProtectStack(bool fatal_on_error = true);
template <StackType stack_type>
bool UnprotectStack();
uint32_t DecrementForceInterpreterCount() REQUIRES(Locks::thread_list_lock_) {
return --tls32_.force_interpreter_count;
}
uint32_t IncrementForceInterpreterCount() REQUIRES(Locks::thread_list_lock_) {
return ++tls32_.force_interpreter_count;
}
void SetForceInterpreterCount(uint32_t value) REQUIRES(Locks::thread_list_lock_) {
tls32_.force_interpreter_count = value;
}
uint32_t ForceInterpreterCount() const {
return tls32_.force_interpreter_count;
}
bool IsForceInterpreter() const {
return tls32_.force_interpreter_count != 0;
}
bool IncrementMakeVisiblyInitializedCounter() {
tls32_.make_visibly_initialized_counter += 1u;
DCHECK_LE(tls32_.make_visibly_initialized_counter, kMakeVisiblyInitializedCounterTriggerCount);
if (tls32_.make_visibly_initialized_counter == kMakeVisiblyInitializedCounterTriggerCount) {
tls32_.make_visibly_initialized_counter = 0u;
return true;
}
return false;
}
void InitStringEntryPoints();
void ModifyDebugDisallowReadBarrier(int8_t delta) {
if (kCheckDebugDisallowReadBarrierCount) {
debug_disallow_read_barrier_ += delta;
}
}
uint8_t GetDebugDisallowReadBarrierCount() const {
return kCheckDebugDisallowReadBarrierCount ? debug_disallow_read_barrier_ : 0u;
}
// Gets the current TLSData associated with the key or nullptr if there isn't any. Note that users
// do not gain ownership of TLSData and must synchronize with SetCustomTls themselves to prevent
// it from being deleted.
TLSData* GetCustomTLS(const char* key) REQUIRES(!Locks::custom_tls_lock_);
// Sets the tls entry at 'key' to data. The thread takes ownership of the TLSData. The destructor
// will be run when the thread exits or when SetCustomTLS is called again with the same key.
void SetCustomTLS(const char* key, TLSData* data) REQUIRES(!Locks::custom_tls_lock_);
// Returns true if the current thread is the jit sensitive thread.
bool IsJitSensitiveThread() const {
return this == jit_sensitive_thread_;
}
bool IsSystemDaemon() const REQUIRES_SHARED(Locks::mutator_lock_);
// Cause the 'this' thread to abort the process by sending SIGABRT. Thus we should get an
// asynchronous stack trace for 'this' thread, rather than waiting for it to process a
// checkpoint. Useful mostly to discover why a thread isn't responding to a suspend request or
// checkpoint. The caller should "suspend" (in the Java sense) 'thread' before invoking this, so
// 'thread' can't get deallocated before we access it.
NO_RETURN void AbortInThis(const std::string& message);
// Returns true if StrictMode events are traced for the current thread.
static bool IsSensitiveThread() {
if (is_sensitive_thread_hook_ != nullptr) {
return (*is_sensitive_thread_hook_)();
}
return false;
}
// Set to the read barrier marking entrypoints to be non-null.
void SetReadBarrierEntrypoints();
ObjPtr<mirror::Object> CreateCompileTimePeer(const char* name,
bool as_daemon,
jobject thread_group)
REQUIRES_SHARED(Locks::mutator_lock_);
ALWAYS_INLINE InterpreterCache* GetInterpreterCache() {
return &interpreter_cache_;
}
// Clear all thread-local interpreter caches.
//
// Since the caches are keyed by memory pointer to dex instructions, this must be
// called when any dex code is unloaded (before different code gets loaded at the
// same memory location).
//
// If presence of cache entry implies some pre-conditions, this must also be
// called if the pre-conditions might no longer hold true.
static void ClearAllInterpreterCaches();
template<PointerSize pointer_size>
static constexpr ThreadOffset<pointer_size> InterpreterCacheOffset() {
return ThreadOffset<pointer_size>(OFFSETOF_MEMBER(Thread, interpreter_cache_));
}
static constexpr int InterpreterCacheSizeLog2() {
return WhichPowerOf2(InterpreterCache::kSize);
}
static constexpr uint32_t AllThreadFlags() {
return enum_cast<uint32_t>(ThreadFlag::kLastFlag) |
(enum_cast<uint32_t>(ThreadFlag::kLastFlag) - 1u);
}
static constexpr uint32_t SuspendOrCheckpointRequestFlags() {
return enum_cast<uint32_t>(ThreadFlag::kSuspendRequest) |
enum_cast<uint32_t>(ThreadFlag::kCheckpointRequest) |
enum_cast<uint32_t>(ThreadFlag::kEmptyCheckpointRequest);
}
static constexpr uint32_t FlipFunctionFlags() {
return enum_cast<uint32_t>(ThreadFlag::kPendingFlipFunction) |
enum_cast<uint32_t>(ThreadFlag::kRunningFlipFunction);
}
static constexpr uint32_t StoredThreadStateValue(ThreadState state) {
return StateAndFlags::EncodeState(state);
}
void ResetSharedMethodHotness() {
tls32_.shared_method_hotness = kSharedMethodHotnessThreshold;
}
uint32_t GetSharedMethodHotness() const {
return tls32_.shared_method_hotness;
}
uint32_t DecrementSharedMethodHotness() {
tls32_.shared_method_hotness = (tls32_.shared_method_hotness - 1) & 0xffff;
return tls32_.shared_method_hotness;
}
private:
// We pretend to acquire this while running a checkpoint to detect lock ordering issues.
// Initialized lazily.
static std::atomic<Mutex*> cp_placeholder_mutex_;
explicit Thread(bool daemon);
// A successfully started thread is only deleted by the thread itself.
// Threads are deleted after they have been removed from the thread list while holding
// suspend_count_lock_ and thread_list_lock_. We refuse to do this while either kSuspendRequest
// or kRunningFlipFunction are set. We can prevent Thread destruction by holding either of those
// locks, ensuring that either of those flags are set, or possibly by registering and checking a
// ThreadExitFlag.
~Thread() REQUIRES(!Locks::mutator_lock_, !Locks::thread_suspend_count_lock_);
// Thread destruction actions that do not invalidate the thread. Checkpoints and flip_functions
// may still be called on this Thread object, though not by this thread, during and after the
// Destroy() call.
void Destroy(bool should_run_callbacks);
// Deletes and clears the tlsPtr_.jpeer field. Done in a way so that both it and opeer cannot be
// observed to be set at the same time by instrumentation.
void DeleteJPeer(JNIEnv* env);
// Attaches the calling native thread to the runtime, returning the new native peer.
// Used to implement JNI AttachCurrentThread and AttachCurrentThreadAsDaemon calls.
template <typename PeerAction>
static Thread* Attach(const char* thread_name,
bool as_daemon,
PeerAction p,
bool should_run_callbacks);
void CreatePeer(const char* name, bool as_daemon, jobject thread_group);
template<bool kTransactionActive>
static void InitPeer(ObjPtr<mirror::Object> peer,
bool as_daemon,
ObjPtr<mirror::Object> thread_group,
ObjPtr<mirror::String> thread_name,
jint thread_priority)
REQUIRES_SHARED(Locks::mutator_lock_);
// Avoid use, callers should use SetState.
// Used only by `Thread` destructor and stack trace collection in semi-space GC (currently
// disabled by `kStoreStackTraces = false`). May not be called on a runnable thread other
// than Thread::Current().
// NO_THREAD_SAFETY_ANALYSIS: This function is "Unsafe" and can be called in
// different states, so clang cannot perform the thread safety analysis.
ThreadState SetStateUnsafe(ThreadState new_state) NO_THREAD_SAFETY_ANALYSIS {
StateAndFlags old_state_and_flags = GetStateAndFlags(std::memory_order_relaxed);
ThreadState old_state = old_state_and_flags.GetState();
if (old_state == new_state) {
// Nothing to do.
} else if (old_state == ThreadState::kRunnable) {
DCHECK_EQ(this, Thread::Current());
// Need to run pending checkpoint and suspend barriers. Run checkpoints in runnable state in
// case they need to use a ScopedObjectAccess. If we are holding the mutator lock and a SOA
// attempts to TransitionFromSuspendedToRunnable, it results in a deadlock.
TransitionToSuspendedAndRunCheckpoints(new_state);
// Since we transitioned to a suspended state, check the pass barrier requests.
CheckActiveSuspendBarriers();
} else {
while (true) {
StateAndFlags new_state_and_flags = old_state_and_flags;
new_state_and_flags.SetState(new_state);
if (LIKELY(tls32_.state_and_flags.CompareAndSetWeakAcquire(
old_state_and_flags.GetValue(), new_state_and_flags.GetValue()))) {
break;
}
// Reload state and flags.
old_state_and_flags = GetStateAndFlags(std::memory_order_relaxed);
DCHECK_EQ(old_state, old_state_and_flags.GetState());
}
}
return old_state;
}
MutatorMutex* GetMutatorLock() RETURN_CAPABILITY(Locks::mutator_lock_) {
DCHECK_EQ(tlsPtr_.mutator_lock, Locks::mutator_lock_);
return tlsPtr_.mutator_lock;
}
void VerifyStackImpl() REQUIRES_SHARED(Locks::mutator_lock_);
void DumpState(std::ostream& os) const REQUIRES_SHARED(Locks::mutator_lock_);
DumpOrder DumpStack(std::ostream& os,
bool dump_native_stack = true,
bool force_dump_stack = false) const
REQUIRES_SHARED(Locks::mutator_lock_);
DumpOrder DumpStack(std::ostream& os,
unwindstack::AndroidLocalUnwinder& unwinder,
bool dump_native_stack = true,
bool force_dump_stack = false) const
REQUIRES_SHARED(Locks::mutator_lock_);
// Out-of-line conveniences for debugging in gdb.
static Thread* CurrentFromGdb(); // Like Thread::Current.
// Like Thread::Dump(std::cerr).
void DumpFromGdb() const REQUIRES_SHARED(Locks::mutator_lock_);
// A wrapper around CreateCallback used when userfaultfd GC is used to
// identify the GC by stacktrace.
static NO_INLINE void* CreateCallbackWithUffdGc(void* arg);
static void* CreateCallback(void* arg);
void HandleUncaughtExceptions() REQUIRES_SHARED(Locks::mutator_lock_);
void RemoveFromThreadGroup() REQUIRES_SHARED(Locks::mutator_lock_);
// Initialize a thread.
//
// The third parameter is not mandatory. If given, the thread will use this JNIEnvExt. In case
// Init succeeds, this means the thread takes ownership of it. If Init fails, it is the caller's
// responsibility to destroy the given JNIEnvExt. If the parameter is null, Init will try to
// create a JNIEnvExt on its own (and potentially fail at that stage, indicated by a return value
// of false).
bool Init(ThreadList*, JavaVMExt*, JNIEnvExt* jni_env_ext = nullptr)
REQUIRES(Locks::runtime_shutdown_lock_);
void InitCardTable();
void InitCpu();
void CleanupCpu();
void InitTlsEntryPoints();
void InitTid();
void InitPthreadKeySelf();
template <StackType stack_type>
bool InitStack(uint8_t* read_stack_base, size_t read_stack_size, size_t read_guard_size);
void SetUpAlternateSignalStack();
void TearDownAlternateSignalStack();
void MadviseAwayAlternateSignalStack();
ALWAYS_INLINE void TransitionToSuspendedAndRunCheckpoints(ThreadState new_state)
REQUIRES(!Locks::thread_suspend_count_lock_, !Roles::uninterruptible_)
REQUIRES_SHARED(Locks::mutator_lock_);
// Call PassActiveSuspendBarriers() if there are active barriers. Only called on current thread.
ALWAYS_INLINE void CheckActiveSuspendBarriers()
REQUIRES(!Locks::thread_suspend_count_lock_, !Locks::mutator_lock_, !Roles::uninterruptible_);
// Decrement all "suspend barriers" for the current thread, notifying threads that requested our
// suspension. Only called on current thread, when suspended. If suspend_count_ > 0 then we
// promise that we are and will remain "suspended" until the suspend count is decremented.
bool PassActiveSuspendBarriers()
REQUIRES(!Locks::thread_suspend_count_lock_, !Locks::mutator_lock_);
// Add an entry to active_suspend1_barriers.
ALWAYS_INLINE void AddSuspend1Barrier(WrappedSuspend1Barrier* suspend1_barrier)
REQUIRES(Locks::thread_suspend_count_lock_);
// Remove last-added entry from active_suspend1_barriers.
// Only makes sense if we're still holding thread_suspend_count_lock_ since insertion.
// We redundantly pass in the barrier to be removed in order to enable a DCHECK.
ALWAYS_INLINE void RemoveFirstSuspend1Barrier(WrappedSuspend1Barrier* suspend1_barrier)
REQUIRES(Locks::thread_suspend_count_lock_);
// Remove the "barrier" from the list no matter where it appears. Called only under exceptional
// circumstances. The barrier must be in the list.
ALWAYS_INLINE void RemoveSuspend1Barrier(WrappedSuspend1Barrier* suspend1_barrier)
REQUIRES(Locks::thread_suspend_count_lock_);
ALWAYS_INLINE bool HasActiveSuspendBarrier() REQUIRES(Locks::thread_suspend_count_lock_);
// CHECK that the given barrier is no longer on our list.
ALWAYS_INLINE void CheckBarrierInactive(WrappedSuspend1Barrier* suspend1_barrier)
REQUIRES(Locks::thread_suspend_count_lock_);
// Registers the current thread as the jit sensitive thread. Should be called just once.
static void SetJitSensitiveThread() {
if (jit_sensitive_thread_ == nullptr) {
jit_sensitive_thread_ = Thread::Current();
} else {
LOG(WARNING) << "Attempt to set the sensitive thread twice. Tid:"
<< Thread::Current()->GetTid();
}
}
static void SetSensitiveThreadHook(bool (*is_sensitive_thread_hook)()) {
is_sensitive_thread_hook_ = is_sensitive_thread_hook;
}
// Runs a single checkpoint function. If there are no more pending checkpoint functions it will
// clear the kCheckpointRequest flag. The caller is responsible for calling this in a loop until
// the kCheckpointRequest flag is cleared.
void RunCheckpointFunction()
REQUIRES(!Locks::thread_suspend_count_lock_)
REQUIRES_SHARED(Locks::mutator_lock_);
void RunEmptyCheckpoint();
// Return the nearest page-aligned address below the current stack top.
template <StackType>
NO_INLINE uint8_t* FindStackTop();
// Install the protected region for implicit stack checks.
template <StackType>
void InstallImplicitProtection();
template <bool kPrecise>
void VisitRoots(RootVisitor* visitor) REQUIRES_SHARED(Locks::mutator_lock_);
static bool IsAotCompiler();
void SetCachedThreadName(const char* name);
// Helper functions to get/set the tls stack pointer variables.
template <StackType stack_type>
ALWAYS_INLINE void SetStackEnd(uint8_t* new_stack_end);
template <StackType stack_type>
ALWAYS_INLINE uint8_t* GetStackBegin() const;
template <StackType stack_type>
ALWAYS_INLINE void SetStackBegin(uint8_t* new_stack_begin);
template <StackType stack_type>
ALWAYS_INLINE size_t GetStackSize() const;
template <StackType stack_type>
ALWAYS_INLINE void SetStackSize(size_t new_stack_size);
// Helper class for manipulating the 32 bits of atomically changed state and flags.
class StateAndFlags {
public:
explicit StateAndFlags(uint32_t value) :value_(value) {}
uint32_t GetValue() const {
return value_;
}
void SetValue(uint32_t value) {
value_ = value;
}
bool IsAnyOfFlagsSet(uint32_t flags) const {
DCHECK_EQ(flags & ~AllThreadFlags(), 0u);
return (value_ & flags) != 0u;
}
bool IsFlagSet(ThreadFlag flag) const {
return (value_ & enum_cast<uint32_t>(flag)) != 0u;
}
void SetFlag(ThreadFlag flag) {
value_ |= enum_cast<uint32_t>(flag);
}
StateAndFlags WithFlag(ThreadFlag flag) const {
StateAndFlags result = *this;
result.SetFlag(flag);
return result;
}
StateAndFlags WithoutFlag(ThreadFlag flag) const {
StateAndFlags result = *this;
result.ClearFlag(flag);
return result;
}
void ClearFlag(ThreadFlag flag) {
value_ &= ~enum_cast<uint32_t>(flag);
}
ThreadState GetState() const {
ThreadState state = ThreadStateField::Decode(value_);
ValidateThreadState(state);
return state;
}
void SetState(ThreadState state) {
ValidateThreadState(state);
value_ = ThreadStateField::Update(state, value_);
}
StateAndFlags WithState(ThreadState state) const {
StateAndFlags result = *this;
result.SetState(state);
return result;
}
static constexpr uint32_t EncodeState(ThreadState state) {
ValidateThreadState(state);
return ThreadStateField::Encode(state);
}
static constexpr void ValidateThreadState(ThreadState state) {
if (kIsDebugBuild && state != ThreadState::kRunnable) {
CHECK_GE(state, ThreadState::kTerminated);
CHECK_LE(state, ThreadState::kSuspended);
CHECK_NE(state, ThreadState::kObsoleteRunnable);
}
}
// The value holds thread flags and thread state.
uint32_t value_;
static constexpr size_t kThreadStateBitSize = BitSizeOf<std::underlying_type_t<ThreadState>>();
static constexpr size_t kThreadStatePosition = BitSizeOf<uint32_t>() - kThreadStateBitSize;
using ThreadStateField = BitField<ThreadState, kThreadStatePosition, kThreadStateBitSize>;
static_assert(
WhichPowerOf2(enum_cast<uint32_t>(ThreadFlag::kLastFlag)) < kThreadStatePosition);
};
static_assert(sizeof(StateAndFlags) == sizeof(uint32_t), "Unexpected StateAndFlags size");
StateAndFlags GetStateAndFlags(std::memory_order order) const {
return StateAndFlags(tls32_.state_and_flags.load(order));
}
// Format state and flags as a hex string. For diagnostic output.
std::string StateAndFlagsAsHexString() const;
// Run the flip function and notify other threads that may have tried
// to do that concurrently.
void RunFlipFunction(Thread* self) REQUIRES_SHARED(Locks::mutator_lock_);
// Ensure that thread flip function for thread target started running. If no other thread is
// executing it, the calling thread shall run the flip function and then notify other threads
// that have tried to do that concurrently. After this function returns, the
// `ThreadFlag::kPendingFlipFunction` is cleared but another thread may still be running the
// flip function as indicated by the `ThreadFlag::kRunningFlipFunction`. Optional arguments:
// - old_state_and_flags indicates the current and state and flags value for the thread, with
// at least kPendingFlipFunction set. The thread should logically acquire the
// mutator lock before running the flip function. A special zero value indicates that the
// thread already holds the mutator lock, and the actual state_and_flags must be read.
// A non-zero value implies this == Current().
// - If tef is non-null, we check that the target thread has not yet exited, as indicated by
// tef. In that case, we acquire thread_list_lock_ as needed.
// - If finished is non-null, we assign to *finished to indicate whether the flip was known to
// be completed when we returned.
// Returns true if and only if we acquired the mutator lock (which implies that we ran the flip
// function after finding old_state_and_flags unchanged).
static bool EnsureFlipFunctionStarted(Thread* self,
Thread* target,
StateAndFlags old_state_and_flags = StateAndFlags(0),
ThreadExitFlag* tef = nullptr,
/*out*/ bool* finished = nullptr)
REQUIRES(!Locks::thread_list_lock_) TRY_ACQUIRE_SHARED(true, Locks::mutator_lock_);
static void ThreadExitCallback(void* arg);
// Maximum number of suspend barriers.
static constexpr uint32_t kMaxSuspendBarriers = 3;
// Has Thread::Startup been called?
static bool is_started_;
// TLS key used to retrieve the Thread*.
static pthread_key_t pthread_key_self_;
// Used to notify threads that they should attempt to resume, they will suspend again if
// their suspend count is > 0.
static ConditionVariable* resume_cond_ GUARDED_BY(Locks::thread_suspend_count_lock_);
// Hook passed by framework which returns true
// when StrictMode events are traced for the current thread.
static bool (*is_sensitive_thread_hook_)();
// Stores the jit sensitive thread (which for now is the UI thread).
static Thread* jit_sensitive_thread_;
static constexpr uint32_t kMakeVisiblyInitializedCounterTriggerCount = 128;
/***********************************************************************************************/
// Thread local storage. Fields are grouped by size to enable 32 <-> 64 searching to account for
// pointer size differences. To encourage shorter encoding, more frequently used values appear
// first if possible.
/***********************************************************************************************/
struct alignas(4) tls_32bit_sized_values {
// We have no control over the size of 'bool', but want our boolean fields
// to be 4-byte quantities.
using bool32_t = uint32_t;
explicit tls_32bit_sized_values(bool is_daemon)
: state_and_flags(0u),
suspend_count(0),
thin_lock_thread_id(0),
tid(0),
daemon(is_daemon),
throwing_OutOfMemoryError(false),
no_thread_suspension(0),
thread_exit_check_count(0),
is_gc_marking(false),
is_deopt_check_required(false),
weak_ref_access_enabled(WeakRefAccessState::kVisiblyEnabled),
disable_thread_flip_count(0),
user_code_suspend_count(0),
force_interpreter_count(0),
make_visibly_initialized_counter(0),
define_class_counter(0),
num_name_readers(0),
shared_method_hotness(kSharedMethodHotnessThreshold) {}
// The state and flags field must be changed atomically so that flag values aren't lost.
// See `StateAndFlags` for bit assignments of `ThreadFlag` and `ThreadState` values.
// Keeping the state and flags together allows an atomic CAS to change from being
// Suspended to Runnable without a suspend request occurring.
Atomic<uint32_t> state_and_flags;
static_assert(sizeof(state_and_flags) == sizeof(uint32_t),
"Size of state_and_flags and uint32 are different");
// A non-zero value is used to tell the current thread to enter a safe point
// at the next poll.
int suspend_count GUARDED_BY(Locks::thread_suspend_count_lock_);
// Thin lock thread id. This is a small integer used by the thin lock implementation.
// This is not to be confused with the native thread's tid, nor is it the value returned
// by java.lang.Thread.getId --- this is a distinct value, used only for locking. One
// important difference between this id and the ids visible to managed code is that these
// ones get reused (to ensure that they fit in the number of bits available).
uint32_t thin_lock_thread_id;
// System thread id.
uint32_t tid;
// Is the thread a daemon?
const bool32_t daemon;
// A boolean telling us whether we're recursively throwing OOME.
bool32_t throwing_OutOfMemoryError;
// A positive value implies we're in a region where thread suspension isn't expected.
uint32_t no_thread_suspension;
// How many times has our pthread key's destructor been called?
uint32_t thread_exit_check_count;
// True if the GC is in the marking phase. This is used for the CC collector only. This is
// thread local so that we can simplify the logic to check for the fast path of read barriers of
// GC roots.
bool32_t is_gc_marking;
// True if we need to check for deoptimization when returning from the runtime functions. This
// is required only when a class is redefined to prevent executing code that has field offsets
// embedded. For non-debuggable apps redefinition is not allowed and this flag should always be
// set to false.
bool32_t is_deopt_check_required;
// Thread "interrupted" status; stays raised until queried or thrown.
Atomic<bool32_t> interrupted;
AtomicInteger park_state_;
// Determines whether the thread is allowed to directly access a weak ref
// (Reference::GetReferent() and system weaks) and to potentially mark an object alive/gray.
// This is used for concurrent reference processing of the CC collector only. This is thread
// local so that we can enable/disable weak ref access by using a checkpoint and avoid a race
// around the time weak ref access gets disabled and concurrent reference processing begins
// (if weak ref access is disabled during a pause, this is not an issue.) Other collectors use
// Runtime::DisallowNewSystemWeaks() and ReferenceProcessor::EnableSlowPath(). Can be
// concurrently accessed by GetReferent() and set (by iterating over threads).
// Can be changed from kEnabled to kVisiblyEnabled by readers. No other concurrent access is
// possible when that happens.
mutable std::atomic<WeakRefAccessState> weak_ref_access_enabled;
// A thread local version of Heap::disable_thread_flip_count_. This keeps track of how many
// levels of (nested) JNI critical sections the thread is in and is used to detect a nested JNI
// critical section enter.
uint32_t disable_thread_flip_count;
// How much of 'suspend_count_' is by request of user code, used to distinguish threads
// suspended by the runtime from those suspended by user code.
// This should have GUARDED_BY(Locks::user_code_suspension_lock_) but auto analysis cannot be
// told that AssertHeld should be good enough.
int user_code_suspend_count GUARDED_BY(Locks::thread_suspend_count_lock_);
// Count of how many times this thread has been forced to interpreter. If this is not 0 the
// thread must remain in interpreted code as much as possible.
uint32_t force_interpreter_count;
// Counter for calls to initialize a class that's initialized but not visibly initialized.
// When this reaches kMakeVisiblyInitializedCounterTriggerCount, we call the runtime to
// make initialized classes visibly initialized. This is needed because we usually make
// classes visibly initialized in batches but we do not want to be stuck with a class
// initialized but not visibly initialized for a long time even if no more classes are
// being initialized anymore.
uint32_t make_visibly_initialized_counter;
// Counter for how many nested define-classes are ongoing in this thread. Used to allow waiting
// for threads to be done with class-definition work.
uint32_t define_class_counter;
// A count of the number of readers of tlsPtr_.name that may still be looking at a string they
// retrieved.
mutable std::atomic<uint32_t> num_name_readers;
static_assert(std::atomic<uint32_t>::is_always_lock_free);
// Thread-local hotness counter for shared memory methods. Initialized with
// `kSharedMethodHotnessThreshold`. The interpreter decrements it and goes
// into the runtime when hitting zero. Note that all previous decrements
// could have been executed by another method than the one seeing zero.
// There is a second level counter in `Jit::shared_method_counters_` to make
// sure we at least have a few samples before compiling a method.
uint32_t shared_method_hotness;
} tls32_;
struct alignas(8) tls_64bit_sized_values {
tls_64bit_sized_values() : trace_clock_base(0) {
}
// The clock base used for tracing.
uint64_t trace_clock_base;
RuntimeStats stats;
} tls64_;
struct alignas(sizeof(void*)) tls_ptr_sized_values {
tls_ptr_sized_values() : card_table(nullptr),
exception(nullptr),
stack_end(nullptr),
managed_stack(),
suspend_trigger(nullptr),
jni_env(nullptr),
tmp_jni_env(nullptr),
self(nullptr),
opeer(nullptr),
jpeer(nullptr),
stack_begin(nullptr),
stack_size(0),
deps_or_stack_trace_sample(),
wait_next(nullptr),
monitor_enter_object(nullptr),
top_handle_scope(nullptr),
class_loader_override(nullptr),
stacked_shadow_frame_record(nullptr),
deoptimization_context_stack(nullptr),
frame_id_to_shadow_frame(nullptr),
name(nullptr),
pthread_self(0),
active_suspendall_barrier(nullptr),
active_suspend1_barriers(nullptr),
thread_local_pos(nullptr),
thread_local_end(nullptr),
thread_local_start(nullptr),
thread_local_limit(nullptr),
thread_local_objects(0),
checkpoint_function(nullptr),
thread_local_alloc_stack_top(nullptr),
thread_local_alloc_stack_end(nullptr),
mutator_lock(nullptr),
flip_function(nullptr),
thread_local_mark_stack(nullptr),
async_exception(nullptr),
top_reflective_handle_scope(nullptr),
method_trace_buffer(nullptr),
method_trace_buffer_curr_entry(nullptr),
thread_exit_flags(nullptr),
last_no_thread_suspension_cause(nullptr),
last_no_transaction_checks_cause(nullptr) {
std::fill(held_mutexes, held_mutexes + kLockLevelCount, nullptr);
}
// The biased card table, see CardTable for details.
uint8_t* card_table;
// The pending exception or null.
mirror::Throwable* exception;
// The end of this thread's stack. This is the lowest safely-addressable address on the stack.
// We leave extra space so there's room for the code that throws StackOverflowError.
// Note: do not use directly, instead use GetStackEnd/SetStackEnd template function instead.
uint8_t* stack_end;
// The top of the managed stack often manipulated directly by compiler generated code.
ManagedStack managed_stack;
// In certain modes, setting this to 0 will trigger a SEGV and thus a suspend check. It is
// normally set to the address of itself. It should be cleared with release semantics to ensure
// that prior state changes etc. are visible to any thread that faults as a result.
// We assume that the kernel ensures that such changes are then visible to the faulting
// thread, even if it is not an acquire load that faults. (Indeed, it seems unlikely that the
// ordering semantics associated with the faulting load has any impact.)
std::atomic<uintptr_t*> suspend_trigger;
// Every thread may have an associated JNI environment
JNIEnvExt* jni_env;
// Temporary storage to transfer a pre-allocated JNIEnvExt from the creating thread to the
// created thread.
JNIEnvExt* tmp_jni_env;
// Initialized to "this". On certain architectures (such as x86) reading off of Thread::Current
// is easy but getting the address of Thread::Current is hard. This field can be read off of
// Thread::Current to give the address.
Thread* self;
// Our managed peer (an instance of java.lang.Thread). The jobject version is used during thread
// start up, until the thread is registered and the local opeer_ is used.
mirror::Object* opeer;
jobject jpeer;
// The "lowest addressable byte" of the stack.
// Note: do not use directly, instead use GetStackBegin/SetStackBegin template function instead.
uint8_t* stack_begin;
// Size of the stack.
// Note: do not use directly, instead use GetStackSize/SetStackSize template function instead.
size_t stack_size;
// Sampling profiler and AOT verification cannot happen on the same run, so we share
// the same entry for the stack trace and the verifier deps.
union DepsOrStackTraceSample {
DepsOrStackTraceSample() {
verifier_deps = nullptr;
stack_trace_sample = nullptr;
}
// Pointer to previous stack trace captured by sampling profiler.
std::vector<ArtMethod*>* stack_trace_sample;
// When doing AOT verification, per-thread VerifierDeps.
verifier::VerifierDeps* verifier_deps;
} deps_or_stack_trace_sample;
// The next thread in the wait set this thread is part of or null if not waiting.
Thread* wait_next;
// If we're blocked in MonitorEnter, this is the object we're trying to lock.
mirror::Object* monitor_enter_object;
// Top of linked list of handle scopes or null for none.
BaseHandleScope* top_handle_scope;
// Needed to get the right ClassLoader in JNI_OnLoad, but also
// useful for testing.
jobject class_loader_override;
// For gc purpose, a shadow frame record stack that keeps track of:
// 1) shadow frames under construction.
// 2) deoptimization shadow frames.
StackedShadowFrameRecord* stacked_shadow_frame_record;
// Deoptimization return value record stack.
DeoptimizationContextRecord* deoptimization_context_stack;
// For debugger, a linked list that keeps the mapping from frame_id to shadow frame.
// Shadow frames may be created before deoptimization happens so that the debugger can
// set local values there first.
FrameIdToShadowFrame* frame_id_to_shadow_frame;
// A cached copy of the java.lang.Thread's (modified UTF-8) name.
// If this is not null or kThreadNameDuringStartup, then it owns the malloc memory holding
// the string. Updated in an RCU-like manner.
std::atomic<const char*> name;
static_assert(std::atomic<const char*>::is_always_lock_free);
// A cached pthread_t for the pthread underlying this Thread*.
pthread_t pthread_self;
// After a thread observes a suspend request and enters a suspended state,
// it notifies the requestor by arriving at a "suspend barrier". This consists of decrementing
// the atomic integer representing the barrier. (This implementation was introduced in 2015 to
// minimize cost. There may be other options.) These atomic integer barriers are always
// stored on the requesting thread's stack. They are referenced from the target thread's
// data structure in one of two ways; in either case the data structure referring to these
// barriers is guarded by suspend_count_lock:
// 1. A SuspendAll barrier is directly referenced from the target thread. Only one of these
// can be active at a time:
AtomicInteger* active_suspendall_barrier GUARDED_BY(Locks::thread_suspend_count_lock_);
// 2. For individual thread suspensions, active barriers are embedded in a struct that is used
// to link together all suspend requests for this thread. Unlike the SuspendAll case, each
// barrier is referenced by a single target thread, and thus can appear only on a single list.
// The struct as a whole is still stored on the requesting thread's stack.
WrappedSuspend1Barrier* active_suspend1_barriers GUARDED_BY(Locks::thread_suspend_count_lock_);
// thread_local_pos and thread_local_end must be consecutive for ldrd and are 8 byte aligned for
// potentially better performance.
uint8_t* thread_local_pos;
uint8_t* thread_local_end;
// Thread-local allocation pointer. Can be moved above the preceding two to correct alignment.
uint8_t* thread_local_start;
// Thread local limit is how much we can expand the thread local buffer to, it is greater or
// equal to thread_local_end.
uint8_t* thread_local_limit;
size_t thread_local_objects;
// Pending checkpoint function or null if non-pending. If this checkpoint is set and someone
// requests another checkpoint, it goes to the checkpoint overflow list.
Closure* checkpoint_function GUARDED_BY(Locks::thread_suspend_count_lock_);
// Entrypoint function pointers.
// TODO: move this to more of a global offset table model to avoid per-thread duplication.
JniEntryPoints jni_entrypoints;
QuickEntryPoints quick_entrypoints;
// There are RosAlloc::kNumThreadLocalSizeBrackets thread-local size brackets per thread.
void* rosalloc_runs[kNumRosAllocThreadLocalSizeBracketsInThread];
// Thread-local allocation stack data/routines.
StackReference<mirror::Object>* thread_local_alloc_stack_top;
StackReference<mirror::Object>* thread_local_alloc_stack_end;
// Pointer to the mutator lock.
// This is the same as `Locks::mutator_lock_` but cached for faster state transitions.
MutatorMutex* mutator_lock;
// Support for Mutex lock hierarchy bug detection.
BaseMutex* held_mutexes[kLockLevelCount];
// The function used for thread flip. Set while holding Locks::thread_suspend_count_lock_ and
// with all other threads suspended. May be cleared while being read.
std::atomic<Closure*> flip_function;
union {
// Thread-local mark stack for the concurrent copying collector.
gc::accounting::AtomicStack<mirror::Object>* thread_local_mark_stack;
// Thread-local page-sized buffer for userfaultfd GC.
uint8_t* thread_local_gc_buffer;
};
// The pending async-exception or null.
mirror::Throwable* async_exception;
// Top of the linked-list for reflective-handle scopes or null if none.
BaseReflectiveHandleScope* top_reflective_handle_scope;
// Pointer to a thread-local buffer for method tracing.
uintptr_t* method_trace_buffer;
// Pointer to the current entry in the buffer.
uintptr_t* method_trace_buffer_curr_entry;
// Pointer to the first node of an intrusively doubly-linked list of ThreadExitFlags.
ThreadExitFlag* thread_exit_flags GUARDED_BY(Locks::thread_list_lock_);
// If no_thread_suspension_ is > 0, what is causing that assertion.
const char* last_no_thread_suspension_cause;
// If the thread is asserting that there should be no transaction checks,
// what is causing that assertion (debug builds only).
const char* last_no_transaction_checks_cause;
} tlsPtr_;
// Small thread-local cache to be used from the interpreter.
// It is keyed by dex instruction pointer.
// The value is opcode-depended (e.g. field offset).
InterpreterCache interpreter_cache_;
// All fields below this line should not be accessed by native code. This means these fields can
// be modified, rearranged, added or removed without having to modify asm_support.h
// Guards the 'wait_monitor_' members.
Mutex* wait_mutex_ DEFAULT_MUTEX_ACQUIRED_AFTER;
// Condition variable waited upon during a wait.
ConditionVariable* wait_cond_ GUARDED_BY(wait_mutex_);
// Pointer to the monitor lock we're currently waiting on or null if not waiting.
Monitor* wait_monitor_ GUARDED_BY(wait_mutex_);
// Debug disable read barrier count, only is checked for debug builds and only in the runtime.
uint8_t debug_disallow_read_barrier_ = 0;
// Counters used only for debugging and error reporting. Likely to wrap. Small to avoid
// increasing Thread size.
// We currently maintain these unconditionally, since it doesn't cost much, and we seem to have
// persistent issues with suspension timeouts, which these should help to diagnose.
// TODO: Reconsider this.
std::atomic<uint8_t> suspended_count_ = 0; // Number of times we entered a suspended state after
// running checkpoints.
std::atomic<uint8_t> checkpoint_count_ = 0; // Number of checkpoints we started running.
// Note that it is not in the packed struct, may not be accessed for cross compilation.
uintptr_t poison_object_cookie_ = 0;
// Pending extra checkpoints if checkpoint_function_ is already used.
std::list<Closure*> checkpoint_overflow_ GUARDED_BY(Locks::thread_suspend_count_lock_);
// Custom TLS field that can be used by plugins or the runtime. Should not be accessed directly by
// compiled code or entrypoints.
SafeMap<std::string, std::unique_ptr<TLSData>, std::less<>> custom_tls_
GUARDED_BY(Locks::custom_tls_lock_);
#if !defined(__BIONIC__)
#if !defined(ANDROID_HOST_MUSL)
__attribute__((tls_model("initial-exec")))
#endif
static thread_local Thread* self_tls_;
#endif
// True if the thread is some form of runtime thread (ex, GC or JIT).
bool is_runtime_thread_;
// Set during execution of JNI methods that get field and method id's as part of determining if
// the caller is allowed to access all fields and methods in the Core Platform API.
uint32_t core_platform_api_cookie_ = 0;
friend class gc::collector::SemiSpace; // For getting stack traces.
friend class Runtime; // For CreatePeer.
friend class QuickExceptionHandler; // For dumping the stack.
friend class ScopedAssertNoTransactionChecks;
friend class ScopedThreadStateChange;
friend class StubTest; // For accessing entrypoints.
friend class ThreadList; // For ~Thread, Destroy and EnsureFlipFunctionStarted.
friend class EntrypointsOrderTest; // To test the order of tls entries.
friend class JniCompilerTest; // For intercepting JNI entrypoint calls.
DISALLOW_COPY_AND_ASSIGN(Thread);
};
class SCOPED_CAPABILITY ScopedAssertNoThreadSuspension {
public:
ALWAYS_INLINE ScopedAssertNoThreadSuspension(const char* cause,
bool enabled = true)
ACQUIRE(Roles::uninterruptible_)
: enabled_(enabled) {
if (!enabled_) {
return;
}
if (kIsDebugBuild) {
self_ = Thread::Current();
old_cause_ = self_->StartAssertNoThreadSuspension(cause);
} else {
Roles::uninterruptible_.Acquire(); // No-op.
}
}
ALWAYS_INLINE ~ScopedAssertNoThreadSuspension() RELEASE(Roles::uninterruptible_) {
if (!enabled_) {
return;
}
if (kIsDebugBuild) {
self_->EndAssertNoThreadSuspension(old_cause_);
} else {
Roles::uninterruptible_.Release(); // No-op.
}
}
private:
Thread* self_;
const bool enabled_;
const char* old_cause_;
};
class ScopedAllowThreadSuspension {
public:
ALWAYS_INLINE ScopedAllowThreadSuspension() RELEASE(Roles::uninterruptible_) {
if (kIsDebugBuild) {
self_ = Thread::Current();
old_cause_ = self_->EndAssertNoThreadSuspension();
} else {
Roles::uninterruptible_.Release(); // No-op.
}
}
ALWAYS_INLINE ~ScopedAllowThreadSuspension() ACQUIRE(Roles::uninterruptible_) {
if (kIsDebugBuild) {
CHECK(self_->StartAssertNoThreadSuspension(old_cause_) == nullptr);
} else {
Roles::uninterruptible_.Acquire(); // No-op.
}
}
private:
Thread* self_;
const char* old_cause_;
};
class ScopedStackedShadowFramePusher {
public:
ScopedStackedShadowFramePusher(Thread* self, ShadowFrame* sf) : self_(self), sf_(sf) {
DCHECK_EQ(sf->GetLink(), nullptr);
self_->PushStackedShadowFrame(sf, StackedShadowFrameType::kShadowFrameUnderConstruction);
}
~ScopedStackedShadowFramePusher() {
ShadowFrame* sf = self_->PopStackedShadowFrame();
DCHECK_EQ(sf, sf_);
}
private:
Thread* const self_;
ShadowFrame* const sf_;
DISALLOW_COPY_AND_ASSIGN(ScopedStackedShadowFramePusher);
};
// Only works for debug builds.
class ScopedDebugDisallowReadBarriers {
public:
explicit ScopedDebugDisallowReadBarriers(Thread* self) : self_(self) {
self_->ModifyDebugDisallowReadBarrier(1);
}
~ScopedDebugDisallowReadBarriers() {
self_->ModifyDebugDisallowReadBarrier(-1);
}
private:
Thread* const self_;
};
class ThreadLifecycleCallback {
public:
virtual ~ThreadLifecycleCallback() {}
virtual void ThreadStart(Thread* self) REQUIRES_SHARED(Locks::mutator_lock_) = 0;
virtual void ThreadDeath(Thread* self) REQUIRES_SHARED(Locks::mutator_lock_) = 0;
};
// Store an exception from the thread and suppress it for the duration of this object.
class ScopedExceptionStorage {
public:
EXPORT explicit ScopedExceptionStorage(Thread* self) REQUIRES_SHARED(Locks::mutator_lock_);
void SuppressOldException(const char* message = "") REQUIRES_SHARED(Locks::mutator_lock_);
EXPORT ~ScopedExceptionStorage() REQUIRES_SHARED(Locks::mutator_lock_);
private:
Thread* self_;
StackHandleScope<1> hs_;
MutableHandle<mirror::Throwable> excp_;
};
EXPORT std::ostream& operator<<(std::ostream& os, const Thread& thread);
std::ostream& operator<<(std::ostream& os, StackedShadowFrameType thread);
} // namespace art
#endif // ART_RUNTIME_THREAD_H_
|