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 ECMASCRIPT_IC_PROFILE_TYPE_INFO_H
17 #define ECMASCRIPT_IC_PROFILE_TYPE_INFO_H
18
19 #include "ecmascript/js_function.h"
20 #include "ecmascript/tagged_array.h"
21
22 namespace panda::ecmascript {
23 enum class ICKind : uint32_t {
24 NamedLoadIC,
25 NamedStoreIC,
26 LoadIC,
27 StoreIC,
28 NamedGlobalLoadIC,
29 NamedGlobalStoreIC,
30 NamedGlobalTryLoadIC,
31 NamedGlobalTryStoreIC,
32 GlobalLoadIC,
33 GlobalStoreIC,
34 };
35
IsNamedGlobalIC(ICKind kind)36 static inline bool IsNamedGlobalIC(ICKind kind)
37 {
38 return (kind == ICKind::NamedGlobalLoadIC) || (kind == ICKind::NamedGlobalStoreIC) ||
39 (kind == ICKind::NamedGlobalTryLoadIC) || (kind == ICKind::NamedGlobalTryStoreIC);
40 }
41
IsValueGlobalIC(ICKind kind)42 static inline bool IsValueGlobalIC(ICKind kind)
43 {
44 return (kind == ICKind::GlobalLoadIC) || (kind == ICKind::GlobalStoreIC);
45 }
46
IsValueNormalIC(ICKind kind)47 static inline bool IsValueNormalIC(ICKind kind)
48 {
49 return (kind == ICKind::LoadIC) || (kind == ICKind::StoreIC);
50 }
51
IsValueIC(ICKind kind)52 static inline bool IsValueIC(ICKind kind)
53 {
54 return IsValueNormalIC(kind) || IsValueGlobalIC(kind);
55 }
56
IsNamedNormalIC(ICKind kind)57 static inline bool IsNamedNormalIC(ICKind kind)
58 {
59 return (kind == ICKind::NamedLoadIC) || (kind == ICKind::NamedStoreIC);
60 }
61
IsNamedIC(ICKind kind)62 static inline bool IsNamedIC(ICKind kind)
63 {
64 return IsNamedNormalIC(kind) || IsNamedGlobalIC(kind);
65 }
66
IsGlobalLoadIC(ICKind kind)67 static inline bool IsGlobalLoadIC(ICKind kind)
68 {
69 return (kind == ICKind::NamedGlobalLoadIC) || (kind == ICKind::GlobalLoadIC) ||
70 (kind == ICKind::NamedGlobalTryLoadIC);
71 }
72
IsGlobalStoreIC(ICKind kind)73 static inline bool IsGlobalStoreIC(ICKind kind)
74 {
75 return (kind == ICKind::NamedGlobalStoreIC) || (kind == ICKind::GlobalStoreIC) ||
76 (kind == ICKind::NamedGlobalTryStoreIC);
77 }
78
IsGlobalIC(ICKind kind)79 static inline bool IsGlobalIC(ICKind kind)
80 {
81 return IsValueGlobalIC(kind) || IsNamedGlobalIC(kind);
82 }
83
84 std::string ICKindToString(ICKind kind);
85
86 class ProfileTypeInfo : public TaggedArray {
87 public:
88 static const uint32_t MAX_FUNC_CACHE_INDEX = std::numeric_limits<uint32_t>::max();
89 static constexpr uint32_t INVALID_SLOT_INDEX = 0xFF;
90 static constexpr uint32_t MAX_SLOT_INDEX = 0xFFFF;
91
Cast(TaggedObject * object)92 static ProfileTypeInfo *Cast(TaggedObject *object)
93 {
94 ASSERT(JSTaggedValue(object).IsTaggedArray());
95 return static_cast<ProfileTypeInfo *>(object);
96 }
97 };
98
99
100 class ProfileTypeAccessor {
101 public:
102 static constexpr size_t CACHE_MAX_LEN = 8;
103 static constexpr size_t MONO_CASE_NUM = 2;
104 static constexpr size_t POLY_CASE_NUM = 4;
105
106 enum ICState {
107 UNINIT,
108 MONO,
109 POLY,
110 MEGA,
111 };
112
ProfileTypeAccessor(JSThread * thread,JSHandle<ProfileTypeInfo> profileTypeInfo,uint32_t slotId,ICKind kind)113 ProfileTypeAccessor(JSThread* thread, JSHandle<ProfileTypeInfo> profileTypeInfo, uint32_t slotId, ICKind kind)
114 : thread_(thread), profileTypeInfo_(profileTypeInfo), slotId_(slotId), kind_(kind)
115 {
116 }
117 ~ProfileTypeAccessor() = default;
118
119 ICState GetICState() const;
120 static std::string ICStateToString(ICState state);
121 void AddHandlerWithoutKey(JSHandle<JSTaggedValue> hclass, JSHandle<JSTaggedValue> handler) const;
122 void AddElementHandler(JSHandle<JSTaggedValue> hclass, JSHandle<JSTaggedValue> handler) const;
123 void AddHandlerWithKey(JSHandle<JSTaggedValue> key, JSHandle<JSTaggedValue> hclass,
124 JSHandle<JSTaggedValue> handler) const;
125 void AddGlobalHandlerKey(JSHandle<JSTaggedValue> key, JSHandle<JSTaggedValue> handler) const;
126 void AddGlobalRecordHandler(JSHandle<JSTaggedValue> handler) const;
127
GetWeakRef(JSTaggedValue value)128 JSTaggedValue GetWeakRef(JSTaggedValue value) const
129 {
130 return JSTaggedValue(value.CreateAndGetWeakRef());
131 }
132
GetRefFromWeak(const JSTaggedValue & value)133 JSTaggedValue GetRefFromWeak(const JSTaggedValue &value) const
134 {
135 return JSTaggedValue(value.GetWeakReferent());
136 }
137 void SetAsMega() const;
138
GetKind()139 ICKind GetKind() const
140 {
141 return kind_;
142 }
143
144 private:
145 JSThread* thread_;
146 JSHandle<ProfileTypeInfo> profileTypeInfo_;
147 uint32_t slotId_;
148 ICKind kind_;
149 };
150 } // namespace panda::ecmascript
151
152 #endif // ECMASCRIPT_IC_PROFILE_TYPE_INFO_H
153