• 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 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