• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef PANDA_RUNTIME_INCLUDE_THREAD_H_
17 #define PANDA_RUNTIME_INCLUDE_THREAD_H_
18 
19 #include <memory>
20 #include <chrono>
21 #include <limits>
22 #include <thread>
23 #include <atomic>
24 
25 #include "libpandabase/mem/gc_barrier.h"
26 #include "libpandabase/os/mutex.h"
27 #include "libpandabase/os/thread.h"
28 #include "libpandabase/utils/aligned_storage.h"
29 #include "libpandabase/utils/arch.h"
30 #include "libpandabase/utils/list.h"
31 #include "runtime/include/mem/panda_containers.h"
32 #include "runtime/include/mem/panda_smart_pointers.h"
33 #include "runtime/include/object_header-inl.h"
34 #include "runtime/include/stack_walker.h"
35 #include "runtime/include/language_context.h"
36 #include "runtime/include/locks.h"
37 #include "runtime/include/language_context.h"
38 #include "runtime/include/thread_status.h"
39 #include "runtime/interpreter/cache.h"
40 #include "runtime/interpreter/frame.h"
41 #include "runtime/mem/frame_allocator-inl.h"
42 #include "runtime/mem/gc/gc.h"
43 #include "runtime/mem/internal_allocator.h"
44 #include "runtime/mem/tlab.h"
45 #include "runtime/mem/refstorage/reference_storage.h"
46 #include "runtime/entrypoints/entrypoints.h"
47 #include "events/events.h"
48 
49 #define ASSERT_HAVE_ACCESS_TO_MANAGED_OBJECTS()
50 
51 namespace openjdkjvmti {
52 class TiThread;
53 class ScopedNoUserCodeSuspension;
54 }  // namespace openjdkjvmti
55 
56 namespace panda {
57 
58 template <class TYPE>
59 class HandleStorage;
60 template <class TYPE>
61 class GlobalHandleStorage;
62 template <class TYPE>
63 class HandleScope;
64 
65 namespace test {
66 class ThreadTest;
67 }  // namespace test
68 
69 class ThreadManager;
70 class Runtime;
71 class PandaVM;
72 
73 namespace mem {
74 class GCBarrierSet;
75 }  // namespace mem
76 
77 namespace tooling {
78 class PtThreadInfo;
79 }  // namespace tooling
80 
81 struct CustomTLSData {
82     CustomTLSData() = default;
83     virtual ~CustomTLSData() = default;
84 
85     NO_COPY_SEMANTIC(CustomTLSData);
86     NO_MOVE_SEMANTIC(CustomTLSData);
87 };
88 
89 class LockedObjectInfo {
90 public:
LockedObjectInfo(ObjectHeader * obj,void * fp)91     LockedObjectInfo(ObjectHeader *obj, void *fp) : object(obj), stack(fp) {}
92     ~LockedObjectInfo() = default;
93     DEFAULT_COPY_SEMANTIC(LockedObjectInfo);
94     DEFAULT_MOVE_SEMANTIC(LockedObjectInfo);
GetObject()95     inline ObjectHeader *GetObject() const
96     {
97         return object;
98     }
99 
SetObject(ObjectHeader * obj_new)100     inline void SetObject(ObjectHeader *obj_new)
101     {
102         object = obj_new;
103     }
104 
GetStack()105     inline void *GetStack() const
106     {
107         return stack;
108     }
109 
SetStack(void * stack_new)110     inline void SetStack(void *stack_new)
111     {
112         stack = stack_new;
113     }
114 
115 private:
116     ObjectHeader *object;
117     void *stack;
118 };
119 
120 /**
121  *  Hierarchy of thread classes
122  *
123  *         +--------+
124  *         | Thread |
125  *         +--------+
126  *             |
127  *      +---------------+
128  *      | ManagedThread |
129  *      +---------------+
130  *             |
131  *     +-----------------+
132  *     | MTManagedThread |
133  *     +-----------------+
134  *
135  *
136  *  Thread - is the most low-level entity. This class contains pointers to VM with which this thread is associated.
137  *  ManagedThread - stores runtime context to run managed code in single-threaded environment
138  *  MTManagedThread - extends ManagedThread to be able to run code in multi-threaded environment
139  */
140 
141 /**
142  * \brief Class represents arbitrary runtime thread
143  */
144 // NOLINTNEXTLINE(clang-analyzer-optin.performance.Padding)
145 class Thread {
146 public:
147     enum class ThreadType {
148         THREAD_TYPE_NONE,
149         THREAD_TYPE_GC,
150         THREAD_TYPE_COMPILER,
151         THREAD_TYPE_MANAGED,
152         THREAD_TYPE_MT_MANAGED,
153     };
154 
Thread(PandaVM * vm,ThreadType thread_type)155     explicit Thread(PandaVM *vm, ThreadType thread_type) : vm_(vm), thread_type_(thread_type) {}
156     virtual ~Thread() = default;
157     NO_COPY_SEMANTIC(Thread);
158     NO_MOVE_SEMANTIC(Thread);
159 
160     static Thread *GetCurrent();
161     static void SetCurrent(Thread *thread);
162 
GetVM()163     PandaVM *GetVM() const
164     {
165         return vm_;
166     }
167 
SetVM(PandaVM * vm)168     void SetVM(PandaVM *vm)
169     {
170         vm_ = vm;
171     }
172 
GetThreadType()173     ThreadType GetThreadType() const
174     {
175         return thread_type_;
176     }
177 
178 protected:
179     union __attribute__((__aligned__(4))) FlagsAndThreadStatus {
180         FlagsAndThreadStatus() = default;
181         ~FlagsAndThreadStatus() = default;
182         struct __attribute__((packed)) {
183             volatile uint16_t flags;
184             volatile enum ThreadStatus status;
185         } as_struct;
186         volatile uint32_t as_int;
187         uint32_t as_nonvolatile_int;
188         std::atomic_uint32_t as_atomic;
189 
190         NO_COPY_SEMANTIC(FlagsAndThreadStatus);
191         NO_MOVE_SEMANTIC(FlagsAndThreadStatus);
192     };
193 
194     static constexpr size_t STORAGE_32_NUM = 2;
195     // CODECHECK-NOLINTNEXTLINE(C_RULE_ID_GLOBAL_VAR_AS_INTERFACE)
196     struct StoragePacked32 : public AlignedStorage<sizeof(uint64_t), sizeof(uint32_t), STORAGE_32_NUM> {
197         Aligned<bool> is_compiled_frame_ {false};
198         Aligned<union FlagsAndThreadStatus> fts_ {};
199     } stor_32_;  // NOLINT(misc-non-private-member-variables-in-classes)
200     static_assert(sizeof(stor_32_) == StoragePacked32::GetSize());
201 
202     static constexpr size_t STORAGE_PTR_NUM = 9;
203 
204     // CODECHECK-NOLINTNEXTLINE(C_RULE_ID_GLOBAL_VAR_AS_INTERFACE)
205     struct StoragePackedPtr : public AlignedStorage<sizeof(uintptr_t), sizeof(uintptr_t), STORAGE_PTR_NUM> {
206         Aligned<void *> object_ {nullptr};
207         Aligned<Frame *> frame_ {nullptr};
208         Aligned<ObjectHeader *> exception_ {nullptr};
209         Aligned<uintptr_t> native_pc_ {};
210         Aligned<mem::TLAB *> tlab_ {nullptr};
211         Aligned<void *> card_table_addr_ {nullptr};
212         Aligned<void *> card_table_min_addr_ {nullptr};
213         Aligned<void *> concurrent_marking_addr_ {nullptr};
214         Aligned<void *> string_class_ptr_ {nullptr};
215     } stor_ptr_;  // NOLINT(misc-non-private-member-variables-in-classes)
216     static_assert(sizeof(stor_ptr_) == StoragePackedPtr::GetSize());
217 
218 private:
219     PandaVM *vm_ {nullptr};
220     ThreadType thread_type_ {ThreadType::THREAD_TYPE_NONE};
221 };
222 
223 template <typename ThreadT>
224 class ScopedCurrentThread {
225 public:
ScopedCurrentThread(ThreadT * thread)226     explicit ScopedCurrentThread(ThreadT *thread) : thread_(thread)
227     {
228         ASSERT(Thread::GetCurrent() == nullptr);
229 
230         // Set current thread
231         Thread::SetCurrent(thread_);
232     }
233 
~ScopedCurrentThread()234     ~ScopedCurrentThread()
235     {
236         // Reset current thread
237         Thread::SetCurrent(nullptr);
238     }
239 
240     NO_COPY_SEMANTIC(ScopedCurrentThread);
241     NO_MOVE_SEMANTIC(ScopedCurrentThread);
242 
243 private:
244     ThreadT *thread_;
245 };
246 
247 }  // namespace panda
248 
249 #endif  // PANDA_RUNTIME_INCLUDE_THREAD_H_
250