• 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 #include "ecmascript/compiler/argument_accessor.h"
17 #include "ecmascript/compiler/circuit_builder.h"
18 #include "ecmascript/compiler/gate_accessor.h"
19 #include "ecmascript/compiler/graph_editor.h"
20 #include "ecmascript/js_tagged_value-inl.h"
21 #include "ecmascript/mem/assert_scope.h"
22 
23 namespace panda::ecmascript::kungfu {
24 using UseIterator = GateAccessor::UseIterator;
25 
GetNumIns(GateRef gate) const26 size_t GateAccessor::GetNumIns(GateRef gate) const
27 {
28     Gate *gatePtr = circuit_->LoadGatePtr(gate);
29     return gatePtr->GetNumIns();
30 }
31 
GetMark(GateRef gate) const32 MarkCode GateAccessor::GetMark(GateRef gate) const
33 {
34     return circuit_->GetMark(gate);
35 }
36 
SetMark(GateRef gate,MarkCode mark)37 void GateAccessor::SetMark(GateRef gate, MarkCode mark)
38 {
39     circuit_->SetMark(gate, mark);
40 }
41 
IsFinished(GateRef gate) const42 bool GateAccessor::IsFinished(GateRef gate) const
43 {
44     return GetMark(gate) == MarkCode::FINISHED;
45 }
46 
IsVisited(GateRef gate) const47 bool GateAccessor::IsVisited(GateRef gate) const
48 {
49     return GetMark(gate) == MarkCode::VISITED;
50 }
51 
IsPrevisit(GateRef gate) const52 bool GateAccessor::IsPrevisit(GateRef gate) const
53 {
54     return GetMark(gate) == MarkCode::PREVISIT;
55 }
56 
IsNotMarked(GateRef gate) const57 bool GateAccessor::IsNotMarked(GateRef gate) const
58 {
59     return GetMark(gate) == MarkCode::NO_MARK;
60 }
61 
SetFinished(GateRef gate)62 void GateAccessor::SetFinished(GateRef gate)
63 {
64     SetMark(gate, MarkCode::FINISHED);
65 }
66 
SetVisited(GateRef gate)67 void GateAccessor::SetVisited(GateRef gate)
68 {
69     SetMark(gate, MarkCode::VISITED);
70 }
71 
SetPrevisit(GateRef gate)72 void GateAccessor::SetPrevisit(GateRef gate)
73 {
74     SetMark(gate, MarkCode::PREVISIT);
75 }
76 
GetOpCode(GateRef gate) const77 OpCode GateAccessor::GetOpCode(GateRef gate) const
78 {
79     Gate *gatePtr = circuit_->LoadGatePtr(gate);
80     return gatePtr->GetOpCode();
81 }
82 
TryGetValue(GateRef gate) const83 BitField GateAccessor::TryGetValue(GateRef gate) const
84 {
85     Gate *gatePtr = circuit_->LoadGatePtr(gate);
86     return gatePtr->TryGetValue();
87 }
88 
GetICmpCondition(GateRef gate) const89 ICmpCondition GateAccessor::GetICmpCondition(GateRef gate) const
90 {
91     ASSERT(GetOpCode(gate) == OpCode::ICMP);
92     Gate *gatePtr = circuit_->LoadGatePtr(gate);
93     return static_cast<ICmpCondition>(gatePtr->GetOneParameterMetaData()->GetValue());
94 }
95 
GetFCmpCondition(GateRef gate) const96 FCmpCondition GateAccessor::GetFCmpCondition(GateRef gate) const
97 {
98     ASSERT(GetOpCode(gate) == OpCode::FCMP);
99     Gate *gatePtr = circuit_->LoadGatePtr(gate);
100     return static_cast<FCmpCondition>(gatePtr->GetOneParameterMetaData()->GetValue());
101 }
102 
GetOffset(GateRef gate) const103 size_t GateAccessor::GetOffset(GateRef gate) const
104 {
105     ASSERT(GetOpCode(gate) == OpCode::LOAD_CONST_OFFSET ||
106            GetOpCode(gate) == OpCode::STORE_CONST_OFFSET);
107     Gate *gatePtr = circuit_->LoadGatePtr(gate);
108     auto accessor = LoadStoreConstOffsetAccessor(gatePtr->GetOneParameterMetaData()->GetValue());
109     return accessor.GetOffset();
110 }
111 
GetInitOffset(GateRef gate) const112 size_t GateAccessor::GetInitOffset(GateRef gate) const
113 {
114     ASSERT(GetOpCode(gate) == OpCode::INITVREG);
115     Gate *gatePtr = circuit_->LoadGatePtr(gate);
116     return gatePtr->GetOneParameterMetaData()->GetValue();
117 }
118 
GetTrueWeight(GateRef gate) const119 uint32_t GateAccessor::GetTrueWeight(GateRef gate) const
120 {
121     ASSERT(GetOpCode(gate) == OpCode::IF_BRANCH);
122     Gate *gatePtr = circuit_->LoadGatePtr(gate);
123     auto accessor = BranchAccessor(gatePtr->GetOneParameterMetaData()->GetValue());
124     return accessor.GetTrueWeight();
125 }
126 
GetFalseWeight(GateRef gate) const127 uint32_t GateAccessor::GetFalseWeight(GateRef gate) const
128 {
129     ASSERT(GetOpCode(gate) == OpCode::IF_BRANCH);
130     Gate *gatePtr = circuit_->LoadGatePtr(gate);
131     auto accessor = BranchAccessor(gatePtr->GetOneParameterMetaData()->GetValue());
132     return accessor.GetFalseWeight();
133 }
134 
GetMemoryAttribute(GateRef gate) const135 MemoryAttribute GateAccessor::GetMemoryAttribute(GateRef gate) const
136 {
137     auto op = GetOpCode(gate);
138     Gate *gatePtr = circuit_->LoadGatePtr(gate);
139     switch (op) {
140         case OpCode::LOAD:
141         case OpCode::STORE_WITHOUT_BARRIER:
142         case OpCode::STORE: {
143             auto accessor = LoadStoreAccessor(gatePtr->GetOneParameterMetaData()->GetValue());
144             return accessor.GetMemoryAttribute();
145         }
146         case OpCode::LOAD_CONST_OFFSET:
147         case OpCode::STORE_CONST_OFFSET: {
148             auto accessor = LoadStoreConstOffsetAccessor(gatePtr->GetOneParameterMetaData()->GetValue());
149             return accessor.GetMemoryAttribute();
150         }
151         default: {
152             UNREACHABLE();
153             break;
154         }
155     }
156     return MemoryAttribute::Default();
157 }
158 
HasBranchWeight(GateRef gate) const159 bool GateAccessor::HasBranchWeight(GateRef gate) const
160 {
161     ASSERT(GetOpCode(gate) == OpCode::IF_BRANCH);
162     Gate *gatePtr = circuit_->LoadGatePtr(gate);
163     auto accessor = BranchAccessor(gatePtr->GetOneParameterMetaData()->GetValue());
164     return (accessor.GetTrueWeight() != 0) || (accessor.GetFalseWeight() != 0);
165 }
166 
GetIndex(GateRef gate) const167 size_t GateAccessor::GetIndex(GateRef gate) const
168 {
169     ASSERT(GetOpCode(gate) == OpCode::GET_GLOBAL_ENV_OBJ_HCLASS ||
170            GetOpCode(gate) == OpCode::GET_GLOBAL_CONSTANT_VALUE ||
171            GetOpCode(gate) == OpCode::GET_GLOBAL_ENV_OBJ ||
172            GetOpCode(gate) == OpCode::LOAD_HCLASS_FROM_CONSTPOOL ||
173            GetOpCode(gate) == OpCode::LOAD_BUILTIN_OBJECT);
174     Gate *gatePtr = circuit_->LoadGatePtr(gate);
175     return gatePtr->GetOneParameterMetaData()->GetValue();
176 }
177 
GetJSType(GateRef gate) const178 size_t GateAccessor::GetJSType(GateRef gate) const
179 {
180     ASSERT(GetOpCode(gate) == OpCode::IS_SPECIFIC_OBJECT_TYPE);
181     Gate *gatePtr = circuit_->LoadGatePtr(gate);
182     return gatePtr->GetOneParameterMetaData()->GetValue();
183 }
184 
GetArraySize(GateRef gate) const185 uint32_t GateAccessor::GetArraySize(GateRef gate) const
186 {
187     ASSERT(GetOpCode(gate) == OpCode::CREATE_ARRAY ||
188            GetOpCode(gate) == OpCode::CREATE_ARRAY_WITH_BUFFER);
189     Gate *gatePtr = circuit_->LoadGatePtr(gate);
190     auto array = gatePtr->GetOneParameterMetaData()->GetValue();
191     return ArrayMetaDataAccessor(array).GetArrayLength();
192 }
193 
SetArraySize(GateRef gate,uint32_t size)194 void GateAccessor::SetArraySize(GateRef gate, uint32_t size)
195 {
196     ASSERT(GetOpCode(gate) == OpCode::CREATE_ARRAY ||
197            GetOpCode(gate) == OpCode::CREATE_ARRAY_WITH_BUFFER);
198     uint32_t curSize = GetArraySize(gate);
199     if (curSize != size) {
200         Gate *gatePtr = circuit_->LoadGatePtr(gate);
201         ArrayMetaDataAccessor accessor(gatePtr->GetOneParameterMetaData()->GetValue());
202         accessor.SetArrayLength(size);
203         if (GetOpCode(gate) == OpCode::CREATE_ARRAY) {
204             auto meta = circuit_->CreateArray(accessor.ToValue());
205             SetMetaData(gate, meta);
206         } else {
207             auto meta = circuit_->CreateArrayWithBuffer(accessor.ToValue());
208             SetMetaData(gate, meta);
209         }
210     }
211 }
212 
GetElementsKind(GateRef gate) const213 ElementsKind GateAccessor::GetElementsKind(GateRef gate) const
214 {
215     ASSERT(GetOpCode(gate) == OpCode::CREATE_ARRAY ||
216            GetOpCode(gate) == OpCode::CREATE_ARRAY_WITH_BUFFER);
217     Gate *gatePtr = circuit_->LoadGatePtr(gate);
218     auto array = gatePtr->GetOneParameterMetaData()->GetValue();
219     return ArrayMetaDataAccessor(array).GetElementsKind();
220 }
221 
SetElementsKind(GateRef gate,ElementsKind kind)222 void GateAccessor::SetElementsKind(GateRef gate, ElementsKind kind)
223 {
224     ASSERT(GetOpCode(gate) == OpCode::CREATE_ARRAY ||
225            GetOpCode(gate) == OpCode::CREATE_ARRAY_WITH_BUFFER);
226     Gate *gatePtr = circuit_->LoadGatePtr(gate);
227     ArrayMetaDataAccessor accessor(gatePtr->GetOneParameterMetaData()->GetValue());
228     accessor.SetElementsKind(kind);
229     const_cast<OneParameterMetaData *>(gatePtr->GetOneParameterMetaData())->SetValue(accessor.ToValue());
230 }
231 
GetRegionSpaceFlag(GateRef gate) const232 RegionSpaceFlag GateAccessor::GetRegionSpaceFlag(GateRef gate) const
233 {
234     ASSERT(GetOpCode(gate) == OpCode::CREATE_ARRAY ||
235            GetOpCode(gate) == OpCode::CREATE_ARRAY_WITH_BUFFER);
236     Gate *gatePtr = circuit_->LoadGatePtr(gate);
237     auto array = gatePtr->GetOneParameterMetaData()->GetValue();
238     return ArrayMetaDataAccessor(array).GetRegionSpaceFlag();
239 }
240 
GetStringStatus(GateRef gate) const241 uint32_t GateAccessor::GetStringStatus(GateRef gate) const
242 {
243     ASSERT(GetOpCode(gate) == OpCode::STRING_ADD);
244     Gate *gatePtr = circuit_->LoadGatePtr(gate);
245     StringStatusAccessor accessor(gatePtr->GetOneParameterMetaData()->GetValue());
246     return accessor.GetStringStatus();
247 }
248 
SetStringStatus(GateRef gate,uint32_t type)249 void GateAccessor::SetStringStatus(GateRef gate, uint32_t type)
250 {
251     ASSERT(GetOpCode(gate) == OpCode::STRING_ADD);
252     uint32_t curStatus = GetStringStatus(gate);
253     if (curStatus != type) {
254         StringStatusAccessor accessor(static_cast<uint64_t>(type));
255         auto meta = circuit_->StringAdd(accessor.ToValue());
256         SetMetaData(gate, meta);
257     }
258 }
259 
GetTypedUnAccessor(GateRef gate) const260 TypedUnaryAccessor GateAccessor::GetTypedUnAccessor(GateRef gate) const
261 {
262     ASSERT((GetOpCode(gate) == OpCode::TYPED_UNARY_OP));
263     Gate *gatePtr = circuit_->LoadGatePtr(gate);
264     return TypedUnaryAccessor(gatePtr->GetOneParameterMetaData()->GetValue());
265 }
266 
GetTypedBinaryAccessor(GateRef gate) const267 TypedBinaryAccessor GateAccessor::GetTypedBinaryAccessor(GateRef gate) const
268 {
269     Gate *gatePtr = circuit_->LoadGatePtr(gate);
270     return TypedBinaryAccessor(gatePtr->GetOneParameterMetaData()->GetValue());
271 }
272 
GetTypedJumpAccessor(GateRef gate) const273 TypedJumpAccessor GateAccessor::GetTypedJumpAccessor(GateRef gate) const
274 {
275     ASSERT(GetOpCode(gate) == OpCode::TYPED_CONDITION_JUMP);
276     Gate *gatePtr = circuit_->LoadGatePtr(gate);
277     return TypedJumpAccessor(gatePtr->GetOneParameterMetaData()->GetValue());
278 }
279 
GetArrayMetaDataAccessor(GateRef gate) const280 ArrayMetaDataAccessor GateAccessor::GetArrayMetaDataAccessor(GateRef gate) const
281 {
282     ASSERT(GetOpCode(gate) == OpCode::STABLE_ARRAY_CHECK ||
283            GetOpCode(gate) == OpCode::HCLASS_STABLE_ARRAY_CHECK ||
284            GetOpCode(gate) == OpCode::ELEMENTSKIND_CHECK ||
285            GetOpCode(gate) == OpCode::CREATE_ARRAY ||
286            GetOpCode(gate) == OpCode::CREATE_ARRAY_WITH_BUFFER ||
287            GetOpCode(gate) == OpCode::CREATE_ARGUMENTS ||
288            GetOpCode(gate) == OpCode::LOAD_ARRAY_LENGTH);
289     Gate *gatePtr = circuit_->LoadGatePtr(gate);
290     return ArrayMetaDataAccessor(gatePtr->GetOneParameterMetaData()->GetValue());
291 }
292 
NeedPushArgv(GateRef gate) const293 bool GateAccessor::NeedPushArgv(GateRef gate) const
294 {
295     ASSERT(GetOpCode(gate) == OpCode::CALL_NEW);
296     Gate *gatePtr = circuit_->LoadGatePtr(gate);
297     return gatePtr->GetNewConstructMetaData()->NeedPushArgv();
298 }
299 
GetCreateArgumentsAccessor(GateRef gate) const300 CreateArgumentsAccessor GateAccessor::GetCreateArgumentsAccessor(GateRef gate) const
301 {
302     ASSERT(GetOpCode(gate) == OpCode::CREATE_ARGUMENTS);
303     Gate *gatePtr = circuit_->LoadGatePtr(gate);
304     return CreateArgumentsAccessor(gatePtr->GetOneParameterMetaData()->GetValue());
305 }
306 
GetObjectTypeAccessor(GateRef gate) const307 ObjectTypeAccessor GateAccessor::GetObjectTypeAccessor(GateRef gate) const
308 {
309     ASSERT(GetOpCode(gate) == OpCode::OBJECT_TYPE_CHECK);
310     Gate *gatePtr = circuit_->LoadGatePtr(gate);
311     return ObjectTypeAccessor(gatePtr->GetOneParameterMetaData()->GetValue());
312 }
313 
GetBuiltinHClassAccessor(GateRef gate) const314 BuiltinPrototypeHClassAccessor GateAccessor::GetBuiltinHClassAccessor(GateRef gate) const
315 {
316     ASSERT(GetOpCode(gate) == OpCode::BUILTIN_PROTOTYPE_HCLASS_CHECK);
317     Gate *gatePtr = circuit_->LoadGatePtr(gate);
318     return BuiltinPrototypeHClassAccessor(gatePtr->GetOneParameterMetaData()->GetValue());
319 }
320 
GetTypedArrayMetaDataAccessor(GateRef gate) const321 TypedArrayMetaDataAccessor GateAccessor::GetTypedArrayMetaDataAccessor(GateRef gate) const
322 {
323     ASSERT(GetOpCode(gate) == OpCode::TYPED_ARRAY_CHECK || GetOpCode(gate) == OpCode::LOAD_TYPED_ARRAY_LENGTH);
324     Gate *gatePtr = circuit_->LoadGatePtr(gate);
325     return TypedArrayMetaDataAccessor(gatePtr->GetOneParameterMetaData()->GetValue());
326 }
327 
UpdateOnHeapMode(GateRef gate,OnHeapMode onHeapMode)328 void GateAccessor::UpdateOnHeapMode(GateRef gate, OnHeapMode onHeapMode)
329 {
330     ASSERT(GetOpCode(gate) == OpCode::TYPED_ARRAY_CHECK);
331     Gate *gatePtr = circuit_->LoadGatePtr(gate);
332     TypedArrayMetaDataAccessor accessor = GetTypedArrayMetaDataAccessor(gate);
333     uint64_t value = accessor.UpdateOnHeapMode(onHeapMode);
334     const_cast<OneParameterMetaData *>(gatePtr->GetOneParameterMetaData())->SetValue(value);
335 }
336 
GetLoadElementAccessor(GateRef gate) const337 LoadElementAccessor GateAccessor::GetLoadElementAccessor(GateRef gate) const
338 {
339     ASSERT(GetOpCode(gate) == OpCode::LOAD_ELEMENT);
340     Gate *gatePtr = circuit_->LoadGatePtr(gate);
341     return LoadElementAccessor(gatePtr->GetOneParameterMetaData()->GetValue());
342 }
343 
GetStoreElementAccessor(GateRef gate) const344 StoreElementAccessor GateAccessor::GetStoreElementAccessor(GateRef gate) const
345 {
346     ASSERT(GetOpCode(gate) == OpCode::STORE_ELEMENT);
347     Gate *gatePtr = circuit_->LoadGatePtr(gate);
348     return StoreElementAccessor(gatePtr->GetOneParameterMetaData()->GetValue());
349 }
350 
TypedOpIsTypedArray(GateRef gate,TypedOpKind kind) const351 bool GateAccessor::TypedOpIsTypedArray(GateRef gate, TypedOpKind kind) const
352 {
353     switch (kind) {
354         case TypedOpKind::TYPED_LOAD_OP: {
355             TypedLoadOp op = GetTypedLoadOp(gate);
356             return TypedLoadOp::TYPED_ARRAY_FIRST <= op && op <=TypedLoadOp::TYPED_ARRAY_LAST;
357         }
358         case TypedOpKind::TYPED_STORE_OP: {
359             TypedStoreOp op = GetTypedStoreOp(gate);
360             return TypedStoreOp::TYPED_ARRAY_FIRST <= op && op <= TypedStoreOp::TYPED_ARRAY_LAST;
361         }
362         default:
363             LOG_ECMA(FATAL) << "this branch is unreachable";
364             UNREACHABLE();
365     }
366 }
367 
GetTypedLoadOp(GateRef gate) const368 TypedLoadOp GateAccessor::GetTypedLoadOp(GateRef gate) const
369 {
370     ASSERT(GetOpCode(gate) == OpCode::LOAD_ELEMENT);
371     Gate *gatePtr = circuit_->LoadGatePtr(gate);
372     return static_cast<TypedLoadOp>(gatePtr->GetOneParameterMetaData()->GetValue());
373 }
374 
GetTypedStoreOp(GateRef gate) const375 TypedStoreOp GateAccessor::GetTypedStoreOp(GateRef gate) const
376 {
377     ASSERT(GetOpCode(gate) == OpCode::STORE_ELEMENT);
378     Gate *gatePtr = circuit_->LoadGatePtr(gate);
379     return static_cast<TypedStoreOp>(gatePtr->GetOneParameterMetaData()->GetValue());
380 }
381 
GetTypedCallTargetCheckOp(GateRef gate) const382 TypedCallTargetCheckOp GateAccessor::GetTypedCallTargetCheckOp(GateRef gate) const
383 {
384     ASSERT(GetOpCode(gate) == OpCode::TYPED_CALLTARGETCHECK_OP);
385     TypedCallTargetCheckAccessor accessor(TryGetValue(gate));
386     return accessor.GetCallTargetCheckOp();
387 }
388 
GetMemoryType(GateRef gate) const389 MemoryType GateAccessor::GetMemoryType(GateRef gate) const
390 {
391     ASSERT(GetOpCode(gate) == OpCode::STORE_MEMORY);
392     Gate *gatePtr = circuit_->LoadGatePtr(gate);
393     return static_cast<MemoryType>(gatePtr->GetOneParameterMetaData()->GetValue());
394 }
395 
GetHClassIndex(GateRef gate) const396 uint32_t GateAccessor::GetHClassIndex(GateRef gate) const
397 {
398     ASSERT(GetOpCode(gate) == OpCode::STORE_PROPERTY ||
399            GetOpCode(gate) == OpCode::PROTOTYPE_CHECK);
400     Gate *gatePtr = circuit_->LoadGatePtr(gate);
401     return static_cast<uint32_t>(gatePtr->GetOneParameterMetaData()->GetValue());
402 }
403 
GetTypedBinaryOp(GateRef gate) const404 TypedBinOp GateAccessor::GetTypedBinaryOp(GateRef gate) const
405 {
406     ASSERT(GetOpCode(gate) == OpCode::TYPED_BINARY_OP);
407     TypedBinaryAccessor accessor(TryGetValue(gate));
408     return accessor.GetTypedBinOp();
409 }
410 
HasNumberType(GateRef gate) const411 bool GateAccessor::HasNumberType(GateRef gate) const
412 {
413     OpCode op = GetOpCode(gate);
414     if (op == OpCode::TYPED_BINARY_OP) {
415         TypedBinaryAccessor accessor(TryGetValue(gate));
416         return accessor.GetParamType().HasNumberType();
417     }
418     return false;
419 }
420 
HasStringType(GateRef gate,bool onlyInternString) const421 bool GateAccessor::HasStringType(GateRef gate, bool onlyInternString) const
422 {
423     OpCode op = GetOpCode(gate);
424     if (op == OpCode::TYPED_BINARY_OP) {
425         TypedBinaryAccessor accessor(TryGetValue(gate));
426         bool isInternString = accessor.GetParamType().IsInternStringType();
427         if (onlyInternString) {
428             return isInternString;
429         }
430         return isInternString || accessor.GetParamType().IsStringType();
431     }
432     return false;
433 }
434 
IsInternStringType(GateRef gate) const435 bool GateAccessor::IsInternStringType(GateRef gate) const
436 {
437     return HasStringType(gate, true);
438 }
439 
GetFuncGT(GateRef gate) const440 GlobalTSTypeRef GateAccessor::GetFuncGT(GateRef gate) const
441 {
442     ASSERT(GetOpCode(gate) == OpCode::JSINLINETARGET_TYPE_CHECK);
443     Gate *gatePtr = circuit_->LoadGatePtr(gate);
444     auto value = static_cast<uint32_t>((gatePtr->GetOneParameterMetaData()->GetValue()));
445     return GlobalTSTypeRef(value);
446 }
447 
GetParamGateType(GateRef gate) const448 GateType GateAccessor::GetParamGateType(GateRef gate) const
449 {
450     // NOTICE-PGO: consider to delete this function in Part3, only primitive_type_check use,
451     // which is generate in the retype pass
452     ASSERT(GetOpCode(gate) == OpCode::PRIMITIVE_TYPE_CHECK);
453     Gate *gatePtr = circuit_->LoadGatePtr(gate);
454     GateTypeAccessor accessor(gatePtr->GetOneParameterMetaData()->GetValue());
455     return accessor.GetGateType();
456 }
457 
GetParamType(GateRef gate) const458 ParamType GateAccessor::GetParamType(GateRef gate) const
459 {
460     Gate *gatePtr = circuit_->LoadGatePtr(gate);
461     GateTypeAccessor accessor(gatePtr->GetOneParameterMetaData()->GetValue());
462     return accessor.GetParamType();
463 }
464 
IsConvertSupport(GateRef gate) const465 bool GateAccessor::IsConvertSupport(GateRef gate) const
466 {
467     ASSERT(GetOpCode(gate) == OpCode::CONVERT ||
468            GetOpCode(gate) == OpCode::CHECK_AND_CONVERT);
469     Gate *gatePtr = circuit_->LoadGatePtr(gate);
470     ValuePairTypeAccessor accessor(gatePtr->GetOneParameterMetaData()->GetValue());
471     return accessor.IsConvertSupport();
472 }
473 
GetSrcType(GateRef gate) const474 ValueType GateAccessor::GetSrcType(GateRef gate) const
475 {
476     ASSERT(GetOpCode(gate) == OpCode::CONVERT ||
477            GetOpCode(gate) == OpCode::CHECK_AND_CONVERT);
478     Gate *gatePtr = circuit_->LoadGatePtr(gate);
479     ValuePairTypeAccessor accessor(gatePtr->GetOneParameterMetaData()->GetValue());
480     return accessor.GetSrcType();
481 }
482 
GetDstType(GateRef gate) const483 ValueType GateAccessor::GetDstType(GateRef gate) const
484 {
485     ASSERT(GetOpCode(gate) == OpCode::CONVERT ||
486            GetOpCode(gate) == OpCode::CHECK_AND_CONVERT);
487     Gate *gatePtr = circuit_->LoadGatePtr(gate);
488     ValuePairTypeAccessor accessor(gatePtr->GetOneParameterMetaData()->GetValue());
489     return accessor.GetDstType();
490 }
491 
GetFirstValue(GateRef gate) const492 uint32_t GateAccessor::GetFirstValue(GateRef gate) const
493 {
494     ASSERT(GetOpCode(gate) == OpCode::RANGE_GUARD);
495     Gate *gatePtr = circuit_->LoadGatePtr(gate);
496     UInt32PairAccessor accessor(gatePtr->GetOneParameterMetaData()->GetValue());
497     return accessor.GetFirstValue();
498 }
499 
GetSecondValue(GateRef gate) const500 uint32_t GateAccessor::GetSecondValue(GateRef gate) const
501 {
502     ASSERT(GetOpCode(gate) == OpCode::RANGE_GUARD);
503     Gate *gatePtr = circuit_->LoadGatePtr(gate);
504     UInt32PairAccessor accessor(gatePtr->GetOneParameterMetaData()->GetValue());
505     return accessor.GetSecondValue();
506 }
507 
GetVirtualRegisterIndex(GateRef gate) const508 size_t GateAccessor::GetVirtualRegisterIndex(GateRef gate) const
509 {
510     ASSERT(GetOpCode(gate) == OpCode::SAVE_REGISTER ||
511            GetOpCode(gate) == OpCode::RESTORE_REGISTER);
512     Gate *gatePtr = circuit_->LoadGatePtr(gate);
513     return static_cast<size_t>(gatePtr->GetOneParameterMetaData()->GetValue());
514 }
515 
GetConstantValue(GateRef gate) const516 uint64_t GateAccessor::GetConstantValue(GateRef gate) const
517 {
518     ASSERT(GetOpCode(gate) == OpCode::CONSTANT);
519     Gate *gatePtr = circuit_->LoadGatePtr(gate);
520     return gatePtr->GetOneParameterMetaData()->GetValue();
521 }
522 
GetConstantString(GateRef gate) const523 const ChunkVector<char>& GateAccessor::GetConstantString(GateRef gate) const
524 {
525     ASSERT(GetOpCode(gate) == OpCode::CONSTSTRING);
526     Gate *gatePtr = circuit_->LoadGatePtr(gate);
527     return gatePtr->GetStringMetaData()->GetString();
528 }
529 
IsVtable(GateRef gate) const530 bool GateAccessor::IsVtable(GateRef gate) const
531 {
532     ASSERT(GetOpCode(gate) == OpCode::LOAD_PROPERTY);
533     Gate *gatePtr = circuit_->LoadGatePtr(gate);
534     return gatePtr->GetBoolMetaData()->GetBool();
535 }
536 
GetNoGCFlag(GateRef gate) const537 bool GateAccessor::GetNoGCFlag(GateRef gate) const
538 {
539     if (gate == Circuit::NullGate()) {
540         return false;
541     }
542     OpCode op = GetOpCode(gate);
543     if (op != OpCode::TYPEDCALL && op != OpCode::TYPEDFASTCALL) {
544         return false;
545     }
546     return TypedCallIsNoGC(gate);
547 }
548 
TypedCallIsNoGC(GateRef gate) const549 bool GateAccessor::TypedCallIsNoGC(GateRef gate) const
550 {
551     ASSERT(GetOpCode(gate) == OpCode::TYPEDCALL || GetOpCode(gate) == OpCode::TYPEDFASTCALL);
552     Gate *gatePtr = circuit_->LoadGatePtr(gate);
553     return gatePtr->GetTypedCallMetaData()->IsNoGC();
554 }
555 
IsNoGC(GateRef gate) const556 bool GateAccessor::IsNoGC(GateRef gate) const
557 {
558     ASSERT(GetOpCode(gate) == OpCode::CALL_OPTIMIZED || GetOpCode(gate) == OpCode::FAST_CALL_OPTIMIZED);
559     Gate *gatePtr = circuit_->LoadGatePtr(gate);
560     return gatePtr->GetBoolMetaData()->GetBool();
561 }
562 
TryGetPcOffset(GateRef gate) const563 uint32_t GateAccessor::TryGetPcOffset(GateRef gate) const
564 {
565     Gate *gatePtr = circuit_->LoadGatePtr(gate);
566     OpCode op = GetOpCode(gate);
567     switch (op) {
568         case OpCode::JS_BYTECODE:
569             return gatePtr->GetJSBytecodeMetaData()->GetPcOffset();
570         case OpCode::TYPED_CALL_BUILTIN:
571         case OpCode::TYPED_CALL_BUILTIN_SIDE_EFFECT:
572         case OpCode::CONSTRUCT:
573         case OpCode::CALL_NEW:
574         case OpCode::CALL_GETTER:
575         case OpCode::CALL_SETTER:
576         case OpCode::ARRAY_FOR_EACH:
577         case OpCode::ARRAY_FIND_OR_FINDINDEX:
578         case OpCode::ARRAY_FILTER:
579         case OpCode::ARRAY_MAP:
580         case OpCode::ARRAY_SOME:
581         case OpCode::ARRAY_EVERY:
582         case OpCode::FLOAT32_ARRAY_CONSTRUCTOR:
583             return static_cast<uint32_t>(gatePtr->GetOneParameterMetaData()->GetValue());
584         case OpCode::TYPEDCALL:
585         case OpCode::TYPEDFASTCALL:
586             return static_cast<uint32_t>(gatePtr->GetTypedCallMetaData()->GetValue());
587         case OpCode::FRAME_STATE: {
588             UInt32PairAccessor accessor(gatePtr->GetOneParameterMetaData()->GetValue());
589             return accessor.GetFirstValue();
590         }
591         default:
592             break;
593     }
594     return 0;
595 }
596 
TryGetBcIndex(GateRef gate) const597 uint32_t GateAccessor::TryGetBcIndex(GateRef gate) const
598 {
599     Gate *gatePtr = circuit_->LoadGatePtr(gate);
600     OpCode op = GetOpCode(gate);
601     switch (op) {
602         case OpCode::JS_BYTECODE:
603             return gatePtr->GetJSBytecodeMetaData()->GetBcIndex();
604         default:
605             break;
606     }
607     return INVALID_BC_INDEX;
608 }
609 
TryGetMethodOffset(GateRef gate) const610 uint32_t GateAccessor::TryGetMethodOffset(GateRef gate) const
611 {
612     Gate *gatePtr = circuit_->LoadGatePtr(gate);
613     OpCode op = GetOpCode(gate);
614     switch (op) {
615         case OpCode::FRAME_ARGS: {
616             UInt32PairAccessor accessor(gatePtr->GetOneParameterMetaData()->GetValue());
617             return accessor.GetFirstValue();
618         }
619         case OpCode::JS_BYTECODE: {
620             return gatePtr->GetJSBytecodeMetaData()->GetMethodId();
621         }
622         default:
623             break;
624     }
625     return 0;
626 }
627 
GetFrameArgs(GateRef gate) const628 GateRef GateAccessor::GetFrameArgs(GateRef gate) const
629 {
630     if (!HasFrameState(gate)) {
631         return Circuit::NullGate();
632     }
633     if (GetOpCode(gate) == OpCode::FRAME_STATE) {
634         return GetValueIn(gate, 0); // 0: frame args
635     }
636     GateRef frameState = GetFrameState(gate);
637     OpCode op = GetOpCode(frameState);
638     if (op == OpCode::FRAME_ARGS) {
639         return frameState;
640     }
641     if (op == OpCode::FRAME_STATE) {
642         return GetValueIn(frameState, 0); // 0: frame args
643     }
644     return Circuit::NullGate();
645 }
646 
UpdateMethodOffset(GateRef gate,uint32_t methodOffset)647 void GateAccessor::UpdateMethodOffset(GateRef gate, uint32_t methodOffset)
648 {
649     ASSERT(GetOpCode(gate) == OpCode::FRAME_ARGS);
650     Gate *gatePtr = circuit_->LoadGatePtr(gate);
651     UInt32PairAccessor accessor(methodOffset, 0);
652     const_cast<OneParameterMetaData *>(gatePtr->GetOneParameterMetaData())->SetValue(accessor.ToValue());
653 }
654 
TryGetPGOType(GateRef gate) const655 PGOTypeRef GateAccessor::TryGetPGOType(GateRef gate) const
656 {
657     Gate *gatePtr = circuit_->LoadGatePtr(gate);
658     OpCode op = GetOpCode(gate);
659     if (op == OpCode::JS_BYTECODE) {
660         return gatePtr->GetJSBytecodeMetaData()->GetType();
661     }
662     return PGOTypeRef::NoneType();
663 }
664 
TrySetPGOType(GateRef gate,PGOTypeRef type)665 void GateAccessor::TrySetPGOType(GateRef gate, PGOTypeRef type)
666 {
667     Gate *gatePtr = circuit_->LoadGatePtr(gate);
668     OpCode op = GetOpCode(gate);
669     if (op == OpCode::JS_BYTECODE) {
670         const_cast<JSBytecodeMetaData *>(gatePtr->GetJSBytecodeMetaData())->SetType(type);
671     }
672 }
673 
TryGetArrayElementsLength(GateRef gate) const674 uint32_t GateAccessor::TryGetArrayElementsLength(GateRef gate) const
675 {
676     Gate *gatePtr = circuit_->LoadGatePtr(gate);
677     OpCode op = GetOpCode(gate);
678     if (op == OpCode::JS_BYTECODE) {
679         return gatePtr->GetJSBytecodeMetaData()->GetElementsLength();
680     }
681     return 0;
682 }
683 
TrySetArrayElementsLength(GateRef gate,uint32_t length)684 void GateAccessor::TrySetArrayElementsLength(GateRef gate, uint32_t length)
685 {
686     Gate *gatePtr = circuit_->LoadGatePtr(gate);
687     OpCode op = GetOpCode(gate);
688     if (op == OpCode::JS_BYTECODE) {
689         const_cast<JSBytecodeMetaData *>(gatePtr->GetJSBytecodeMetaData())->SetElementsLength(length);
690     }
691 }
692 
TryGetRegionSpaceFlag(GateRef gate) const693 RegionSpaceFlag GateAccessor::TryGetRegionSpaceFlag(GateRef gate) const
694 {
695     Gate *gatePtr = circuit_->LoadGatePtr(gate);
696     OpCode op = GetOpCode(gate);
697     if (op == OpCode::JS_BYTECODE) {
698         return gatePtr->GetJSBytecodeMetaData()->GetRegionSpaceFlag();
699     }
700     return RegionSpaceFlag::IN_YOUNG_SPACE;
701 }
702 
TrySetRegionSpaceFlag(GateRef gate,RegionSpaceFlag flag)703 void GateAccessor::TrySetRegionSpaceFlag(GateRef gate, RegionSpaceFlag flag)
704 {
705     Gate *gatePtr = circuit_->LoadGatePtr(gate);
706     OpCode op = GetOpCode(gate);
707     if (op == OpCode::JS_BYTECODE) {
708         const_cast<JSBytecodeMetaData *>(gatePtr->GetJSBytecodeMetaData())->SetRegionSpaceFlag(flag);
709     }
710 }
711 
TryGetElementsKind(GateRef gate) const712 ElementsKind GateAccessor::TryGetElementsKind(GateRef gate) const
713 {
714     Gate *gatePtr = circuit_->LoadGatePtr(gate);
715     OpCode op = GetOpCode(gate);
716     if (op == OpCode::JS_BYTECODE) {
717         return Elements::FixElementsKind(gatePtr->GetJSBytecodeMetaData()->GetElementsKind());
718     }
719     return ElementsKind::GENERIC;
720 }
721 
722 // Default is getting elementsKind before possible transition
TryGetArrayElementsKind(GateRef gate) const723 ElementsKind GateAccessor::TryGetArrayElementsKind(GateRef gate) const
724 {
725     Gate *gatePtr = circuit_->LoadGatePtr(gate);
726     OpCode op = GetOpCode(gate);
727     if (op == OpCode::JS_BYTECODE) {
728         ElementsKind kind = gatePtr->GetJSBytecodeMetaData()->GetElementsKind();
729         if (Elements::IsGeneric(kind)) {
730             return kind;
731         }
732         std::vector<ElementsKind> kinds = gatePtr->GetJSBytecodeMetaData()->GetElementsKinds();
733         for (auto &x : kinds) {
734             kind = Elements::MergeElementsKind(kind, x);
735         }
736         return kind;
737     }
738     return ElementsKind::GENERIC;
739 }
740 
TryGetArrayElementsKindAfterTransition(GateRef gate) const741 ElementsKind GateAccessor::TryGetArrayElementsKindAfterTransition(GateRef gate) const
742 {
743     Gate *gatePtr = circuit_->LoadGatePtr(gate);
744     OpCode op = GetOpCode(gate);
745     if (op == OpCode::JS_BYTECODE) {
746         ElementsKind kind = gatePtr->GetJSBytecodeMetaData()->GetTransitionElementsKind();
747         if (Elements::IsGeneric(kind)) {
748             return kind;
749         }
750         std::vector<ElementsKind> kinds = gatePtr->GetJSBytecodeMetaData()->GetTransitionElementsKinds();
751         for (auto &x : kinds) {
752             kind = Elements::MergeElementsKind(kind, x);
753         }
754         return kind;
755     }
756     return ElementsKind::GENERIC;
757 }
758 
TrySetElementsKind(GateRef gate,ElementsKind kind)759 void GateAccessor::TrySetElementsKind(GateRef gate, ElementsKind kind)
760 {
761     Gate *gatePtr = circuit_->LoadGatePtr(gate);
762     OpCode op = GetOpCode(gate);
763     if (op == OpCode::JS_BYTECODE) {
764         const_cast<JSBytecodeMetaData *>(gatePtr->GetJSBytecodeMetaData())->SetElementsKind(kind);
765     }
766 }
767 
TrySetTransitionElementsKind(GateRef gate,ElementsKind kind)768 void GateAccessor::TrySetTransitionElementsKind(GateRef gate, ElementsKind kind)
769 {
770     Gate *gatePtr = circuit_->LoadGatePtr(gate);
771     OpCode op = GetOpCode(gate);
772     if (op == OpCode::JS_BYTECODE) {
773         const_cast<JSBytecodeMetaData *>(gatePtr->GetJSBytecodeMetaData())->SetTransitionElementsKind(kind);
774     }
775 }
776 
TrySetOnHeapMode(GateRef gate,OnHeapMode onHeapMode) const777 void GateAccessor::TrySetOnHeapMode(GateRef gate, OnHeapMode onHeapMode) const
778 {
779     Gate *gatePtr = circuit_->LoadGatePtr(gate);
780     OpCode op = GetOpCode(gate);
781     if (op == OpCode::JS_BYTECODE) {
782         const_cast<JSBytecodeMetaData *>(gatePtr->GetJSBytecodeMetaData())->SetOnHeapMode(onHeapMode);
783     }
784 }
785 
TryGetOnHeapMode(GateRef gate) const786 OnHeapMode GateAccessor::TryGetOnHeapMode(GateRef gate) const
787 {
788     Gate *gatePtr = circuit_->LoadGatePtr(gate);
789     OpCode op = GetOpCode(gate);
790     if (op == OpCode::JS_BYTECODE) {
791         return gatePtr->GetJSBytecodeMetaData()->GetOnHeapMode();
792     }
793     return OnHeapMode::NONE;
794 }
795 
GetByteCodeOpcode(GateRef gate) const796 EcmaOpcode GateAccessor::GetByteCodeOpcode(GateRef gate) const
797 {
798     ASSERT(GetOpCode(gate) == OpCode::JS_BYTECODE);
799     Gate *gatePtr = circuit_->LoadGatePtr(gate);
800     return gatePtr->GetJSBytecodeMetaData()->GetByteCodeOpcode();
801 }
802 
Print(GateRef gate) const803 void GateAccessor::Print(GateRef gate) const
804 {
805     Gate *gatePtr = circuit_->LoadGatePtr(gate);
806     auto comment = circuit_->GetComment(gate);
807     gatePtr->Print("", false, -1, comment);
808 }
809 
ToString(GateRef gate) const810 std::string GateAccessor::ToString(GateRef gate) const
811 {
812     Gate *gatePtr = circuit_->LoadGatePtr(gate);
813     return gatePtr->ToString();
814 }
815 
816 #ifndef NDEBUG
PrintById(size_t id) const817 void GateAccessor::PrintById(size_t id) const
818 {
819     GateRef gate = circuit_->GetGateRefById(id);
820     if (gate != Circuit::NullGate()) {
821         Gate *gatePtr = circuit_->LoadGatePtr(gate);
822         gatePtr->PrintWithBytecode(circuit_->GetComment(gate));
823     } else {
824         LOG_COMPILER(INFO) << "id overflow!";
825     }
826 }
827 #endif
828 
PrintWithBytecode(GateRef gate) const829 void GateAccessor::PrintWithBytecode(GateRef gate) const
830 {
831     Gate *gatePtr = circuit_->LoadGatePtr(gate);
832     gatePtr->PrintWithBytecode(circuit_->GetComment(gate));
833 }
834 
ShortPrint(GateRef gate) const835 void GateAccessor::ShortPrint(GateRef gate) const
836 {
837     Gate *gatePtr = circuit_->LoadGatePtr(gate);
838     gatePtr->ShortPrint();
839 }
840 
GetId(GateRef gate) const841 GateId GateAccessor::GetId(GateRef gate) const
842 {
843     Gate *gatePtr = circuit_->LoadGatePtr(gate);
844     return gatePtr->GetId();
845 }
846 
GetInValueStarts(GateRef gate) const847 size_t GateAccessor::GetInValueStarts(GateRef gate) const
848 {
849     Gate *gatePtr = circuit_->LoadGatePtr(gate);
850     return gatePtr->GetInValueStarts();
851 }
852 
GetValueIn(GateRef gate,size_t idx) const853 GateRef GateAccessor::GetValueIn(GateRef gate, size_t idx) const
854 {
855     Gate *gatePtr = circuit_->LoadGatePtr(gate);
856     ASSERT(idx < gatePtr->GetInValueCount());
857     size_t valueIndex = gatePtr->GetInValueStarts();
858     return circuit_->GetIn(gate, valueIndex + idx);
859 }
860 
GetNumValueIn(GateRef gate) const861 size_t GateAccessor::GetNumValueIn(GateRef gate) const
862 {
863     Gate *gatePtr = circuit_->LoadGatePtr(gate);
864     return gatePtr->GetInValueCount();
865 }
866 
GetValueIns(GateRef gate) const867 std::vector<GateRef> GateAccessor::GetValueIns(GateRef gate) const
868 {
869     size_t num = GetNumValueIn(gate);
870     std::vector<GateRef> valueIns(num);
871     for (size_t i = 0; i < num; ++i) {
872         valueIns[i] = GetValueIn(gate, i);
873     }
874     return valueIns;
875 }
876 
IsGCRelated(GateRef gate) const877 bool GateAccessor::IsGCRelated(GateRef gate) const
878 {
879     return GetGateType(gate).IsGCRelated();
880 }
881 
GetIn(GateRef gate,size_t idx) const882 GateRef GateAccessor::GetIn(GateRef gate, size_t idx) const
883 {
884     return circuit_->GetIn(gate, idx);
885 }
886 
GetState(GateRef gate,size_t idx) const887 GateRef GateAccessor::GetState(GateRef gate, size_t idx) const
888 {
889     ASSERT(idx < circuit_->LoadGatePtr(gate)->GetStateCount());
890     return circuit_->GetIn(gate, idx);
891 }
892 
GetInStates(GateRef gate,std::vector<GateRef> & ins) const893 void GateAccessor::GetInStates(GateRef gate, std::vector<GateRef>& ins) const
894 {
895     const Gate *curGate = circuit_->LoadGatePtrConst(gate);
896     for (size_t idx = 0; idx < curGate->GetStateCount(); idx++) {
897         ins.push_back(circuit_->GetGateRef(curGate->GetInGateConst(idx)));
898     }
899 }
900 
GetIns(GateRef gate,std::vector<GateRef> & ins) const901 void GateAccessor::GetIns(GateRef gate, std::vector<GateRef>& ins) const
902 {
903     const Gate *curGate = circuit_->LoadGatePtrConst(gate);
904     for (size_t idx = 0; idx < curGate->GetNumIns(); idx++) {
905         ins.push_back(circuit_->GetGateRef(curGate->GetInGateConst(idx)));
906     }
907 }
908 
GetOuts(GateRef gate,std::vector<GateRef> & outs) const909 void GateAccessor::GetOuts(GateRef gate, std::vector<GateRef>& outs) const
910 {
911     const Gate *curGate = circuit_->LoadGatePtrConst(gate);
912     if (!curGate->IsFirstOutNull()) {
913         const Out *curOut = curGate->GetFirstOutConst();
914         GateRef ref = circuit_->GetGateRef(curOut->GetGateConst());
915         outs.push_back(ref);
916         while (!curOut->IsNextOutNull()) {
917             curOut = curOut->GetNextOutConst();
918             ref = circuit_->GetGateRef(curOut->GetGateConst());
919             outs.push_back(ref);
920         }
921     }
922 }
923 
HasOuts(GateRef gate) const924 bool GateAccessor::HasOuts(GateRef gate) const
925 {
926     const Gate *curGate = circuit_->LoadGatePtrConst(gate);
927     return !curGate->IsFirstOutNull();
928 }
929 
DeleteGateIfNoUse(GateRef gate)930 void GateAccessor::DeleteGateIfNoUse(GateRef gate)
931 {
932     if (!HasOuts(gate)) {
933         DeleteGate(gate);
934     }
935 }
936 
GetOutStates(GateRef gate,std::vector<GateRef> & outStates) const937 void GateAccessor::GetOutStates(GateRef gate, std::vector<GateRef>& outStates) const
938 {
939     const Gate *curGate = circuit_->LoadGatePtrConst(gate);
940     if (!curGate->IsFirstOutNull()) {
941         const Out *curOut = curGate->GetFirstOutConst();
942         GateRef ref = circuit_->GetGateRef(curOut->GetGateConst());
943         if (GetMetaData(ref)->IsState()) {
944             outStates.push_back(ref);
945         }
946         while (!curOut->IsNextOutNull()) {
947             curOut = curOut->GetNextOutConst();
948             ref = circuit_->GetGateRef(curOut->GetGateConst());
949             if (GetMetaData(ref)->IsState()) {
950                 outStates.push_back(ref);
951             }
952         }
953     }
954 }
955 
GetStateUses(GateRef gate,std::vector<GateRef> & stateUses)956 void GateAccessor::GetStateUses(GateRef gate, std::vector<GateRef> &stateUses)
957 {
958     stateUses.clear();
959     auto uses = Uses(gate);
960     for (auto it = uses.begin(); it != uses.end(); it++) {
961         if (IsStateIn(it)) {
962             stateUses.emplace_back(*it);
963         }
964     }
965 }
966 
GetDependUses(GateRef gate,std::vector<GateRef> & dependUses)967 void GateAccessor::GetDependUses(GateRef gate, std::vector<GateRef> &dependUses)
968 {
969     dependUses.clear();
970     auto uses = Uses(gate);
971     for (auto it = uses.begin(); it != uses.end(); it++) {
972         if (IsDependIn(it)) {
973             dependUses.emplace_back(*it);
974         }
975     }
976 }
977 
GetValueUses(GateRef gate,std::vector<GateRef> & valueUses)978 void GateAccessor::GetValueUses(GateRef gate, std::vector<GateRef> &valueUses)
979 {
980     valueUses.clear();
981     auto uses = Uses(gate);
982     for (auto it = uses.begin(); it != uses.end(); it++) {
983         if (IsValueIn(it)) {
984             valueUses.emplace_back(*it);
985         }
986     }
987 }
988 
GetValueUsesCount(GateRef gate)989 size_t GateAccessor::GetValueUsesCount(GateRef gate)
990 {
991     size_t count = 0;
992     auto uses = Uses(gate);
993     for (auto it = uses.begin(); it != uses.end(); it++) {
994         if (IsValueIn(it)) {
995             count++;
996         }
997     }
998     return count;
999 }
1000 
GetAllGates(std::vector<GateRef> & gates) const1001 void GateAccessor::GetAllGates(std::vector<GateRef>& gates) const
1002 {
1003     circuit_->GetAllGates(gates);
1004 }
1005 
IsInGateNull(GateRef gate,size_t idx) const1006 bool GateAccessor::IsInGateNull(GateRef gate, size_t idx) const
1007 {
1008     return circuit_->IsInGateNull(gate, idx);
1009 }
1010 
IsValueSelector(GateRef g) const1011 bool GateAccessor::IsValueSelector(GateRef g) const
1012 {
1013     return GetOpCode(g) == OpCode::VALUE_SELECTOR;
1014 }
1015 
IsSelector(GateRef g) const1016 bool GateAccessor::IsSelector(GateRef g) const
1017 {
1018     auto op = GetOpCode(g);
1019     return (op == OpCode::VALUE_SELECTOR) || (op == OpCode::DEPEND_SELECTOR);
1020 }
1021 
IsFrameValues(GateRef g) const1022 bool GateAccessor::IsFrameValues(GateRef g) const
1023 {
1024     auto op = GetOpCode(g);
1025     return op == OpCode::FRAME_VALUES;
1026 }
1027 
IsIn(GateRef g,GateRef in) const1028 bool GateAccessor::IsIn(GateRef g, GateRef in) const
1029 {
1030     size_t n = GetNumIns(g);
1031     for (size_t id = 0; id < n; id++) {
1032         GateRef i = GetIn(g, id);
1033         if (i == in) {
1034             return true;
1035         }
1036     }
1037     return false;
1038 }
1039 
IsSimpleState(GateRef g) const1040 bool GateAccessor::IsSimpleState(GateRef g) const
1041 {
1042     auto op = GetOpCode(g);
1043     return (op == OpCode::IF_TRUE ||
1044             op == OpCode::IF_FALSE ||
1045             op == OpCode::SWITCH_CASE ||
1046             op == OpCode::DEFAULT_CASE ||
1047             op == OpCode::LOOP_BACK ||
1048             op == OpCode::MERGE ||
1049             op == OpCode::VALUE_SELECTOR ||
1050             op == OpCode::DEPEND_SELECTOR ||
1051             op == OpCode::DEPEND_RELAY ||
1052             op == OpCode::ORDINARY_BLOCK);
1053 }
1054 
IsControlCase(GateRef gate) const1055 bool GateAccessor::IsControlCase(GateRef gate) const
1056 {
1057     return circuit_->IsControlCase(gate);
1058 }
1059 
IsLoopExit(GateRef gate) const1060 bool GateAccessor::IsLoopExit(GateRef gate) const
1061 {
1062     return (GetOpCode(gate) == OpCode::LOOP_EXIT);
1063 }
1064 
IsLoopExitRelated(GateRef gate) const1065 bool GateAccessor::IsLoopExitRelated(GateRef gate) const
1066 {
1067     return (GetOpCode(gate) == OpCode::LOOP_EXIT) ||
1068            (GetOpCode(gate) == OpCode::LOOP_EXIT_DEPEND) ||
1069            (GetOpCode(gate) == OpCode::LOOP_EXIT_VALUE);
1070 }
1071 
IsLoopHead(GateRef gate) const1072 bool GateAccessor::IsLoopHead(GateRef gate) const
1073 {
1074     return circuit_->IsLoopHead(gate);
1075 }
1076 
IsLoopBack(GateRef gate) const1077 bool GateAccessor::IsLoopBack(GateRef gate) const
1078 {
1079     return GetOpCode(gate) == OpCode::LOOP_BACK;
1080 }
1081 
IsState(GateRef gate) const1082 bool GateAccessor::IsState(GateRef gate) const
1083 {
1084     return GetMetaData(gate)->IsState();
1085 }
1086 
IsConstant(GateRef gate) const1087 bool GateAccessor::IsConstant(GateRef gate) const
1088 {
1089     return GetMetaData(gate)->IsConstant();
1090 }
1091 
IsDependSelector(GateRef gate) const1092 bool GateAccessor::IsDependSelector(GateRef gate) const
1093 {
1094     return GetMetaData(gate)->IsDependSelector();
1095 }
1096 
IsConstantValue(GateRef gate,uint64_t value) const1097 bool GateAccessor::IsConstantValue(GateRef gate, uint64_t value) const
1098 {
1099     if (GetOpCode(gate) == OpCode::CONSTANT) {
1100         uint64_t bitField = GetConstantValue(gate);
1101         return bitField == value;
1102     }
1103     return false;
1104 }
1105 
IsConstantTaggedValue(GateRef gate,uint64_t value) const1106 bool GateAccessor::IsConstantTaggedValue(GateRef gate, uint64_t value) const
1107 {
1108     if (GetMachineType(gate) != MachineType::I64 || GetGateType(gate).IsNJSValueType()) {
1109         return false;
1110     }
1111     if (GetOpCode(gate) == OpCode::CONSTANT) {
1112         uint64_t bitField = GetConstantValue(gate);
1113         return bitField == value;
1114     }
1115     return false;
1116 }
1117 
IsConstantUndefined(GateRef gate) const1118 bool GateAccessor::IsConstantUndefined(GateRef gate) const
1119 {
1120     return IsConstantTaggedValue(gate, JSTaggedValue::VALUE_UNDEFINED);
1121 }
1122 
IsUndefinedOrNullOrHole(GateRef gate) const1123 bool GateAccessor::IsUndefinedOrNullOrHole(GateRef gate) const
1124 {
1125     return IsConstantTaggedValue(gate, JSTaggedValue::VALUE_UNDEFINED) ||
1126            IsConstantTaggedValue(gate, JSTaggedValue::VALUE_NULL) ||
1127            IsConstantTaggedValue(gate, JSTaggedValue::VALUE_HOLE);
1128 }
1129 
IsTypedOperator(GateRef gate) const1130 bool GateAccessor::IsTypedOperator(GateRef gate) const
1131 {
1132     return GetMetaData(gate)->IsTypedOperator();
1133 }
1134 
IsNotWrite(GateRef gate) const1135 bool GateAccessor::IsNotWrite(GateRef gate) const
1136 {
1137     return GetMetaData(gate)->IsNotWrite();
1138 }
1139 
IsCheckWithTwoIns(GateRef gate) const1140 bool GateAccessor::IsCheckWithTwoIns(GateRef gate) const
1141 {
1142     return GetMetaData(gate)->IsCheckWithTwoIns();
1143 }
1144 
IsCheckWithOneIn(GateRef gate) const1145 bool GateAccessor::IsCheckWithOneIn(GateRef gate) const
1146 {
1147     return GetMetaData(gate)->IsCheckWithOneIn();
1148 }
1149 
IsSchedulable(GateRef gate) const1150 bool GateAccessor::IsSchedulable(GateRef gate) const
1151 {
1152     return GetMetaData(gate)->IsSchedulable();
1153 }
1154 
IsVirtualState(GateRef gate) const1155 bool GateAccessor::IsVirtualState(GateRef gate) const
1156 {
1157     return GetMetaData(gate)->IsVirtualState();
1158 }
1159 
IsGeneralState(GateRef gate) const1160 bool GateAccessor::IsGeneralState(GateRef gate) const
1161 {
1162     return GetMetaData(gate)->IsGeneralState();
1163 }
1164 
IsIfOrSwitchRelated(GateRef gate) const1165 bool GateAccessor::IsIfOrSwitchRelated(GateRef gate) const
1166 {
1167     return GetMetaData(gate)->IsIfOrSwitchRelated();
1168 }
1169 
GetDep(GateRef gate,size_t idx) const1170 GateRef GateAccessor::GetDep(GateRef gate, size_t idx) const
1171 {
1172     Gate *gatePtr = circuit_->LoadGatePtr(gate);
1173     ASSERT(idx < gatePtr->GetDependCount());
1174     size_t dependIndex = gatePtr->GetStateCount();
1175     return circuit_->GetIn(gate, dependIndex + idx);
1176 }
1177 
GetImmediateId(GateRef gate) const1178 size_t GateAccessor::GetImmediateId(GateRef gate) const
1179 {
1180     Gate *gatePtr = circuit_->LoadGatePtr(gate);
1181     ASSERT(gatePtr->GetGateType() == GateType::NJSValue());
1182     ASSERT(gatePtr->GetOpCode() == OpCode::CONSTANT);
1183     ASSERT(gatePtr->GetMachineType() == MachineType::I64);
1184     size_t imm = gatePtr->GetOneParameterMetaData()->GetValue();
1185     return imm;
1186 }
1187 
SetDep(GateRef gate,GateRef depGate,size_t idx)1188 void GateAccessor::SetDep(GateRef gate, GateRef depGate, size_t idx)
1189 {
1190     Gate *gatePtr = circuit_->LoadGatePtr(gate);
1191     ASSERT(idx < gatePtr->GetDependCount());
1192     size_t dependIndex = gatePtr->GetStateCount();
1193     gatePtr->ModifyIn(dependIndex + idx, circuit_->LoadGatePtr(depGate));
1194 }
1195 
ReplaceIn(const UseIterator & useIt,GateRef replaceGate)1196 UseIterator GateAccessor::ReplaceIn(const UseIterator &useIt, GateRef replaceGate)
1197 {
1198     UseIterator next = useIt;
1199     next++;
1200     Gate *curGatePtr = circuit_->LoadGatePtr(*useIt);
1201     Gate *replaceGatePtr = circuit_->LoadGatePtr(replaceGate);
1202     curGatePtr->ModifyIn(useIt.GetIndex(), replaceGatePtr);
1203     return next;
1204 }
1205 
GetGateType(GateRef gate) const1206 GateType GateAccessor::GetGateType(GateRef gate) const
1207 {
1208     return circuit_->LoadGatePtr(gate)->GetGateType();
1209 }
1210 
SetGateType(GateRef gate,GateType gt)1211 void GateAccessor::SetGateType(GateRef gate, GateType gt)
1212 {
1213     circuit_->LoadGatePtr(gate)->SetGateType(gt);
1214 }
1215 
ReplaceHirIfSuccess(const UseIterator & useIt,GateRef state)1216 UseIterator GateAccessor::ReplaceHirIfSuccess(const UseIterator &useIt, GateRef state)
1217 {
1218     ASSERT(GetOpCode(*useIt) == OpCode::IF_SUCCESS);
1219     auto uses = Uses(*useIt);
1220     for (auto it = uses.begin(); it != uses.end();) {
1221         if (IsStateIn(it)) {
1222             it = ReplaceIn(it, state);
1223         }
1224     }
1225     auto next = DeleteGate(useIt);
1226     return next;
1227 }
1228 
ReplaceHirIfException(const UseIterator & useIt,StateDepend replacement)1229 UseIterator GateAccessor::ReplaceHirIfException(const UseIterator &useIt, StateDepend replacement)
1230 {
1231     ASSERT(GetOpCode(*useIt) == OpCode::IF_EXCEPTION);
1232     auto uses = Uses(*useIt);
1233     for (auto it = uses.begin(); it != uses.end();) {
1234         if (IsStateIn(it)) {
1235             it = ReplaceIn(it, replacement.State());
1236         } else if (IsDependIn(it)) {
1237             it = ReplaceIn(it, replacement.Depend());
1238         } else {
1239             ASSERT(!IsValueIn(it));
1240         }
1241     }
1242     UseIterator next = useIt;
1243     next++;
1244     return next;
1245 }
1246 
ExceptionReturn(GateRef state,GateRef depend)1247 void GateAccessor::ExceptionReturn(GateRef state, GateRef depend)
1248 {
1249     CircuitBuilder builder(circuit_);
1250     auto constant = builder.ExceptionConstant();
1251     builder.Return(state, depend, constant);
1252 }
1253 
ReplaceHirWithIfBranch(GateRef hirGate,StateDepend success,StateDepend exception,GateRef value)1254 void GateAccessor::ReplaceHirWithIfBranch(GateRef hirGate, StateDepend success,
1255                                           StateDepend exception, GateRef value)
1256 {
1257     auto uses = Uses(hirGate);
1258     GateRef ifException = Circuit::NullGate();
1259     for (auto it = uses.begin(); it != uses.end();) {
1260         if (IsStateIn(it)) {
1261             const OpCode op = GetOpCode(*it);
1262             if (op == OpCode::IF_SUCCESS) {
1263                 it = ReplaceHirIfSuccess(it, success.State());
1264             } else if (op == OpCode::IF_EXCEPTION) {
1265                 ifException = *it;
1266                 it = ReplaceHirIfException(it, exception);
1267             } else if (GetMetaData(*it)->IsVirtualState()) {
1268                 it = ReplaceIn(it, success.State());
1269             } else {
1270                 ExceptionReturn(exception.State(), exception.Depend());
1271                 it = ReplaceIn(it, success.State());
1272             }
1273         } else if (IsDependIn(it)) {
1274             const OpCode op = GetOpCode(*it);
1275             if (op == OpCode::IF_EXCEPTION) {
1276                 // ignore it now.
1277                 it++;
1278             } else {
1279                 it = ReplaceIn(it, success.Depend());
1280             }
1281         } else {
1282             ASSERT(IsValueIn(it));
1283             it = ReplaceIn(it, value);
1284         }
1285     }
1286 
1287     if (ifException != Circuit::NullGate()) {
1288         DeleteGate(ifException);
1289     }
1290 
1291     // delete old gate
1292     DeleteGate(hirGate);
1293 }
1294 
ReplaceHirDirectly(GateRef hirGate,StateDepend replacement,GateRef value)1295 void GateAccessor::ReplaceHirDirectly(GateRef hirGate,
1296     StateDepend replacement, GateRef value)
1297 {
1298     auto uses = Uses(hirGate);
1299     for (auto it = uses.begin(); it != uses.end();) {
1300         if (IsStateIn(it)) {
1301             ASSERT(GetOpCode(*it) != OpCode::IF_SUCCESS &&
1302                 GetOpCode(*it) != OpCode::IF_EXCEPTION);
1303             it = ReplaceIn(it, replacement.State());
1304         } else if (IsDependIn(it)) {
1305             it = ReplaceIn(it, replacement.Depend());
1306         } else {
1307             ASSERT(IsValueIn(it));
1308             it = ReplaceIn(it, value);
1309         }
1310     }
1311 
1312     // delete old gate
1313     DeleteGate(hirGate);
1314 }
1315 
ReplaceHirAndDeleteIfException(GateRef hirGate,StateDepend replacement,GateRef value)1316 void GateAccessor::ReplaceHirAndDeleteIfException(GateRef hirGate,
1317     StateDepend replacement, GateRef value)
1318 {
1319     if (value != Circuit::NullGate()) {
1320         auto type = GetGateType(hirGate);
1321         if (!type.IsAnyType()) {
1322             SetGateType(value, type);
1323         }
1324     }
1325     GateRef ifException = Circuit::NullGate();
1326     auto uses = Uses(hirGate);
1327     for (auto it = uses.begin(); it != uses.end();) {
1328         if (IsStateIn(it)) {
1329             const OpCode op = GetOpCode(*it);
1330             if (op == OpCode::IF_SUCCESS) {
1331                 it = ReplaceHirIfSuccess(it, replacement.State());
1332             } else if (op == OpCode::IF_EXCEPTION) {
1333                 ifException = *it;
1334                 it = ReplaceIn(it, circuit_->DeadGate());
1335             } else {
1336                 it = ReplaceIn(it, replacement.State());
1337             }
1338         } else if (IsDependIn(it)) {
1339             const OpCode op = GetOpCode(*it);
1340             if (op == OpCode::IF_EXCEPTION) {
1341                 it = ReplaceIn(it, circuit_->DeadGate());
1342             } else {
1343                 it = ReplaceIn(it, replacement.Depend());
1344             }
1345         } else {
1346             ASSERT(IsValueIn(it));
1347             it = ReplaceIn(it, value);
1348         }
1349     }
1350 
1351     // delete old gate
1352     DeleteGate(hirGate);
1353     if (ifException != Circuit::NullGate()) {
1354         ReplaceGate(ifException, circuit_->DeadGate());
1355     }
1356     #ifndef NDEBUG
1357         GetCircuit()->AddComment(value,  "old V " + std::to_string(GetId(hirGate)));
1358         GetCircuit()->AddComment(replacement.Depend(),  "old D " + std::to_string(GetId(hirGate)));
1359     #endif
1360 }
1361 
DeleteGate(const UseIterator & useIt)1362 UseIterator GateAccessor::DeleteGate(const UseIterator &useIt)
1363 {
1364     auto next = useIt;
1365     next++;
1366     circuit_->DeleteGate(*useIt);
1367     return next;
1368 }
1369 
DecreaseIn(const UseIterator & useIt)1370 void GateAccessor::DecreaseIn(const UseIterator &useIt)
1371 {
1372     size_t idx = useIt.GetIndex();
1373     circuit_->DecreaseIn(*useIt, idx);
1374 }
1375 
DecreaseIn(GateRef gate,size_t index)1376 void GateAccessor::DecreaseIn(GateRef gate, size_t index)
1377 {
1378     circuit_->DecreaseIn(gate, index);
1379 }
1380 
NewIn(GateRef gate,size_t idx,GateRef in)1381 void GateAccessor::NewIn(GateRef gate, size_t idx, GateRef in)
1382 {
1383     circuit_->NewIn(gate, idx, in);
1384 }
1385 
GetStateCount(GateRef gate) const1386 size_t GateAccessor::GetStateCount(GateRef gate) const
1387 {
1388     return circuit_->LoadGatePtr(gate)->GetStateCount();
1389 }
1390 
GetDependCount(GateRef gate) const1391 size_t GateAccessor::GetDependCount(GateRef gate) const
1392 {
1393     return circuit_->LoadGatePtr(gate)->GetDependCount();
1394 }
1395 
GetInValueCount(GateRef gate) const1396 size_t GateAccessor::GetInValueCount(GateRef gate) const
1397 {
1398     return circuit_->LoadGatePtr(gate)->GetInValueCount();
1399 }
1400 
UpdateAllUses(GateRef oldIn,GateRef newIn)1401 void GateAccessor::UpdateAllUses(GateRef oldIn, GateRef newIn)
1402 {
1403     if (oldIn == newIn) {
1404         return;
1405     }
1406     auto uses = Uses(oldIn);
1407     for (auto useIt = uses.begin(); useIt != uses.end();) {
1408         useIt = ReplaceIn(useIt, newIn);
1409     }
1410 }
1411 
ReplaceIn(GateRef gate,size_t index,GateRef in)1412 void GateAccessor::ReplaceIn(GateRef gate, size_t index, GateRef in)
1413 {
1414     circuit_->ModifyIn(gate, index, in);
1415 }
1416 
DeleteIn(GateRef gate,size_t idx)1417 void GateAccessor::DeleteIn(GateRef gate, size_t idx)
1418 {
1419     ASSERT(idx < circuit_->LoadGatePtrConst(gate)->GetNumIns());
1420     ASSERT(!circuit_->IsInGateNull(gate, idx));
1421     circuit_->LoadGatePtr(gate)->DeleteIn(idx);
1422 }
1423 
ReplaceStateIn(GateRef gate,GateRef in,size_t index)1424 void GateAccessor::ReplaceStateIn(GateRef gate, GateRef in, size_t index)
1425 {
1426     ASSERT(index < GetStateCount(gate));
1427     circuit_->ModifyIn(gate, index, in);
1428 }
1429 
ReplaceDependIn(GateRef gate,GateRef in,size_t index)1430 void GateAccessor::ReplaceDependIn(GateRef gate, GateRef in, size_t index)
1431 {
1432     ASSERT(index < GetDependCount(gate));
1433     size_t stateCount = GetStateCount(gate);
1434     circuit_->ModifyIn(gate, stateCount + index, in);
1435 }
1436 
ReplaceOrNewDependIn(GateRef gate,GateRef in,size_t index)1437 void GateAccessor::ReplaceOrNewDependIn(GateRef gate, GateRef in, size_t index)
1438 {
1439     ASSERT(index < GetDependCount(gate));
1440     size_t stateCount = GetStateCount(gate);
1441     auto depend = GetDep(gate);
1442     if (depend == Circuit::NullGate()) {
1443         circuit_->NewIn(gate, stateCount + index, in);
1444     } else {
1445         circuit_->ModifyIn(gate, stateCount + index, in);
1446     }
1447 }
1448 
ReplaceValueIn(GateRef gate,GateRef in,size_t index)1449 void GateAccessor::ReplaceValueIn(GateRef gate, GateRef in, size_t index)
1450 {
1451     ASSERT(index < GetInValueCount(gate));
1452     size_t valueStartIndex = GetInValueStarts(gate);
1453     circuit_->ModifyIn(gate, valueStartIndex + index, in);
1454 }
1455 
DeleteGate(GateRef gate)1456 void GateAccessor::DeleteGate(GateRef gate)
1457 {
1458     circuit_->DeleteGate(gate);
1459 }
1460 
GetMachineType(GateRef gate) const1461 MachineType GateAccessor::GetMachineType(GateRef gate) const
1462 {
1463     return circuit_->GetMachineType(gate);
1464 }
1465 
SetMachineType(GateRef gate,MachineType type)1466 void GateAccessor::SetMachineType(GateRef gate, MachineType type)
1467 {
1468     circuit_->SetMachineType(gate, type);
1469 }
1470 
GetConstantGate(MachineType bitValue,BitField bitfield,GateType type) const1471 GateRef GateAccessor::GetConstantGate(MachineType bitValue, BitField bitfield, GateType type) const
1472 {
1473     return circuit_->GetConstantGate(bitValue, bitfield, type);
1474 }
1475 
GetInitialEnvGate(GateRef depend,GateRef jsFunc) const1476 GateRef GateAccessor::GetInitialEnvGate(GateRef depend, GateRef jsFunc) const
1477 {
1478     return circuit_->GetInitialEnvGate(depend, jsFunc);
1479 }
1480 
IsConstantNumber(GateRef gate) const1481 bool GateAccessor::IsConstantNumber(GateRef gate) const
1482 {
1483     DISALLOW_GARBAGE_COLLECTION;
1484     if (GetGateType(gate).IsNJSValueType() ||
1485         (GetOpCode(gate) != OpCode::CONSTANT)) {
1486         return false;
1487     }
1488     JSTaggedValue value(GetConstantValue(gate));
1489     return value.IsNumber();
1490 }
1491 
GetFloat64FromConstant(GateRef gate) const1492 double GateAccessor::GetFloat64FromConstant(GateRef gate) const
1493 {
1494     DISALLOW_GARBAGE_COLLECTION;
1495     ASSERT(GetOpCode(gate) == OpCode::CONSTANT);
1496     uint64_t rawValue = GetConstantValue(gate);
1497     if (GetGateType(gate).IsNJSValueType()) {
1498         ASSERT(GetMachineType(gate) == MachineType::F64);
1499         return base::bit_cast<double>(rawValue);
1500     }
1501     JSTaggedValue value(rawValue);
1502     return value.GetDouble();
1503 }
1504 
GetInt32FromConstant(GateRef gate) const1505 int GateAccessor::GetInt32FromConstant(GateRef gate) const
1506 {
1507     DISALLOW_GARBAGE_COLLECTION;
1508     ASSERT(GetOpCode(gate) == OpCode::CONSTANT);
1509     uint64_t rawValue = GetConstantValue(gate);
1510     if (GetGateType(gate).IsNJSValueType()) {
1511         ASSERT(GetMachineType(gate) == MachineType::I32);
1512         return static_cast<int>(rawValue);
1513     }
1514     JSTaggedValue value(rawValue);
1515     return value.GetInt();
1516 }
1517 
IsStateIn(const UseIterator & useIt) const1518 bool GateAccessor::IsStateIn(const UseIterator &useIt) const
1519 {
1520     size_t stateStartIndex = 0;
1521     size_t stateEndIndex = stateStartIndex + GetStateCount(*useIt);
1522     size_t index = useIt.GetIndex();
1523     return (index >= stateStartIndex && index < stateEndIndex);
1524 }
1525 
IsDependIn(const UseIterator & useIt) const1526 bool GateAccessor::IsDependIn(const UseIterator &useIt) const
1527 {
1528     size_t dependStartIndex = GetStateCount(*useIt);
1529     size_t dependEndIndex = dependStartIndex + GetDependCount(*useIt);
1530     size_t index = useIt.GetIndex();
1531     return (index >= dependStartIndex && index < dependEndIndex);
1532 }
1533 
IsValueIn(const UseIterator & useIt) const1534 bool GateAccessor::IsValueIn(const UseIterator &useIt) const
1535 {
1536     size_t valueStartIndex = GetInValueStarts(*useIt);
1537     size_t valueEndIndex = valueStartIndex + GetInValueCount(*useIt);
1538     size_t index = useIt.GetIndex();
1539     return (index >= valueStartIndex && index < valueEndIndex);
1540 }
1541 
IsFrameStateIn(const UseIterator & useIt) const1542 bool GateAccessor::IsFrameStateIn(const UseIterator &useIt) const
1543 {
1544     size_t index = useIt.GetIndex();
1545     return IsFrameStateIn(*useIt, index);
1546 }
1547 
IsStateIn(GateRef gate,size_t index) const1548 bool GateAccessor::IsStateIn(GateRef gate, size_t index) const
1549 {
1550     size_t stateStartIndex = 0;
1551     size_t stateEndIndex = stateStartIndex + GetStateCount(gate);
1552     return (index >= stateStartIndex && index < stateEndIndex);
1553 }
1554 
IsDependIn(GateRef gate,size_t index) const1555 bool GateAccessor::IsDependIn(GateRef gate, size_t index) const
1556 {
1557     size_t dependStartIndex = GetStateCount(gate);
1558     size_t dependEndIndex = dependStartIndex + GetDependCount(gate);
1559     return (index >= dependStartIndex && index < dependEndIndex);
1560 }
1561 
IsValueIn(GateRef gate,size_t index) const1562 bool GateAccessor::IsValueIn(GateRef gate, size_t index) const
1563 {
1564     size_t valueStartIndex = GetInValueStarts(gate);
1565     size_t valueEndIndex = valueStartIndex + GetInValueCount(gate);
1566     return (index >= valueStartIndex && index < valueEndIndex);
1567 }
1568 
IsFrameStateIn(GateRef gate,size_t index) const1569 bool GateAccessor::IsFrameStateIn(GateRef gate, size_t index) const
1570 {
1571     Gate *gatePtr = circuit_->LoadGatePtr(gate);
1572     size_t frameStateStartIndex = gatePtr->GetInFrameStateStarts();
1573     size_t FrameStateEndIndex = frameStateStartIndex + gatePtr->GetInFrameStateCount();
1574     return (index >= frameStateStartIndex && index < FrameStateEndIndex);
1575 }
1576 
ReplaceGate(GateRef gate,GateRef state,GateRef depend,GateRef value)1577 void GateAccessor::ReplaceGate(GateRef gate, GateRef state, GateRef depend, GateRef value)
1578 {
1579     if (value != Circuit::NullGate()) {
1580         GateType type = GetGateType(gate);
1581         GateType valueType = GetGateType(value);
1582         if (!type.IsAnyType() && !valueType.IsNJSValueType()) {
1583             SetGateType(value, type);
1584         }
1585     }
1586 
1587     auto uses = Uses(gate);
1588     for (auto useIt = uses.begin(); useIt != uses.end();) {
1589         if (IsStateIn(useIt)) {
1590             ASSERT(state != Circuit::NullGate());
1591             useIt = ReplaceIn(useIt, state);
1592         } else if (IsDependIn(useIt)) {
1593             ASSERT(depend != Circuit::NullGate());
1594             useIt = ReplaceIn(useIt, depend);
1595         } else if (IsValueIn(useIt)) {
1596             ASSERT(value != Circuit::NullGate());
1597             useIt = ReplaceIn(useIt, value);
1598         } else {
1599             LOG_ECMA(FATAL) << "this branch is unreachable";
1600             UNREACHABLE();
1601         }
1602     }
1603 #ifndef NDEBUG
1604     GetCircuit()->AddComment(value,  "old V " + std::to_string(GetId(gate)));
1605 #endif
1606     DeleteGate(gate);
1607 }
1608 
ReplaceGate(GateRef gate,GateRef replacement)1609 void GateAccessor::ReplaceGate(GateRef gate, GateRef replacement)
1610 {
1611     GateRef depend = Circuit::NullGate();
1612     if (GetDependCount(gate) > 0) {
1613         ASSERT(GetDependCount(gate) == 1); // 1: one dep
1614         depend = GetDep(gate);
1615     }
1616     GateRef state = Circuit::NullGate();
1617     if (GetStateCount(gate) > 0) {
1618         ASSERT(GetStateCount(gate) == 1);  // 1: one state
1619         state = GetState(gate);
1620     }
1621     return ReplaceGate(gate, StateDepend {state, depend}, replacement);
1622 }
1623 
ReplaceGate(GateRef gate,StateDepend stateDepend,GateRef replacement)1624 void GateAccessor::ReplaceGate(GateRef gate, StateDepend stateDepend, GateRef replacement)
1625 {
1626     ASSERT(gate != replacement);
1627     auto state = stateDepend.State();
1628     auto depend = stateDepend.Depend();
1629     auto uses = Uses(gate);
1630     for (auto it = uses.begin(); it != uses.end();) {
1631         if (IsStateIn(it)) {
1632             ASSERT(state != Circuit::NullGate());
1633             it = ReplaceIn(it, state);
1634         } else if (IsDependIn(it)) {
1635             ASSERT(depend != Circuit::NullGate());
1636             it = ReplaceIn(it, depend);
1637         } else {
1638             it = ReplaceIn(it, replacement);
1639         }
1640     }
1641 #ifndef NDEBUG
1642     GetCircuit()->AddComment(replacement,  "old V " + std::to_string(GetId(gate)));
1643 #endif
1644     DeleteGate(gate);
1645 }
1646 
ReplaceControlGate(GateRef gate,GateRef newState)1647 void GateAccessor::ReplaceControlGate(GateRef gate, GateRef newState)
1648 {
1649     auto uses = Uses(gate);
1650     for (auto useIt = uses.begin(); useIt != uses.end();) {
1651         if (IsStateIn(useIt)) {
1652             OpCode opcode = GetOpCode(*useIt);
1653             if (opcode == OpCode::VALUE_SELECTOR || opcode == OpCode::DEPEND_SELECTOR) {
1654                 useIt++;
1655             } else {
1656                 useIt = ReplaceIn(useIt, newState);
1657             }
1658         } else {
1659             LOG_ECMA(FATAL) << "this branch is unreachable";
1660             UNREACHABLE();
1661         }
1662     }
1663     // Do not delete this gate
1664 }
1665 
1666 // When Insert newGate, all the stateIn from state and dependIn from depend can be replaced to newGate
ReplaceInAfterInsert(GateRef state,GateRef depend,GateRef newGate)1667 void GateAccessor::ReplaceInAfterInsert(GateRef state, GateRef depend, GateRef newGate)
1668 {
1669     auto uses = Uses(state);
1670     for (auto useIt = uses.begin(); useIt != uses.end();) {
1671         if (IsStateIn(useIt) && (*useIt != newGate)) {
1672             ASSERT(newGate != Circuit::NullGate());
1673             // Exception, for example, IF_TRUE / IF_FALSE -> DEPEND_RELAY,
1674             // or LOOP_BEGIN / MERGE -> DEPEND_SELECTOR cannot be replaced
1675             if (!IsState(*useIt)) {
1676                 useIt++;
1677                 continue;
1678             }
1679             useIt = ReplaceIn(useIt, newGate);
1680         } else {
1681             useIt++;
1682         }
1683     }
1684 
1685     uses = Uses(depend);
1686     for (auto useIt = uses.begin(); useIt != uses.end();) {
1687         if (IsDependIn(useIt) && (*useIt != newGate)) {
1688             ASSERT(newGate != Circuit::NullGate());
1689             useIt = ReplaceIn(useIt, newGate);
1690         } else {
1691             useIt++;
1692         }
1693     }
1694 }
1695 
1696 // When loopExit, find stateSplit after DEPEND_SELECTOR
GetFrameStateDependIn(GateRef gate,GateRef & dependIn)1697 void GateAccessor::GetFrameStateDependIn(GateRef gate, GateRef &dependIn)
1698 {
1699     auto uses = Uses(gate);
1700     size_t stateSplitCount = 0;
1701     GateRef stateSplit = Circuit::NullGate();
1702     for (auto it = uses.begin(); it != uses.end();) {
1703         if (GetOpCode(*it) == OpCode::STATE_SPLIT) {
1704             ASSERT(stateSplitCount < 1); // only one state Split;
1705             stateSplitCount++;
1706             stateSplit = *it;
1707             break;
1708         } else {
1709             ++it;
1710         }
1711     }
1712 
1713     ASSERT(stateSplitCount <= 1);
1714     if (stateSplitCount == 1 && stateSplit != Circuit::NullGate()) {
1715         dependIn = stateSplit;
1716     }
1717 }
1718 
1719 // When ifOp or loopExit, insertAfter
1720 // stateIn: IF_TRUE / IF_FALSE / MERGE
1721 // dependIn: DEPEND_RELAY / DEPEND_SELECTOR, if stateSplit follow closely, after the stateSplit.
1722 
GetStateInAndDependIn(GateRef insertAfter,GateRef & stateIn,GateRef & dependIn)1723 void GateAccessor::GetStateInAndDependIn(GateRef insertAfter, GateRef &stateIn, GateRef &dependIn)
1724 {
1725     if (GetOpCode(insertAfter) == OpCode::IF_TRUE || GetOpCode(insertAfter) == OpCode::IF_FALSE
1726         || GetOpCode(insertAfter) == OpCode::IF_SUCCESS) {
1727         auto uses = Uses(insertAfter);
1728         for (auto it = uses.begin(); it != uses.end();) {
1729             if (GetOpCode(*it) == OpCode::DEPEND_RELAY) {
1730                 stateIn = insertAfter;
1731                 dependIn = (*it);
1732                 break;
1733             } else {
1734                 ++it;
1735             }
1736         }
1737     } else if (GetOpCode(insertAfter) == OpCode::MERGE) {
1738         auto uses = Uses(insertAfter);
1739         for (auto it = uses.begin(); it != uses.end();) {
1740             if (GetOpCode(*it) == OpCode::DEPEND_SELECTOR) {
1741                 stateIn = insertAfter;
1742                 dependIn = (*it);
1743                 GetFrameStateDependIn(*it, dependIn);
1744                 break;
1745             } else {
1746                 ++it;
1747             }
1748         }
1749     }
1750     ASSERT(GetDependCount(dependIn) > 0);
1751 }
1752 
GetFrameDepth(GateRef gate,OpCode op)1753 size_t GateAccessor::GetFrameDepth(GateRef gate, OpCode op)
1754 {
1755     if (GetOpCode(gate) != op) {
1756         return 0;
1757     }
1758     size_t depth = 0;
1759     GateRef prev = GetFrameState(gate);
1760     while ((GetOpCode(prev) == op)) {
1761         depth++;
1762         prev = GetFrameState(prev);
1763     }
1764     return depth;
1765 }
1766 
GetFrameState(GateRef gate) const1767 GateRef GateAccessor::GetFrameState(GateRef gate) const
1768 {
1769     ASSERT(HasFrameState(gate));
1770     Gate *gatePtr = circuit_->LoadGatePtr(gate);
1771     size_t index = gatePtr->GetInFrameStateStarts();
1772     return circuit_->GetIn(gate, index);
1773 }
1774 
FindNearestFrameState(GateRef gate) const1775 GateRef GateAccessor::FindNearestFrameState(GateRef gate) const
1776 {
1777     auto statesplit = FindNearestStateSplit(gate);
1778     return GetFrameState(statesplit);
1779 }
1780 
FindNearestStateSplit(GateRef gate) const1781 GateRef GateAccessor::FindNearestStateSplit(GateRef gate) const
1782 {
1783     auto statesplit = gate;
1784     while (GetOpCode(statesplit) != OpCode::STATE_SPLIT) {
1785         statesplit = GetDep(statesplit);
1786     }
1787     return statesplit;
1788 }
1789 
HasFrameState(GateRef gate) const1790 bool GateAccessor::HasFrameState(GateRef gate) const
1791 {
1792     return GetMetaData(gate)->HasFrameState();
1793 }
1794 
ReplaceFrameStateIn(GateRef gate,GateRef in)1795 void GateAccessor::ReplaceFrameStateIn(GateRef gate, GateRef in)
1796 {
1797     ASSERT(HasFrameState(gate));
1798     Gate *gatePtr = circuit_->LoadGatePtr(gate);
1799     size_t index = gatePtr->GetInFrameStateStarts();
1800     circuit_->ModifyIn(gate, index, in);
1801 }
1802 
GetRoot(OpCode opcode) const1803 GateRef GateAccessor::GetRoot(OpCode opcode) const
1804 {
1805     GateRef root = circuit_->GetRoot();
1806     if (opcode == OpCode::CIRCUIT_ROOT) {
1807         return root;
1808     }
1809 
1810     auto uses = ConstUses(root);
1811     for (auto useIt = uses.begin(); useIt != uses.end(); ++useIt) {
1812         if (GetOpCode(*useIt) == opcode) {
1813             return *useIt;
1814         }
1815     }
1816     return Circuit::NullGate();
1817 }
1818 
GetGlueFromArgList() const1819 GateRef GateAccessor::GetGlueFromArgList() const
1820 {
1821     auto argRoot = GetArgRoot();
1822     ASSERT(static_cast<size_t>(CommonArgIdx::GLUE) == 0);
1823     const Gate *curGate = circuit_->LoadGatePtrConst(argRoot);
1824 
1825     const Out *curOut = curGate->GetFirstOutConst();
1826     ASSERT(!curGate->IsFirstOutNull());
1827     while (!curOut->IsNextOutNull()) {
1828         curOut = curOut->GetNextOutConst();
1829     }
1830     return circuit_->GetGateRef(curOut->GetGateConst());
1831 }
1832 
GetArgsOuts(std::vector<GateRef> & outs) const1833 void GateAccessor::GetArgsOuts(std::vector<GateRef>& outs) const
1834 {
1835     auto argRoot = GetArgRoot();
1836     GetOuts(argRoot, outs);
1837 }
1838 
GetReturnOuts(std::vector<GateRef> & outs) const1839 void GateAccessor::GetReturnOuts(std::vector<GateRef>& outs) const
1840 {
1841     auto returnRoot = GetReturnRoot();
1842     GetOuts(returnRoot, outs);
1843 }
1844 
GetMetaData(GateRef gate) const1845 const GateMetaData *GateAccessor::GetMetaData(GateRef gate) const
1846 {
1847     return circuit_->LoadGatePtrConst(gate)->GetMetaData();
1848 }
1849 
SetMetaData(GateRef gate,const GateMetaData * meta)1850 void GateAccessor::SetMetaData(GateRef gate, const GateMetaData* meta)
1851 {
1852     return circuit_->LoadGatePtr(gate)->SetMetaData(meta);
1853 }
1854 
IsFixed(GateRef g) const1855 bool GateAccessor::IsFixed(GateRef g) const
1856 {
1857     return GetMetaData(g)->IsFixed();
1858 }
1859 
IsProlog(GateRef g) const1860 bool GateAccessor::IsProlog(GateRef g) const
1861 {
1862     return GetMetaData(g)->IsProlog();
1863 }
1864 
IsCFGMerge(GateRef g) const1865 bool GateAccessor::IsCFGMerge(GateRef g) const
1866 {
1867     return GetMetaData(g)->IsCFGMerge();
1868 }
1869 
MetaDataEqu(GateRef g1,GateRef g2) const1870 bool GateAccessor::MetaDataEqu(GateRef g1, GateRef g2) const
1871 {
1872     return GetMetaData(g1) == GetMetaData(g2);
1873 }
1874 
MetaDataValueEqu(GateRef g1,GateRef g2) const1875 bool GateAccessor::MetaDataValueEqu(GateRef g1, GateRef g2) const
1876 {
1877     const GateMetaData *g1Meta = GetMetaData(g1);
1878     const GateMetaData *g2Meta = GetMetaData(g2);
1879 
1880     return g1Meta->equal(*g2Meta);
1881 }
1882 
IsNop(GateRef g) const1883 bool GateAccessor::IsNop(GateRef g) const
1884 {
1885     return GetMetaData(g)->IsNop();
1886 }
1887 
IsDead(GateRef gate) const1888 bool GateAccessor::IsDead(GateRef gate) const
1889 {
1890     return GetMetaData(gate)->IsDead();
1891 }
1892 
IsRoot(GateRef g) const1893 bool GateAccessor::IsRoot(GateRef g) const
1894 {
1895     return GetMetaData(g)->IsRoot();
1896 }
1897 
GetMetaData(GateRef g) const1898 const GateMetaData *ConstGateAccessor::GetMetaData(GateRef g) const
1899 {
1900     return circuit_->LoadGatePtrConst(g)->GetMetaData();
1901 }
1902 
IsFixed(GateRef g) const1903 bool ConstGateAccessor::IsFixed(GateRef g) const
1904 {
1905     return GetMetaData(g)->IsFixed();
1906 }
1907 
IsProlog(GateRef g) const1908 bool ConstGateAccessor::IsProlog(GateRef g) const
1909 {
1910     return GetMetaData(g)->IsProlog();
1911 }
1912 
IsSchedulable(GateRef g) const1913 bool ConstGateAccessor::IsSchedulable(GateRef g) const
1914 {
1915     return GetMetaData(g)->IsSchedulable();
1916 }
1917 
GetDependSelectorFromMerge(GateRef gate)1918 GateRef GateAccessor::GetDependSelectorFromMerge(GateRef gate)
1919 {
1920     GateRef depend = Circuit::NullGate();
1921     auto uses = Uses(gate);
1922     for (auto useIt = uses.begin(); useIt != uses.end(); useIt++) {
1923         if (GetOpCode(*useIt) == OpCode::DEPEND_SELECTOR) {
1924             depend = *useIt;
1925             break;
1926         }
1927     }
1928     ASSERT(depend != Circuit::NullGate());
1929     return depend;
1930 }
1931 
HasIfExceptionUse(GateRef gate) const1932 bool GateAccessor::HasIfExceptionUse(GateRef gate) const
1933 {
1934     ASSERT(GetStateCount(gate) > 0);
1935     auto uses = ConstUses(gate);
1936     for (auto it = uses.begin(); it != uses.end(); it++) {
1937         if (GetOpCode(*it) == OpCode::IF_EXCEPTION) {
1938             return true;
1939         }
1940     }
1941     return false;
1942 }
1943 
IsHeapObjectFromElementsKind(GateRef gate)1944 bool GateAccessor::IsHeapObjectFromElementsKind(GateRef gate)
1945 {
1946     OpCode opcode = GetOpCode(gate);
1947     if (opcode == OpCode::JS_BYTECODE) {
1948         auto bc = GetByteCodeOpcode(gate);
1949         if (bc == EcmaOpcode::LDOBJBYVALUE_IMM8_V8 || bc == EcmaOpcode::LDOBJBYVALUE_IMM16_V8 ||
1950             bc == EcmaOpcode::LDTHISBYVALUE_IMM8 || bc == EcmaOpcode::LDTHISBYVALUE_IMM16) {
1951             ElementsKind kind = TryGetElementsKind(gate);
1952             return Elements::IsObject(kind);
1953         }
1954         return false;
1955     }
1956 
1957     if (opcode == OpCode::LOAD_ELEMENT) {
1958         TypedLoadOp typedOp = GetTypedLoadOp(gate);
1959         return typedOp == TypedLoadOp::ARRAY_LOAD_OBJECT_ELEMENT;
1960     }
1961 
1962     return false;
1963 }
1964 
IsConstString(GateRef gate)1965 bool GateAccessor::IsConstString(GateRef gate)
1966 {
1967     OpCode op = GetOpCode(gate);
1968     if (op == OpCode::JS_BYTECODE) {
1969         EcmaOpcode ecmaOpcode = GetByteCodeOpcode(gate);
1970         return ecmaOpcode == EcmaOpcode::LDA_STR_ID16;
1971     }
1972     return false;
1973 }
1974 
IsSingleCharGate(GateRef gate)1975 bool GateAccessor::IsSingleCharGate(GateRef gate)
1976 {
1977     OpCode op = GetOpCode(gate);
1978     if (op == OpCode::LOAD_ELEMENT) {
1979         return GetTypedLoadOp(gate) == TypedLoadOp::STRING_LOAD_ELEMENT;
1980     }
1981     return false;
1982 }
1983 
UseForTypeOpProfilerGate(GateRef gate) const1984 bool GateAccessor::UseForTypeOpProfilerGate(GateRef gate) const
1985 {
1986     OpCode op = GetOpCode(gate);
1987     switch (op) {
1988 #define DECLARE_GATE_OPCODE(NAME, OP, R, S, D, V) \
1989         case OpCode::OP:                          \
1990             return true;
1991 
1992     MCR_IMMUTABLE_META_DATA_CACHE_LIST(DECLARE_GATE_OPCODE)
1993     MCR_GATE_META_DATA_LIST_WITH_PC_OFFSET(DECLARE_GATE_OPCODE)
1994     MCR_GATE_META_DATA_LIST_FOR_CALL(DECLARE_GATE_OPCODE)
1995     MCR_GATE_META_DATA_LIST_WITH_VALUE(DECLARE_GATE_OPCODE)
1996     MCR_GATE_META_DATA_LIST_WITH_BOOL(DECLARE_GATE_OPCODE)
1997     MCR_GATE_META_DATA_LIST_WITH_GATE_TYPE(DECLARE_GATE_OPCODE)
1998     MCR_GATE_META_DATA_LIST_WITH_VALUE_IN(DECLARE_GATE_OPCODE)
1999 #undef DECLARE_GATE_OPCODE
2000         default:
2001             return false;
2002     }
2003 }
2004 
GetStringIdFromLdaStrGate(GateRef gate)2005 uint32_t GateAccessor::GetStringIdFromLdaStrGate(GateRef gate)
2006 {
2007     ASSERT(GetByteCodeOpcode(gate) == EcmaOpcode::LDA_STR_ID16);
2008     GateRef stringId = GetValueIn(gate, 0);
2009     return GetConstantValue(stringId);
2010 }
2011 
IsLoopBackUse(GateRef gate,const UseIterator & useIt) const2012 bool GateAccessor::IsLoopBackUse(GateRef gate, const UseIterator &useIt) const
2013 {
2014     if (IsLoopBack(gate) && IsStateIn(useIt)) {
2015         return IsLoopHead(*useIt);
2016     }
2017     if ((IsValueSelector(*useIt) && IsValueIn(useIt)) ||
2018         (IsDependSelector(*useIt) && IsDependIn(useIt))) {
2019         return IsLoopHead(GetState(*useIt));
2020     }
2021     return false;
2022 }
2023 
IsCreateArray(GateRef gate) const2024 bool GateAccessor::IsCreateArray(GateRef gate) const
2025 {
2026     if (GetOpCode(gate) != OpCode::JS_BYTECODE) {
2027         return false;
2028     }
2029     EcmaOpcode ecmaop = GetByteCodeOpcode(gate);
2030     switch (ecmaop) {
2031         case EcmaOpcode::CREATEEMPTYARRAY_IMM8:
2032         case EcmaOpcode::CREATEEMPTYARRAY_IMM16:
2033         case EcmaOpcode::CREATEARRAYWITHBUFFER_IMM8_ID16:
2034         case EcmaOpcode::CREATEARRAYWITHBUFFER_IMM16_ID16:
2035             return true;
2036         default:
2037             return false;
2038     }
2039     UNREACHABLE();
2040     return false;
2041 }
2042 
SetStoreNoBarrier(GateRef gate,bool isNoBarrier)2043 void GateAccessor::SetStoreNoBarrier(GateRef gate, bool isNoBarrier)
2044 {
2045     ASSERT(GetOpCode(gate) == OpCode::MONO_STORE_PROPERTY_LOOK_UP_PROTO ||
2046            GetOpCode(gate) == OpCode::MONO_STORE_PROPERTY);
2047     Gate *gatePtr = circuit_->LoadGatePtr(gate);
2048     const_cast<BoolMetaData *>(gatePtr->GetBoolMetaData())->SetBool(isNoBarrier);
2049 }
2050 
IsNoBarrier(GateRef gate) const2051 bool GateAccessor::IsNoBarrier(GateRef gate) const
2052 {
2053     ASSERT(GetOpCode(gate) == OpCode::MONO_STORE_PROPERTY_LOOK_UP_PROTO ||
2054            GetOpCode(gate) == OpCode::MONO_STORE_PROPERTY);
2055     Gate *gatePtr = circuit_->LoadGatePtr(gate);
2056     return gatePtr->GetBoolMetaData()->GetBool();
2057 }
2058 
TryGetMegaProp(GateRef gate) const2059 bool GateAccessor::TryGetMegaProp(GateRef gate) const
2060 {
2061     const PGORWOpType *k = TryGetPGOType(gate).GetPGORWOpType();
2062     if (k->GetCount() > 0) {
2063         return k->GetObjectInfo(0).IsMegaStateType();
2064     } else {
2065         return false;
2066     }
2067 }
2068 
GetConstpoolId(GateRef gate) const2069 uint32_t GateAccessor::GetConstpoolId(GateRef gate) const
2070 {
2071     ASSERT(GetOpCode(gate) == OpCode::GET_SHARED_CONSTPOOL);
2072     Gate *gatePtr = circuit_->LoadGatePtr(gate);
2073     return gatePtr->GetOneParameterMetaData()->GetValue();
2074 }
2075 
GetFrameValue(GateRef gate)2076 GateRef GateAccessor::GetFrameValue(GateRef gate)
2077 {
2078     ASSERT(GetOpCode(gate) == OpCode::FRAME_STATE);
2079     return GetValueIn(gate, 1);
2080 }
2081 
GetRevCompareOpForTypedBinOp(TypedBinOp op)2082 TypedBinOp GateAccessor::GetRevCompareOpForTypedBinOp(TypedBinOp op)
2083 {
2084     switch (op) {
2085         case TypedBinOp::TYPED_LESS:
2086             return TypedBinOp::TYPED_GREATEREQ;
2087         case TypedBinOp::TYPED_LESSEQ:
2088             return TypedBinOp::TYPED_GREATER;
2089         case TypedBinOp::TYPED_GREATER:
2090             return TypedBinOp::TYPED_LESSEQ;
2091         case TypedBinOp::TYPED_GREATEREQ:
2092             return TypedBinOp::TYPED_LESS;
2093         case TypedBinOp::TYPED_EQ:
2094             return TypedBinOp::TYPED_NOTEQ;
2095         case TypedBinOp::TYPED_NOTEQ:
2096             return TypedBinOp::TYPED_EQ;
2097         default:
2098             UNREACHABLE();
2099             return op;
2100     }
2101 }
2102 
GetSwapCompareOpForTypedBinOp(TypedBinOp op)2103 TypedBinOp GateAccessor::GetSwapCompareOpForTypedBinOp(TypedBinOp op)
2104 {
2105     switch (op) {
2106         case TypedBinOp::TYPED_LESS:
2107             return TypedBinOp::TYPED_GREATER;
2108         case TypedBinOp::TYPED_LESSEQ:
2109             return TypedBinOp::TYPED_GREATEREQ;
2110         case TypedBinOp::TYPED_GREATER:
2111             return TypedBinOp::TYPED_LESS;
2112         case TypedBinOp::TYPED_GREATEREQ:
2113             return TypedBinOp::TYPED_LESSEQ;
2114         case TypedBinOp::TYPED_EQ:
2115             return TypedBinOp::TYPED_EQ;
2116         case TypedBinOp::TYPED_NOTEQ:
2117             return TypedBinOp::TYPED_NOTEQ;
2118         default:
2119             UNREACHABLE();
2120             return op;
2121     }
2122 }
2123 }  // namespace panda::ecmascript::kungfu
2124