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_TYPES_PGO_TYPE_GENERATOR_H 17 #define ECMASCRIPT_PGO_PROFILER_TYPES_PGO_TYPE_GENERATOR_H 18 19 #include "ecmascript/js_tagged_value.h" 20 #include "ecmascript/js_hclass.h" 21 #include "ecmascript/mem/c_containers.h" 22 #include "ecmascript/pgo_profiler/types/pgo_profile_type.h" 23 #include "ecmascript/platform/mutex.h" 24 #include "utils/span.h" 25 26 namespace panda::ecmascript::pgo { 27 class PGOTypeGenerator { 28 public: GenerateProfileType(ProfileType rootType,JSTaggedType hclass)29 ProfileType GenerateProfileType(ProfileType rootType, JSTaggedType hclass) 30 { 31 { 32 LockHolder lock(mutex_); 33 auto iter = exsitId_.find(hclass); 34 if (iter != exsitId_.end()) { 35 return iter->second; 36 } 37 } 38 39 CString result = JSHClass::DumpToString(hclass); 40 uint32_t traceId = ComputeHashCode(result); 41 ProfileType type(rootType.GetAbcId(), traceId, rootType.GetKind()); 42 LockHolder lock(mutex_); 43 exsitId_.emplace(hclass, type); 44 return type; 45 } 46 GetProfileType(JSTaggedType hclass)47 ProfileType GetProfileType(JSTaggedType hclass) 48 { 49 LockHolder lock(mutex_); 50 auto iter = exsitId_.find(hclass); 51 if (iter != exsitId_.end()) { 52 return iter->second; 53 } 54 return ProfileType::PROFILE_TYPE_NONE; 55 } 56 InsertProfileType(JSTaggedType hclass,ProfileType type)57 void InsertProfileType(JSTaggedType hclass, ProfileType type) 58 { 59 LockHolder lock(mutex_); 60 auto iter = exsitId_.find(hclass); 61 if (iter != exsitId_.end()) { 62 return; 63 } 64 exsitId_.emplace(hclass, type); 65 } 66 UpdateProfileType(JSTaggedType oldHClass,JSTaggedType newHClass)67 void UpdateProfileType(JSTaggedType oldHClass, JSTaggedType newHClass) 68 { 69 LockHolder lock(mutex_); 70 auto iter = exsitId_.find(oldHClass); 71 if (iter != exsitId_.end()) { 72 auto profileType = iter->second; 73 exsitId_.erase(oldHClass); 74 exsitId_.emplace(newHClass, profileType); 75 } 76 } 77 ProcessReferences(const WeakRootVisitor & visitor)78 void ProcessReferences(const WeakRootVisitor &visitor) 79 { 80 for (auto iter = exsitId_.begin(); iter != exsitId_.end();) { 81 JSTaggedType object = iter->first; 82 auto fwd = visitor(reinterpret_cast<TaggedObject *>(object)); 83 if (fwd == nullptr) { 84 iter = exsitId_.erase(iter); 85 continue; 86 } 87 if (fwd != reinterpret_cast<TaggedObject *>(object)) { 88 UNREACHABLE(); 89 } 90 ++iter; 91 } 92 } 93 94 private: 95 static constexpr uint32_t INVALID_ID = 0; 96 ComputeHashCode(const CString & string)97 uint32_t ComputeHashCode(const CString &string) 98 { 99 uint32_t hash = INVALID_ID; 100 Span<const char> sp(string.c_str(), string.size()); 101 for (auto c : sp) { 102 constexpr size_t SHIFT = 5; 103 hash = (hash << SHIFT) - hash + c; 104 } 105 return hash; 106 } 107 108 Mutex mutex_; 109 CMap<JSTaggedType, ProfileType> exsitId_; 110 }; 111 } // namespace panda::ecmascript::pgo 112 #endif // ECMASCRIPT_PGO_PROFILER_TYPES_PGO_TYPE_GENERATOR_H 113