• 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::LOAD_HCLASS_CONST_OFFSET ||
107            GetOpCode(gate) == OpCode::STORE_CONST_OFFSET ||
108            GetOpCode(gate) == OpCode::STORE_HCLASS_CONST_OFFSET);
109     Gate *gatePtr = circuit_->LoadGatePtr(gate);
110     auto accessor = LoadStoreConstOffsetAccessor(gatePtr->GetOneParameterMetaData()->GetValue());
111     return accessor.GetOffset();
112 }
113 
GetInitOffset(GateRef gate) const114 size_t GateAccessor::GetInitOffset(GateRef gate) const
115 {
116     ASSERT(GetOpCode(gate) == OpCode::INITVREG);
117     Gate *gatePtr = circuit_->LoadGatePtr(gate);
118     return gatePtr->GetOneParameterMetaData()->GetValue();
119 }
120 
GetTrueWeight(GateRef gate) const121 uint32_t GateAccessor::GetTrueWeight(GateRef gate) const
122 {
123     ASSERT(GetOpCode(gate) == OpCode::IF_BRANCH);
124     Gate *gatePtr = circuit_->LoadGatePtr(gate);
125     auto accessor = BranchAccessor(gatePtr->GetOneParameterMetaData()->GetValue());
126     return accessor.GetTrueWeight();
127 }
128 
GetFalseWeight(GateRef gate) const129 uint32_t GateAccessor::GetFalseWeight(GateRef gate) const
130 {
131     ASSERT(GetOpCode(gate) == OpCode::IF_BRANCH);
132     Gate *gatePtr = circuit_->LoadGatePtr(gate);
133     auto accessor = BranchAccessor(gatePtr->GetOneParameterMetaData()->GetValue());
134     return accessor.GetFalseWeight();
135 }
136 
GetMemoryAttribute(GateRef gate) const137 MemoryAttribute GateAccessor::GetMemoryAttribute(GateRef gate) const
138 {
139     auto op = GetOpCode(gate);
140     Gate *gatePtr = circuit_->LoadGatePtr(gate);
141     switch (op) {
142         case OpCode::FETCH_OR:
143         case OpCode::LOAD_WITHOUT_BARRIER:
144         case OpCode::LOAD:
145         case OpCode::LOAD_HCLASS_OPCODE:
146         case OpCode::STORE_WITHOUT_BARRIER:
147         case OpCode::STORE: {
148             auto accessor = LoadStoreAccessor(gatePtr->GetOneParameterMetaData()->GetValue());
149             return accessor.GetMemoryAttribute();
150         }
151         case OpCode::LOAD_CONST_OFFSET:
152         case OpCode::LOAD_HCLASS_CONST_OFFSET:
153         case OpCode::STORE_CONST_OFFSET:
154         case OpCode::STORE_HCLASS_CONST_OFFSET: {
155             auto accessor = LoadStoreConstOffsetAccessor(gatePtr->GetOneParameterMetaData()->GetValue());
156             return accessor.GetMemoryAttribute();
157         }
158         default: {
159             UNREACHABLE();
160             break;
161         }
162     }
163     return MemoryAttribute::Default();
164 }
165 
HasBranchWeight(GateRef gate) const166 bool GateAccessor::HasBranchWeight(GateRef gate) const
167 {
168     ASSERT(GetOpCode(gate) == OpCode::IF_BRANCH);
169     Gate *gatePtr = circuit_->LoadGatePtr(gate);
170     auto accessor = BranchAccessor(gatePtr->GetOneParameterMetaData()->GetValue());
171     return (accessor.GetTrueWeight() != 0) || (accessor.GetFalseWeight() != 0);
172 }
173 
GetIndex(GateRef gate) const174 size_t GateAccessor::GetIndex(GateRef gate) const
175 {
176     ASSERT(GetOpCode(gate) == OpCode::GET_GLOBAL_ENV_OBJ_HCLASS ||
177            GetOpCode(gate) == OpCode::GET_GLOBAL_CONSTANT_VALUE ||
178            GetOpCode(gate) == OpCode::GET_GLOBAL_ENV_OBJ ||
179            GetOpCode(gate) == OpCode::LOAD_HCLASS_FROM_CONSTPOOL ||
180            GetOpCode(gate) == OpCode::LOAD_BUILTIN_OBJECT);
181     Gate *gatePtr = circuit_->LoadGatePtr(gate);
182     return gatePtr->GetOneParameterMetaData()->GetValue();
183 }
184 
GetJSType(GateRef gate) const185 size_t GateAccessor::GetJSType(GateRef gate) const
186 {
187     ASSERT(GetOpCode(gate) == OpCode::IS_SPECIFIC_OBJECT_TYPE);
188     Gate *gatePtr = circuit_->LoadGatePtr(gate);
189     return gatePtr->GetOneParameterMetaData()->GetValue();
190 }
191 
GetArraySize(GateRef gate) const192 uint32_t GateAccessor::GetArraySize(GateRef gate) const
193 {
194     ASSERT(GetOpCode(gate) == OpCode::CREATE_ARRAY ||
195            GetOpCode(gate) == OpCode::CREATE_ARRAY_WITH_BUFFER);
196     Gate *gatePtr = circuit_->LoadGatePtr(gate);
197     auto array = gatePtr->GetOneParameterMetaData()->GetValue();
198     return ArrayMetaDataAccessor(array).GetArrayLength();
199 }
200 
SetArraySize(GateRef gate,uint32_t size)201 void GateAccessor::SetArraySize(GateRef gate, uint32_t size)
202 {
203     ASSERT(GetOpCode(gate) == OpCode::CREATE_ARRAY ||
204            GetOpCode(gate) == OpCode::CREATE_ARRAY_WITH_BUFFER);
205     uint32_t curSize = GetArraySize(gate);
206     if (curSize != size) {
207         Gate *gatePtr = circuit_->LoadGatePtr(gate);
208         ArrayMetaDataAccessor accessor(gatePtr->GetOneParameterMetaData()->GetValue());
209         accessor.SetArrayLength(size);
210         if (GetOpCode(gate) == OpCode::CREATE_ARRAY) {
211             auto meta = circuit_->CreateArray(accessor.ToValue());
212             SetMetaData(gate, meta);
213         } else {
214             auto meta = circuit_->CreateArrayWithBuffer(accessor.ToValue());
215             SetMetaData(gate, meta);
216         }
217     }
218 }
219 
GetElementsKind(GateRef gate) const220 ElementsKind GateAccessor::GetElementsKind(GateRef gate) const
221 {
222     ASSERT(GetOpCode(gate) == OpCode::CREATE_ARRAY ||
223            GetOpCode(gate) == OpCode::CREATE_ARRAY_WITH_BUFFER);
224     Gate *gatePtr = circuit_->LoadGatePtr(gate);
225     auto array = gatePtr->GetOneParameterMetaData()->GetValue();
226     return ArrayMetaDataAccessor(array).GetElementsKind();
227 }
228 
SetElementsKind(GateRef gate,ElementsKind kind)229 void GateAccessor::SetElementsKind(GateRef gate, ElementsKind kind)
230 {
231     ASSERT(GetOpCode(gate) == OpCode::CREATE_ARRAY ||
232            GetOpCode(gate) == OpCode::CREATE_ARRAY_WITH_BUFFER);
233     Gate *gatePtr = circuit_->LoadGatePtr(gate);
234     ArrayMetaDataAccessor accessor(gatePtr->GetOneParameterMetaData()->GetValue());
235     accessor.SetElementsKind(kind);
236     const_cast<OneParameterMetaData *>(gatePtr->GetOneParameterMetaData())->SetValue(accessor.ToValue());
237 }
238 
GetRegionSpaceFlag(GateRef gate) const239 RegionSpaceFlag GateAccessor::GetRegionSpaceFlag(GateRef gate) const
240 {
241     ASSERT(GetOpCode(gate) == OpCode::CREATE_ARRAY ||
242            GetOpCode(gate) == OpCode::CREATE_ARRAY_WITH_BUFFER);
243     Gate *gatePtr = circuit_->LoadGatePtr(gate);
244     auto array = gatePtr->GetOneParameterMetaData()->GetValue();
245     return ArrayMetaDataAccessor(array).GetRegionSpaceFlag();
246 }
247 
GetStringStatus(GateRef gate) const248 uint32_t GateAccessor::GetStringStatus(GateRef gate) const
249 {
250     ASSERT(GetOpCode(gate) == OpCode::STRING_ADD);
251     Gate *gatePtr = circuit_->LoadGatePtr(gate);
252     StringStatusAccessor accessor(gatePtr->GetOneParameterMetaData()->GetValue());
253     return accessor.GetStringStatus();
254 }
255 
SetStringStatus(GateRef gate,uint32_t type)256 void GateAccessor::SetStringStatus(GateRef gate, uint32_t type)
257 {
258     ASSERT(GetOpCode(gate) == OpCode::STRING_ADD);
259     uint32_t curStatus = GetStringStatus(gate);
260     if (curStatus != type) {
261         StringStatusAccessor accessor(static_cast<uint64_t>(type));
262         auto meta = circuit_->StringAdd(accessor.ToValue());
263         SetMetaData(gate, meta);
264     }
265 }
266 
GetTypedUnAccessor(GateRef gate) const267 TypedUnaryAccessor GateAccessor::GetTypedUnAccessor(GateRef gate) const
268 {
269     ASSERT((GetOpCode(gate) == OpCode::TYPED_UNARY_OP));
270     Gate *gatePtr = circuit_->LoadGatePtr(gate);
271     return TypedUnaryAccessor(gatePtr->GetOneParameterMetaData()->GetValue());
272 }
273 
GetTypedBinaryAccessor(GateRef gate) const274 TypedBinaryAccessor GateAccessor::GetTypedBinaryAccessor(GateRef gate) const
275 {
276     Gate *gatePtr = circuit_->LoadGatePtr(gate);
277     return TypedBinaryAccessor(gatePtr->GetOneParameterMetaData()->GetValue());
278 }
279 
GetTypedJumpAccessor(GateRef gate) const280 TypedJumpAccessor GateAccessor::GetTypedJumpAccessor(GateRef gate) const
281 {
282     ASSERT(GetOpCode(gate) == OpCode::TYPED_CONDITION_JUMP);
283     Gate *gatePtr = circuit_->LoadGatePtr(gate);
284     return TypedJumpAccessor(gatePtr->GetOneParameterMetaData()->GetValue());
285 }
286 
GetArrayMetaDataAccessor(GateRef gate) const287 ArrayMetaDataAccessor GateAccessor::GetArrayMetaDataAccessor(GateRef gate) const
288 {
289     ASSERT(GetOpCode(gate) == OpCode::STABLE_ARRAY_CHECK ||
290            GetOpCode(gate) == OpCode::HCLASS_STABLE_ARRAY_CHECK ||
291            GetOpCode(gate) == OpCode::ELEMENTSKIND_CHECK ||
292            GetOpCode(gate) == OpCode::CREATE_ARRAY ||
293            GetOpCode(gate) == OpCode::CREATE_ARRAY_WITH_BUFFER ||
294            GetOpCode(gate) == OpCode::CREATE_ARGUMENTS ||
295            GetOpCode(gate) == OpCode::LOAD_ARRAY_LENGTH);
296     Gate *gatePtr = circuit_->LoadGatePtr(gate);
297     return ArrayMetaDataAccessor(gatePtr->GetOneParameterMetaData()->GetValue());
298 }
299 
NeedPushArgv(GateRef gate) const300 bool GateAccessor::NeedPushArgv(GateRef gate) const
301 {
302     ASSERT(GetOpCode(gate) == OpCode::CALL_NEW);
303     Gate *gatePtr = circuit_->LoadGatePtr(gate);
304     return gatePtr->GetNewConstructMetaData()->NeedPushArgv();
305 }
306 
IsFastCall(GateRef gate) const307 bool GateAccessor::IsFastCall(GateRef gate) const
308 {
309     ASSERT(GetOpCode(gate) == OpCode::CALL_NEW);
310     Gate *gatePtr = circuit_->LoadGatePtr(gate);
311     return gatePtr->GetNewConstructMetaData()->IsFastCall();
312 }
313 
GetCreateArgumentsAccessor(GateRef gate) const314 CreateArgumentsAccessor GateAccessor::GetCreateArgumentsAccessor(GateRef gate) const
315 {
316     ASSERT(GetOpCode(gate) == OpCode::CREATE_ARGUMENTS);
317     Gate *gatePtr = circuit_->LoadGatePtr(gate);
318     return CreateArgumentsAccessor(gatePtr->GetOneParameterMetaData()->GetValue());
319 }
320 
GetObjectTypeAccessor(GateRef gate) const321 ObjectTypeAccessor GateAccessor::GetObjectTypeAccessor(GateRef gate) const
322 {
323     ASSERT(GetOpCode(gate) == OpCode::OBJECT_TYPE_CHECK);
324     Gate *gatePtr = circuit_->LoadGatePtr(gate);
325     return ObjectTypeAccessor(gatePtr->GetOneParameterMetaData()->GetValue());
326 }
327 
GetBuiltinHClassAccessor(GateRef gate) const328 BuiltinPrototypeHClassAccessor GateAccessor::GetBuiltinHClassAccessor(GateRef gate) const
329 {
330     ASSERT(GetOpCode(gate) == OpCode::BUILTIN_PROTOTYPE_HCLASS_CHECK ||
331            GetOpCode(gate) == OpCode::BUILTIN_INSTANCE_HCLASS_CHECK);
332     Gate *gatePtr = circuit_->LoadGatePtr(gate);
333     return BuiltinPrototypeHClassAccessor(gatePtr->GetOneParameterMetaData()->GetValue());
334 }
335 
GetTypedArrayMetaDataAccessor(GateRef gate) const336 TypedArrayMetaDataAccessor GateAccessor::GetTypedArrayMetaDataAccessor(GateRef gate) const
337 {
338     ASSERT(GetOpCode(gate) == OpCode::TYPED_ARRAY_CHECK || GetOpCode(gate) == OpCode::LOAD_TYPED_ARRAY_LENGTH);
339     Gate *gatePtr = circuit_->LoadGatePtr(gate);
340     return TypedArrayMetaDataAccessor(gatePtr->GetOneParameterMetaData()->GetValue());
341 }
342 
UpdateOnHeapMode(GateRef gate,OnHeapMode onHeapMode)343 void GateAccessor::UpdateOnHeapMode(GateRef gate, OnHeapMode onHeapMode)
344 {
345     ASSERT(GetOpCode(gate) == OpCode::TYPED_ARRAY_CHECK);
346     Gate *gatePtr = circuit_->LoadGatePtr(gate);
347     TypedArrayMetaDataAccessor accessor = GetTypedArrayMetaDataAccessor(gate);
348     uint64_t value = accessor.UpdateOnHeapMode(onHeapMode);
349     const_cast<OneParameterMetaData *>(gatePtr->GetOneParameterMetaData())->SetValue(value);
350 }
351 
GetLoadElementAccessor(GateRef gate) const352 LoadElementAccessor GateAccessor::GetLoadElementAccessor(GateRef gate) const
353 {
354     ASSERT(GetOpCode(gate) == OpCode::LOAD_ELEMENT);
355     Gate *gatePtr = circuit_->LoadGatePtr(gate);
356     return LoadElementAccessor(gatePtr->GetOneParameterMetaData()->GetValue());
357 }
358 
GetStoreElementAccessor(GateRef gate) const359 StoreElementAccessor GateAccessor::GetStoreElementAccessor(GateRef gate) const
360 {
361     ASSERT(GetOpCode(gate) == OpCode::STORE_ELEMENT);
362     Gate *gatePtr = circuit_->LoadGatePtr(gate);
363     return StoreElementAccessor(gatePtr->GetOneParameterMetaData()->GetValue());
364 }
365 
TypedOpIsTypedArray(GateRef gate,TypedOpKind kind) const366 bool GateAccessor::TypedOpIsTypedArray(GateRef gate, TypedOpKind kind) const
367 {
368     switch (kind) {
369         case TypedOpKind::TYPED_LOAD_OP: {
370             TypedLoadOp op = GetTypedLoadOp(gate);
371             return TypedLoadOp::TYPED_ARRAY_FIRST <= op && op <=TypedLoadOp::TYPED_ARRAY_LAST;
372         }
373         case TypedOpKind::TYPED_STORE_OP: {
374             TypedStoreOp op = GetTypedStoreOp(gate);
375             return TypedStoreOp::TYPED_ARRAY_FIRST <= op && op <= TypedStoreOp::TYPED_ARRAY_LAST;
376         }
377         default:
378             LOG_ECMA(FATAL) << "this branch is unreachable";
379             UNREACHABLE();
380     }
381 }
382 
GetTypedLoadOp(GateRef gate) const383 TypedLoadOp GateAccessor::GetTypedLoadOp(GateRef gate) const
384 {
385     ASSERT(GetOpCode(gate) == OpCode::LOAD_ELEMENT);
386     Gate *gatePtr = circuit_->LoadGatePtr(gate);
387     return static_cast<TypedLoadOp>(gatePtr->GetOneParameterMetaData()->GetValue());
388 }
389 
GetTypedStoreOp(GateRef gate) const390 TypedStoreOp GateAccessor::GetTypedStoreOp(GateRef gate) const
391 {
392     ASSERT(GetOpCode(gate) == OpCode::STORE_ELEMENT);
393     Gate *gatePtr = circuit_->LoadGatePtr(gate);
394     return static_cast<TypedStoreOp>(gatePtr->GetOneParameterMetaData()->GetValue());
395 }
396 
GetTypedCallTargetCheckOp(GateRef gate) const397 TypedCallTargetCheckOp GateAccessor::GetTypedCallTargetCheckOp(GateRef gate) const
398 {
399     ASSERT(GetOpCode(gate) == OpCode::TYPED_CALLTARGETCHECK_OP);
400     TypedCallTargetCheckAccessor accessor(TryGetValue(gate));
401     return accessor.GetCallTargetCheckOp();
402 }
403 
GetMemoryType(GateRef gate) const404 MemoryType GateAccessor::GetMemoryType(GateRef gate) const
405 {
406     ASSERT(GetOpCode(gate) == OpCode::STORE_MEMORY);
407     Gate *gatePtr = circuit_->LoadGatePtr(gate);
408     return static_cast<MemoryType>(gatePtr->GetOneParameterMetaData()->GetValue());
409 }
410 
GetHClassIndex(GateRef gate) const411 uint32_t GateAccessor::GetHClassIndex(GateRef gate) const
412 {
413     ASSERT(GetOpCode(gate) == OpCode::STORE_PROPERTY ||
414            GetOpCode(gate) == OpCode::PROTOTYPE_CHECK);
415     Gate *gatePtr = circuit_->LoadGatePtr(gate);
416     return static_cast<uint32_t>(gatePtr->GetOneParameterMetaData()->GetValue());
417 }
418 
GetTypedBinaryOp(GateRef gate) const419 TypedBinOp GateAccessor::GetTypedBinaryOp(GateRef gate) const
420 {
421     ASSERT(GetOpCode(gate) == OpCode::TYPED_BINARY_OP);
422     TypedBinaryAccessor accessor(TryGetValue(gate));
423     return accessor.GetTypedBinOp();
424 }
425 
HasNumberType(GateRef gate) const426 bool GateAccessor::HasNumberType(GateRef gate) const
427 {
428     OpCode op = GetOpCode(gate);
429     if (op == OpCode::TYPED_BINARY_OP) {
430         TypedBinaryAccessor accessor(TryGetValue(gate));
431         return accessor.GetParamType().HasNumberType();
432     }
433     return false;
434 }
435 
HasStringType(GateRef gate,bool onlyInternString) const436 bool GateAccessor::HasStringType(GateRef gate, bool onlyInternString) const
437 {
438     OpCode op = GetOpCode(gate);
439     if (op == OpCode::TYPED_BINARY_OP) {
440         TypedBinaryAccessor accessor(TryGetValue(gate));
441         bool isInternString = accessor.GetParamType().IsInternStringType();
442         if (onlyInternString) {
443             return isInternString;
444         }
445         return isInternString || accessor.GetParamType().IsStringType();
446     }
447     return false;
448 }
449 
IsInternStringType(GateRef gate) const450 bool GateAccessor::IsInternStringType(GateRef gate) const
451 {
452     return HasStringType(gate, true);
453 }
454 
GetFuncGT(GateRef gate) const455 GlobalTSTypeRef GateAccessor::GetFuncGT(GateRef gate) const
456 {
457     ASSERT(GetOpCode(gate) == OpCode::JSINLINETARGET_TYPE_CHECK ||
458            GetOpCode(gate) == OpCode::JSINLINETARGET_HEAPCONSTANT_CHECK);
459     Gate *gatePtr = circuit_->LoadGatePtr(gate);
460     auto value = static_cast<uint32_t>((gatePtr->GetOneParameterMetaData()->GetValue()));
461     return GlobalTSTypeRef(value);
462 }
463 
GetParamGateType(GateRef gate) const464 GateType GateAccessor::GetParamGateType(GateRef gate) const
465 {
466     // NOTICE-PGO: consider to delete this function in Part3, only primitive_type_check use,
467     // which is generate in the retype pass
468     ASSERT(GetOpCode(gate) == OpCode::PRIMITIVE_TYPE_CHECK);
469     Gate *gatePtr = circuit_->LoadGatePtr(gate);
470     GateTypeAccessor accessor(gatePtr->GetOneParameterMetaData()->GetValue());
471     return accessor.GetGateType();
472 }
473 
GetParamType(GateRef gate) const474 ParamType GateAccessor::GetParamType(GateRef gate) const
475 {
476     Gate *gatePtr = circuit_->LoadGatePtr(gate);
477     GateTypeAccessor accessor(gatePtr->GetOneParameterMetaData()->GetValue());
478     return accessor.GetParamType();
479 }
480 
IsConvertSupport(GateRef gate) const481 bool GateAccessor::IsConvertSupport(GateRef gate) const
482 {
483     ASSERT(GetOpCode(gate) == OpCode::CONVERT ||
484            GetOpCode(gate) == OpCode::CHECK_AND_CONVERT);
485     Gate *gatePtr = circuit_->LoadGatePtr(gate);
486     ValuePairTypeAccessor accessor(gatePtr->GetOneParameterMetaData()->GetValue());
487     return accessor.IsConvertSupport();
488 }
489 
GetSrcType(GateRef gate) const490 ValueType GateAccessor::GetSrcType(GateRef gate) const
491 {
492     ASSERT(GetOpCode(gate) == OpCode::CONVERT ||
493            GetOpCode(gate) == OpCode::CHECK_AND_CONVERT);
494     Gate *gatePtr = circuit_->LoadGatePtr(gate);
495     ValuePairTypeAccessor accessor(gatePtr->GetOneParameterMetaData()->GetValue());
496     return accessor.GetSrcType();
497 }
498 
GetDstType(GateRef gate) const499 ValueType GateAccessor::GetDstType(GateRef gate) const
500 {
501     ASSERT(GetOpCode(gate) == OpCode::CONVERT ||
502            GetOpCode(gate) == OpCode::CHECK_AND_CONVERT);
503     Gate *gatePtr = circuit_->LoadGatePtr(gate);
504     ValuePairTypeAccessor accessor(gatePtr->GetOneParameterMetaData()->GetValue());
505     return accessor.GetDstType();
506 }
507 
GetFirstValue(GateRef gate) const508 uint32_t GateAccessor::GetFirstValue(GateRef gate) const
509 {
510     ASSERT(GetOpCode(gate) == OpCode::RANGE_GUARD);
511     Gate *gatePtr = circuit_->LoadGatePtr(gate);
512     UInt32PairAccessor accessor(gatePtr->GetOneParameterMetaData()->GetValue());
513     return accessor.GetFirstValue();
514 }
515 
GetSecondValue(GateRef gate) const516 uint32_t GateAccessor::GetSecondValue(GateRef gate) const
517 {
518     ASSERT(GetOpCode(gate) == OpCode::RANGE_GUARD);
519     Gate *gatePtr = circuit_->LoadGatePtr(gate);
520     UInt32PairAccessor accessor(gatePtr->GetOneParameterMetaData()->GetValue());
521     return accessor.GetSecondValue();
522 }
523 
GetVirtualRegisterIndex(GateRef gate) const524 size_t GateAccessor::GetVirtualRegisterIndex(GateRef gate) const
525 {
526     ASSERT(GetOpCode(gate) == OpCode::SAVE_REGISTER ||
527            GetOpCode(gate) == OpCode::RESTORE_REGISTER);
528     Gate *gatePtr = circuit_->LoadGatePtr(gate);
529     return static_cast<size_t>(gatePtr->GetOneParameterMetaData()->GetValue());
530 }
531 
GetConstantValue(GateRef gate) const532 uint64_t GateAccessor::GetConstantValue(GateRef gate) const
533 {
534     ASSERT(GetOpCode(gate) == OpCode::CONSTANT || GetOpCode(gate) == OpCode::HEAP_CONSTANT);
535     Gate *gatePtr = circuit_->LoadGatePtr(gate);
536     return gatePtr->GetOneParameterMetaData()->GetValue();
537 }
538 
GetConstantString(GateRef gate) const539 const ChunkVector<char>& GateAccessor::GetConstantString(GateRef gate) const
540 {
541     ASSERT(GetOpCode(gate) == OpCode::CONSTSTRING);
542     Gate *gatePtr = circuit_->LoadGatePtr(gate);
543     return gatePtr->GetStringMetaData()->GetString();
544 }
545 
IsVtable(GateRef gate) const546 bool GateAccessor::IsVtable(GateRef gate) const
547 {
548     ASSERT(GetOpCode(gate) == OpCode::LOAD_PROPERTY);
549     Gate *gatePtr = circuit_->LoadGatePtr(gate);
550     return gatePtr->GetBoolMetaData()->GetBool();
551 }
552 
GetNoGCFlag(GateRef gate) const553 bool GateAccessor::GetNoGCFlag(GateRef gate) const
554 {
555     if (gate == Circuit::NullGate()) {
556         return false;
557     }
558     OpCode op = GetOpCode(gate);
559     if (op != OpCode::TYPEDCALL && op != OpCode::TYPEDFASTCALL) {
560         return false;
561     }
562     return TypedCallIsNoGC(gate);
563 }
564 
TypedCallIsNoGC(GateRef gate) const565 bool GateAccessor::TypedCallIsNoGC(GateRef gate) const
566 {
567     ASSERT(GetOpCode(gate) == OpCode::TYPEDCALL || GetOpCode(gate) == OpCode::TYPEDFASTCALL);
568     Gate *gatePtr = circuit_->LoadGatePtr(gate);
569     return gatePtr->GetTypedCallMetaData()->IsNoGC();
570 }
571 
IsNoGC(GateRef gate) const572 bool GateAccessor::IsNoGC(GateRef gate) const
573 {
574     ASSERT(GetOpCode(gate) == OpCode::CALL_OPTIMIZED || GetOpCode(gate) == OpCode::FAST_CALL_OPTIMIZED);
575     Gate *gatePtr = circuit_->LoadGatePtr(gate);
576     return gatePtr->GetBoolMetaData()->GetBool();
577 }
578 
TryGetPcOffset(GateRef gate) const579 uint32_t GateAccessor::TryGetPcOffset(GateRef gate) const
580 {
581     Gate *gatePtr = circuit_->LoadGatePtr(gate);
582     OpCode op = GetOpCode(gate);
583     switch (op) {
584         case OpCode::JS_BYTECODE:
585             return gatePtr->GetJSBytecodeMetaData()->GetPcOffset();
586         case OpCode::TYPED_CALL_BUILTIN:
587         case OpCode::TYPED_CALL_BUILTIN_SIDE_EFFECT:
588         case OpCode::CONSTRUCT:
589         case OpCode::CALL_NEW:
590         case OpCode::CALL_NEW_BUILTIN:
591         case OpCode::CALL_GETTER:
592         case OpCode::CALL_SETTER:
593         case OpCode::ARRAY_FOR_EACH:
594         case OpCode::ARRAY_FIND_OR_FINDINDEX:
595         case OpCode::ARRAY_FILTER:
596         case OpCode::ARRAY_MAP:
597         case OpCode::ARRAY_SOME:
598         case OpCode::ARRAY_EVERY:
599         case OpCode::FLOAT32_ARRAY_CONSTRUCTOR:
600             return static_cast<uint32_t>(gatePtr->GetOneParameterMetaData()->GetValue());
601         case OpCode::TYPEDCALL:
602         case OpCode::TYPEDFASTCALL:
603             return static_cast<uint32_t>(gatePtr->GetTypedCallMetaData()->GetValue());
604         case OpCode::FRAME_STATE: {
605             UInt32PairAccessor accessor(gatePtr->GetOneParameterMetaData()->GetValue());
606             return accessor.GetFirstValue();
607         }
608         default:
609             break;
610     }
611     return 0;
612 }
613 
TryGetBcIndex(GateRef gate) const614 uint32_t GateAccessor::TryGetBcIndex(GateRef gate) const
615 {
616     Gate *gatePtr = circuit_->LoadGatePtr(gate);
617     OpCode op = GetOpCode(gate);
618     switch (op) {
619         case OpCode::JS_BYTECODE:
620             return gatePtr->GetJSBytecodeMetaData()->GetBcIndex();
621         default:
622             break;
623     }
624     return INVALID_BC_INDEX;
625 }
626 
TryGetMethodOffset(GateRef gate) const627 uint32_t GateAccessor::TryGetMethodOffset(GateRef gate) const
628 {
629     Gate *gatePtr = circuit_->LoadGatePtr(gate);
630     OpCode op = GetOpCode(gate);
631     switch (op) {
632         case OpCode::FRAME_ARGS: {
633             UInt32PairAccessor accessor(gatePtr->GetOneParameterMetaData()->GetValue());
634             return accessor.GetFirstValue();
635         }
636         case OpCode::JS_BYTECODE: {
637             return gatePtr->GetJSBytecodeMetaData()->GetMethodId();
638         }
639         default:
640             break;
641     }
642     return 0;
643 }
644 
GetFrameArgs(GateRef gate) const645 GateRef GateAccessor::GetFrameArgs(GateRef gate) const
646 {
647     if (!HasFrameState(gate)) {
648         return Circuit::NullGate();
649     }
650     if (GetOpCode(gate) == OpCode::FRAME_STATE) {
651         return GetValueIn(gate, 0); // 0: frame args
652     }
653     GateRef frameState = GetFrameState(gate);
654     OpCode op = GetOpCode(frameState);
655     if (op == OpCode::FRAME_ARGS) {
656         return frameState;
657     }
658     if (op == OpCode::FRAME_STATE) {
659         return GetValueIn(frameState, 0); // 0: frame args
660     }
661     return Circuit::NullGate();
662 }
663 
UpdateMethodOffset(GateRef gate,uint32_t methodOffset)664 void GateAccessor::UpdateMethodOffset(GateRef gate, uint32_t methodOffset)
665 {
666     ASSERT(GetOpCode(gate) == OpCode::FRAME_ARGS);
667     Gate *gatePtr = circuit_->LoadGatePtr(gate);
668     UInt32PairAccessor accessor(methodOffset, 0);
669     const_cast<OneParameterMetaData *>(gatePtr->GetOneParameterMetaData())->SetValue(accessor.ToValue());
670 }
671 
TryGetPGOType(GateRef gate) const672 PGOTypeRef GateAccessor::TryGetPGOType(GateRef gate) const
673 {
674     Gate *gatePtr = circuit_->LoadGatePtr(gate);
675     OpCode op = GetOpCode(gate);
676     if (op == OpCode::JS_BYTECODE) {
677         return gatePtr->GetJSBytecodeMetaData()->GetType();
678     }
679     return PGOTypeRef::NoneType();
680 }
681 
TrySetPGOType(GateRef gate,PGOTypeRef type)682 void GateAccessor::TrySetPGOType(GateRef gate, PGOTypeRef type)
683 {
684     Gate *gatePtr = circuit_->LoadGatePtr(gate);
685     OpCode op = GetOpCode(gate);
686     if (op == OpCode::JS_BYTECODE) {
687         const_cast<JSBytecodeMetaData *>(gatePtr->GetJSBytecodeMetaData())->SetType(type);
688     }
689 }
690 
TryGetArrayElementsLength(GateRef gate) const691 uint32_t GateAccessor::TryGetArrayElementsLength(GateRef gate) const
692 {
693     Gate *gatePtr = circuit_->LoadGatePtr(gate);
694     OpCode op = GetOpCode(gate);
695     if (op == OpCode::JS_BYTECODE) {
696         return gatePtr->GetJSBytecodeMetaData()->GetElementsLength();
697     }
698     return 0;
699 }
700 
TrySetArrayElementsLength(GateRef gate,uint32_t length)701 void GateAccessor::TrySetArrayElementsLength(GateRef gate, uint32_t length)
702 {
703     Gate *gatePtr = circuit_->LoadGatePtr(gate);
704     OpCode op = GetOpCode(gate);
705     if (op == OpCode::JS_BYTECODE) {
706         const_cast<JSBytecodeMetaData *>(gatePtr->GetJSBytecodeMetaData())->SetElementsLength(length);
707     }
708 }
709 
TryGetRegionSpaceFlag(GateRef gate) const710 RegionSpaceFlag GateAccessor::TryGetRegionSpaceFlag(GateRef gate) const
711 {
712     Gate *gatePtr = circuit_->LoadGatePtr(gate);
713     OpCode op = GetOpCode(gate);
714     if (op == OpCode::JS_BYTECODE) {
715         return gatePtr->GetJSBytecodeMetaData()->GetRegionSpaceFlag();
716     }
717     return RegionSpaceFlag::IN_YOUNG_SPACE;
718 }
719 
TrySetRegionSpaceFlag(GateRef gate,RegionSpaceFlag flag)720 void GateAccessor::TrySetRegionSpaceFlag(GateRef gate, RegionSpaceFlag flag)
721 {
722     Gate *gatePtr = circuit_->LoadGatePtr(gate);
723     OpCode op = GetOpCode(gate);
724     if (op == OpCode::JS_BYTECODE) {
725         const_cast<JSBytecodeMetaData *>(gatePtr->GetJSBytecodeMetaData())->SetRegionSpaceFlag(flag);
726     }
727 }
728 
TryGetElementsKind(GateRef gate) const729 ElementsKind GateAccessor::TryGetElementsKind(GateRef gate) const
730 {
731     Gate *gatePtr = circuit_->LoadGatePtr(gate);
732     OpCode op = GetOpCode(gate);
733     if (op == OpCode::JS_BYTECODE) {
734         return Elements::FixElementsKind(gatePtr->GetJSBytecodeMetaData()->GetElementsKind());
735     }
736     return ElementsKind::GENERIC;
737 }
738 
739 // Default is getting elementsKind before possible transition
TryGetArrayElementsKind(GateRef gate) const740 ElementsKind GateAccessor::TryGetArrayElementsKind(GateRef gate) const
741 {
742     Gate *gatePtr = circuit_->LoadGatePtr(gate);
743     OpCode op = GetOpCode(gate);
744     if (op == OpCode::JS_BYTECODE) {
745         ElementsKind kind = gatePtr->GetJSBytecodeMetaData()->GetElementsKind();
746         if (Elements::IsGeneric(kind)) {
747             return kind;
748         }
749         std::vector<ElementsKind> kinds = gatePtr->GetJSBytecodeMetaData()->GetElementsKinds();
750         for (auto &x : kinds) {
751             kind = Elements::MergeElementsKind(kind, x);
752         }
753         return kind;
754     }
755     return ElementsKind::GENERIC;
756 }
757 
TryGetArrayElementsKindAfterTransition(GateRef gate) const758 ElementsKind GateAccessor::TryGetArrayElementsKindAfterTransition(GateRef gate) const
759 {
760     Gate *gatePtr = circuit_->LoadGatePtr(gate);
761     OpCode op = GetOpCode(gate);
762     if (op == OpCode::JS_BYTECODE) {
763         ElementsKind kind = gatePtr->GetJSBytecodeMetaData()->GetTransitionElementsKind();
764         if (Elements::IsGeneric(kind)) {
765             return kind;
766         }
767         std::vector<ElementsKind> kinds = gatePtr->GetJSBytecodeMetaData()->GetTransitionElementsKinds();
768         for (auto &x : kinds) {
769             kind = Elements::MergeElementsKind(kind, x);
770         }
771         return kind;
772     }
773     return ElementsKind::GENERIC;
774 }
775 
TrySetElementsKind(GateRef gate,ElementsKind kind)776 void GateAccessor::TrySetElementsKind(GateRef gate, ElementsKind kind)
777 {
778     Gate *gatePtr = circuit_->LoadGatePtr(gate);
779     OpCode op = GetOpCode(gate);
780     if (op == OpCode::JS_BYTECODE) {
781         const_cast<JSBytecodeMetaData *>(gatePtr->GetJSBytecodeMetaData())->SetElementsKind(kind);
782     }
783 }
784 
TrySetTransitionElementsKind(GateRef gate,ElementsKind kind)785 void GateAccessor::TrySetTransitionElementsKind(GateRef gate, ElementsKind kind)
786 {
787     Gate *gatePtr = circuit_->LoadGatePtr(gate);
788     OpCode op = GetOpCode(gate);
789     if (op == OpCode::JS_BYTECODE) {
790         const_cast<JSBytecodeMetaData *>(gatePtr->GetJSBytecodeMetaData())->SetTransitionElementsKind(kind);
791     }
792 }
793 
TrySetOnHeapMode(GateRef gate,OnHeapMode onHeapMode) const794 void GateAccessor::TrySetOnHeapMode(GateRef gate, OnHeapMode onHeapMode) const
795 {
796     Gate *gatePtr = circuit_->LoadGatePtr(gate);
797     OpCode op = GetOpCode(gate);
798     if (op == OpCode::JS_BYTECODE) {
799         const_cast<JSBytecodeMetaData *>(gatePtr->GetJSBytecodeMetaData())->SetOnHeapMode(onHeapMode);
800     }
801 }
802 
TryGetOnHeapMode(GateRef gate) const803 OnHeapMode GateAccessor::TryGetOnHeapMode(GateRef gate) const
804 {
805     Gate *gatePtr = circuit_->LoadGatePtr(gate);
806     OpCode op = GetOpCode(gate);
807     if (op == OpCode::JS_BYTECODE) {
808         return gatePtr->GetJSBytecodeMetaData()->GetOnHeapMode();
809     }
810     return OnHeapMode::NONE;
811 }
812 
GetByteCodeOpcode(GateRef gate) const813 EcmaOpcode GateAccessor::GetByteCodeOpcode(GateRef gate) const
814 {
815     ASSERT(GetOpCode(gate) == OpCode::JS_BYTECODE);
816     Gate *gatePtr = circuit_->LoadGatePtr(gate);
817     return gatePtr->GetJSBytecodeMetaData()->GetByteCodeOpcode();
818 }
819 
Print(GateRef gate) const820 void GateAccessor::Print(GateRef gate) const
821 {
822     Gate *gatePtr = circuit_->LoadGatePtr(gate);
823     auto comment = circuit_->GetComment(gate);
824     gatePtr->Print("", false, -1, comment);
825 }
826 
ToString(GateRef gate) const827 std::string GateAccessor::ToString(GateRef gate) const
828 {
829     Gate *gatePtr = circuit_->LoadGatePtr(gate);
830     return gatePtr->ToString();
831 }
832 
833 #ifndef NDEBUG
PrintById(size_t id) const834 void GateAccessor::PrintById(size_t id) const
835 {
836     GateRef gate = circuit_->GetGateRefById(id);
837     if (gate != Circuit::NullGate()) {
838         Gate *gatePtr = circuit_->LoadGatePtr(gate);
839         gatePtr->PrintWithBytecode(circuit_->GetComment(gate));
840     } else {
841         LOG_COMPILER(INFO) << "id overflow!";
842     }
843 }
844 #endif
845 
PrintWithBytecode(GateRef gate) const846 void GateAccessor::PrintWithBytecode(GateRef gate) const
847 {
848     Gate *gatePtr = circuit_->LoadGatePtr(gate);
849     gatePtr->PrintWithBytecode(circuit_->GetComment(gate));
850 }
851 
ShortPrint(GateRef gate) const852 void GateAccessor::ShortPrint(GateRef gate) const
853 {
854     Gate *gatePtr = circuit_->LoadGatePtr(gate);
855     gatePtr->ShortPrint();
856 }
857 
GetId(GateRef gate) const858 GateId GateAccessor::GetId(GateRef gate) const
859 {
860     Gate *gatePtr = circuit_->LoadGatePtr(gate);
861     return gatePtr->GetId();
862 }
863 
GetInValueStarts(GateRef gate) const864 size_t GateAccessor::GetInValueStarts(GateRef gate) const
865 {
866     Gate *gatePtr = circuit_->LoadGatePtr(gate);
867     return gatePtr->GetInValueStarts();
868 }
869 
GetValueIn(GateRef gate,size_t idx) const870 GateRef GateAccessor::GetValueIn(GateRef gate, size_t idx) const
871 {
872     Gate *gatePtr = circuit_->LoadGatePtr(gate);
873     ASSERT(idx < gatePtr->GetInValueCount());
874     size_t valueIndex = gatePtr->GetInValueStarts();
875     return circuit_->GetIn(gate, valueIndex + idx);
876 }
877 
GetNumValueIn(GateRef gate) const878 size_t GateAccessor::GetNumValueIn(GateRef gate) const
879 {
880     Gate *gatePtr = circuit_->LoadGatePtr(gate);
881     return gatePtr->GetInValueCount();
882 }
883 
GetValueIns(GateRef gate) const884 std::vector<GateRef> GateAccessor::GetValueIns(GateRef gate) const
885 {
886     size_t num = GetNumValueIn(gate);
887     std::vector<GateRef> valueIns(num);
888     for (size_t i = 0; i < num; ++i) {
889         valueIns[i] = GetValueIn(gate, i);
890     }
891     return valueIns;
892 }
893 
IsGCRelated(GateRef gate) const894 bool GateAccessor::IsGCRelated(GateRef gate) const
895 {
896     return GetGateType(gate).IsGCRelated();
897 }
898 
GetIn(GateRef gate,size_t idx) const899 GateRef GateAccessor::GetIn(GateRef gate, size_t idx) const
900 {
901     return circuit_->GetIn(gate, idx);
902 }
903 
GetState(GateRef gate,size_t idx) const904 GateRef GateAccessor::GetState(GateRef gate, size_t idx) const
905 {
906     ASSERT(idx < circuit_->LoadGatePtr(gate)->GetStateCount());
907     return circuit_->GetIn(gate, idx);
908 }
909 
GetInStates(GateRef gate,std::vector<GateRef> & ins) const910 void GateAccessor::GetInStates(GateRef gate, std::vector<GateRef>& ins) const
911 {
912     const Gate *curGate = circuit_->LoadGatePtrConst(gate);
913     for (size_t idx = 0; idx < curGate->GetStateCount(); idx++) {
914         ins.push_back(circuit_->GetGateRef(curGate->GetInGateConst(idx)));
915     }
916 }
917 
GetIns(GateRef gate,std::vector<GateRef> & ins) const918 void GateAccessor::GetIns(GateRef gate, std::vector<GateRef>& ins) const
919 {
920     const Gate *curGate = circuit_->LoadGatePtrConst(gate);
921     for (size_t idx = 0; idx < curGate->GetNumIns(); idx++) {
922         ins.push_back(circuit_->GetGateRef(curGate->GetInGateConst(idx)));
923     }
924 }
925 
GetOuts(GateRef gate,std::vector<GateRef> & outs) const926 void GateAccessor::GetOuts(GateRef gate, std::vector<GateRef>& outs) const
927 {
928     const Gate *curGate = circuit_->LoadGatePtrConst(gate);
929     if (!curGate->IsFirstOutNull()) {
930         const Out *curOut = curGate->GetFirstOutConst();
931         GateRef ref = circuit_->GetGateRef(curOut->GetGateConst());
932         outs.push_back(ref);
933         while (!curOut->IsNextOutNull()) {
934             curOut = curOut->GetNextOutConst();
935             ref = circuit_->GetGateRef(curOut->GetGateConst());
936             outs.push_back(ref);
937         }
938     }
939 }
940 
HasOuts(GateRef gate) const941 bool GateAccessor::HasOuts(GateRef gate) const
942 {
943     const Gate *curGate = circuit_->LoadGatePtrConst(gate);
944     return !curGate->IsFirstOutNull();
945 }
946 
DeleteGateIfNoUse(GateRef gate)947 void GateAccessor::DeleteGateIfNoUse(GateRef gate)
948 {
949     if (!HasOuts(gate)) {
950         DeleteGate(gate);
951     }
952 }
953 
GetOutStates(GateRef gate,std::vector<GateRef> & outStates) const954 void GateAccessor::GetOutStates(GateRef gate, std::vector<GateRef>& outStates) const
955 {
956     const Gate *curGate = circuit_->LoadGatePtrConst(gate);
957     if (!curGate->IsFirstOutNull()) {
958         const Out *curOut = curGate->GetFirstOutConst();
959         GateRef ref = circuit_->GetGateRef(curOut->GetGateConst());
960         if (GetMetaData(ref)->IsState()) {
961             outStates.push_back(ref);
962         }
963         while (!curOut->IsNextOutNull()) {
964             curOut = curOut->GetNextOutConst();
965             ref = circuit_->GetGateRef(curOut->GetGateConst());
966             if (GetMetaData(ref)->IsState()) {
967                 outStates.push_back(ref);
968             }
969         }
970     }
971 }
972 
GetStateUses(GateRef gate,std::vector<GateRef> & stateUses)973 void GateAccessor::GetStateUses(GateRef gate, std::vector<GateRef> &stateUses)
974 {
975     stateUses.clear();
976     auto uses = Uses(gate);
977     for (auto it = uses.begin(); it != uses.end(); it++) {
978         if (IsStateIn(it)) {
979             stateUses.emplace_back(*it);
980         }
981     }
982 }
983 
GetDependUses(GateRef gate,std::vector<GateRef> & dependUses)984 void GateAccessor::GetDependUses(GateRef gate, std::vector<GateRef> &dependUses)
985 {
986     dependUses.clear();
987     auto uses = Uses(gate);
988     for (auto it = uses.begin(); it != uses.end(); it++) {
989         if (IsDependIn(it)) {
990             dependUses.emplace_back(*it);
991         }
992     }
993 }
994 
GetValueUses(GateRef gate,std::vector<GateRef> & valueUses)995 void GateAccessor::GetValueUses(GateRef gate, std::vector<GateRef> &valueUses)
996 {
997     valueUses.clear();
998     auto uses = Uses(gate);
999     for (auto it = uses.begin(); it != uses.end(); it++) {
1000         if (IsValueIn(it)) {
1001             valueUses.emplace_back(*it);
1002         }
1003     }
1004 }
1005 
GetValueUsesCount(GateRef gate)1006 size_t GateAccessor::GetValueUsesCount(GateRef gate)
1007 {
1008     size_t count = 0;
1009     auto uses = Uses(gate);
1010     for (auto it = uses.begin(); it != uses.end(); it++) {
1011         if (IsValueIn(it)) {
1012             count++;
1013         }
1014     }
1015     return count;
1016 }
1017 
GetAllGates(std::vector<GateRef> & gates) const1018 void GateAccessor::GetAllGates(std::vector<GateRef>& gates) const
1019 {
1020     circuit_->GetAllGates(gates);
1021 }
1022 
IsBoolType(GateRef gate) const1023 bool GateAccessor::IsBoolType(GateRef gate) const
1024 {
1025     return GetMachineType(gate) == MachineType::I1;
1026 }
1027 
IsInGateNull(GateRef gate,size_t idx) const1028 bool GateAccessor::IsInGateNull(GateRef gate, size_t idx) const
1029 {
1030     return circuit_->IsInGateNull(gate, idx);
1031 }
1032 
IsValueSelector(GateRef g) const1033 bool GateAccessor::IsValueSelector(GateRef g) const
1034 {
1035     return GetOpCode(g) == OpCode::VALUE_SELECTOR;
1036 }
1037 
IsSelector(GateRef g) const1038 bool GateAccessor::IsSelector(GateRef g) const
1039 {
1040     auto op = GetOpCode(g);
1041     return (op == OpCode::VALUE_SELECTOR) || (op == OpCode::DEPEND_SELECTOR);
1042 }
1043 
IsFrameValues(GateRef g) const1044 bool GateAccessor::IsFrameValues(GateRef g) const
1045 {
1046     auto op = GetOpCode(g);
1047     return op == OpCode::FRAME_VALUES;
1048 }
1049 
IsIn(GateRef g,GateRef in) const1050 bool GateAccessor::IsIn(GateRef g, GateRef in) const
1051 {
1052     size_t n = GetNumIns(g);
1053     for (size_t id = 0; id < n; id++) {
1054         GateRef i = GetIn(g, id);
1055         if (i == in) {
1056             return true;
1057         }
1058     }
1059     return false;
1060 }
1061 
IsSimpleState(GateRef g) const1062 bool GateAccessor::IsSimpleState(GateRef g) const
1063 {
1064     auto op = GetOpCode(g);
1065     return (op == OpCode::IF_TRUE ||
1066             op == OpCode::IF_FALSE ||
1067             op == OpCode::SWITCH_CASE ||
1068             op == OpCode::DEFAULT_CASE ||
1069             op == OpCode::LOOP_BACK ||
1070             op == OpCode::MERGE ||
1071             op == OpCode::VALUE_SELECTOR ||
1072             op == OpCode::DEPEND_SELECTOR ||
1073             op == OpCode::DEPEND_RELAY ||
1074             op == OpCode::ORDINARY_BLOCK);
1075 }
1076 
IsControlCase(GateRef gate) const1077 bool GateAccessor::IsControlCase(GateRef gate) const
1078 {
1079     return circuit_->IsControlCase(gate);
1080 }
1081 
IsLoopExit(GateRef gate) const1082 bool GateAccessor::IsLoopExit(GateRef gate) const
1083 {
1084     return (GetOpCode(gate) == OpCode::LOOP_EXIT);
1085 }
1086 
IsLoopExitRelated(GateRef gate) const1087 bool GateAccessor::IsLoopExitRelated(GateRef gate) const
1088 {
1089     return (GetOpCode(gate) == OpCode::LOOP_EXIT) ||
1090            (GetOpCode(gate) == OpCode::LOOP_EXIT_DEPEND) ||
1091            (GetOpCode(gate) == OpCode::LOOP_EXIT_VALUE);
1092 }
1093 
IsLoopHead(GateRef gate) const1094 bool GateAccessor::IsLoopHead(GateRef gate) const
1095 {
1096     return circuit_->IsLoopHead(gate);
1097 }
1098 
IsLoopBack(GateRef gate) const1099 bool GateAccessor::IsLoopBack(GateRef gate) const
1100 {
1101     return GetOpCode(gate) == OpCode::LOOP_BACK;
1102 }
1103 
IsState(GateRef gate) const1104 bool GateAccessor::IsState(GateRef gate) const
1105 {
1106     return GetMetaData(gate)->IsState();
1107 }
1108 
IsConstant(GateRef gate) const1109 bool GateAccessor::IsConstant(GateRef gate) const
1110 {
1111     return GetMetaData(gate)->IsConstant();
1112 }
1113 
IsDependSelector(GateRef gate) const1114 bool GateAccessor::IsDependSelector(GateRef gate) const
1115 {
1116     return GetMetaData(gate)->IsDependSelector();
1117 }
1118 
IsConstantValue(GateRef gate,uint64_t value) const1119 bool GateAccessor::IsConstantValue(GateRef gate, uint64_t value) const
1120 {
1121     if (GetOpCode(gate) == OpCode::CONSTANT) {
1122         uint64_t bitField = GetConstantValue(gate);
1123         return bitField == value;
1124     }
1125     return false;
1126 }
1127 
IsConstantTaggedValue(GateRef gate,uint64_t value) const1128 bool GateAccessor::IsConstantTaggedValue(GateRef gate, uint64_t value) const
1129 {
1130     if (GetMachineType(gate) != MachineType::I64 || GetGateType(gate).IsNJSValueType()) {
1131         return false;
1132     }
1133     if (GetOpCode(gate) == OpCode::CONSTANT) {
1134         uint64_t bitField = GetConstantValue(gate);
1135         return bitField == value;
1136     }
1137     return false;
1138 }
1139 
IsConstantUndefined(GateRef gate) const1140 bool GateAccessor::IsConstantUndefined(GateRef gate) const
1141 {
1142     return IsConstantTaggedValue(gate, JSTaggedValue::VALUE_UNDEFINED);
1143 }
1144 
IsUndefinedOrNullOrHole(GateRef gate) const1145 bool GateAccessor::IsUndefinedOrNullOrHole(GateRef gate) const
1146 {
1147     return IsConstantTaggedValue(gate, JSTaggedValue::VALUE_UNDEFINED) ||
1148            IsConstantTaggedValue(gate, JSTaggedValue::VALUE_NULL) ||
1149            IsConstantTaggedValue(gate, JSTaggedValue::VALUE_HOLE);
1150 }
1151 
IsTypedOperator(GateRef gate) const1152 bool GateAccessor::IsTypedOperator(GateRef gate) const
1153 {
1154     return GetMetaData(gate)->IsTypedOperator();
1155 }
1156 
IsNotWrite(GateRef gate) const1157 bool GateAccessor::IsNotWrite(GateRef gate) const
1158 {
1159     return GetMetaData(gate)->IsNotWrite();
1160 }
1161 
IsCheckWithTwoIns(GateRef gate) const1162 bool GateAccessor::IsCheckWithTwoIns(GateRef gate) const
1163 {
1164     return GetMetaData(gate)->IsCheckWithTwoIns();
1165 }
1166 
IsCheckWithOneIn(GateRef gate) const1167 bool GateAccessor::IsCheckWithOneIn(GateRef gate) const
1168 {
1169     return GetMetaData(gate)->IsCheckWithOneIn();
1170 }
1171 
IsSchedulable(GateRef gate) const1172 bool GateAccessor::IsSchedulable(GateRef gate) const
1173 {
1174     return GetMetaData(gate)->IsSchedulable();
1175 }
1176 
IsVirtualState(GateRef gate) const1177 bool GateAccessor::IsVirtualState(GateRef gate) const
1178 {
1179     return GetMetaData(gate)->IsVirtualState();
1180 }
1181 
IsGeneralState(GateRef gate) const1182 bool GateAccessor::IsGeneralState(GateRef gate) const
1183 {
1184     return GetMetaData(gate)->IsGeneralState();
1185 }
1186 
IsIfOrSwitchRelated(GateRef gate) const1187 bool GateAccessor::IsIfOrSwitchRelated(GateRef gate) const
1188 {
1189     return GetMetaData(gate)->IsIfOrSwitchRelated();
1190 }
1191 
GetDep(GateRef gate,size_t idx) const1192 GateRef GateAccessor::GetDep(GateRef gate, size_t idx) const
1193 {
1194     Gate *gatePtr = circuit_->LoadGatePtr(gate);
1195     ASSERT(idx < gatePtr->GetDependCount());
1196     size_t dependIndex = gatePtr->GetStateCount();
1197     return circuit_->GetIn(gate, dependIndex + idx);
1198 }
1199 
GetImmediateId(GateRef gate) const1200 size_t GateAccessor::GetImmediateId(GateRef gate) const
1201 {
1202     Gate *gatePtr = circuit_->LoadGatePtr(gate);
1203     ASSERT(gatePtr->GetGateType() == GateType::NJSValue());
1204     ASSERT(gatePtr->GetOpCode() == OpCode::CONSTANT);
1205     ASSERT(gatePtr->GetMachineType() == MachineType::I64);
1206     size_t imm = gatePtr->GetOneParameterMetaData()->GetValue();
1207     return imm;
1208 }
1209 
SetDep(GateRef gate,GateRef depGate,size_t idx)1210 void GateAccessor::SetDep(GateRef gate, GateRef depGate, size_t idx)
1211 {
1212     Gate *gatePtr = circuit_->LoadGatePtr(gate);
1213     ASSERT(idx < gatePtr->GetDependCount());
1214     size_t dependIndex = gatePtr->GetStateCount();
1215     gatePtr->ModifyIn(dependIndex + idx, circuit_->LoadGatePtr(depGate));
1216 }
1217 
ReplaceIn(const UseIterator & useIt,GateRef replaceGate)1218 UseIterator GateAccessor::ReplaceIn(const UseIterator &useIt, GateRef replaceGate)
1219 {
1220     UseIterator next = useIt;
1221     next++;
1222     Gate *curGatePtr = circuit_->LoadGatePtr(*useIt);
1223     Gate *replaceGatePtr = circuit_->LoadGatePtr(replaceGate);
1224     curGatePtr->ModifyIn(useIt.GetIndex(), replaceGatePtr);
1225     return next;
1226 }
1227 
GetGateType(GateRef gate) const1228 GateType GateAccessor::GetGateType(GateRef gate) const
1229 {
1230     return circuit_->LoadGatePtr(gate)->GetGateType();
1231 }
1232 
SetGateType(GateRef gate,GateType gt)1233 void GateAccessor::SetGateType(GateRef gate, GateType gt)
1234 {
1235     circuit_->LoadGatePtr(gate)->SetGateType(gt);
1236 }
1237 
ReplaceHirIfSuccess(const UseIterator & useIt,GateRef state)1238 UseIterator GateAccessor::ReplaceHirIfSuccess(const UseIterator &useIt, GateRef state)
1239 {
1240     ASSERT(GetOpCode(*useIt) == OpCode::IF_SUCCESS);
1241     auto uses = Uses(*useIt);
1242     for (auto it = uses.begin(); it != uses.end();) {
1243         if (IsStateIn(it)) {
1244             it = ReplaceIn(it, state);
1245         }
1246     }
1247     auto next = DeleteGate(useIt);
1248     return next;
1249 }
1250 
ReplaceHirIfException(const UseIterator & useIt,StateDepend replacement)1251 UseIterator GateAccessor::ReplaceHirIfException(const UseIterator &useIt, StateDepend replacement)
1252 {
1253     ASSERT(GetOpCode(*useIt) == OpCode::IF_EXCEPTION);
1254     auto uses = Uses(*useIt);
1255     for (auto it = uses.begin(); it != uses.end();) {
1256         if (IsStateIn(it)) {
1257             it = ReplaceIn(it, replacement.State());
1258         } else if (IsDependIn(it)) {
1259             it = ReplaceIn(it, replacement.Depend());
1260         } else {
1261             ASSERT(!IsValueIn(it));
1262         }
1263     }
1264     UseIterator next = useIt;
1265     next++;
1266     return next;
1267 }
1268 
ExceptionReturn(GateRef state,GateRef depend)1269 void GateAccessor::ExceptionReturn(GateRef state, GateRef depend)
1270 {
1271     CircuitBuilder builder(circuit_);
1272     auto constant = builder.ExceptionConstant();
1273     builder.Return(state, depend, constant);
1274 }
1275 
ReplaceHirWithIfBranch(GateRef hirGate,StateDepend success,StateDepend exception,GateRef value)1276 void GateAccessor::ReplaceHirWithIfBranch(GateRef hirGate, StateDepend success,
1277                                           StateDepend exception, GateRef value)
1278 {
1279     auto uses = Uses(hirGate);
1280     GateRef ifException = Circuit::NullGate();
1281     for (auto it = uses.begin(); it != uses.end();) {
1282         if (IsStateIn(it)) {
1283             const OpCode op = GetOpCode(*it);
1284             if (op == OpCode::IF_SUCCESS) {
1285                 it = ReplaceHirIfSuccess(it, success.State());
1286             } else if (op == OpCode::IF_EXCEPTION) {
1287                 ifException = *it;
1288                 it = ReplaceHirIfException(it, exception);
1289             } else if (GetMetaData(*it)->IsVirtualState()) {
1290                 it = ReplaceIn(it, success.State());
1291             } else {
1292                 ExceptionReturn(exception.State(), exception.Depend());
1293                 it = ReplaceIn(it, success.State());
1294             }
1295         } else if (IsDependIn(it)) {
1296             const OpCode op = GetOpCode(*it);
1297             if (op == OpCode::IF_EXCEPTION) {
1298                 // ignore it now.
1299                 it++;
1300             } else {
1301                 it = ReplaceIn(it, success.Depend());
1302             }
1303         } else {
1304             ASSERT(IsValueIn(it));
1305             it = ReplaceIn(it, value);
1306         }
1307     }
1308 
1309     if (ifException != Circuit::NullGate()) {
1310         DeleteGate(ifException);
1311     }
1312 
1313     // delete old gate
1314     DeleteGate(hirGate);
1315 }
1316 
ReplaceHirDirectly(GateRef hirGate,StateDepend replacement,GateRef value)1317 void GateAccessor::ReplaceHirDirectly(GateRef hirGate,
1318     StateDepend replacement, GateRef value)
1319 {
1320     auto uses = Uses(hirGate);
1321     for (auto it = uses.begin(); it != uses.end();) {
1322         if (IsStateIn(it)) {
1323             ASSERT(GetOpCode(*it) != OpCode::IF_SUCCESS &&
1324                 GetOpCode(*it) != OpCode::IF_EXCEPTION);
1325             it = ReplaceIn(it, replacement.State());
1326         } else if (IsDependIn(it)) {
1327             it = ReplaceIn(it, replacement.Depend());
1328         } else {
1329             ASSERT(IsValueIn(it));
1330             it = ReplaceIn(it, value);
1331         }
1332     }
1333 
1334     // delete old gate
1335     DeleteGate(hirGate);
1336 }
1337 
ReplaceHirAndReplaceDeadIfException(GateRef hirGate,StateDepend replacement,GateRef value)1338 void GateAccessor::ReplaceHirAndReplaceDeadIfException(GateRef hirGate,
1339     StateDepend replacement, GateRef value)
1340 {
1341     if (value != Circuit::NullGate()) {
1342         auto type = GetGateType(hirGate);
1343         if (!type.IsAnyType()) {
1344             SetGateType(value, type);
1345         }
1346     }
1347     GateRef ifException = Circuit::NullGate();
1348     auto uses = Uses(hirGate);
1349     for (auto it = uses.begin(); it != uses.end();) {
1350         if (IsStateIn(it)) {
1351             const OpCode op = GetOpCode(*it);
1352             if (op == OpCode::IF_SUCCESS) {
1353                 it = ReplaceHirIfSuccess(it, replacement.State());
1354             } else if (op == OpCode::IF_EXCEPTION) {
1355                 ifException = *it;
1356                 it = ReplaceIn(it, circuit_->DeadGate());
1357             } else {
1358                 it = ReplaceIn(it, replacement.State());
1359             }
1360         } else if (IsDependIn(it)) {
1361             const OpCode op = GetOpCode(*it);
1362             if (op == OpCode::IF_EXCEPTION) {
1363                 it = ReplaceIn(it, circuit_->DeadGate());
1364             } else {
1365                 it = ReplaceIn(it, replacement.Depend());
1366             }
1367         } else {
1368             ASSERT(IsValueIn(it));
1369             it = ReplaceIn(it, value);
1370         }
1371     }
1372 
1373     // delete old gate
1374     DeleteGate(hirGate);
1375     if (ifException != Circuit::NullGate()) {
1376         ReplaceGate(ifException, circuit_->DeadGate());
1377     }
1378     #ifndef NDEBUG
1379         GetCircuit()->AddComment(value,  "old V " + std::to_string(GetId(hirGate)));
1380         GetCircuit()->AddComment(replacement.Depend(),  "old D " + std::to_string(GetId(hirGate)));
1381     #endif
1382 }
1383 
DeleteGate(const UseIterator & useIt)1384 UseIterator GateAccessor::DeleteGate(const UseIterator &useIt)
1385 {
1386     auto next = useIt;
1387     next++;
1388     circuit_->DeleteGate(*useIt);
1389     return next;
1390 }
1391 
DecreaseIn(const UseIterator & useIt)1392 void GateAccessor::DecreaseIn(const UseIterator &useIt)
1393 {
1394     size_t idx = useIt.GetIndex();
1395     circuit_->DecreaseIn(*useIt, idx);
1396 }
1397 
DecreaseIn(GateRef gate,size_t index)1398 void GateAccessor::DecreaseIn(GateRef gate, size_t index)
1399 {
1400     circuit_->DecreaseIn(gate, index);
1401 }
1402 
NewIn(GateRef gate,size_t idx,GateRef in)1403 void GateAccessor::NewIn(GateRef gate, size_t idx, GateRef in)
1404 {
1405     circuit_->NewIn(gate, idx, in);
1406 }
1407 
GetStateCount(GateRef gate) const1408 size_t GateAccessor::GetStateCount(GateRef gate) const
1409 {
1410     return circuit_->LoadGatePtr(gate)->GetStateCount();
1411 }
1412 
GetDependCount(GateRef gate) const1413 size_t GateAccessor::GetDependCount(GateRef gate) const
1414 {
1415     return circuit_->LoadGatePtr(gate)->GetDependCount();
1416 }
1417 
GetInValueCount(GateRef gate) const1418 size_t GateAccessor::GetInValueCount(GateRef gate) const
1419 {
1420     return circuit_->LoadGatePtr(gate)->GetInValueCount();
1421 }
1422 
UpdateAllUses(GateRef oldIn,GateRef newIn)1423 void GateAccessor::UpdateAllUses(GateRef oldIn, GateRef newIn)
1424 {
1425     if (oldIn == newIn) {
1426         return;
1427     }
1428     auto uses = Uses(oldIn);
1429     for (auto useIt = uses.begin(); useIt != uses.end();) {
1430         useIt = ReplaceIn(useIt, newIn);
1431     }
1432 }
1433 
ReplaceIn(GateRef gate,size_t index,GateRef in)1434 void GateAccessor::ReplaceIn(GateRef gate, size_t index, GateRef in)
1435 {
1436     circuit_->ModifyIn(gate, index, in);
1437 }
1438 
DeleteIn(GateRef gate,size_t idx)1439 void GateAccessor::DeleteIn(GateRef gate, size_t idx)
1440 {
1441     ASSERT(idx < circuit_->LoadGatePtrConst(gate)->GetNumIns());
1442     ASSERT(!circuit_->IsInGateNull(gate, idx));
1443     circuit_->LoadGatePtr(gate)->DeleteIn(idx);
1444 }
1445 
ReplaceStateIn(GateRef gate,GateRef in,size_t index)1446 void GateAccessor::ReplaceStateIn(GateRef gate, GateRef in, size_t index)
1447 {
1448     ASSERT(index < GetStateCount(gate));
1449     circuit_->ModifyIn(gate, index, in);
1450 }
1451 
ReplaceDependIn(GateRef gate,GateRef in,size_t index)1452 void GateAccessor::ReplaceDependIn(GateRef gate, GateRef in, size_t index)
1453 {
1454     ASSERT(index < GetDependCount(gate));
1455     size_t stateCount = GetStateCount(gate);
1456     circuit_->ModifyIn(gate, stateCount + index, in);
1457 }
1458 
ReplaceOrNewDependIn(GateRef gate,GateRef in,size_t index)1459 void GateAccessor::ReplaceOrNewDependIn(GateRef gate, GateRef in, size_t index)
1460 {
1461     ASSERT(index < GetDependCount(gate));
1462     size_t stateCount = GetStateCount(gate);
1463     auto depend = GetDep(gate);
1464     if (depend == Circuit::NullGate()) {
1465         circuit_->NewIn(gate, stateCount + index, in);
1466     } else {
1467         circuit_->ModifyIn(gate, stateCount + index, in);
1468     }
1469 }
1470 
ReplaceValueIn(GateRef gate,GateRef in,size_t index)1471 void GateAccessor::ReplaceValueIn(GateRef gate, GateRef in, size_t index)
1472 {
1473     ASSERT(index < GetInValueCount(gate));
1474     size_t valueStartIndex = GetInValueStarts(gate);
1475     circuit_->ModifyIn(gate, valueStartIndex + index, in);
1476 }
1477 
DeleteGate(GateRef gate)1478 void GateAccessor::DeleteGate(GateRef gate)
1479 {
1480     circuit_->DeleteGate(gate);
1481 }
1482 
GetMachineType(GateRef gate) const1483 MachineType GateAccessor::GetMachineType(GateRef gate) const
1484 {
1485     return circuit_->GetMachineType(gate);
1486 }
1487 
SetMachineType(GateRef gate,MachineType type)1488 void GateAccessor::SetMachineType(GateRef gate, MachineType type)
1489 {
1490     circuit_->SetMachineType(gate, type);
1491 }
1492 
GetConstantGate(MachineType bitValue,BitField bitfield,GateType type) const1493 GateRef GateAccessor::GetConstantGate(MachineType bitValue, BitField bitfield, GateType type) const
1494 {
1495     return circuit_->GetConstantGate(bitValue, bitfield, type);
1496 }
1497 
GetInitialEnvGate(GateRef depend,GateRef jsFunc) const1498 GateRef GateAccessor::GetInitialEnvGate(GateRef depend, GateRef jsFunc) const
1499 {
1500     return circuit_->GetInitialEnvGate(depend, jsFunc);
1501 }
1502 
IsConstantNumber(GateRef gate) const1503 bool GateAccessor::IsConstantNumber(GateRef gate) const
1504 {
1505     DISALLOW_GARBAGE_COLLECTION;
1506     if (GetGateType(gate).IsNJSValueType() ||
1507         (GetOpCode(gate) != OpCode::CONSTANT)) {
1508         return false;
1509     }
1510     JSTaggedValue value(GetConstantValue(gate));
1511     return value.IsNumber();
1512 }
1513 
GetFloat64FromConstant(GateRef gate) const1514 double GateAccessor::GetFloat64FromConstant(GateRef gate) const
1515 {
1516     DISALLOW_GARBAGE_COLLECTION;
1517     ASSERT(GetOpCode(gate) == OpCode::CONSTANT);
1518     uint64_t rawValue = GetConstantValue(gate);
1519     if (GetGateType(gate).IsNJSValueType()) {
1520         ASSERT(GetMachineType(gate) == MachineType::F64);
1521         return base::bit_cast<double>(rawValue);
1522     }
1523     JSTaggedValue value(rawValue);
1524     return value.GetDouble();
1525 }
1526 
GetInt32FromConstant(GateRef gate) const1527 int GateAccessor::GetInt32FromConstant(GateRef gate) const
1528 {
1529     DISALLOW_GARBAGE_COLLECTION;
1530     ASSERT(GetOpCode(gate) == OpCode::CONSTANT);
1531     uint64_t rawValue = GetConstantValue(gate);
1532     if (GetGateType(gate).IsNJSValueType()) {
1533         ASSERT(GetMachineType(gate) == MachineType::I32);
1534         return static_cast<int>(rawValue);
1535     }
1536     JSTaggedValue value(rawValue);
1537     return value.GetInt();
1538 }
1539 
IsStateIn(const UseIterator & useIt) const1540 bool GateAccessor::IsStateIn(const UseIterator &useIt) const
1541 {
1542     size_t stateStartIndex = 0;
1543     size_t stateEndIndex = stateStartIndex + GetStateCount(*useIt);
1544     size_t index = useIt.GetIndex();
1545     return (index >= stateStartIndex && index < stateEndIndex);
1546 }
1547 
IsDependIn(const UseIterator & useIt) const1548 bool GateAccessor::IsDependIn(const UseIterator &useIt) const
1549 {
1550     size_t dependStartIndex = GetStateCount(*useIt);
1551     size_t dependEndIndex = dependStartIndex + GetDependCount(*useIt);
1552     size_t index = useIt.GetIndex();
1553     return (index >= dependStartIndex && index < dependEndIndex);
1554 }
1555 
IsValueIn(const UseIterator & useIt) const1556 bool GateAccessor::IsValueIn(const UseIterator &useIt) const
1557 {
1558     size_t valueStartIndex = GetInValueStarts(*useIt);
1559     size_t valueEndIndex = valueStartIndex + GetInValueCount(*useIt);
1560     size_t index = useIt.GetIndex();
1561     return (index >= valueStartIndex && index < valueEndIndex);
1562 }
1563 
IsFrameStateIn(const UseIterator & useIt) const1564 bool GateAccessor::IsFrameStateIn(const UseIterator &useIt) const
1565 {
1566     size_t index = useIt.GetIndex();
1567     return IsFrameStateIn(*useIt, index);
1568 }
1569 
IsStateIn(GateRef gate,size_t index) const1570 bool GateAccessor::IsStateIn(GateRef gate, size_t index) const
1571 {
1572     size_t stateStartIndex = 0;
1573     size_t stateEndIndex = stateStartIndex + GetStateCount(gate);
1574     return (index >= stateStartIndex && index < stateEndIndex);
1575 }
1576 
IsDependIn(GateRef gate,size_t index) const1577 bool GateAccessor::IsDependIn(GateRef gate, size_t index) const
1578 {
1579     size_t dependStartIndex = GetStateCount(gate);
1580     size_t dependEndIndex = dependStartIndex + GetDependCount(gate);
1581     return (index >= dependStartIndex && index < dependEndIndex);
1582 }
1583 
IsValueIn(GateRef gate,size_t index) const1584 bool GateAccessor::IsValueIn(GateRef gate, size_t index) const
1585 {
1586     size_t valueStartIndex = GetInValueStarts(gate);
1587     size_t valueEndIndex = valueStartIndex + GetInValueCount(gate);
1588     return (index >= valueStartIndex && index < valueEndIndex);
1589 }
1590 
IsFrameStateIn(GateRef gate,size_t index) const1591 bool GateAccessor::IsFrameStateIn(GateRef gate, size_t index) const
1592 {
1593     Gate *gatePtr = circuit_->LoadGatePtr(gate);
1594     size_t frameStateStartIndex = gatePtr->GetInFrameStateStarts();
1595     size_t FrameStateEndIndex = frameStateStartIndex + gatePtr->GetInFrameStateCount();
1596     return (index >= frameStateStartIndex && index < FrameStateEndIndex);
1597 }
1598 
ReplaceGate(GateRef gate,GateRef state,GateRef depend,GateRef value)1599 void GateAccessor::ReplaceGate(GateRef gate, GateRef state, GateRef depend, GateRef value)
1600 {
1601     if (value != Circuit::NullGate()) {
1602         GateType type = GetGateType(gate);
1603         GateType valueType = GetGateType(value);
1604         if (!type.IsAnyType() && !valueType.IsNJSValueType()) {
1605             SetGateType(value, type);
1606         }
1607     }
1608 
1609     auto uses = Uses(gate);
1610     for (auto useIt = uses.begin(); useIt != uses.end();) {
1611         if (IsStateIn(useIt)) {
1612             ASSERT(state != Circuit::NullGate());
1613             useIt = ReplaceIn(useIt, state);
1614         } else if (IsDependIn(useIt)) {
1615             ASSERT(depend != Circuit::NullGate());
1616             useIt = ReplaceIn(useIt, depend);
1617         } else if (IsValueIn(useIt)) {
1618             ASSERT(value != Circuit::NullGate());
1619             useIt = ReplaceIn(useIt, value);
1620         } else {
1621             LOG_ECMA(FATAL) << "this branch is unreachable";
1622             UNREACHABLE();
1623         }
1624     }
1625 #ifndef NDEBUG
1626     GetCircuit()->AddComment(value,  "old V " + std::to_string(GetId(gate)));
1627 #endif
1628     DeleteGate(gate);
1629 }
1630 
ReplaceGate(GateRef gate,GateRef replacement)1631 void GateAccessor::ReplaceGate(GateRef gate, GateRef replacement)
1632 {
1633     GateRef depend = Circuit::NullGate();
1634     if (GetDependCount(gate) > 0) {
1635         ASSERT(GetDependCount(gate) == 1); // 1: one dep
1636         depend = GetDep(gate);
1637     }
1638     GateRef state = Circuit::NullGate();
1639     if (GetStateCount(gate) > 0) {
1640         ASSERT(GetStateCount(gate) == 1);  // 1: one state
1641         state = GetState(gate);
1642     }
1643     return ReplaceGate(gate, StateDepend {state, depend}, replacement);
1644 }
1645 
ReplaceGate(GateRef gate,StateDepend stateDepend,GateRef replacement)1646 void GateAccessor::ReplaceGate(GateRef gate, StateDepend stateDepend, GateRef replacement)
1647 {
1648     ASSERT(gate != replacement);
1649     auto state = stateDepend.State();
1650     auto depend = stateDepend.Depend();
1651     auto uses = Uses(gate);
1652     for (auto it = uses.begin(); it != uses.end();) {
1653         if (IsStateIn(it)) {
1654             ASSERT(state != Circuit::NullGate());
1655             it = ReplaceIn(it, state);
1656         } else if (IsDependIn(it)) {
1657             ASSERT(depend != Circuit::NullGate());
1658             it = ReplaceIn(it, depend);
1659         } else {
1660             it = ReplaceIn(it, replacement);
1661         }
1662     }
1663 #ifndef NDEBUG
1664     GetCircuit()->AddComment(replacement,  "old V " + std::to_string(GetId(gate)));
1665 #endif
1666     DeleteGate(gate);
1667 }
1668 
ReplaceControlGate(GateRef gate,GateRef newState)1669 void GateAccessor::ReplaceControlGate(GateRef gate, GateRef newState)
1670 {
1671     auto uses = Uses(gate);
1672     for (auto useIt = uses.begin(); useIt != uses.end();) {
1673         if (IsStateIn(useIt)) {
1674             OpCode opcode = GetOpCode(*useIt);
1675             if (opcode == OpCode::VALUE_SELECTOR || opcode == OpCode::DEPEND_SELECTOR) {
1676                 useIt++;
1677             } else {
1678                 useIt = ReplaceIn(useIt, newState);
1679             }
1680         } else {
1681             LOG_ECMA(FATAL) << "this branch is unreachable";
1682             UNREACHABLE();
1683         }
1684     }
1685     // Do not delete this gate
1686 }
1687 
1688 // When Insert newGate, all the stateIn from state and dependIn from depend can be replaced to newGate
ReplaceInAfterInsert(GateRef state,GateRef depend,GateRef newGate)1689 void GateAccessor::ReplaceInAfterInsert(GateRef state, GateRef depend, GateRef newGate)
1690 {
1691     auto uses = Uses(state);
1692     for (auto useIt = uses.begin(); useIt != uses.end();) {
1693         if (IsStateIn(useIt) && (*useIt != newGate)) {
1694             ASSERT(newGate != Circuit::NullGate());
1695             // Exception, for example, IF_TRUE / IF_FALSE -> DEPEND_RELAY,
1696             // or LOOP_BEGIN / MERGE -> DEPEND_SELECTOR cannot be replaced
1697             if (!IsState(*useIt)) {
1698                 useIt++;
1699                 continue;
1700             }
1701             useIt = ReplaceIn(useIt, newGate);
1702         } else {
1703             useIt++;
1704         }
1705     }
1706 
1707     uses = Uses(depend);
1708     for (auto useIt = uses.begin(); useIt != uses.end();) {
1709         if (IsDependIn(useIt) && (*useIt != newGate)) {
1710             ASSERT(newGate != Circuit::NullGate());
1711             useIt = ReplaceIn(useIt, newGate);
1712         } else {
1713             useIt++;
1714         }
1715     }
1716 }
1717 
1718 // When loopExit, find stateSplit after DEPEND_SELECTOR
GetFrameStateDependIn(GateRef gate,GateRef & dependIn)1719 void GateAccessor::GetFrameStateDependIn(GateRef gate, GateRef &dependIn)
1720 {
1721     auto uses = Uses(gate);
1722     size_t stateSplitCount = 0;
1723     GateRef stateSplit = Circuit::NullGate();
1724     for (auto it = uses.begin(); it != uses.end();) {
1725         if (GetOpCode(*it) == OpCode::STATE_SPLIT) {
1726             ASSERT(stateSplitCount < 1); // only one state Split;
1727             stateSplitCount++;
1728             stateSplit = *it;
1729             break;
1730         } else {
1731             ++it;
1732         }
1733     }
1734 
1735     ASSERT(stateSplitCount <= 1);
1736     if (stateSplitCount == 1 && stateSplit != Circuit::NullGate()) {
1737         dependIn = stateSplit;
1738     }
1739 }
1740 
1741 // When ifOp or loopExit, insertAfter
1742 // stateIn: IF_TRUE / IF_FALSE / MERGE
1743 // dependIn: DEPEND_RELAY / DEPEND_SELECTOR, if stateSplit follow closely, after the stateSplit.
1744 
GetStateInAndDependIn(GateRef insertAfter,GateRef & stateIn,GateRef & dependIn)1745 void GateAccessor::GetStateInAndDependIn(GateRef insertAfter, GateRef &stateIn, GateRef &dependIn)
1746 {
1747     if (GetOpCode(insertAfter) == OpCode::IF_TRUE || GetOpCode(insertAfter) == OpCode::IF_FALSE
1748         || GetOpCode(insertAfter) == OpCode::IF_SUCCESS) {
1749         auto uses = Uses(insertAfter);
1750         for (auto it = uses.begin(); it != uses.end();) {
1751             if (GetOpCode(*it) == OpCode::DEPEND_RELAY) {
1752                 stateIn = insertAfter;
1753                 dependIn = (*it);
1754                 break;
1755             } else {
1756                 ++it;
1757             }
1758         }
1759     } else if (GetOpCode(insertAfter) == OpCode::MERGE) {
1760         auto uses = Uses(insertAfter);
1761         for (auto it = uses.begin(); it != uses.end();) {
1762             if (GetOpCode(*it) == OpCode::DEPEND_SELECTOR) {
1763                 stateIn = insertAfter;
1764                 dependIn = (*it);
1765                 GetFrameStateDependIn(*it, dependIn);
1766                 break;
1767             } else {
1768                 ++it;
1769             }
1770         }
1771     }
1772     ASSERT(GetDependCount(dependIn) > 0);
1773 }
1774 
GetFrameDepth(GateRef gate,OpCode op)1775 size_t GateAccessor::GetFrameDepth(GateRef gate, OpCode op)
1776 {
1777     if (GetOpCode(gate) != op) {
1778         return 0;
1779     }
1780     size_t depth = 0;
1781     GateRef prev = GetFrameState(gate);
1782     while ((GetOpCode(prev) == op)) {
1783         depth++;
1784         prev = GetFrameState(prev);
1785     }
1786     return depth;
1787 }
1788 
GetFrameState(GateRef gate) const1789 GateRef GateAccessor::GetFrameState(GateRef gate) const
1790 {
1791     ASSERT(HasFrameState(gate));
1792     Gate *gatePtr = circuit_->LoadGatePtr(gate);
1793     size_t index = gatePtr->GetInFrameStateStarts();
1794     return circuit_->GetIn(gate, index);
1795 }
1796 
FindNearestFrameState(GateRef gate) const1797 GateRef GateAccessor::FindNearestFrameState(GateRef gate) const
1798 {
1799     auto statesplit = FindNearestStateSplit(gate);
1800     return GetFrameState(statesplit);
1801 }
1802 
FindNearestStateSplit(GateRef gate) const1803 GateRef GateAccessor::FindNearestStateSplit(GateRef gate) const
1804 {
1805     auto statesplit = gate;
1806     while (GetOpCode(statesplit) != OpCode::STATE_SPLIT) {
1807         statesplit = GetDep(statesplit);
1808     }
1809     return statesplit;
1810 }
1811 
HasFrameState(GateRef gate) const1812 bool GateAccessor::HasFrameState(GateRef gate) const
1813 {
1814     return GetMetaData(gate)->HasFrameState();
1815 }
1816 
ReplaceFrameStateIn(GateRef gate,GateRef in)1817 void GateAccessor::ReplaceFrameStateIn(GateRef gate, GateRef in)
1818 {
1819     ASSERT(HasFrameState(gate));
1820     Gate *gatePtr = circuit_->LoadGatePtr(gate);
1821     size_t index = gatePtr->GetInFrameStateStarts();
1822     circuit_->ModifyIn(gate, index, in);
1823 }
1824 
GetRoot(OpCode opcode) const1825 GateRef GateAccessor::GetRoot(OpCode opcode) const
1826 {
1827     GateRef root = circuit_->GetRoot();
1828     if (opcode == OpCode::CIRCUIT_ROOT) {
1829         return root;
1830     }
1831 
1832     auto uses = ConstUses(root);
1833     for (auto useIt = uses.begin(); useIt != uses.end(); ++useIt) {
1834         if (GetOpCode(*useIt) == opcode) {
1835             return *useIt;
1836         }
1837     }
1838     return Circuit::NullGate();
1839 }
1840 
GetGlueFromArgList() const1841 GateRef GateAccessor::GetGlueFromArgList() const
1842 {
1843     auto argRoot = GetArgRoot();
1844     ASSERT(static_cast<size_t>(CommonArgIdx::GLUE) == 0);
1845     const Gate *curGate = circuit_->LoadGatePtrConst(argRoot);
1846 
1847     const Out *curOut = curGate->GetFirstOutConst();
1848     ASSERT(!curGate->IsFirstOutNull());
1849     while (!curOut->IsNextOutNull()) {
1850         curOut = curOut->GetNextOutConst();
1851     }
1852     return circuit_->GetGateRef(curOut->GetGateConst());
1853 }
1854 
GetArgsOuts(std::vector<GateRef> & outs) const1855 void GateAccessor::GetArgsOuts(std::vector<GateRef>& outs) const
1856 {
1857     auto argRoot = GetArgRoot();
1858     GetOuts(argRoot, outs);
1859 }
1860 
GetReturnOuts(std::vector<GateRef> & outs) const1861 void GateAccessor::GetReturnOuts(std::vector<GateRef>& outs) const
1862 {
1863     auto returnRoot = GetReturnRoot();
1864     GetOuts(returnRoot, outs);
1865 }
1866 
GetMetaData(GateRef gate) const1867 const GateMetaData *GateAccessor::GetMetaData(GateRef gate) const
1868 {
1869     return circuit_->LoadGatePtrConst(gate)->GetMetaData();
1870 }
1871 
SetMetaData(GateRef gate,const GateMetaData * meta)1872 void GateAccessor::SetMetaData(GateRef gate, const GateMetaData* meta)
1873 {
1874     return circuit_->LoadGatePtr(gate)->SetMetaData(meta);
1875 }
1876 
IsFixed(GateRef g) const1877 bool GateAccessor::IsFixed(GateRef g) const
1878 {
1879     return GetMetaData(g)->IsFixed();
1880 }
1881 
IsProlog(GateRef g) const1882 bool GateAccessor::IsProlog(GateRef g) const
1883 {
1884     return GetMetaData(g)->IsProlog();
1885 }
1886 
IsCFGMerge(GateRef g) const1887 bool GateAccessor::IsCFGMerge(GateRef g) const
1888 {
1889     return GetMetaData(g)->IsCFGMerge();
1890 }
1891 
MetaDataEqu(GateRef g1,GateRef g2) const1892 bool GateAccessor::MetaDataEqu(GateRef g1, GateRef g2) const
1893 {
1894     return GetMetaData(g1) == GetMetaData(g2);
1895 }
1896 
MetaDataValueEqu(GateRef g1,GateRef g2) const1897 bool GateAccessor::MetaDataValueEqu(GateRef g1, GateRef g2) const
1898 {
1899     const GateMetaData *g1Meta = GetMetaData(g1);
1900     const GateMetaData *g2Meta = GetMetaData(g2);
1901 
1902     return g1Meta->equal(*g2Meta);
1903 }
1904 
IsNop(GateRef g) const1905 bool GateAccessor::IsNop(GateRef g) const
1906 {
1907     return GetMetaData(g)->IsNop();
1908 }
1909 
IsDead(GateRef gate) const1910 bool GateAccessor::IsDead(GateRef gate) const
1911 {
1912     return GetMetaData(gate)->IsDead();
1913 }
1914 
IsRoot(GateRef g) const1915 bool GateAccessor::IsRoot(GateRef g) const
1916 {
1917     return GetMetaData(g)->IsRoot();
1918 }
1919 
GetMetaData(GateRef g) const1920 const GateMetaData *ConstGateAccessor::GetMetaData(GateRef g) const
1921 {
1922     return circuit_->LoadGatePtrConst(g)->GetMetaData();
1923 }
1924 
IsFixed(GateRef g) const1925 bool ConstGateAccessor::IsFixed(GateRef g) const
1926 {
1927     return GetMetaData(g)->IsFixed();
1928 }
1929 
IsProlog(GateRef g) const1930 bool ConstGateAccessor::IsProlog(GateRef g) const
1931 {
1932     return GetMetaData(g)->IsProlog();
1933 }
1934 
IsSchedulable(GateRef g) const1935 bool ConstGateAccessor::IsSchedulable(GateRef g) const
1936 {
1937     return GetMetaData(g)->IsSchedulable();
1938 }
1939 
GetDependSelectorFromMerge(GateRef gate)1940 GateRef GateAccessor::GetDependSelectorFromMerge(GateRef gate)
1941 {
1942     GateRef depend = Circuit::NullGate();
1943     auto uses = Uses(gate);
1944     for (auto useIt = uses.begin(); useIt != uses.end(); useIt++) {
1945         if (GetOpCode(*useIt) == OpCode::DEPEND_SELECTOR) {
1946             depend = *useIt;
1947             break;
1948         }
1949     }
1950     ASSERT(depend != Circuit::NullGate());
1951     return depend;
1952 }
1953 
HasIfExceptionUse(GateRef gate) const1954 bool GateAccessor::HasIfExceptionUse(GateRef gate) const
1955 {
1956     ASSERT(GetStateCount(gate) > 0);
1957     auto uses = ConstUses(gate);
1958     for (auto it = uses.begin(); it != uses.end(); it++) {
1959         if (GetOpCode(*it) == OpCode::IF_EXCEPTION) {
1960             return true;
1961         }
1962     }
1963     return false;
1964 }
1965 
IsHeapObjectFromElementsKind(GateRef gate)1966 bool GateAccessor::IsHeapObjectFromElementsKind(GateRef gate)
1967 {
1968     OpCode opcode = GetOpCode(gate);
1969     if (opcode == OpCode::JS_BYTECODE) {
1970         auto bc = GetByteCodeOpcode(gate);
1971         if (bc == EcmaOpcode::LDOBJBYVALUE_IMM8_V8 || bc == EcmaOpcode::LDOBJBYVALUE_IMM16_V8 ||
1972             bc == EcmaOpcode::LDTHISBYVALUE_IMM8 || bc == EcmaOpcode::LDTHISBYVALUE_IMM16) {
1973             ElementsKind kind = TryGetElementsKind(gate);
1974             return Elements::IsObject(kind);
1975         }
1976         return false;
1977     }
1978 
1979     if (opcode == OpCode::LOAD_ELEMENT) {
1980         TypedLoadOp typedOp = GetTypedLoadOp(gate);
1981         return typedOp == TypedLoadOp::ARRAY_LOAD_OBJECT_ELEMENT;
1982     }
1983 
1984     return false;
1985 }
1986 
IsConstString(GateRef gate)1987 bool GateAccessor::IsConstString(GateRef gate)
1988 {
1989     OpCode op = GetOpCode(gate);
1990     if (op == OpCode::JS_BYTECODE) {
1991         EcmaOpcode ecmaOpcode = GetByteCodeOpcode(gate);
1992         return ecmaOpcode == EcmaOpcode::LDA_STR_ID16;
1993     }
1994     return false;
1995 }
1996 
IsSingleCharGate(GateRef gate)1997 bool GateAccessor::IsSingleCharGate(GateRef gate)
1998 {
1999     OpCode op = GetOpCode(gate);
2000     if (op == OpCode::LOAD_ELEMENT) {
2001         return GetTypedLoadOp(gate) == TypedLoadOp::STRING_LOAD_ELEMENT;
2002     }
2003     return false;
2004 }
2005 
UseForTypeOpProfilerGate(GateRef gate) const2006 bool GateAccessor::UseForTypeOpProfilerGate(GateRef gate) const
2007 {
2008     OpCode op = GetOpCode(gate);
2009     switch (op) {
2010 #define DECLARE_GATE_OPCODE(NAME, OP, R, S, D, V) \
2011         case OpCode::OP:                          \
2012             return true;
2013 
2014     MCR_IMMUTABLE_META_DATA_CACHE_LIST(DECLARE_GATE_OPCODE)
2015     MCR_GATE_META_DATA_LIST_WITH_PC_OFFSET(DECLARE_GATE_OPCODE)
2016     MCR_GATE_META_DATA_LIST_FOR_CALL(DECLARE_GATE_OPCODE)
2017     MCR_GATE_META_DATA_LIST_WITH_VALUE(DECLARE_GATE_OPCODE)
2018     MCR_GATE_META_DATA_LIST_WITH_BOOL(DECLARE_GATE_OPCODE)
2019     MCR_GATE_META_DATA_LIST_WITH_GATE_TYPE(DECLARE_GATE_OPCODE)
2020     MCR_GATE_META_DATA_LIST_WITH_VALUE_IN(DECLARE_GATE_OPCODE)
2021 #undef DECLARE_GATE_OPCODE
2022         default:
2023             return false;
2024     }
2025 }
2026 
GetStringIdFromLdaStrGate(GateRef gate)2027 uint32_t GateAccessor::GetStringIdFromLdaStrGate(GateRef gate)
2028 {
2029     ASSERT(GetByteCodeOpcode(gate) == EcmaOpcode::LDA_STR_ID16);
2030     GateRef stringId = GetValueIn(gate, 0);
2031     return GetConstantValue(stringId);
2032 }
2033 
IsLoopBackUse(GateRef gate,const UseIterator & useIt) const2034 bool GateAccessor::IsLoopBackUse(GateRef gate, const UseIterator &useIt) const
2035 {
2036     if (IsLoopBack(gate) && IsStateIn(useIt)) {
2037         return IsLoopHead(*useIt);
2038     }
2039     if ((IsValueSelector(*useIt) && IsValueIn(useIt)) ||
2040         (IsDependSelector(*useIt) && IsDependIn(useIt))) {
2041         return IsLoopHead(GetState(*useIt));
2042     }
2043     return false;
2044 }
2045 
IsCreateArray(GateRef gate) const2046 bool GateAccessor::IsCreateArray(GateRef gate) const
2047 {
2048     if (GetOpCode(gate) != OpCode::JS_BYTECODE) {
2049         return false;
2050     }
2051     EcmaOpcode ecmaop = GetByteCodeOpcode(gate);
2052     switch (ecmaop) {
2053         case EcmaOpcode::CREATEEMPTYARRAY_IMM8:
2054         case EcmaOpcode::CREATEEMPTYARRAY_IMM16:
2055         case EcmaOpcode::CREATEARRAYWITHBUFFER_IMM8_ID16:
2056         case EcmaOpcode::CREATEARRAYWITHBUFFER_IMM16_ID16:
2057             return true;
2058         default:
2059             return false;
2060     }
2061     UNREACHABLE();
2062     return false;
2063 }
2064 
SetStoreNoBarrier(GateRef gate,bool isNoBarrier)2065 void GateAccessor::SetStoreNoBarrier(GateRef gate, bool isNoBarrier)
2066 {
2067     ASSERT(GetOpCode(gate) == OpCode::MONO_STORE_PROPERTY_LOOK_UP_PROTO ||
2068            GetOpCode(gate) == OpCode::MONO_STORE_PROPERTY);
2069     Gate *gatePtr = circuit_->LoadGatePtr(gate);
2070     const_cast<BoolMetaData *>(gatePtr->GetBoolMetaData())->SetBool(isNoBarrier);
2071 }
2072 
IsNoBarrier(GateRef gate) const2073 bool GateAccessor::IsNoBarrier(GateRef gate) const
2074 {
2075     ASSERT(GetOpCode(gate) == OpCode::MONO_STORE_PROPERTY_LOOK_UP_PROTO ||
2076            GetOpCode(gate) == OpCode::MONO_STORE_PROPERTY);
2077     Gate *gatePtr = circuit_->LoadGatePtr(gate);
2078     return gatePtr->GetBoolMetaData()->GetBool();
2079 }
2080 
TryGetMegaProp(GateRef gate) const2081 bool GateAccessor::TryGetMegaProp(GateRef gate) const
2082 {
2083     const PGORWOpType *k = TryGetPGOType(gate).GetPGORWOpType();
2084     if (k->GetCount() > 0) {
2085         return k->GetObjectInfo(0).IsMegaStateType();
2086     } else {
2087         return false;
2088     }
2089 }
2090 
GetConstpoolId(GateRef gate) const2091 uint32_t GateAccessor::GetConstpoolId(GateRef gate) const
2092 {
2093     ASSERT(GetOpCode(gate) == OpCode::GET_SHARED_CONSTPOOL);
2094     Gate *gatePtr = circuit_->LoadGatePtr(gate);
2095     return gatePtr->GetOneParameterMetaData()->GetValue();
2096 }
2097 
GetFrameValue(GateRef gate)2098 GateRef GateAccessor::GetFrameValue(GateRef gate)
2099 {
2100     ASSERT(GetOpCode(gate) == OpCode::FRAME_STATE);
2101     return GetValueIn(gate, 1);
2102 }
2103 
GetRevCompareOpForTypedBinOp(TypedBinOp op)2104 TypedBinOp GateAccessor::GetRevCompareOpForTypedBinOp(TypedBinOp op)
2105 {
2106     switch (op) {
2107         case TypedBinOp::TYPED_LESS:
2108             return TypedBinOp::TYPED_GREATEREQ;
2109         case TypedBinOp::TYPED_LESSEQ:
2110             return TypedBinOp::TYPED_GREATER;
2111         case TypedBinOp::TYPED_GREATER:
2112             return TypedBinOp::TYPED_LESSEQ;
2113         case TypedBinOp::TYPED_GREATEREQ:
2114             return TypedBinOp::TYPED_LESS;
2115         case TypedBinOp::TYPED_EQ:
2116             return TypedBinOp::TYPED_NOTEQ;
2117         case TypedBinOp::TYPED_NOTEQ:
2118             return TypedBinOp::TYPED_EQ;
2119         default:
2120             UNREACHABLE();
2121             return op;
2122     }
2123 }
2124 
GetSwapCompareOpForTypedBinOp(TypedBinOp op)2125 TypedBinOp GateAccessor::GetSwapCompareOpForTypedBinOp(TypedBinOp op)
2126 {
2127     switch (op) {
2128         case TypedBinOp::TYPED_LESS:
2129             return TypedBinOp::TYPED_GREATER;
2130         case TypedBinOp::TYPED_LESSEQ:
2131             return TypedBinOp::TYPED_GREATEREQ;
2132         case TypedBinOp::TYPED_GREATER:
2133             return TypedBinOp::TYPED_LESS;
2134         case TypedBinOp::TYPED_GREATEREQ:
2135             return TypedBinOp::TYPED_LESSEQ;
2136         case TypedBinOp::TYPED_EQ:
2137             return TypedBinOp::TYPED_EQ;
2138         case TypedBinOp::TYPED_NOTEQ:
2139             return TypedBinOp::TYPED_NOTEQ;
2140         default:
2141             UNREACHABLE();
2142             return op;
2143     }
2144 }
2145 
GetMetaDataHash(GateRef gate) const2146 uint64_t GateAccessor::GetMetaDataHash(GateRef gate) const
2147 {
2148     return GetMetaData(gate)->GetHashCode();
2149 }
2150 
2151 }  // namespace panda::ecmascript::kungfu
2152