• 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.h"
21 
22 namespace panda::ecmascript::kungfu {
23 using UseIterator = GateAccessor::UseIterator;
24 
GetNumIns(GateRef gate) const25 size_t GateAccessor::GetNumIns(GateRef gate) const
26 {
27     Gate *gatePtr = circuit_->LoadGatePtr(gate);
28     return gatePtr->GetNumIns();
29 }
30 
GetMark(GateRef gate) const31 MarkCode GateAccessor::GetMark(GateRef gate) const
32 {
33     return circuit_->GetMark(gate);
34 }
35 
SetMark(GateRef gate,MarkCode mark)36 void GateAccessor::SetMark(GateRef gate, MarkCode mark)
37 {
38     circuit_->SetMark(gate, mark);
39 }
40 
IsFinished(GateRef gate) const41 bool GateAccessor::IsFinished(GateRef gate) const
42 {
43     return GetMark(gate) == MarkCode::FINISHED;
44 }
45 
IsVisited(GateRef gate) const46 bool GateAccessor::IsVisited(GateRef gate) const
47 {
48     return GetMark(gate) == MarkCode::VISITED;
49 }
50 
IsNotMarked(GateRef gate) const51 bool GateAccessor::IsNotMarked(GateRef gate) const
52 {
53     return GetMark(gate) == MarkCode::NO_MARK;
54 }
55 
SetFinished(GateRef gate)56 void GateAccessor::SetFinished(GateRef gate)
57 {
58     SetMark(gate, MarkCode::FINISHED);
59 }
60 
SetVisited(GateRef gate)61 void GateAccessor::SetVisited(GateRef gate)
62 {
63     SetMark(gate, MarkCode::VISITED);
64 }
65 
GetOpCode(GateRef gate) const66 OpCode GateAccessor::GetOpCode(GateRef gate) const
67 {
68     Gate *gatePtr = circuit_->LoadGatePtr(gate);
69     return gatePtr->GetOpCode();
70 }
71 
TryGetValue(GateRef gate) const72 BitField GateAccessor::TryGetValue(GateRef gate) const
73 {
74     Gate *gatePtr = circuit_->LoadGatePtr(gate);
75     return gatePtr->TryGetValue();
76 }
77 
GetICmpCondition(GateRef gate) const78 ICmpCondition GateAccessor::GetICmpCondition(GateRef gate) const
79 {
80     ASSERT(GetOpCode(gate) == OpCode::ICMP);
81     Gate *gatePtr = circuit_->LoadGatePtr(gate);
82     return static_cast<ICmpCondition>(gatePtr->GetOneParameterMetaData()->GetValue());
83 }
84 
GetFCmpCondition(GateRef gate) const85 FCmpCondition GateAccessor::GetFCmpCondition(GateRef gate) const
86 {
87     ASSERT(GetOpCode(gate) == OpCode::FCMP);
88     Gate *gatePtr = circuit_->LoadGatePtr(gate);
89     return static_cast<FCmpCondition>(gatePtr->GetOneParameterMetaData()->GetValue());
90 }
91 
GetOffset(GateRef gate) const92 size_t GateAccessor::GetOffset(GateRef gate) const
93 {
94     ASSERT(GetOpCode(gate) == OpCode::LOAD_CONST_OFFSET ||
95            GetOpCode(gate) == OpCode::STORE_CONST_OFFSET);
96     Gate *gatePtr = circuit_->LoadGatePtr(gate);
97     return gatePtr->GetOneParameterMetaData()->GetValue();
98 }
99 
GetIndex(GateRef gate) const100 size_t GateAccessor::GetIndex(GateRef gate) const
101 {
102     ASSERT(GetOpCode(gate) == OpCode::GET_GLOBAL_ENV_OBJ_HCLASS ||
103            GetOpCode(gate) == OpCode::GET_GLOBAL_CONSTANT_VALUE);
104     Gate *gatePtr = circuit_->LoadGatePtr(gate);
105     return gatePtr->GetOneParameterMetaData()->GetValue();
106 }
107 
GetArraySize(GateRef gate) const108 size_t GateAccessor::GetArraySize(GateRef gate) const
109 {
110     ASSERT(GetOpCode(gate) == OpCode::CREATE_ARRAY ||
111            GetOpCode(gate) == OpCode::CREATE_ARRAY_WITH_BUFFER);
112     Gate *gatePtr = circuit_->LoadGatePtr(gate);
113     return gatePtr->GetOneParameterMetaData()->GetValue();
114 }
115 
SetArraySize(GateRef gate,size_t size)116 void GateAccessor::SetArraySize(GateRef gate, size_t size)
117 {
118     ASSERT(GetOpCode(gate) == OpCode::CREATE_ARRAY ||
119            GetOpCode(gate) == OpCode::CREATE_ARRAY_WITH_BUFFER);
120     Gate *gatePtr = circuit_->LoadGatePtr(gate);
121     const_cast<OneParameterMetaData *>(gatePtr->GetOneParameterMetaData())->SetValue(size);
122 }
123 
GetTypedUnAccessor(GateRef gate) const124 TypedUnaryAccessor GateAccessor::GetTypedUnAccessor(GateRef gate) const
125 {
126     ASSERT((GetOpCode(gate) == OpCode::TYPED_UNARY_OP));
127     Gate *gatePtr = circuit_->LoadGatePtr(gate);
128     return TypedUnaryAccessor(gatePtr->GetOneParameterMetaData()->GetValue());
129 }
130 
GetTypedJumpAccessor(GateRef gate) const131 TypedJumpAccessor GateAccessor::GetTypedJumpAccessor(GateRef gate) const
132 {
133     ASSERT(GetOpCode(gate) == OpCode::TYPED_CONDITION_JUMP);
134     Gate *gatePtr = circuit_->LoadGatePtr(gate);
135     return TypedJumpAccessor(gatePtr->GetOneParameterMetaData()->GetValue());
136 }
137 
GetArrayMetaDataAccessor(GateRef gate) const138 ArrayMetaDataAccessor GateAccessor::GetArrayMetaDataAccessor(GateRef gate) const
139 {
140     ASSERT(GetOpCode(gate) == OpCode::STABLE_ARRAY_CHECK ||
141            GetOpCode(gate) == OpCode::HCLASS_STABLE_ARRAY_CHECK);
142     Gate *gatePtr = circuit_->LoadGatePtr(gate);
143     return ArrayMetaDataAccessor(gatePtr->GetOneParameterMetaData()->GetValue());
144 }
145 
GetObjectTypeAccessor(GateRef gate) const146 ObjectTypeAccessor GateAccessor::GetObjectTypeAccessor(GateRef gate) const
147 {
148     ASSERT(GetOpCode(gate) == OpCode::OBJECT_TYPE_CHECK ||
149            GetOpCode(gate) == OpCode::OBJECT_TYPE_COMPARE);
150     Gate *gatePtr = circuit_->LoadGatePtr(gate);
151     return ObjectTypeAccessor(gatePtr->GetOneParameterMetaData()->GetValue());
152 }
153 
GetTypedLoadOp(GateRef gate) const154 TypedLoadOp GateAccessor::GetTypedLoadOp(GateRef gate) const
155 {
156     ASSERT(GetOpCode(gate) == OpCode::LOAD_ELEMENT);
157     Gate *gatePtr = circuit_->LoadGatePtr(gate);
158     return static_cast<TypedLoadOp>(gatePtr->GetOneParameterMetaData()->GetValue());
159 }
160 
GetTypedStoreOp(GateRef gate) const161 TypedStoreOp GateAccessor::GetTypedStoreOp(GateRef gate) const
162 {
163     ASSERT(GetOpCode(gate) == OpCode::STORE_ELEMENT);
164     Gate *gatePtr = circuit_->LoadGatePtr(gate);
165     return static_cast<TypedStoreOp>(gatePtr->GetOneParameterMetaData()->GetValue());
166 }
167 
GetTypedCallTargetCheckOp(GateRef gate) const168 TypedCallTargetCheckOp GateAccessor::GetTypedCallTargetCheckOp(GateRef gate) const
169 {
170     ASSERT(GetOpCode(gate) == OpCode::TYPED_CALLTARGETCHECK_OP);
171     Gate *gatePtr = circuit_->LoadGatePtr(gate);
172     return gatePtr->GetTypedCallTargetCheckMetaData()->GetTypedCallTargetCheckOp();
173 }
174 
GetMemoryType(GateRef gate) const175 MemoryType GateAccessor::GetMemoryType(GateRef gate) const
176 {
177     ASSERT(GetOpCode(gate) == OpCode::STORE_MEMORY);
178     Gate *gatePtr = circuit_->LoadGatePtr(gate);
179     return static_cast<MemoryType>(gatePtr->GetOneParameterMetaData()->GetValue());
180 }
181 
GetTypedBinaryOp(GateRef gate) const182 TypedBinOp GateAccessor::GetTypedBinaryOp(GateRef gate) const
183 {
184     ASSERT(GetOpCode(gate) == OpCode::TYPED_BINARY_OP);
185     Gate *gatePtr = circuit_->LoadGatePtr(gate);
186     return gatePtr->GetTypedBinaryMetaData()->GetTypedBinaryOp();
187 }
188 
GetTypedBinaryType(GateRef gate) const189 PGOSampleType GateAccessor::GetTypedBinaryType(GateRef gate) const
190 {
191     ASSERT(GetOpCode(gate) == OpCode::TYPED_BINARY_OP);
192     Gate *gatePtr = circuit_->LoadGatePtr(gate);
193     return gatePtr->GetTypedBinaryMetaData()->GetType();
194 }
195 
HasNumberType(GateRef gate) const196 bool GateAccessor::HasNumberType(GateRef gate) const
197 {
198     auto sampleType = GetTypedBinaryType(gate);
199     if (sampleType.IsNumber()) {
200         return true;
201     }
202     if (sampleType.IsNone()) {
203         GateType leftType = GetLeftType(gate);
204         GateType rightType = GetRightType(gate);
205         if (leftType.IsNumberType() && rightType.IsNumberType()) {
206             return true;
207         }
208     }
209     return false;
210 }
211 
GetFuncGT(GateRef gate) const212 GlobalTSTypeRef GateAccessor::GetFuncGT(GateRef gate) const
213 {
214     ASSERT(GetOpCode(gate) == OpCode::JSINLINETARGET_TYPE_CHECK);
215     Gate *gatePtr = circuit_->LoadGatePtr(gate);
216     auto value = static_cast<uint32_t>((gatePtr->GetOneParameterMetaData()->GetValue()));
217     return GlobalTSTypeRef(value);
218 }
219 
GetParamGateType(GateRef gate) const220 GateType GateAccessor::GetParamGateType(GateRef gate) const
221 {
222     ASSERT(GetOpCode(gate) == OpCode::PRIMITIVE_TYPE_CHECK ||
223            GetOpCode(gate) == OpCode::TYPED_ARRAY_CHECK ||
224            GetOpCode(gate) == OpCode::INDEX_CHECK ||
225            GetOpCode(gate) == OpCode::TYPED_CALLTARGETCHECK_OP ||
226            GetOpCode(gate) == OpCode::CREATE_ARRAY_WITH_BUFFER);
227     Gate *gatePtr = circuit_->LoadGatePtr(gate);
228     GateTypeAccessor accessor(gatePtr->GetOneParameterMetaData()->GetValue());
229     return accessor.GetGateType();
230 }
231 
IsConvertSupport(GateRef gate) const232 bool GateAccessor::IsConvertSupport(GateRef gate) const
233 {
234     ASSERT(GetOpCode(gate) == OpCode::CONVERT ||
235            GetOpCode(gate) == OpCode::CHECK_AND_CONVERT);
236     Gate *gatePtr = circuit_->LoadGatePtr(gate);
237     ValuePairTypeAccessor accessor(gatePtr->GetOneParameterMetaData()->GetValue());
238     return accessor.IsConvertSupport();
239 }
240 
GetSrcType(GateRef gate) const241 ValueType GateAccessor::GetSrcType(GateRef gate) const
242 {
243     ASSERT(GetOpCode(gate) == OpCode::CONVERT ||
244            GetOpCode(gate) == OpCode::CHECK_AND_CONVERT);
245     Gate *gatePtr = circuit_->LoadGatePtr(gate);
246     ValuePairTypeAccessor accessor(gatePtr->GetOneParameterMetaData()->GetValue());
247     return accessor.GetSrcType();
248 }
249 
GetDstType(GateRef gate) const250 ValueType GateAccessor::GetDstType(GateRef gate) const
251 {
252     ASSERT(GetOpCode(gate) == OpCode::CONVERT ||
253            GetOpCode(gate) == OpCode::CHECK_AND_CONVERT);
254     Gate *gatePtr = circuit_->LoadGatePtr(gate);
255     ValuePairTypeAccessor accessor(gatePtr->GetOneParameterMetaData()->GetValue());
256     return accessor.GetDstType();
257 }
258 
GetLeftType(GateRef gate) const259 GateType GateAccessor::GetLeftType(GateRef gate) const
260 {
261     ASSERT(GetOpCode(gate) == OpCode::TYPED_UNARY_OP ||
262            GetOpCode(gate) == OpCode::TYPED_BINARY_OP ||
263            GetOpCode(gate) == OpCode::TYPE_CONVERT);
264     Gate *gatePtr = circuit_->LoadGatePtr(gate);
265     GatePairTypeAccessor accessor(gatePtr->GetOneParameterMetaData()->GetValue());
266     return accessor.GetLeftType();
267 }
268 
GetRightType(GateRef gate) const269 GateType GateAccessor::GetRightType(GateRef gate) const
270 {
271     ASSERT(GetOpCode(gate) == OpCode::TYPED_BINARY_OP ||
272            GetOpCode(gate) == OpCode::TYPE_CONVERT);
273     Gate *gatePtr = circuit_->LoadGatePtr(gate);
274     GatePairTypeAccessor accessor(gatePtr->GetOneParameterMetaData()->GetValue());
275     return accessor.GetRightType();
276 }
277 
GetFirstValue(GateRef gate) const278 uint32_t GateAccessor::GetFirstValue(GateRef gate) const
279 {
280     ASSERT(GetOpCode(gate) == OpCode::RANGE_GUARD);
281     Gate *gatePtr = circuit_->LoadGatePtr(gate);
282     UInt32PairAccessor accessor(gatePtr->GetOneParameterMetaData()->GetValue());
283     return accessor.GetFirstValue();
284 }
285 
GetSecondValue(GateRef gate) const286 uint32_t GateAccessor::GetSecondValue(GateRef gate) const
287 {
288     ASSERT(GetOpCode(gate) == OpCode::RANGE_GUARD);
289     Gate *gatePtr = circuit_->LoadGatePtr(gate);
290     UInt32PairAccessor accessor(gatePtr->GetOneParameterMetaData()->GetValue());
291     return accessor.GetSecondValue();
292 }
293 
GetVirtualRegisterIndex(GateRef gate) const294 size_t GateAccessor::GetVirtualRegisterIndex(GateRef gate) const
295 {
296     ASSERT(GetOpCode(gate) == OpCode::SAVE_REGISTER ||
297            GetOpCode(gate) == OpCode::RESTORE_REGISTER);
298     Gate *gatePtr = circuit_->LoadGatePtr(gate);
299     return static_cast<size_t>(gatePtr->GetOneParameterMetaData()->GetValue());
300 }
301 
GetConstantValue(GateRef gate) const302 uint64_t GateAccessor::GetConstantValue(GateRef gate) const
303 {
304     ASSERT(GetOpCode(gate) == OpCode::CONSTANT);
305     Gate *gatePtr = circuit_->LoadGatePtr(gate);
306     return gatePtr->GetOneParameterMetaData()->GetValue();
307 }
308 
GetConstantString(GateRef gate) const309 const ChunkVector<char>& GateAccessor::GetConstantString(GateRef gate) const
310 {
311     ASSERT(GetOpCode(gate) == OpCode::CONSTSTRING);
312     Gate *gatePtr = circuit_->LoadGatePtr(gate);
313     return gatePtr->GetStringMetaData()->GetString();
314 }
315 
IsVtable(GateRef gate) const316 bool GateAccessor::IsVtable(GateRef gate) const
317 {
318     ASSERT(GetOpCode(gate) == OpCode::LOAD_PROPERTY);
319     Gate *gatePtr = circuit_->LoadGatePtr(gate);
320     return gatePtr->GetBoolMetaData()->GetBool();
321 }
322 
GetNoGCFlag(GateRef gate) const323 bool GateAccessor::GetNoGCFlag(GateRef gate) const
324 {
325     if (gate == Circuit::NullGate()) {
326         return false;
327     }
328     OpCode op = GetOpCode(gate);
329     if (op != OpCode::TYPEDCALL && op != OpCode::TYPEDFASTCALL) {
330         return false;
331     }
332     return TypedCallIsNoGC(gate);
333 }
334 
TypedCallIsNoGC(GateRef gate) const335 bool GateAccessor::TypedCallIsNoGC(GateRef gate) const
336 {
337     ASSERT(GetOpCode(gate) == OpCode::TYPEDCALL || GetOpCode(gate) == OpCode::TYPEDFASTCALL);
338     Gate *gatePtr = circuit_->LoadGatePtr(gate);
339     return gatePtr->GetTypedCallMetaData()->IsNoGC();
340 }
341 
IsNoGC(GateRef gate) const342 bool GateAccessor::IsNoGC(GateRef gate) const
343 {
344     ASSERT(GetOpCode(gate) == OpCode::CALL_OPTIMIZED || GetOpCode(gate) == OpCode::FAST_CALL_OPTIMIZED);
345     Gate *gatePtr = circuit_->LoadGatePtr(gate);
346     return gatePtr->GetBoolMetaData()->GetBool();
347 }
348 
TryGetPcOffset(GateRef gate) const349 uint32_t GateAccessor::TryGetPcOffset(GateRef gate) const
350 {
351     Gate *gatePtr = circuit_->LoadGatePtr(gate);
352     OpCode op = GetOpCode(gate);
353     switch (op) {
354         case OpCode::JS_BYTECODE:
355             return gatePtr->GetJSBytecodeMetaData()->GetPcOffset();
356         case OpCode::TYPED_CALL_BUILTIN:
357         case OpCode::CONSTRUCT:
358         case OpCode::CALL_GETTER:
359         case OpCode::CALL_SETTER:
360             return static_cast<uint32_t>(gatePtr->GetOneParameterMetaData()->GetValue());
361         case OpCode::TYPEDCALL:
362         case OpCode::TYPEDFASTCALL:
363             return static_cast<uint32_t>(gatePtr->GetTypedCallMetaData()->GetValue());
364         case OpCode::FRAME_STATE: {
365             UInt32PairAccessor accessor(gatePtr->GetOneParameterMetaData()->GetValue());
366             return accessor.GetFirstValue();
367         }
368         default:
369             break;
370     }
371     return 0;
372 }
373 
TryGetPGOType(GateRef gate) const374 PGOSampleType GateAccessor::TryGetPGOType(GateRef gate) const
375 {
376     Gate *gatePtr = circuit_->LoadGatePtr(gate);
377     OpCode op = GetOpCode(gate);
378     if (op == OpCode::JS_BYTECODE) {
379         return gatePtr->GetJSBytecodeMetaData()->GetType();
380     }
381     return PGOSampleType::NoneType();
382 }
383 
TrySetPGOType(GateRef gate,PGOSampleType type)384 void GateAccessor::TrySetPGOType(GateRef gate, PGOSampleType type)
385 {
386     Gate *gatePtr = circuit_->LoadGatePtr(gate);
387     OpCode op = GetOpCode(gate);
388     if (op == OpCode::JS_BYTECODE) {
389         const_cast<JSBytecodeMetaData *>(gatePtr->GetJSBytecodeMetaData())->SetType(type);
390     }
391 }
392 
TryGetElementsKind(GateRef gate) const393 ElementsKind GateAccessor::TryGetElementsKind(GateRef gate) const
394 {
395     Gate *gatePtr = circuit_->LoadGatePtr(gate);
396     OpCode op = GetOpCode(gate);
397     if (op == OpCode::JS_BYTECODE) {
398         return gatePtr->GetJSBytecodeMetaData()->GetElementsKind();
399     }
400     return ElementsKind::GENERIC;
401 }
402 
TrySetElementsKind(GateRef gate,ElementsKind kind)403 void GateAccessor::TrySetElementsKind(GateRef gate, ElementsKind kind)
404 {
405     Gate *gatePtr = circuit_->LoadGatePtr(gate);
406     OpCode op = GetOpCode(gate);
407     if (op == OpCode::JS_BYTECODE) {
408         const_cast<JSBytecodeMetaData *>(gatePtr->GetJSBytecodeMetaData())->SetElementsKind(kind);
409     }
410 }
411 
GetByteCodeOpcode(GateRef gate) const412 EcmaOpcode GateAccessor::GetByteCodeOpcode(GateRef gate) const
413 {
414     ASSERT(GetOpCode(gate) == OpCode::JS_BYTECODE);
415     Gate *gatePtr = circuit_->LoadGatePtr(gate);
416     return gatePtr->GetJSBytecodeMetaData()->GetByteCodeOpcode();
417 }
418 
Print(GateRef gate) const419 void GateAccessor::Print(GateRef gate) const
420 {
421     Gate *gatePtr = circuit_->LoadGatePtr(gate);
422     gatePtr->Print();
423 }
424 
ShortPrint(GateRef gate) const425 void GateAccessor::ShortPrint(GateRef gate) const
426 {
427     Gate *gatePtr = circuit_->LoadGatePtr(gate);
428     gatePtr->ShortPrint();
429 }
430 
GetId(GateRef gate) const431 GateId GateAccessor::GetId(GateRef gate) const
432 {
433     Gate *gatePtr = circuit_->LoadGatePtr(gate);
434     return gatePtr->GetId();
435 }
436 
GetInValueStarts(GateRef gate) const437 size_t GateAccessor::GetInValueStarts(GateRef gate) const
438 {
439     Gate *gatePtr = circuit_->LoadGatePtr(gate);
440     return gatePtr->GetInValueStarts();
441 }
442 
GetValueIn(GateRef gate,size_t idx) const443 GateRef GateAccessor::GetValueIn(GateRef gate, size_t idx) const
444 {
445     Gate *gatePtr = circuit_->LoadGatePtr(gate);
446     ASSERT(idx < gatePtr->GetInValueCount());
447     size_t valueIndex = gatePtr->GetInValueStarts();
448     return circuit_->GetIn(gate, valueIndex + idx);
449 }
450 
GetNumValueIn(GateRef gate) const451 size_t GateAccessor::GetNumValueIn(GateRef gate) const
452 {
453     Gate *gatePtr = circuit_->LoadGatePtr(gate);
454     return gatePtr->GetInValueCount();
455 }
456 
IsGCRelated(GateRef gate) const457 bool GateAccessor::IsGCRelated(GateRef gate) const
458 {
459     return GetGateType(gate).IsGCRelated();
460 }
461 
GetIn(GateRef gate,size_t idx) const462 GateRef GateAccessor::GetIn(GateRef gate, size_t idx) const
463 {
464     return circuit_->GetIn(gate, idx);
465 }
466 
GetState(GateRef gate,size_t idx) const467 GateRef GateAccessor::GetState(GateRef gate, size_t idx) const
468 {
469     ASSERT(idx < circuit_->LoadGatePtr(gate)->GetStateCount());
470     return circuit_->GetIn(gate, idx);
471 }
472 
GetInStates(GateRef gate,std::vector<GateRef> & ins) const473 void GateAccessor::GetInStates(GateRef gate, std::vector<GateRef>& ins) const
474 {
475     const Gate *curGate = circuit_->LoadGatePtrConst(gate);
476     for (size_t idx = 0; idx < curGate->GetStateCount(); idx++) {
477         ins.push_back(circuit_->GetGateRef(curGate->GetInGateConst(idx)));
478     }
479 }
480 
GetIns(GateRef gate,std::vector<GateRef> & ins) const481 void GateAccessor::GetIns(GateRef gate, std::vector<GateRef>& ins) const
482 {
483     const Gate *curGate = circuit_->LoadGatePtrConst(gate);
484     for (size_t idx = 0; idx < curGate->GetNumIns(); idx++) {
485         ins.push_back(circuit_->GetGateRef(curGate->GetInGateConst(idx)));
486     }
487 }
488 
GetOuts(GateRef gate,std::vector<GateRef> & outs) const489 void GateAccessor::GetOuts(GateRef gate, std::vector<GateRef>& outs) const
490 {
491     const Gate *curGate = circuit_->LoadGatePtrConst(gate);
492     if (!curGate->IsFirstOutNull()) {
493         const Out *curOut = curGate->GetFirstOutConst();
494         GateRef ref = circuit_->GetGateRef(curOut->GetGateConst());
495         outs.push_back(ref);
496         while (!curOut->IsNextOutNull()) {
497             curOut = curOut->GetNextOutConst();
498             ref = circuit_->GetGateRef(curOut->GetGateConst());
499             outs.push_back(ref);
500         }
501     }
502 }
503 
HasOuts(GateRef gate) const504 bool GateAccessor::HasOuts(GateRef gate) const
505 {
506     const Gate *curGate = circuit_->LoadGatePtrConst(gate);
507     return !curGate->IsFirstOutNull();
508 }
509 
DeleteGateIfNoUse(GateRef gate)510 void GateAccessor::DeleteGateIfNoUse(GateRef gate)
511 {
512     if (!HasOuts(gate)) {
513         DeleteGate(gate);
514     }
515 }
516 
GetOutStates(GateRef gate,std::vector<GateRef> & outStates) const517 void GateAccessor::GetOutStates(GateRef gate, std::vector<GateRef>& outStates) const
518 {
519     const Gate *curGate = circuit_->LoadGatePtrConst(gate);
520     if (!curGate->IsFirstOutNull()) {
521         const Out *curOut = curGate->GetFirstOutConst();
522         GateRef ref = circuit_->GetGateRef(curOut->GetGateConst());
523         if (GetMetaData(ref)->IsState()) {
524             outStates.push_back(ref);
525         }
526         while (!curOut->IsNextOutNull()) {
527             curOut = curOut->GetNextOutConst();
528             ref = circuit_->GetGateRef(curOut->GetGateConst());
529             if (GetMetaData(ref)->IsState()) {
530                 outStates.push_back(ref);
531             }
532         }
533     }
534 }
535 
GetStateUses(GateRef gate,std::vector<GateRef> & stateUses)536 void GateAccessor::GetStateUses(GateRef gate, std::vector<GateRef> &stateUses)
537 {
538     stateUses.clear();
539     auto uses = Uses(gate);
540     for (auto it = uses.begin(); it != uses.end(); it++) {
541         if (IsStateIn(it)) {
542             stateUses.emplace_back(*it);
543         }
544     }
545 }
546 
GetDependUses(GateRef gate,std::vector<GateRef> & dependUses)547 void GateAccessor::GetDependUses(GateRef gate, std::vector<GateRef> &dependUses)
548 {
549     dependUses.clear();
550     auto uses = Uses(gate);
551     for (auto it = uses.begin(); it != uses.end(); it++) {
552         if (IsDependIn(it)) {
553             dependUses.emplace_back(*it);
554         }
555     }
556 }
557 
GetValueUses(GateRef gate,std::vector<GateRef> & valueUses)558 void GateAccessor::GetValueUses(GateRef gate, std::vector<GateRef> &valueUses)
559 {
560     valueUses.clear();
561     auto uses = Uses(gate);
562     for (auto it = uses.begin(); it != uses.end(); it++) {
563         if (IsValueIn(it)) {
564             valueUses.emplace_back(*it);
565         }
566     }
567 }
568 
GetAllGates(std::vector<GateRef> & gates) const569 void GateAccessor::GetAllGates(std::vector<GateRef>& gates) const
570 {
571     circuit_->GetAllGates(gates);
572 }
573 
IsInGateNull(GateRef gate,size_t idx) const574 bool GateAccessor::IsInGateNull(GateRef gate, size_t idx) const
575 {
576     return circuit_->IsInGateNull(gate, idx);
577 }
578 
IsValueSelector(GateRef g) const579 bool GateAccessor::IsValueSelector(GateRef g) const
580 {
581     return GetOpCode(g) == OpCode::VALUE_SELECTOR;
582 }
583 
IsSelector(GateRef g) const584 bool GateAccessor::IsSelector(GateRef g) const
585 {
586     auto op = GetOpCode(g);
587     return (op == OpCode::VALUE_SELECTOR) || (op == OpCode::DEPEND_SELECTOR);
588 }
589 
IsIn(GateRef g,GateRef in) const590 bool GateAccessor::IsIn(GateRef g, GateRef in) const
591 {
592     size_t n = GetNumIns(g);
593     for (size_t id = 0; id < n; id++) {
594         GateRef i = GetIn(g, id);
595         if (i == in) {
596             return true;
597         }
598     }
599     return false;
600 }
601 
IsSimpleState(GateRef g) const602 bool GateAccessor::IsSimpleState(GateRef g) const
603 {
604     auto op = GetOpCode(g);
605     return (op == OpCode::IF_TRUE ||
606             op == OpCode::IF_FALSE ||
607             op == OpCode::SWITCH_CASE ||
608             op == OpCode::DEFAULT_CASE ||
609             op == OpCode::LOOP_BACK ||
610             op == OpCode::MERGE ||
611             op == OpCode::VALUE_SELECTOR ||
612             op == OpCode::DEPEND_SELECTOR ||
613             op == OpCode::DEPEND_RELAY ||
614             op == OpCode::ORDINARY_BLOCK);
615 }
616 
IsControlCase(GateRef gate) const617 bool GateAccessor::IsControlCase(GateRef gate) const
618 {
619     return circuit_->IsControlCase(gate);
620 }
621 
IsLoopExit(GateRef gate) const622 bool GateAccessor::IsLoopExit(GateRef gate) const
623 {
624     return (GetOpCode(gate) == OpCode::LOOP_EXIT);
625 }
626 
IsLoopExitRelated(GateRef gate) const627 bool GateAccessor::IsLoopExitRelated(GateRef gate) const
628 {
629     return (GetOpCode(gate) == OpCode::LOOP_EXIT) ||
630            (GetOpCode(gate) == OpCode::LOOP_EXIT_DEPEND) ||
631            (GetOpCode(gate) == OpCode::LOOP_EXIT_VALUE);
632 }
633 
IsLoopHead(GateRef gate) const634 bool GateAccessor::IsLoopHead(GateRef gate) const
635 {
636     return circuit_->IsLoopHead(gate);
637 }
638 
IsLoopBack(GateRef gate) const639 bool GateAccessor::IsLoopBack(GateRef gate) const
640 {
641     return GetOpCode(gate) == OpCode::LOOP_BACK;
642 }
643 
IsState(GateRef gate) const644 bool GateAccessor::IsState(GateRef gate) const
645 {
646     return GetMetaData(gate)->IsState();
647 }
648 
IsConstant(GateRef gate) const649 bool GateAccessor::IsConstant(GateRef gate) const
650 {
651     return GetMetaData(gate)->IsConstant();
652 }
653 
IsDependSelector(GateRef gate) const654 bool GateAccessor::IsDependSelector(GateRef gate) const
655 {
656     return GetMetaData(gate)->IsDependSelector();
657 }
658 
IsConstantValue(GateRef gate,uint64_t value) const659 bool GateAccessor::IsConstantValue(GateRef gate, uint64_t value) const
660 {
661     if (GetOpCode(gate) == OpCode::CONSTANT) {
662         uint64_t bitField = GetConstantValue(gate);
663         return bitField == value;
664     }
665     return false;
666 }
667 
IsConstantUndefined(GateRef gate) const668 bool GateAccessor::IsConstantUndefined(GateRef gate) const
669 {
670     return IsConstantValue(gate, JSTaggedValue::VALUE_UNDEFINED);
671 }
672 
IsTypedOperator(GateRef gate) const673 bool GateAccessor::IsTypedOperator(GateRef gate) const
674 {
675     return GetMetaData(gate)->IsTypedOperator();
676 }
677 
IsNotWrite(GateRef gate) const678 bool GateAccessor::IsNotWrite(GateRef gate) const
679 {
680     return GetMetaData(gate)->IsNotWrite();
681 }
682 
IsCheckWithTwoIns(GateRef gate) const683 bool GateAccessor::IsCheckWithTwoIns(GateRef gate) const
684 {
685     return GetMetaData(gate)->IsCheckWithTwoIns();
686 }
687 
IsCheckWithOneIn(GateRef gate) const688 bool GateAccessor::IsCheckWithOneIn(GateRef gate) const
689 {
690     return GetMetaData(gate)->IsCheckWithOneIn();
691 }
692 
IsSchedulable(GateRef gate) const693 bool GateAccessor::IsSchedulable(GateRef gate) const
694 {
695     return GetMetaData(gate)->IsSchedulable();
696 }
697 
IsVirtualState(GateRef gate) const698 bool GateAccessor::IsVirtualState(GateRef gate) const
699 {
700     return GetMetaData(gate)->IsVirtualState();
701 }
702 
IsGeneralState(GateRef gate) const703 bool GateAccessor::IsGeneralState(GateRef gate) const
704 {
705     return GetMetaData(gate)->IsGeneralState();
706 }
707 
GetDep(GateRef gate,size_t idx) const708 GateRef GateAccessor::GetDep(GateRef gate, size_t idx) const
709 {
710     Gate *gatePtr = circuit_->LoadGatePtr(gate);
711     ASSERT(idx < gatePtr->GetDependCount());
712     size_t dependIndex = gatePtr->GetStateCount();
713     return circuit_->GetIn(gate, dependIndex + idx);
714 }
715 
GetImmediateId(GateRef gate) const716 size_t GateAccessor::GetImmediateId(GateRef gate) const
717 {
718     Gate *gatePtr = circuit_->LoadGatePtr(gate);
719     ASSERT(gatePtr->GetGateType() == GateType::NJSValue());
720     ASSERT(gatePtr->GetOpCode() == OpCode::CONSTANT);
721     ASSERT(gatePtr->GetMachineType() == MachineType::I64);
722     size_t imm = gatePtr->GetOneParameterMetaData()->GetValue();
723     return imm;
724 }
725 
SetDep(GateRef gate,GateRef depGate,size_t idx)726 void GateAccessor::SetDep(GateRef gate, GateRef depGate, size_t idx)
727 {
728     Gate *gatePtr = circuit_->LoadGatePtr(gate);
729     ASSERT(idx < gatePtr->GetDependCount());
730     size_t dependIndex = gatePtr->GetStateCount();
731     gatePtr->ModifyIn(dependIndex + idx, circuit_->LoadGatePtr(depGate));
732 }
733 
ReplaceIn(const UseIterator & useIt,GateRef replaceGate)734 UseIterator GateAccessor::ReplaceIn(const UseIterator &useIt, GateRef replaceGate)
735 {
736     UseIterator next = useIt;
737     next++;
738     Gate *curGatePtr = circuit_->LoadGatePtr(*useIt);
739     Gate *replaceGatePtr = circuit_->LoadGatePtr(replaceGate);
740     curGatePtr->ModifyIn(useIt.GetIndex(), replaceGatePtr);
741     return next;
742 }
743 
GetGateType(GateRef gate) const744 GateType GateAccessor::GetGateType(GateRef gate) const
745 {
746     return circuit_->LoadGatePtr(gate)->GetGateType();
747 }
748 
SetGateType(GateRef gate,GateType gt)749 void GateAccessor::SetGateType(GateRef gate, GateType gt)
750 {
751     circuit_->LoadGatePtr(gate)->SetGateType(gt);
752 }
753 
ReplaceHirIfSuccess(const UseIterator & useIt,GateRef state)754 UseIterator GateAccessor::ReplaceHirIfSuccess(const UseIterator &useIt, GateRef state)
755 {
756     ASSERT(GetOpCode(*useIt) == OpCode::IF_SUCCESS);
757     auto uses = Uses(*useIt);
758     for (auto it = uses.begin(); it != uses.end();) {
759         if (IsStateIn(it)) {
760             it = ReplaceIn(it, state);
761         }
762     }
763     auto next = DeleteGate(useIt);
764     return next;
765 }
766 
ReplaceHirIfException(const UseIterator & useIt,StateDepend replacement)767 UseIterator GateAccessor::ReplaceHirIfException(const UseIterator &useIt, StateDepend replacement)
768 {
769     ASSERT(GetOpCode(*useIt) == OpCode::IF_EXCEPTION);
770     auto uses = Uses(*useIt);
771     for (auto it = uses.begin(); it != uses.end();) {
772         if (IsStateIn(it)) {
773             it = ReplaceIn(it, replacement.State());
774         } else if (IsDependIn(it)) {
775             it = ReplaceIn(it, replacement.Depend());
776         } else {
777             ASSERT(!IsValueIn(it));
778         }
779     }
780     UseIterator next = useIt;
781     next++;
782     return next;
783 }
784 
ExceptionReturn(GateRef state,GateRef depend)785 void GateAccessor::ExceptionReturn(GateRef state, GateRef depend)
786 {
787     CircuitBuilder builder(circuit_);
788     auto constant = builder.ExceptionConstant();
789     builder.Return(state, depend, constant);
790 }
791 
ReplaceHirWithIfBranch(GateRef hirGate,StateDepend success,StateDepend exception,GateRef value)792 void GateAccessor::ReplaceHirWithIfBranch(GateRef hirGate, StateDepend success,
793                                           StateDepend exception, GateRef value)
794 {
795     auto uses = Uses(hirGate);
796     GateRef ifException = Circuit::NullGate();
797     for (auto it = uses.begin(); it != uses.end();) {
798         if (IsStateIn(it)) {
799             const OpCode op = GetOpCode(*it);
800             if (op == OpCode::IF_SUCCESS) {
801                 it = ReplaceHirIfSuccess(it, success.State());
802             } else if (op == OpCode::IF_EXCEPTION) {
803                 ifException = *it;
804                 it = ReplaceHirIfException(it, exception);
805             } else if (GetMetaData(*it)->IsVirtualState()) {
806                 it = ReplaceIn(it, success.State());
807             } else {
808                 ExceptionReturn(exception.State(), exception.Depend());
809                 it = ReplaceIn(it, success.State());
810             }
811         } else if (IsDependIn(it)) {
812             const OpCode op = GetOpCode(*it);
813             if (op == OpCode::IF_EXCEPTION) {
814                 // ignore it now.
815                 it++;
816             } else {
817                 it = ReplaceIn(it, success.Depend());
818             }
819         } else {
820             ASSERT(IsValueIn(it));
821             it = ReplaceIn(it, value);
822         }
823     }
824 
825     if (ifException != Circuit::NullGate()) {
826         DeleteGate(ifException);
827     }
828 
829     // delete old gate
830     DeleteGate(hirGate);
831 }
832 
ReplaceHirDirectly(GateRef hirGate,StateDepend replacement,GateRef value)833 void GateAccessor::ReplaceHirDirectly(GateRef hirGate,
834     StateDepend replacement, GateRef value)
835 {
836     auto uses = Uses(hirGate);
837     for (auto it = uses.begin(); it != uses.end();) {
838         if (IsStateIn(it)) {
839             ASSERT(GetOpCode(*it) != OpCode::IF_SUCCESS &&
840                 GetOpCode(*it) != OpCode::IF_EXCEPTION);
841             it = ReplaceIn(it, replacement.State());
842         } else if (IsDependIn(it)) {
843             it = ReplaceIn(it, replacement.Depend());
844         } else {
845             ASSERT(IsValueIn(it));
846             it = ReplaceIn(it, value);
847         }
848     }
849 
850     // delete old gate
851     DeleteGate(hirGate);
852 }
853 
ReplaceHirAndDeleteIfException(GateRef hirGate,StateDepend replacement,GateRef value)854 void GateAccessor::ReplaceHirAndDeleteIfException(GateRef hirGate,
855     StateDepend replacement, GateRef value)
856 {
857     if (value != Circuit::NullGate()) {
858         auto type = GetGateType(hirGate);
859         if (!type.IsAnyType()) {
860             SetGateType(value, type);
861         }
862     }
863     GateRef ifException = Circuit::NullGate();
864     auto uses = Uses(hirGate);
865     for (auto it = uses.begin(); it != uses.end();) {
866         if (IsStateIn(it)) {
867             const OpCode op = GetOpCode(*it);
868             if (op == OpCode::IF_SUCCESS) {
869                 it = ReplaceHirIfSuccess(it, replacement.State());
870             } else if (op == OpCode::IF_EXCEPTION) {
871                 ifException = *it;
872                 it = ReplaceIn(it, circuit_->DeadGate());
873             } else {
874                 it = ReplaceIn(it, replacement.State());
875             }
876         } else if (IsDependIn(it)) {
877             const OpCode op = GetOpCode(*it);
878             if (op == OpCode::IF_EXCEPTION) {
879                 it = ReplaceIn(it, circuit_->DeadGate());
880             } else {
881                 it = ReplaceIn(it, replacement.Depend());
882             }
883         } else {
884             ASSERT(IsValueIn(it));
885             it = ReplaceIn(it, value);
886         }
887     }
888 
889     // delete old gate
890     DeleteGate(hirGate);
891     if (ifException != Circuit::NullGate()) {
892         GraphEditor::RemoveDeadState(circuit_, ifException);
893     }
894 }
895 
EliminateRedundantPhi()896 void GateAccessor::EliminateRedundantPhi()
897 {
898     GraphEditor::EliminateRedundantPhi(circuit_);
899 }
900 
DeleteGate(const UseIterator & useIt)901 UseIterator GateAccessor::DeleteGate(const UseIterator &useIt)
902 {
903     auto next = useIt;
904     next++;
905     circuit_->DeleteGate(*useIt);
906     return next;
907 }
908 
DecreaseIn(const UseIterator & useIt)909 void GateAccessor::DecreaseIn(const UseIterator &useIt)
910 {
911     size_t idx = useIt.GetIndex();
912     circuit_->DecreaseIn(*useIt, idx);
913 }
914 
915 
DecreaseIn(GateRef gate,size_t index)916 void GateAccessor::DecreaseIn(GateRef gate, size_t index)
917 {
918     circuit_->DecreaseIn(gate, index);
919 }
920 
NewIn(GateRef gate,size_t idx,GateRef in)921 void GateAccessor::NewIn(GateRef gate, size_t idx, GateRef in)
922 {
923     circuit_->NewIn(gate, idx, in);
924 }
925 
GetStateCount(GateRef gate) const926 size_t GateAccessor::GetStateCount(GateRef gate) const
927 {
928     return circuit_->LoadGatePtr(gate)->GetStateCount();
929 }
930 
GetDependCount(GateRef gate) const931 size_t GateAccessor::GetDependCount(GateRef gate) const
932 {
933     return circuit_->LoadGatePtr(gate)->GetDependCount();
934 }
935 
GetInValueCount(GateRef gate) const936 size_t GateAccessor::GetInValueCount(GateRef gate) const
937 {
938     return circuit_->LoadGatePtr(gate)->GetInValueCount();
939 }
940 
UpdateAllUses(GateRef oldIn,GateRef newIn)941 void GateAccessor::UpdateAllUses(GateRef oldIn, GateRef newIn)
942 {
943     if (oldIn == newIn) {
944         return;
945     }
946     auto uses = Uses(oldIn);
947     for (auto useIt = uses.begin(); useIt != uses.end();) {
948         useIt = ReplaceIn(useIt, newIn);
949     }
950 }
951 
ReplaceIn(GateRef gate,size_t index,GateRef in)952 void GateAccessor::ReplaceIn(GateRef gate, size_t index, GateRef in)
953 {
954     circuit_->ModifyIn(gate, index, in);
955 }
956 
DeleteIn(GateRef gate,size_t idx)957 void GateAccessor::DeleteIn(GateRef gate, size_t idx)
958 {
959     ASSERT(idx < circuit_->LoadGatePtrConst(gate)->GetNumIns());
960     ASSERT(!circuit_->IsInGateNull(gate, idx));
961     circuit_->LoadGatePtr(gate)->DeleteIn(idx);
962 }
963 
ReplaceStateIn(GateRef gate,GateRef in,size_t index)964 void GateAccessor::ReplaceStateIn(GateRef gate, GateRef in, size_t index)
965 {
966     ASSERT(index < GetStateCount(gate));
967     circuit_->ModifyIn(gate, index, in);
968 }
969 
ReplaceDependIn(GateRef gate,GateRef in,size_t index)970 void GateAccessor::ReplaceDependIn(GateRef gate, GateRef in, size_t index)
971 {
972     ASSERT(index < GetDependCount(gate));
973     size_t stateCount = GetStateCount(gate);
974     circuit_->ModifyIn(gate, stateCount + index, in);
975 }
976 
ReplaceValueIn(GateRef gate,GateRef in,size_t index)977 void GateAccessor::ReplaceValueIn(GateRef gate, GateRef in, size_t index)
978 {
979     ASSERT(index < GetInValueCount(gate));
980     size_t valueStartIndex = GetInValueStarts(gate);
981     circuit_->ModifyIn(gate, valueStartIndex + index, in);
982 }
983 
DeleteGate(GateRef gate)984 void GateAccessor::DeleteGate(GateRef gate)
985 {
986     circuit_->DeleteGate(gate);
987 }
988 
GetMachineType(GateRef gate) const989 MachineType GateAccessor::GetMachineType(GateRef gate) const
990 {
991     return circuit_->GetMachineType(gate);
992 }
993 
SetMachineType(GateRef gate,MachineType type)994 void GateAccessor::SetMachineType(GateRef gate, MachineType type)
995 {
996     circuit_->SetMachineType(gate, type);
997 }
998 
GetConstantGate(MachineType bitValue,BitField bitfield,GateType type) const999 GateRef GateAccessor::GetConstantGate(MachineType bitValue, BitField bitfield, GateType type) const
1000 {
1001     return circuit_->GetConstantGate(bitValue, bitfield, type);
1002 }
1003 
GetInitialEnvGate(GateRef jsFunc) const1004 GateRef GateAccessor::GetInitialEnvGate(GateRef jsFunc) const
1005 {
1006     return circuit_->GetInitialEnvGate(jsFunc);
1007 }
1008 
IsConstantNumber(GateRef gate) const1009 bool GateAccessor::IsConstantNumber(GateRef gate) const
1010 {
1011     DISALLOW_GARBAGE_COLLECTION;
1012     if (GetGateType(gate).IsNJSValueType() ||
1013         (GetOpCode(gate) != OpCode::CONSTANT)) {
1014         return false;
1015     }
1016     JSTaggedValue value(GetConstantValue(gate));
1017     return value.IsNumber();
1018 }
1019 
GetFloat64FromConstant(GateRef gate) const1020 double GateAccessor::GetFloat64FromConstant(GateRef gate) const
1021 {
1022     DISALLOW_GARBAGE_COLLECTION;
1023     ASSERT(GetOpCode(gate) == OpCode::CONSTANT);
1024     uint64_t rawValue = GetConstantValue(gate);
1025     if (GetGateType(gate).IsNJSValueType()) {
1026         ASSERT(GetMachineType(gate) == MachineType::F64);
1027         return base::bit_cast<double>(rawValue);
1028     }
1029     JSTaggedValue value(rawValue);
1030     return value.GetDouble();
1031 }
1032 
GetInt32FromConstant(GateRef gate) const1033 int GateAccessor::GetInt32FromConstant(GateRef gate) const
1034 {
1035     DISALLOW_GARBAGE_COLLECTION;
1036     ASSERT(GetOpCode(gate) == OpCode::CONSTANT);
1037     uint64_t rawValue = GetConstantValue(gate);
1038     if (GetGateType(gate).IsNJSValueType()) {
1039         ASSERT(GetMachineType(gate) == MachineType::I32);
1040         return static_cast<int>(rawValue);
1041     }
1042     JSTaggedValue value(rawValue);
1043     return value.GetInt();
1044 }
1045 
IsStateIn(const UseIterator & useIt) const1046 bool GateAccessor::IsStateIn(const UseIterator &useIt) const
1047 {
1048     size_t stateStartIndex = 0;
1049     size_t stateEndIndex = stateStartIndex + GetStateCount(*useIt);
1050     size_t index = useIt.GetIndex();
1051     return (index >= stateStartIndex && index < stateEndIndex);
1052 }
1053 
IsDependIn(const UseIterator & useIt) const1054 bool GateAccessor::IsDependIn(const UseIterator &useIt) const
1055 {
1056     size_t dependStartIndex = GetStateCount(*useIt);
1057     size_t dependEndIndex = dependStartIndex + GetDependCount(*useIt);
1058     size_t index = useIt.GetIndex();
1059     return (index >= dependStartIndex && index < dependEndIndex);
1060 }
1061 
IsValueIn(const UseIterator & useIt) const1062 bool GateAccessor::IsValueIn(const UseIterator &useIt) const
1063 {
1064     size_t valueStartIndex = GetInValueStarts(*useIt);
1065     size_t valueEndIndex = valueStartIndex + GetInValueCount(*useIt);
1066     size_t index = useIt.GetIndex();
1067     return (index >= valueStartIndex && index < valueEndIndex);
1068 }
1069 
IsFrameStateIn(const UseIterator & useIt) const1070 bool GateAccessor::IsFrameStateIn(const UseIterator &useIt) const
1071 {
1072     size_t index = useIt.GetIndex();
1073     return IsFrameStateIn(*useIt, index);
1074 }
1075 
IsStateIn(GateRef gate,size_t index) const1076 bool GateAccessor::IsStateIn(GateRef gate, size_t index) const
1077 {
1078     size_t stateStartIndex = 0;
1079     size_t stateEndIndex = stateStartIndex + GetStateCount(gate);
1080     return (index >= stateStartIndex && index < stateEndIndex);
1081 }
1082 
IsDependIn(GateRef gate,size_t index) const1083 bool GateAccessor::IsDependIn(GateRef gate, size_t index) const
1084 {
1085     size_t dependStartIndex = GetStateCount(gate);
1086     size_t dependEndIndex = dependStartIndex + GetDependCount(gate);
1087     return (index >= dependStartIndex && index < dependEndIndex);
1088 }
1089 
IsValueIn(GateRef gate,size_t index) const1090 bool GateAccessor::IsValueIn(GateRef gate, size_t index) const
1091 {
1092     size_t valueStartIndex = GetInValueStarts(gate);
1093     size_t valueEndIndex = valueStartIndex + GetInValueCount(gate);
1094     return (index >= valueStartIndex && index < valueEndIndex);
1095 }
1096 
IsFrameStateIn(GateRef gate,size_t index) const1097 bool GateAccessor::IsFrameStateIn(GateRef gate, size_t index) const
1098 {
1099     Gate *gatePtr = circuit_->LoadGatePtr(gate);
1100     size_t frameStateStartIndex = gatePtr->GetInFrameStateStarts();
1101     size_t FrameStateEndIndex = frameStateStartIndex + gatePtr->GetInFrameStateCount();
1102     return (index >= frameStateStartIndex && index < FrameStateEndIndex);
1103 }
1104 
ReplaceGate(GateRef gate,GateRef state,GateRef depend,GateRef value)1105 void GateAccessor::ReplaceGate(GateRef gate, GateRef state, GateRef depend, GateRef value)
1106 {
1107     if (value != Circuit::NullGate()) {
1108         GateType type = GetGateType(gate);
1109         GateType valueType = GetGateType(value);
1110         if (!type.IsAnyType() && !valueType.IsNJSValueType()) {
1111             SetGateType(value, type);
1112         }
1113     }
1114 
1115     auto uses = Uses(gate);
1116     for (auto useIt = uses.begin(); useIt != uses.end();) {
1117         if (IsStateIn(useIt)) {
1118             ASSERT(state != Circuit::NullGate());
1119             useIt = ReplaceIn(useIt, state);
1120         } else if (IsDependIn(useIt)) {
1121             ASSERT(depend != Circuit::NullGate());
1122             useIt = ReplaceIn(useIt, depend);
1123         } else if (IsValueIn(useIt)) {
1124             ASSERT(value != Circuit::NullGate());
1125             useIt = ReplaceIn(useIt, value);
1126         } else {
1127             LOG_ECMA(FATAL) << "this branch is unreachable";
1128             UNREACHABLE();
1129         }
1130     }
1131     DeleteGate(gate);
1132 }
1133 
GetFrameState(GateRef gate) const1134 GateRef GateAccessor::GetFrameState(GateRef gate) const
1135 {
1136     ASSERT(HasFrameState(gate));
1137     Gate *gatePtr = circuit_->LoadGatePtr(gate);
1138     size_t index = gatePtr->GetInFrameStateStarts();
1139     return circuit_->GetIn(gate, index);
1140 }
1141 
FindNearestFrameState(GateRef gate) const1142 GateRef GateAccessor::FindNearestFrameState(GateRef gate) const
1143 {
1144     auto statesplit = FindNearestStateSplit(gate);
1145     return GetFrameState(statesplit);
1146 }
1147 
FindNearestStateSplit(GateRef gate) const1148 GateRef GateAccessor::FindNearestStateSplit(GateRef gate) const
1149 {
1150     auto statesplit = gate;
1151     while (GetOpCode(statesplit) != OpCode::STATE_SPLIT) {
1152         statesplit = GetDep(statesplit);
1153     }
1154     return statesplit;
1155 }
1156 
HasFrameState(GateRef gate) const1157 bool GateAccessor::HasFrameState(GateRef gate) const
1158 {
1159     return GetMetaData(gate)->HasFrameState();
1160 }
1161 
ReplaceFrameStateIn(GateRef gate,GateRef in)1162 void GateAccessor::ReplaceFrameStateIn(GateRef gate, GateRef in)
1163 {
1164     ASSERT(HasFrameState(gate));
1165     Gate *gatePtr = circuit_->LoadGatePtr(gate);
1166     size_t index = gatePtr->GetInFrameStateStarts();
1167     circuit_->ModifyIn(gate, index, in);
1168 }
1169 
GetRoot(OpCode opcode) const1170 GateRef GateAccessor::GetRoot(OpCode opcode) const
1171 {
1172     GateRef root = circuit_->GetRoot();
1173     if (opcode == OpCode::CIRCUIT_ROOT) {
1174         return root;
1175     }
1176 
1177     auto uses = ConstUses(root);
1178     for (auto useIt = uses.begin(); useIt != uses.end(); ++useIt) {
1179         if (GetOpCode(*useIt) == opcode) {
1180             return *useIt;
1181         }
1182     }
1183     return Circuit::NullGate();
1184 }
1185 
GetGlueFromArgList() const1186 GateRef GateAccessor::GetGlueFromArgList() const
1187 {
1188     auto argRoot = GetArgRoot();
1189     ASSERT(static_cast<size_t>(CommonArgIdx::GLUE) == 0);
1190     const Gate *curGate = circuit_->LoadGatePtrConst(argRoot);
1191 
1192     const Out *curOut = curGate->GetFirstOutConst();
1193     ASSERT(!curGate->IsFirstOutNull());
1194     while (!curOut->IsNextOutNull()) {
1195         curOut = curOut->GetNextOutConst();
1196     }
1197     return circuit_->GetGateRef(curOut->GetGateConst());
1198 }
1199 
GetArgsOuts(std::vector<GateRef> & outs) const1200 void GateAccessor::GetArgsOuts(std::vector<GateRef>& outs) const
1201 {
1202     auto argRoot = GetArgRoot();
1203     GetOuts(argRoot, outs);
1204 }
1205 
GetReturnOuts(std::vector<GateRef> & outs) const1206 void GateAccessor::GetReturnOuts(std::vector<GateRef>& outs) const
1207 {
1208     auto returnRoot = GetReturnRoot();
1209     GetOuts(returnRoot, outs);
1210 }
1211 
GetMetaData(GateRef gate) const1212 const GateMetaData *GateAccessor::GetMetaData(GateRef gate) const
1213 {
1214     return circuit_->LoadGatePtrConst(gate)->GetMetaData();
1215 }
1216 
SetMetaData(GateRef gate,const GateMetaData * meta)1217 void GateAccessor::SetMetaData(GateRef gate, const GateMetaData* meta)
1218 {
1219     return circuit_->LoadGatePtr(gate)->SetMetaData(meta);
1220 }
1221 
IsFixed(GateRef g) const1222 bool GateAccessor::IsFixed(GateRef g) const
1223 {
1224     return GetMetaData(g)->IsFixed();
1225 }
1226 
IsProlog(GateRef g) const1227 bool GateAccessor::IsProlog(GateRef g) const
1228 {
1229     return GetMetaData(g)->IsProlog();
1230 }
1231 
IsCFGMerge(GateRef g) const1232 bool GateAccessor::IsCFGMerge(GateRef g) const
1233 {
1234     return GetMetaData(g)->IsCFGMerge();
1235 }
1236 
MetaDataEqu(GateRef g1,GateRef g2) const1237 bool GateAccessor::MetaDataEqu(GateRef g1, GateRef g2) const
1238 {
1239     return GetMetaData(g1) == GetMetaData(g2);
1240 }
1241 
IsNop(GateRef g) const1242 bool GateAccessor::IsNop(GateRef g) const
1243 {
1244     return GetMetaData(g)->IsNop();
1245 }
1246 
IsRoot(GateRef g) const1247 bool GateAccessor::IsRoot(GateRef g) const
1248 {
1249     return GetMetaData(g)->IsRoot();
1250 }
1251 
GetMetaData(GateRef g) const1252 const GateMetaData *ConstGateAccessor::GetMetaData(GateRef g) const
1253 {
1254     return circuit_->LoadGatePtrConst(g)->GetMetaData();
1255 }
1256 
IsFixed(GateRef g) const1257 bool ConstGateAccessor::IsFixed(GateRef g) const
1258 {
1259     return GetMetaData(g)->IsFixed();
1260 }
1261 
IsProlog(GateRef g) const1262 bool ConstGateAccessor::IsProlog(GateRef g) const
1263 {
1264     return GetMetaData(g)->IsProlog();
1265 }
1266 
IsSchedulable(GateRef g) const1267 bool ConstGateAccessor::IsSchedulable(GateRef g) const
1268 {
1269     return GetMetaData(g)->IsSchedulable();
1270 }
1271 
GetDependSelectorFromMerge(GateRef gate)1272 GateRef GateAccessor::GetDependSelectorFromMerge(GateRef gate)
1273 {
1274     GateRef depend = Circuit::NullGate();
1275     auto uses = Uses(gate);
1276     for (auto useIt = uses.begin(); useIt != uses.end(); useIt++) {
1277         if (GetOpCode(*useIt) == OpCode::DEPEND_SELECTOR) {
1278             depend = *useIt;
1279             break;
1280         }
1281     }
1282     ASSERT(depend != Circuit::NullGate());
1283     return depend;
1284 }
1285 
HasIfExceptionUse(GateRef gate) const1286 bool GateAccessor::HasIfExceptionUse(GateRef gate) const
1287 {
1288     ASSERT(GetStateCount(gate) > 0);
1289     auto uses = ConstUses(gate);
1290     for (auto it = uses.begin(); it != uses.end(); it++) {
1291         if (GetOpCode(*it) == OpCode::IF_EXCEPTION) {
1292             return true;
1293         }
1294     }
1295     return false;
1296 }
1297 
IsHeapObjectFromElementsKind(GateRef gate)1298 bool GateAccessor::IsHeapObjectFromElementsKind(GateRef gate)
1299 {
1300     OpCode opcode = GetOpCode(gate);
1301     if (opcode == OpCode::JS_BYTECODE) {
1302         auto bc = GetByteCodeOpcode(gate);
1303         if (bc == EcmaOpcode::LDOBJBYVALUE_IMM8_V8 || bc == EcmaOpcode::LDOBJBYVALUE_IMM16_V8 ||
1304             bc == EcmaOpcode::LDTHISBYVALUE_IMM8 || bc == EcmaOpcode::LDTHISBYVALUE_IMM16) {
1305             ElementsKind kind = TryGetElementsKind(gate);
1306             return Elements::IsObject(kind);
1307         }
1308         return false;
1309     }
1310 
1311     if (opcode == OpCode::LOAD_ELEMENT) {
1312         TypedLoadOp typedOp = GetTypedLoadOp(gate);
1313         return typedOp == TypedLoadOp::ARRAY_LOAD_OBJECT_ELEMENT;
1314     }
1315 
1316     return false;
1317 }
1318 }  // namespace panda::ecmascript::kungfu
1319