• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 ECMASCRIPT_PGO_PROFILER_PGO_UTILS_H
17 #define ECMASCRIPT_PGO_PROFILER_PGO_UTILS_H
18 
19 #include <algorithm>
20 #include <list>
21 #include <mutex>
22 #include <string>
23 
24 #include "libpandafile/file.h"
25 #include "mem/mem.h"
26 
27 #include "ecmascript/common.h"
28 #include "ecmascript/log.h"
29 #include "ecmascript/log_wrapper.h"
30 #include "ecmascript/platform/mutex.h"
31 
32 namespace panda::ecmascript::pgo {
33 static constexpr Alignment ALIGN_SIZE = Alignment::LOG_ALIGN_4;
34 using PGOMethodId = panda_file::File::EntityId;
35 using ApEntityId = uint32_t;
36 
37 class DumpUtils {
38 public:
39     static const std::string ELEMENT_SEPARATOR;
40     static const std::string BLOCK_SEPARATOR;
41     static const std::string TYPE_SEPARATOR;
42     static const std::string BLOCK_START;
43     static const std::string ARRAY_START;
44     static const std::string ARRAY_END;
45     static const std::string NEW_LINE;
46     static const std::string SPACE;
47     static const std::string ALIGN;
48     static const std::string BLOCK_AND_ARRAY_START;
49     static const std::string VERSION_HEADER;
50     static const std::string PANDA_FILE_INFO_HEADER;
51     static const uint32_t HEX_FORMAT_WIDTH_FOR_32BITS;
52 };
53 
54 class DumpJsonUtils {
55 public:
56     static inline const std::string ABC_FILE_POOL = "abcFilePool";
57     static inline const std::string ABC_FILE = "abcFile";
58     static inline const std::string RECORD_DETAIL = "recordDetail";
59     static inline const std::string MODULE_NAME = "moduleName";
60     static inline const std::string FUNCTION = "function";
61     static inline const std::string FUNCTION_NAME = "functionName";
62     static inline const std::string TYPE = "type";
63     static inline const std::string TYPE_OFFSET = "typeOffset";
64     static inline const std::string TYPE_NAME = "typeName";
65     static inline const std::string IS_ROOT = "isRoot";
66     static inline const std::string KIND = "kind";
67     static inline const std::string ABC_ID = "abcId";
68     static inline const std::string ID = "id";
69 };
70 
71 class ApNameUtils {
72 public:
73     static const std::string AP_SUFFIX;
74     static const std::string RUNTIME_AP_PREFIX;
75     static const std::string MERGED_AP_PREFIX;
76     static const std::string DEFAULT_AP_NAME;
77     static std::string PUBLIC_API GetRuntimeApName(const std::string &ohosModuleName);
78     static std::string PUBLIC_API GetMergedApName(const std::string &ohosModuleName);
79     static std::string PUBLIC_API GetOhosPkgApName(const std::string &ohosModuleName);
80 
81 private:
82     static std::string GetBriefApName(const std::string &ohosModuleName);
83 };
84 
85 class ConcurrentGuardValue {
86 public:
87     mutable std::atomic_int last_tid {0};
88     mutable std::atomic_int count {0};
89 
Gettid()90     int Gettid()
91     {
92         return os::thread::GetCurrentThreadId();
93     }
94 };
95 
96 class ConcurrentGuard {
97 private:
98     std::string operation_;
99 
100 public:
101     ConcurrentGuard(ConcurrentGuardValue& v, std::string operation = "ConcurrentGuard")
operation_(operation)102         : operation_(operation), v_(v)
103     {
104         auto tid = v_.Gettid();
105         auto except = 0;
106         auto desired = 1;
107         if (!v_.count.compare_exchange_strong(except, desired) && v_.last_tid != tid) {
108             LOG_PGO(FATAL) << "[" << operation_ << "] total thead count should be 0, but get " << except
109                            << ", current tid: " << tid << ", last tid: " << v_.last_tid;
110         }
111         v_.last_tid = tid;
112     }
~ConcurrentGuard()113     ~ConcurrentGuard()
114     {
115         auto tid = v_.Gettid();
116         auto except = 1;
117         auto desired = 0;
118         if (!v_.count.compare_exchange_strong(except, desired) && v_.last_tid != tid) {
119             LOG_PGO(FATAL) << "[" << operation_ << "] total thead count should be 1, but get " << except
120                            << ", current tid: " << tid << ", last tid: " << v_.last_tid;
121         }
122     };
123 
124 private:
125     ConcurrentGuardValue& v_;
126 };
127 
128 class PGOProfiler;
129 class PGOPendingProfilers {
130 public:
PushBack(PGOProfiler * value)131     void PushBack(PGOProfiler* value)
132     {
133         WriteLockHolder lock(listMutex_);
134         if (std::find(list_.begin(), list_.end(), value) == list_.end()) {
135             list_.push_back(value);
136         }
137     }
138 
PopFront()139     PGOProfiler* PopFront()
140     {
141         WriteLockHolder lock(listMutex_);
142         if (list_.empty()) {
143             return nullptr;
144         }
145         PGOProfiler* value = list_.front();
146         list_.pop_front();
147         return value;
148     }
149 
Front()150     PGOProfiler* Front() const
151     {
152         ReadLockHolder lock(listMutex_);
153         if (list_.empty()) {
154             return nullptr;
155         }
156         return list_.front();
157     }
158 
Pop()159     void Pop()
160     {
161         WriteLockHolder lock(listMutex_);
162         if (list_.empty()) {
163             return;
164         }
165         list_.pop_front();
166     }
167 
Empty()168     bool Empty() const
169     {
170         ReadLockHolder lock(listMutex_);
171         return list_.empty();
172     }
173 
Size()174     size_t Size() const
175     {
176         ReadLockHolder lock(listMutex_);
177         return list_.size();
178     }
179 
Remove(PGOProfiler * profiler)180     void Remove(PGOProfiler* profiler)
181     {
182         WriteLockHolder lock(listMutex_);
183         list_.remove(profiler);
184     }
185 
186 private:
187     std::list<PGOProfiler*> list_;
188     mutable RWLock listMutex_;
189 };
190 }  // namespace panda::ecmascript::pgo
191 #endif // ECMASCRIPT_PGO_PROFILER_PGO_UTILS_H