/
thread.hpp
2339 lines (1951 loc) · 91.9 KB
/
thread.hpp
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
/*
* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2021, Azul Systems, Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef SHARE_VM_RUNTIME_THREAD_HPP
#define SHARE_VM_RUNTIME_THREAD_HPP
#include "jni.h"
#include "gc/shared/gcThreadLocalData.hpp"
#include "gc/shared/threadLocalAllocBuffer.hpp"
#include "memory/allocation.hpp"
#include "oops/oop.hpp"
#include "prims/jvmtiExport.hpp"
#include "runtime/frame.hpp"
#include "runtime/globals.hpp"
#include "runtime/handshake.hpp"
#include "runtime/javaFrameAnchor.hpp"
#include "runtime/jniHandles.hpp"
#include "runtime/mutexLocker.hpp"
#include "runtime/os.hpp"
#include "runtime/osThread.hpp"
#include "runtime/park.hpp"
#include "runtime/safepoint.hpp"
#include "runtime/stubRoutines.hpp"
#include "runtime/threadHeapSampler.hpp"
#include "runtime/threadLocalStorage.hpp"
#include "runtime/threadStatisticalInfo.hpp"
#include "runtime/unhandledOops.hpp"
#include "utilities/align.hpp"
#include "utilities/exceptions.hpp"
#include "utilities/globalDefinitions.hpp"
#include "utilities/macros.hpp"
#ifdef ZERO
# include "stack_zero.hpp"
#endif
#if INCLUDE_JFR
#include "jfr/support/jfrThreadExtension.hpp"
#endif
class SafeThreadsListPtr;
class ThreadSafepointState;
class ThreadsList;
class ThreadsSMRSupport;
class JvmtiThreadState;
class JvmtiGetLoadedClassesClosure;
class ThreadStatistics;
class ConcurrentLocksDump;
class ParkEvent;
class Parker;
class ciEnv;
class CompileThread;
class CompileLog;
class CompileTask;
class CompileQueue;
class CompilerCounters;
class vframeArray;
class DeoptResourceMark;
class jvmtiDeferredLocalVariableSet;
class GCTaskQueue;
class ThreadClosure;
class IdealGraphPrinter;
class Metadata;
template <class T, MEMFLAGS F> class ChunkedList;
typedef ChunkedList<Metadata*, mtInternal> MetadataOnStackBuffer;
DEBUG_ONLY(class ResourceMark;)
class WorkerThread;
// Class hierarchy
// - Thread
// - JavaThread
// - various subclasses eg CompilerThread, ServiceThread
// - NonJavaThread
// - NamedThread
// - VMThread
// - ConcurrentGCThread
// - WorkerThread
// - GangWorker
// - GCTaskThread
// - WatcherThread
// - JfrThreadSampler
//
// All Thread subclasses must be either JavaThread or NonJavaThread.
// This means !t->is_Java_thread() iff t is a NonJavaThread, or t is
// a partially constructed/destroyed Thread.
class Thread: public ThreadShadow {
friend class VMStructs;
friend class JVMCIVMStructs;
private:
#ifndef USE_LIBRARY_BASED_TLS_ONLY
// Current thread is maintained as a thread-local variable
static THREAD_LOCAL_DECL Thread* _thr_current;
#endif
private:
// Thread local data area available to the GC. The internal
// structure and contents of this data area is GC-specific.
// Only GC and GC barrier code should access this data area.
GCThreadLocalData _gc_data;
public:
static ByteSize gc_data_offset() {
return byte_offset_of(Thread, _gc_data);
}
template <typename T> T* gc_data() {
STATIC_ASSERT(sizeof(T) <= sizeof(_gc_data));
return reinterpret_cast<T*>(&_gc_data);
}
// Exception handling
// (Note: _pending_exception and friends are in ThreadShadow)
//oop _pending_exception; // pending exception for current thread
// const char* _exception_file; // file information for exception (debugging only)
// int _exception_line; // line information for exception (debugging only)
protected:
// Support for forcing alignment of thread objects for biased locking
void* _real_malloc_address;
// JavaThread lifecycle support:
friend class SafeThreadsListPtr; // for _threads_list_ptr, cmpxchg_threads_hazard_ptr(), {dec_,inc_,}nested_threads_hazard_ptr_cnt(), {g,s}et_threads_hazard_ptr(), inc_nested_handle_cnt(), tag_hazard_ptr() access
friend class ScanHazardPtrGatherProtectedThreadsClosure; // for cmpxchg_threads_hazard_ptr(), get_threads_hazard_ptr(), is_hazard_ptr_tagged() access
friend class ScanHazardPtrGatherThreadsListClosure; // for get_threads_hazard_ptr(), untag_hazard_ptr() access
friend class ScanHazardPtrPrintMatchingThreadsClosure; // for get_threads_hazard_ptr(), is_hazard_ptr_tagged() access
friend class ThreadsSMRSupport; // for _nested_threads_hazard_ptr_cnt, _threads_hazard_ptr, _threads_list_ptr access
ThreadsList* volatile _threads_hazard_ptr;
SafeThreadsListPtr* _threads_list_ptr;
ThreadsList* cmpxchg_threads_hazard_ptr(ThreadsList* exchange_value, ThreadsList* compare_value);
ThreadsList* get_threads_hazard_ptr();
void set_threads_hazard_ptr(ThreadsList* new_list);
static bool is_hazard_ptr_tagged(ThreadsList* list) {
return (intptr_t(list) & intptr_t(1)) == intptr_t(1);
}
static ThreadsList* tag_hazard_ptr(ThreadsList* list) {
return (ThreadsList*)(intptr_t(list) | intptr_t(1));
}
static ThreadsList* untag_hazard_ptr(ThreadsList* list) {
return (ThreadsList*)(intptr_t(list) & ~intptr_t(1));
}
// This field is enabled via -XX:+EnableThreadSMRStatistics:
uint _nested_threads_hazard_ptr_cnt;
void dec_nested_threads_hazard_ptr_cnt() {
assert(_nested_threads_hazard_ptr_cnt != 0, "mismatched {dec,inc}_nested_threads_hazard_ptr_cnt()");
_nested_threads_hazard_ptr_cnt--;
}
void inc_nested_threads_hazard_ptr_cnt() {
_nested_threads_hazard_ptr_cnt++;
}
uint nested_threads_hazard_ptr_cnt() {
return _nested_threads_hazard_ptr_cnt;
}
public:
void* operator new(size_t size) throw() { return allocate(size, true); }
void* operator new(size_t size, const std::nothrow_t& nothrow_constant) throw() {
return allocate(size, false); }
void operator delete(void* p);
protected:
static void* allocate(size_t size, bool throw_excpt, MEMFLAGS flags = mtThread);
private:
// ***************************************************************
// Suspend and resume support
// ***************************************************************
//
// VM suspend/resume no longer exists - it was once used for various
// things including safepoints but was deprecated and finally removed
// in Java 7. Because VM suspension was considered "internal" Java-level
// suspension was considered "external", and this legacy naming scheme
// remains.
//
// External suspend/resume requests come from JVM_SuspendThread,
// JVM_ResumeThread, JVMTI SuspendThread, and finally JVMTI
// ResumeThread. External
// suspend requests cause _external_suspend to be set and external
// resume requests cause _external_suspend to be cleared.
// External suspend requests do not nest on top of other external
// suspend requests. The higher level APIs reject suspend requests
// for already suspended threads.
//
// The external_suspend
// flag is checked by has_special_runtime_exit_condition() and java thread
// will self-suspend when handle_special_runtime_exit_condition() is
// called. Most uses of the _thread_blocked state in JavaThreads are
// considered the same as being externally suspended; if the blocking
// condition lifts, the JavaThread will self-suspend. Other places
// where VM checks for external_suspend include:
// + mutex granting (do not enter monitors when thread is suspended)
// + state transitions from _thread_in_native
//
// In general, java_suspend() does not wait for an external suspend
// request to complete. When it returns, the only guarantee is that
// the _external_suspend field is true.
//
// wait_for_ext_suspend_completion() is used to wait for an external
// suspend request to complete. External suspend requests are usually
// followed by some other interface call that requires the thread to
// be quiescent, e.g., GetCallTrace(). By moving the "wait time" into
// the interface that requires quiescence, we give the JavaThread a
// chance to self-suspend before we need it to be quiescent. This
// improves overall suspend/query performance.
//
// _suspend_flags controls the behavior of java_ suspend/resume.
// It must be set under the protection of SR_lock. Read from the flag is
// OK without SR_lock as long as the value is only used as a hint.
// (e.g., check _external_suspend first without lock and then recheck
// inside SR_lock and finish the suspension)
//
// _suspend_flags is also overloaded for other "special conditions" so
// that a single check indicates whether any special action is needed
// eg. for async exceptions.
// -------------------------------------------------------------------
// Notes:
// 1. The suspend/resume logic no longer uses ThreadState in OSThread
// but we still update its value to keep other part of the system (mainly
// JVMTI) happy. ThreadState is legacy code (see notes in
// osThread.hpp).
//
// 2. It would be more natural if set_external_suspend() is private and
// part of java_suspend(), but that probably would affect the suspend/query
// performance. Need more investigation on this.
// suspend/resume lock: used for self-suspend
Monitor* _SR_lock;
protected:
enum SuspendFlags {
// NOTE: avoid using the sign-bit as cc generates different test code
// when the sign-bit is used, and sometimes incorrectly - see CR 6398077
_external_suspend = 0x20000000U, // thread is asked to self suspend
_ext_suspended = 0x40000000U, // thread has self-suspended
_deopt_suspend = 0x10000000U, // thread needs to self suspend for deopt
_has_async_exception = 0x00000001U, // there is a pending async exception
_critical_native_unlock = 0x00000002U, // Must call back to unlock JNI critical lock
_trace_flag = 0x00000004U // call tracing backend
};
// various suspension related flags - atomically updated
// overloaded for async exception checking in check_special_condition_for_native_trans.
volatile uint32_t _suspend_flags;
private:
int _num_nested_signal;
DEBUG_ONLY(bool _suspendible_thread;)
public:
void enter_signal_handler() { _num_nested_signal++; }
void leave_signal_handler() { _num_nested_signal--; }
bool is_inside_signal_handler() const { return _num_nested_signal > 0; }
#ifdef ASSERT
void set_suspendible_thread() {
_suspendible_thread = true;
}
void clear_suspendible_thread() {
_suspendible_thread = false;
}
bool is_suspendible_thread() { return _suspendible_thread; }
#endif
private:
// Active_handles points to a block of handles
JNIHandleBlock* _active_handles;
// One-element thread local free list
JNIHandleBlock* _free_handle_block;
// Point to the last handle mark
HandleMark* _last_handle_mark;
// The parity of the last strong_roots iteration in which this thread was
// claimed as a task.
int _oops_do_parity;
// Support for GlobalCounter
private:
volatile uintx _rcu_counter;
public:
volatile uintx* get_rcu_counter() {
return &_rcu_counter;
}
public:
void set_last_handle_mark(HandleMark* mark) { _last_handle_mark = mark; }
HandleMark* last_handle_mark() const { return _last_handle_mark; }
private:
// debug support for checking if code does allow safepoints or not
// GC points in the VM can happen because of allocation, invoking a VM operation, or blocking on
// mutex, or blocking on an object synchronizer (Java locking).
// If !allow_safepoint(), then an assertion failure will happen in any of the above cases
// If !allow_allocation(), then an assertion failure will happen during allocation
// (Hence, !allow_safepoint() => !allow_allocation()).
//
// The two classes NoSafepointVerifier and No_Allocation_Verifier are used to set these counters.
//
NOT_PRODUCT(int _allow_safepoint_count;) // If 0, thread allow a safepoint to happen
debug_only(int _allow_allocation_count;) // If 0, the thread is allowed to allocate oops.
// Used by SkipGCALot class.
NOT_PRODUCT(bool _skip_gcalot;) // Should we elide gc-a-lot?
friend class NoAllocVerifier;
friend class NoSafepointVerifier;
friend class PauseNoSafepointVerifier;
friend class GCLocker;
volatile void* _polling_page; // Thread local polling page
ThreadLocalAllocBuffer _tlab; // Thread-local eden
jlong _allocated_bytes; // Cumulative number of bytes allocated on
// the Java heap
ThreadHeapSampler _heap_sampler; // For use when sampling the memory.
ThreadStatisticalInfo _statistical_info; // Statistics about the thread
JFR_ONLY(DEFINE_THREAD_LOCAL_FIELD_JFR;) // Thread-local data for jfr
int _vm_operation_started_count; // VM_Operation support
int _vm_operation_completed_count; // VM_Operation support
ObjectMonitor* _current_pending_monitor; // ObjectMonitor this thread
// is waiting to lock
bool _current_pending_monitor_is_from_java; // locking is from Java code
// ObjectMonitor on which this thread called Object.wait()
ObjectMonitor* _current_waiting_monitor;
// Private thread-local objectmonitor list - a simple cache organized as a SLL.
public:
ObjectMonitor* omFreeList;
int omFreeCount; // length of omFreeList
int omFreeProvision; // reload chunk size
ObjectMonitor* omInUseList; // SLL to track monitors in circulation
int omInUseCount; // length of omInUseList
#ifdef ASSERT
private:
bool _visited_for_critical_count;
public:
void set_visited_for_critical_count(bool z) { _visited_for_critical_count = z; }
bool was_visited_for_critical_count() const { return _visited_for_critical_count; }
#endif
public:
enum {
is_definitely_current_thread = true
};
// Constructor
Thread();
virtual ~Thread() = 0; // Thread is abstract.
// Manage Thread::current()
void initialize_thread_current();
static void clear_thread_current(); // TLS cleanup needed before threads terminate
protected:
// To be implemented by children.
virtual void run() = 0;
public:
// invokes <ChildThreadClass>::run(), with common preparations and cleanups.
void call_run();
// Testers
virtual bool is_VM_thread() const { return false; }
virtual bool is_Java_thread() const { return false; }
virtual bool is_Compiler_thread() const { return false; }
virtual bool is_Code_cache_sweeper_thread() const { return false; }
virtual bool is_service_thread() const { return false; }
virtual bool is_hidden_from_external_view() const { return false; }
virtual bool is_jvmti_agent_thread() const { return false; }
// True iff the thread can perform GC operations at a safepoint.
// Generally will be true only of VM thread and parallel GC WorkGang
// threads.
virtual bool is_GC_task_thread() const { return false; }
virtual bool is_Watcher_thread() const { return false; }
virtual bool is_ConcurrentGC_thread() const { return false; }
virtual bool is_Named_thread() const { return false; }
virtual bool is_Worker_thread() const { return false; }
// Can this thread make Java upcalls
virtual bool can_call_java() const { return false; }
// Casts
virtual WorkerThread* as_Worker_thread() const { return NULL; }
virtual char* name() const { return (char*)"Unknown thread"; }
// Returns the current thread (ASSERTS if NULL)
static inline Thread* current();
// Returns the current thread, or NULL if not attached
static inline Thread* current_or_null();
// Returns the current thread, or NULL if not attached, and is
// safe for use from signal-handlers
static inline Thread* current_or_null_safe();
// Common thread operations
#ifdef ASSERT
static void check_for_dangling_thread_pointer(Thread *thread);
#endif
static void set_priority(Thread* thread, ThreadPriority priority);
static ThreadPriority get_priority(const Thread* const thread);
static void start(Thread* thread);
static void interrupt(Thread* thr);
static bool is_interrupted(Thread* thr, bool clear_interrupted);
void set_native_thread_name(const char *name) {
assert(Thread::current() == this, "set_native_thread_name can only be called on the current thread");
os::set_native_thread_name(name);
}
ObjectMonitor** omInUseList_addr() { return (ObjectMonitor **)&omInUseList; }
Monitor* SR_lock() const { return _SR_lock; }
bool has_async_exception() const { return (_suspend_flags & _has_async_exception) != 0; }
inline void set_suspend_flag(SuspendFlags f);
inline void clear_suspend_flag(SuspendFlags f);
inline void set_has_async_exception();
inline void clear_has_async_exception();
bool do_critical_native_unlock() const { return (_suspend_flags & _critical_native_unlock) != 0; }
inline void set_critical_native_unlock();
inline void clear_critical_native_unlock();
inline void set_trace_flag();
inline void clear_trace_flag();
// Support for Unhandled Oop detection
// Add the field for both, fastdebug and debug, builds to keep
// Thread's fields layout the same.
// Note: CHECK_UNHANDLED_OOPS is defined only for fastdebug build.
#ifdef CHECK_UNHANDLED_OOPS
private:
UnhandledOops* _unhandled_oops;
#elif defined(ASSERT)
private:
void* _unhandled_oops;
#endif
#ifdef CHECK_UNHANDLED_OOPS
public:
UnhandledOops* unhandled_oops() { return _unhandled_oops; }
// Mark oop safe for gc. It may be stack allocated but won't move.
void allow_unhandled_oop(oop *op) {
if (CheckUnhandledOops) unhandled_oops()->allow_unhandled_oop(op);
}
// Clear oops at safepoint so crashes point to unhandled oop violator
void clear_unhandled_oops() {
if (CheckUnhandledOops) unhandled_oops()->clear_unhandled_oops();
}
#endif // CHECK_UNHANDLED_OOPS
public:
#ifndef PRODUCT
bool skip_gcalot() { return _skip_gcalot; }
void set_skip_gcalot(bool v) { _skip_gcalot = v; }
#endif
// Installs a pending exception to be inserted later
static void send_async_exception(oop thread_oop, oop java_throwable);
// Resource area
ResourceArea* resource_area() const { return _resource_area; }
void set_resource_area(ResourceArea* area) { _resource_area = area; }
OSThread* osthread() const { return _osthread; }
void set_osthread(OSThread* thread) { _osthread = thread; }
// JNI handle support
JNIHandleBlock* active_handles() const { return _active_handles; }
void set_active_handles(JNIHandleBlock* block) { _active_handles = block; }
JNIHandleBlock* free_handle_block() const { return _free_handle_block; }
void set_free_handle_block(JNIHandleBlock* block) { _free_handle_block = block; }
// Internal handle support
HandleArea* handle_area() const { return _handle_area; }
void set_handle_area(HandleArea* area) { _handle_area = area; }
GrowableArray<Metadata*>* metadata_handles() const { return _metadata_handles; }
void set_metadata_handles(GrowableArray<Metadata*>* handles){ _metadata_handles = handles; }
// Thread-Local Allocation Buffer (TLAB) support
ThreadLocalAllocBuffer& tlab() { return _tlab; }
void initialize_tlab() {
if (UseTLAB) {
tlab().initialize();
}
}
jlong allocated_bytes() { return _allocated_bytes; }
void set_allocated_bytes(jlong value) { _allocated_bytes = value; }
void incr_allocated_bytes(jlong size) { _allocated_bytes += size; }
inline jlong cooked_allocated_bytes();
ThreadHeapSampler& heap_sampler() { return _heap_sampler; }
ThreadStatisticalInfo& statistical_info() { return _statistical_info; }
JFR_ONLY(DEFINE_THREAD_LOCAL_ACCESSOR_JFR;)
bool is_trace_suspend() { return (_suspend_flags & _trace_flag) != 0; }
// VM operation support
int vm_operation_ticket() { return ++_vm_operation_started_count; }
int vm_operation_completed_count() { return _vm_operation_completed_count; }
void increment_vm_operation_completed_count() { _vm_operation_completed_count++; }
// For tracking the heavyweight monitor the thread is pending on.
ObjectMonitor* current_pending_monitor() {
return _current_pending_monitor;
}
void set_current_pending_monitor(ObjectMonitor* monitor) {
_current_pending_monitor = monitor;
}
void set_current_pending_monitor_is_from_java(bool from_java) {
_current_pending_monitor_is_from_java = from_java;
}
bool current_pending_monitor_is_from_java() {
return _current_pending_monitor_is_from_java;
}
// For tracking the ObjectMonitor on which this thread called Object.wait()
ObjectMonitor* current_waiting_monitor() {
return _current_waiting_monitor;
}
void set_current_waiting_monitor(ObjectMonitor* monitor) {
_current_waiting_monitor = monitor;
}
// GC support
// Apply "f->do_oop" to all root oops in "this".
// Used by JavaThread::oops_do.
// Apply "cf->do_code_blob" (if !NULL) to all code blobs active in frames
virtual void oops_do(OopClosure* f, CodeBlobClosure* cf);
// Handles the parallel case for the method below.
private:
bool claim_oops_do_par_case(int collection_parity);
public:
// Requires that "collection_parity" is that of the current roots
// iteration. If "is_par" is false, sets the parity of "this" to
// "collection_parity", and returns "true". If "is_par" is true,
// uses an atomic instruction to set the current threads parity to
// "collection_parity", if it is not already. Returns "true" iff the
// calling thread does the update, this indicates that the calling thread
// has claimed the thread's stack as a root groop in the current
// collection.
bool claim_oops_do(bool is_par, int collection_parity) {
if (!is_par) {
_oops_do_parity = collection_parity;
return true;
} else {
return claim_oops_do_par_case(collection_parity);
}
}
// jvmtiRedefineClasses support
void metadata_handles_do(void f(Metadata*));
// Used by fast lock support
virtual bool is_lock_owned(address adr) const;
// Check if address is in the stack of the thread (not just for locks).
// Warning: the method can only be used on the running thread
bool is_in_stack(address adr) const;
// Check if address is in the usable part of the stack (excludes protected
// guard pages)
bool is_in_usable_stack(address adr) const;
// Sets this thread as starting thread. Returns failure if thread
// creation fails due to lack of memory, too many threads etc.
bool set_as_starting_thread();
protected:
// OS data associated with the thread
OSThread* _osthread; // Platform-specific thread information
// Thread local resource area for temporary allocation within the VM
ResourceArea* _resource_area;
DEBUG_ONLY(ResourceMark* _current_resource_mark;)
// Thread local handle area for allocation of handles within the VM
HandleArea* _handle_area;
GrowableArray<Metadata*>* _metadata_handles;
// Support for stack overflow handling, get_thread, etc.
address _stack_base;
size_t _stack_size;
uintptr_t _self_raw_id; // used by get_thread (mutable)
int _lgrp_id;
volatile void** polling_page_addr() { return &_polling_page; }
public:
// Stack overflow support
address stack_base() const { assert(_stack_base != NULL,"Sanity check"); return _stack_base; }
void set_stack_base(address base) { _stack_base = base; }
size_t stack_size() const { return _stack_size; }
void set_stack_size(size_t size) { _stack_size = size; }
address stack_end() const { return stack_base() - stack_size(); }
void record_stack_base_and_size();
void register_thread_stack_with_NMT() NOT_NMT_RETURN;
bool on_local_stack(address adr) const {
// QQQ this has knowledge of direction, ought to be a stack method
return (_stack_base > adr && adr >= stack_end());
}
uintptr_t self_raw_id() { return _self_raw_id; }
void set_self_raw_id(uintptr_t value) { _self_raw_id = value; }
int lgrp_id() const { return _lgrp_id; }
void set_lgrp_id(int value) { _lgrp_id = value; }
// Printing
void print_on(outputStream* st, bool print_extended_info) const;
virtual void print_on(outputStream* st) const { print_on(st, false); }
void print() const { print_on(tty); }
virtual void print_on_error(outputStream* st, char* buf, int buflen) const;
void print_value_on(outputStream* st) const;
// Debug-only code
#ifdef ASSERT
private:
// Deadlock detection support for Mutex locks. List of locks own by thread.
Monitor* _owned_locks;
// Mutex::set_owner_implementation is the only place where _owned_locks is modified,
// thus the friendship
friend class Mutex;
friend class Monitor;
public:
void print_owned_locks_on(outputStream* st) const;
void print_owned_locks() const { print_owned_locks_on(tty); }
Monitor* owned_locks() const { return _owned_locks; }
bool owns_locks() const { return owned_locks() != NULL; }
bool owns_locks_but_compiled_lock() const;
int oops_do_parity() const { return _oops_do_parity; }
// Deadlock detection
bool allow_allocation() { return _allow_allocation_count == 0; }
ResourceMark* current_resource_mark() { return _current_resource_mark; }
void set_current_resource_mark(ResourceMark* rm) { _current_resource_mark = rm; }
#endif
void check_for_valid_safepoint_state(bool potential_vm_operation) PRODUCT_RETURN;
private:
volatile int _jvmti_env_iteration_count;
public:
void entering_jvmti_env_iteration() { ++_jvmti_env_iteration_count; }
void leaving_jvmti_env_iteration() { --_jvmti_env_iteration_count; }
bool is_inside_jvmti_env_iteration() { return _jvmti_env_iteration_count > 0; }
// Code generation
static ByteSize exception_file_offset() { return byte_offset_of(Thread, _exception_file); }
static ByteSize exception_line_offset() { return byte_offset_of(Thread, _exception_line); }
static ByteSize active_handles_offset() { return byte_offset_of(Thread, _active_handles); }
static ByteSize stack_base_offset() { return byte_offset_of(Thread, _stack_base); }
static ByteSize stack_size_offset() { return byte_offset_of(Thread, _stack_size); }
static ByteSize polling_page_offset() { return byte_offset_of(Thread, _polling_page); }
#define TLAB_FIELD_OFFSET(name) \
static ByteSize tlab_##name##_offset() { return byte_offset_of(Thread, _tlab) + ThreadLocalAllocBuffer::name##_offset(); }
TLAB_FIELD_OFFSET(start)
TLAB_FIELD_OFFSET(end)
TLAB_FIELD_OFFSET(top)
TLAB_FIELD_OFFSET(pf_top)
TLAB_FIELD_OFFSET(size) // desired_size
TLAB_FIELD_OFFSET(refill_waste_limit)
TLAB_FIELD_OFFSET(number_of_refills)
TLAB_FIELD_OFFSET(fast_refill_waste)
TLAB_FIELD_OFFSET(slow_allocations)
#undef TLAB_FIELD_OFFSET
static ByteSize allocated_bytes_offset() { return byte_offset_of(Thread, _allocated_bytes); }
JFR_ONLY(DEFINE_THREAD_LOCAL_OFFSET_JFR;)
public:
volatile intptr_t _Stalled;
volatile int _TypeTag;
ParkEvent * _ParkEvent; // for synchronized()
ParkEvent * _SleepEvent; // for Thread.sleep
ParkEvent * _MutexEvent; // for native internal Mutex/Monitor
ParkEvent * _MuxEvent; // for low-level muxAcquire-muxRelease
int NativeSyncRecursion; // diagnostic
volatile int _OnTrap; // Resume-at IP delta
jint _hashStateW; // Marsaglia Shift-XOR thread-local RNG
jint _hashStateX; // thread-specific hashCode generator state
jint _hashStateY;
jint _hashStateZ;
void * _schedctl;
volatile jint rng[4]; // RNG for spin loop
// Low-level leaf-lock primitives used to implement synchronization
// and native monitor-mutex infrastructure.
// Not for general synchronization use.
static void SpinAcquire(volatile int * Lock, const char * Name);
static void SpinRelease(volatile int * Lock);
static void muxAcquire(volatile intptr_t * Lock, const char * Name);
static void muxAcquireW(volatile intptr_t * Lock, ParkEvent * ev);
static void muxRelease(volatile intptr_t * Lock);
#if defined(__APPLE__) && defined(AARCH64)
private:
DEBUG_ONLY(bool _wx_init);
WXMode _wx_state;
public:
void init_wx();
WXMode enable_wx(WXMode new_state);
#endif // __APPLE__ && AARCH64
private:
bool _in_asgct;
public:
bool in_asgct() const { return _in_asgct; }
void set_in_asgct(bool value) { _in_asgct = value; }
static bool current_in_asgct() {
Thread *cur = Thread::current_or_null_safe();
return cur != NULL && cur->in_asgct();
}
};
class ThreadInAsgct {
private:
Thread* _thread;
public:
ThreadInAsgct(Thread* thread) : _thread(thread) {
assert(thread != NULL, "invariant");
assert(!thread->in_asgct(), "invariant");
thread->set_in_asgct(true);
}
~ThreadInAsgct() {
assert(_thread->in_asgct(), "invariant");
_thread->set_in_asgct(false);
}
};
// Inline implementation of Thread::current()
inline Thread* Thread::current() {
Thread* current = current_or_null();
assert(current != NULL, "Thread::current() called on detached thread");
return current;
}
inline Thread* Thread::current_or_null() {
#ifndef USE_LIBRARY_BASED_TLS_ONLY
return _thr_current;
#else
if (ThreadLocalStorage::is_initialized()) {
return ThreadLocalStorage::thread();
}
return NULL;
#endif
}
inline Thread* Thread::current_or_null_safe() {
if (ThreadLocalStorage::is_initialized()) {
return ThreadLocalStorage::thread();
}
return NULL;
}
class NonJavaThread: public Thread {
friend class VMStructs;
NonJavaThread* volatile _next;
class List;
static List _the_list;
public:
NonJavaThread();
~NonJavaThread();
class Iterator;
};
// Provides iteration over the list of NonJavaThreads. Because list
// management occurs in the NonJavaThread constructor and destructor,
// entries in the list may not be fully constructed instances of a
// derived class. Threads created after an iterator is constructed
// will not be visited by the iterator. The scope of an iterator is a
// critical section; there must be no safepoint checks in that scope.
class NonJavaThread::Iterator : public StackObj {
uint _protect_enter;
NonJavaThread* _current;
NONCOPYABLE(Iterator);
public:
Iterator();
~Iterator();
bool end() const { return _current == NULL; }
NonJavaThread* current() const { return _current; }
void step();
};
// Name support for threads. non-JavaThread subclasses with multiple
// uniquely named instances should derive from this.
class NamedThread: public NonJavaThread {
friend class VMStructs;
enum {
max_name_len = 64
};
private:
char* _name;
// log JavaThread being processed by oops_do
JavaThread* _processed_thread;
uint _gc_id; // The current GC id when a thread takes part in GC
public:
NamedThread();
~NamedThread();
// May only be called once per thread.
void set_name(const char* format, ...) ATTRIBUTE_PRINTF(2, 3);
void initialize_named_thread();
virtual bool is_Named_thread() const { return true; }
virtual char* name() const { return _name == NULL ? (char*)"Unknown Thread" : _name; }
JavaThread *processed_thread() { return _processed_thread; }
void set_processed_thread(JavaThread *thread) { _processed_thread = thread; }
virtual void print_on(outputStream* st) const;
void set_gc_id(uint gc_id) { _gc_id = gc_id; }
uint gc_id() { return _gc_id; }
};
// Worker threads are named and have an id of an assigned work.
class WorkerThread: public NamedThread {
private:
uint _id;
public:
WorkerThread() : _id(0) { }
virtual bool is_Worker_thread() const { return true; }
virtual WorkerThread* as_Worker_thread() const {
assert(is_Worker_thread(), "Dubious cast to WorkerThread*?");
return (WorkerThread*) this;
}
void set_id(uint work_id) { _id = work_id; }
uint id() const { return _id; }
};
// A single WatcherThread is used for simulating timer interrupts.
class WatcherThread: public NonJavaThread {
friend class VMStructs;
public:
virtual void run();
private:
static WatcherThread* _watcher_thread;
static bool _startable;
// volatile due to at least one lock-free read
volatile static bool _should_terminate;
public:
enum SomeConstants {
delay_interval = 10 // interrupt delay in milliseconds
};
// Constructor
WatcherThread();
// No destruction allowed
~WatcherThread() {
guarantee(false, "WatcherThread deletion must fix the race with VM termination");
}
// Tester
bool is_Watcher_thread() const { return true; }
// Printing
char* name() const { return (char*)"VM Periodic Task Thread"; }
void print_on(outputStream* st) const;
void unpark();
// Returns the single instance of WatcherThread
static WatcherThread* watcher_thread() { return _watcher_thread; }
// Create and start the single instance of WatcherThread, or stop it on shutdown
static void start();
static void stop();
// Only allow start once the VM is sufficiently initialized
// Otherwise the first task to enroll will trigger the start
static void make_startable();
private:
int sleep() const;
};
class CompilerThread;
typedef void (*ThreadFunction)(JavaThread*, TRAPS);
class JavaThread: public Thread {
friend class VMStructs;
friend class JVMCIVMStructs;
friend class WhiteBox;
private:
JavaThread* _next; // The next thread in the Threads list
bool _in_asgct; // Is set when this JavaThread is handling ASGCT call
bool _on_thread_list; // Is set when this JavaThread is added to the Threads list
oop _threadObj; // The Java level thread object
#ifdef ASSERT
private:
int _java_call_counter;
public:
int java_call_counter() { return _java_call_counter; }
void inc_java_call_counter() { _java_call_counter++; }
void dec_java_call_counter() {
assert(_java_call_counter > 0, "Invalid nesting of JavaCallWrapper");
_java_call_counter--;
}
private: // restore original namespace restriction
#endif // ifdef ASSERT
#ifndef PRODUCT
public:
enum {
jump_ring_buffer_size = 16
};
private: // restore original namespace restriction
#endif
JavaFrameAnchor _anchor; // Encapsulation of current java frame and it state
ThreadFunction _entry_point;
JNIEnv _jni_environment;
// Deopt support
DeoptResourceMark* _deopt_mark; // Holds special ResourceMark for deoptimization
intptr_t* _must_deopt_id; // id of frame that needs to be deopted once we
// transition out of native
CompiledMethod* _deopt_nmethod; // CompiledMethod that is currently being deoptimized
vframeArray* _vframe_array_head; // Holds the heap of the active vframeArrays
vframeArray* _vframe_array_last; // Holds last vFrameArray we popped
// Because deoptimization is lazy we must save jvmti requests to set locals
// in compiled frames until we deoptimize and we have an interpreter frame.
// This holds the pointer to array (yeah like there might be more than one) of
// description of compiled vframes that have locals that need to be updated.
GrowableArray<jvmtiDeferredLocalVariableSet*>* _deferred_locals_updates;