• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 #include "ecmascript/compiler/ic_stub_builder.h"
16 #include "ecmascript/compiler/stub_builder-inl.h"
17 
18 namespace panda::ecmascript::kungfu {
NamedICAccessor(Variable * cachedHandler,Label * tryICHandler)19 void ICStubBuilder::NamedICAccessor(Variable* cachedHandler, Label *tryICHandler)
20 {
21     auto env = GetEnvironment();
22     Label receiverIsHeapObject(env);
23     Label tryIC(env);
24 
25     Branch(TaggedIsHeapObject(receiver_), &receiverIsHeapObject, slowPath_);
26     Bind(&receiverIsHeapObject);
27     {
28         Branch(TaggedIsUndefined(profileTypeInfo_), tryFastPath_, &tryIC);
29         Bind(&tryIC);
30         {
31             Label isHeapObject(env);
32             Label notHeapObject(env);
33             GateRef firstValue = GetValueFromTaggedArray(
34                 profileTypeInfo_, slotId_);
35             Branch(TaggedIsHeapObject(firstValue), &isHeapObject, &notHeapObject);
36             Bind(&isHeapObject);
37             {
38                 Label tryPoly(env);
39                 GateRef hclass = LoadHClass(receiver_);
40                 Branch(Equal(LoadObjectFromWeakRef(firstValue), hclass),
41                        tryICHandler,
42                        &tryPoly);
43                 Bind(&tryPoly);
44                 {
45                     cachedHandler->WriteVariable(CheckPolyHClass(firstValue, hclass));
46                     Branch(TaggedIsHole(cachedHandler->ReadVariable()), slowPath_, tryICHandler);
47                 }
48             }
49             Bind(&notHeapObject);
50             {
51                 Branch(TaggedIsUndefined(firstValue), slowPath_, tryFastPath_);
52             }
53         }
54     }
55 }
56 
ValuedICAccessor(Variable * cachedHandler,Label * tryICHandler,Label * tryElementIC)57 void ICStubBuilder::ValuedICAccessor(Variable* cachedHandler, Label *tryICHandler, Label* tryElementIC)
58 {
59     auto env = GetEnvironment();
60     Label receiverIsHeapObject(env);
61 
62     Branch(TaggedIsHeapObject(receiver_), &receiverIsHeapObject, slowPath_);
63     Bind(&receiverIsHeapObject);
64     {
65         Label tryIC(env);
66         Branch(TaggedIsUndefined(profileTypeInfo_), tryFastPath_, &tryIC);
67         Bind(&tryIC);
68         {
69             Label isHeapObject(env);
70             Label notHeapObject(env);
71             GateRef firstValue = GetValueFromTaggedArray(
72                 profileTypeInfo_, slotId_);
73             Branch(TaggedIsHeapObject(firstValue), &isHeapObject, &notHeapObject);
74             Bind(&isHeapObject);
75             {
76                 Label tryPoly(env);
77                 GateRef hclass = LoadHClass(receiver_);
78                 Branch(Equal(LoadObjectFromWeakRef(firstValue), hclass),
79                        tryElementIC,
80                        &tryPoly);
81                 Bind(&tryPoly);
82                 {
83                     Label firstIsKey(env);
84                     Branch(Int64Equal(firstValue, propKey_), &firstIsKey, slowPath_);
85                     Bind(&firstIsKey);
86                     GateRef handler = CheckPolyHClass(cachedHandler->ReadVariable(), hclass);
87                     cachedHandler->WriteVariable(handler);
88                     Branch(TaggedIsHole(cachedHandler->ReadVariable()), slowPath_, tryICHandler);
89                 }
90             }
91             Bind(&notHeapObject);
92             {
93                 Branch(TaggedIsUndefined(firstValue), slowPath_, tryFastPath_);
94             }
95         }
96     }
97 }
98 
LoadICByName(Variable * result,Label * tryFastPath,Label * slowPath,Label * success,ProfileOperation callback)99 void ICStubBuilder::LoadICByName(
100     Variable *result, Label *tryFastPath, Label *slowPath, Label *success, ProfileOperation callback)
101 {
102     auto env = GetEnvironment();
103     Label loadWithHandler(env);
104 
105     SetLabels(tryFastPath, slowPath, success);
106     GateRef secondValue = GetValueFromTaggedArray(
107         profileTypeInfo_, Int32Add(slotId_, Int32(1)));
108     DEFVARIABLE(cachedHandler, VariableType::JS_ANY(), secondValue);
109     NamedICAccessor(&cachedHandler, &loadWithHandler);
110     Bind(&loadWithHandler);
111     {
112         GateRef ret = LoadICWithHandler(glue_, receiver_, receiver_, *cachedHandler, callback);
113         result->WriteVariable(ret);
114         Branch(TaggedIsHole(ret), slowPath_, success_);
115     }
116 }
117 
StoreICByName(Variable * result,Label * tryFastPath,Label * slowPath,Label * success)118 void ICStubBuilder::StoreICByName(Variable* result, Label* tryFastPath, Label *slowPath, Label *success)
119 {
120     auto env = GetEnvironment();
121     Label storeWithHandler(env);
122 
123     SetLabels(tryFastPath, slowPath, success);
124     GateRef secondValue = GetValueFromTaggedArray(
125         profileTypeInfo_, Int32Add(slotId_, Int32(1)));
126     DEFVARIABLE(cachedHandler, VariableType::JS_ANY(), secondValue);
127     NamedICAccessor(&cachedHandler, &storeWithHandler);
128     Bind(&storeWithHandler);
129     {
130         GateRef ret = StoreICWithHandler(glue_, receiver_, receiver_, value_, *cachedHandler, callback_);
131         result->WriteVariable(ret);
132         Branch(TaggedIsHole(ret), slowPath_, success_);
133     }
134 }
135 
LoadICByValue(Variable * result,Label * tryFastPath,Label * slowPath,Label * success,ProfileOperation callback)136 void ICStubBuilder::LoadICByValue(
137     Variable *result, Label *tryFastPath, Label *slowPath, Label *success, ProfileOperation callback)
138 {
139     auto env = GetEnvironment();
140     Label loadWithHandler(env);
141     Label loadElement(env);
142 
143     SetLabels(tryFastPath, slowPath, success);
144     GateRef secondValue = GetValueFromTaggedArray(
145         profileTypeInfo_, Int32Add(slotId_, Int32(1)));
146     DEFVARIABLE(cachedHandler, VariableType::JS_ANY(), secondValue);
147     ValuedICAccessor(&cachedHandler, &loadWithHandler, &loadElement);
148     Bind(&loadElement);
149     {
150         GateRef ret = LoadElement(glue_, receiver_, propKey_, callback);
151         result->WriteVariable(ret);
152         Branch(TaggedIsHole(ret), slowPath_, success_);
153     }
154     Bind(&loadWithHandler);
155     {
156         GateRef ret = LoadICWithHandler(glue_, receiver_, receiver_, *cachedHandler, callback);
157         result->WriteVariable(ret);
158         Branch(TaggedIsHole(ret), slowPath_, success_);
159     }
160 }
161 
StoreICByValue(Variable * result,Label * tryFastPath,Label * slowPath,Label * success)162 void ICStubBuilder::StoreICByValue(Variable* result, Label* tryFastPath, Label *slowPath, Label *success)
163 {
164     auto env = GetEnvironment();
165     Label storeWithHandler(env);
166     Label storeElement(env);
167 
168     SetLabels(tryFastPath, slowPath, success);
169     GateRef secondValue = GetValueFromTaggedArray(
170         profileTypeInfo_, Int32Add(slotId_, Int32(1)));
171     DEFVARIABLE(cachedHandler, VariableType::JS_ANY(), secondValue);
172     ValuedICAccessor(&cachedHandler, &storeWithHandler, &storeElement);
173     Bind(&storeElement);
174     {
175         GateRef ret = ICStoreElement(glue_, receiver_, propKey_, value_, secondValue, callback_);
176         result->WriteVariable(ret);
177         Branch(TaggedIsHole(ret), slowPath_, success_);
178     }
179     Bind(&storeWithHandler);
180     {
181         GateRef ret = StoreICWithHandler(glue_, receiver_, receiver_, value_, *cachedHandler, callback_);
182         result->WriteVariable(ret);
183         Branch(TaggedIsHole(ret), slowPath_, success_);
184     }
185 }
186 
TryLoadGlobalICByName(Variable * result,Label * tryFastPath,Label * slowPath,Label * success)187 void ICStubBuilder::TryLoadGlobalICByName(Variable* result, Label* tryFastPath, Label *slowPath, Label *success)
188 {
189     auto env = GetEnvironment();
190     Label tryIC(env);
191 
192     SetLabels(tryFastPath, slowPath, success);
193     Branch(TaggedIsUndefined(profileTypeInfo_), tryFastPath_, &tryIC);
194     Bind(&tryIC);
195     {
196         GateRef handler = GetValueFromTaggedArray(profileTypeInfo_, slotId_);
197         Label isHeapObject(env);
198         Branch(TaggedIsHeapObject(handler), &isHeapObject, slowPath_);
199         Bind(&isHeapObject);
200         {
201             GateRef ret = LoadGlobal(handler);
202             result->WriteVariable(ret);
203             Branch(TaggedIsHole(ret), slowPath_, success_);
204         }
205     }
206 }
207 
TryStoreGlobalICByName(Variable * result,Label * tryFastPath,Label * slowPath,Label * success)208 void ICStubBuilder::TryStoreGlobalICByName(Variable* result, Label* tryFastPath, Label *slowPath, Label *success)
209 {
210     auto env = GetEnvironment();
211     Label tryIC(env);
212 
213     SetLabels(tryFastPath, slowPath, success);
214     Branch(TaggedIsUndefined(profileTypeInfo_), tryFastPath_, &tryIC);
215     Bind(&tryIC);
216     {
217         GateRef handler = GetValueFromTaggedArray(profileTypeInfo_, slotId_);
218         Label isHeapObject(env);
219         Branch(TaggedIsHeapObject(handler), &isHeapObject, slowPath_);
220         Bind(&isHeapObject);
221         {
222             GateRef ret = StoreGlobal(glue_, value_, handler);
223             result->WriteVariable(ret);
224             Branch(TaggedIsHole(ret), slowPath_, success_);
225         }
226     }
227 }
228 }  // namespace panda::ecmascript::kungfu
229