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