• 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)99 void ICStubBuilder::LoadICByName(Variable* result, Label* tryFastPath, Label *slowPath, Label *success)
100 {
101     auto env = GetEnvironment();
102     Label loadWithHandler(env);
103 
104     SetLabels(tryFastPath, slowPath, success);
105     GateRef secondValue = GetValueFromTaggedArray(
106         profileTypeInfo_, Int32Add(slotId_, Int32(1)));
107     DEFVARIABLE(cachedHandler, VariableType::JS_ANY(), secondValue);
108     NamedICAccessor(&cachedHandler, &loadWithHandler);
109     Bind(&loadWithHandler);
110     {
111         GateRef ret = LoadICWithHandler(glue_, receiver_, receiver_, *cachedHandler);
112         result->WriteVariable(ret);
113         Branch(TaggedIsHole(ret), slowPath_, success_);
114     }
115 }
116 
StoreICByName(Variable * result,Label * tryFastPath,Label * slowPath,Label * success)117 void ICStubBuilder::StoreICByName(Variable* result, Label* tryFastPath, Label *slowPath, Label *success)
118 {
119     auto env = GetEnvironment();
120     Label storeWithHandler(env);
121 
122     SetLabels(tryFastPath, slowPath, success);
123     GateRef secondValue = GetValueFromTaggedArray(
124         profileTypeInfo_, Int32Add(slotId_, Int32(1)));
125     DEFVARIABLE(cachedHandler, VariableType::JS_ANY(), secondValue);
126     NamedICAccessor(&cachedHandler, &storeWithHandler);
127     Bind(&storeWithHandler);
128     {
129         GateRef ret = StoreICWithHandler(glue_, receiver_, receiver_, value_, *cachedHandler);
130         result->WriteVariable(ret);
131         Branch(TaggedIsHole(ret), slowPath_, success_);
132     }
133 }
134 
LoadICByValue(Variable * result,Label * tryFastPath,Label * slowPath,Label * success)135 void ICStubBuilder::LoadICByValue(Variable* result, Label* tryFastPath, Label *slowPath, Label *success)
136 {
137     auto env = GetEnvironment();
138     Label loadWithHandler(env);
139     Label loadElement(env);
140 
141     SetLabels(tryFastPath, slowPath, success);
142     GateRef secondValue = GetValueFromTaggedArray(
143         profileTypeInfo_, Int32Add(slotId_, Int32(1)));
144     DEFVARIABLE(cachedHandler, VariableType::JS_ANY(), secondValue);
145     ValuedICAccessor(&cachedHandler, &loadWithHandler, &loadElement);
146     Bind(&loadElement);
147     {
148         GateRef ret = LoadElement(receiver_, propKey_);
149         result->WriteVariable(ret);
150         Branch(TaggedIsHole(ret), slowPath_, success_);
151     }
152     Bind(&loadWithHandler);
153     {
154         GateRef ret = LoadICWithHandler(glue_, receiver_, receiver_, *cachedHandler);
155         result->WriteVariable(ret);
156         Branch(TaggedIsHole(ret), slowPath_, success_);
157     }
158 }
159 
StoreICByValue(Variable * result,Label * tryFastPath,Label * slowPath,Label * success)160 void ICStubBuilder::StoreICByValue(Variable* result, Label* tryFastPath, Label *slowPath, Label *success)
161 {
162     auto env = GetEnvironment();
163     Label storeWithHandler(env);
164     Label storeElement(env);
165 
166     SetLabels(tryFastPath, slowPath, success);
167     GateRef secondValue = GetValueFromTaggedArray(
168         profileTypeInfo_, Int32Add(slotId_, Int32(1)));
169     DEFVARIABLE(cachedHandler, VariableType::JS_ANY(), secondValue);
170     ValuedICAccessor(&cachedHandler, &storeWithHandler, &storeElement);
171     Bind(&storeElement);
172     {
173         GateRef ret = ICStoreElement(glue_, receiver_, propKey_, value_, secondValue);
174         result->WriteVariable(ret);
175         Branch(TaggedIsHole(ret), slowPath_, success_);
176     }
177     Bind(&storeWithHandler);
178     {
179         GateRef ret = StoreICWithHandler(glue_, receiver_, receiver_, value_, *cachedHandler);
180         result->WriteVariable(ret);
181         Branch(TaggedIsHole(ret), slowPath_, success_);
182     }
183 }
184 
TryLoadGlobalICByName(Variable * result,Label * tryFastPath,Label * slowPath,Label * success)185 void ICStubBuilder::TryLoadGlobalICByName(Variable* result, Label* tryFastPath, Label *slowPath, Label *success)
186 {
187     auto env = GetEnvironment();
188     Label tryIC(env);
189 
190     SetLabels(tryFastPath, slowPath, success);
191     Branch(TaggedIsUndefined(profileTypeInfo_), tryFastPath_, &tryIC);
192     Bind(&tryIC);
193     {
194         GateRef handler = GetValueFromTaggedArray(profileTypeInfo_, slotId_);
195         Label isHeapObject(env);
196         Branch(TaggedIsHeapObject(handler), &isHeapObject, slowPath_);
197         Bind(&isHeapObject);
198         {
199             GateRef ret = LoadGlobal(handler);
200             result->WriteVariable(ret);
201             Branch(TaggedIsHole(ret), slowPath_, success_);
202         }
203     }
204 }
205 
TryStoreGlobalICByName(Variable * result,Label * tryFastPath,Label * slowPath,Label * success)206 void ICStubBuilder::TryStoreGlobalICByName(Variable* result, Label* tryFastPath, Label *slowPath, Label *success)
207 {
208     auto env = GetEnvironment();
209     Label tryIC(env);
210 
211     SetLabels(tryFastPath, slowPath, success);
212     Branch(TaggedIsUndefined(profileTypeInfo_), tryFastPath_, &tryIC);
213     Bind(&tryIC);
214     {
215         GateRef handler = GetValueFromTaggedArray(profileTypeInfo_, slotId_);
216         Label isHeapObject(env);
217         Branch(TaggedIsHeapObject(handler), &isHeapObject, slowPath_);
218         Bind(&isHeapObject);
219         {
220             GateRef ret = StoreGlobal(glue_, value_, handler);
221             result->WriteVariable(ret);
222             Branch(TaggedIsHole(ret), slowPath_, success_);
223         }
224     }
225 }
226 }  // namespace panda::ecmascript::kungfu