14514f5e3Sopenharmony_ci/* 24514f5e3Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd. 34514f5e3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 44514f5e3Sopenharmony_ci * you may not use this file except in compliance with the License. 54514f5e3Sopenharmony_ci * You may obtain a copy of the License at 64514f5e3Sopenharmony_ci * 74514f5e3Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 84514f5e3Sopenharmony_ci * 94514f5e3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 104514f5e3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 114514f5e3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 124514f5e3Sopenharmony_ci * See the License for the specific language governing permissions and 134514f5e3Sopenharmony_ci * limitations under the License. 144514f5e3Sopenharmony_ci */ 154514f5e3Sopenharmony_ci 164514f5e3Sopenharmony_ci#include "ecmascript/compiler/post_schedule.h" 174514f5e3Sopenharmony_ci 184514f5e3Sopenharmony_ci#include <ecmascript/stubs/runtime_stubs.h> 194514f5e3Sopenharmony_ci 204514f5e3Sopenharmony_ci#include "ecmascript/compiler/circuit_builder-inl.h" 214514f5e3Sopenharmony_ci#include "ecmascript/js_thread.h" 224514f5e3Sopenharmony_ci 234514f5e3Sopenharmony_cinamespace panda::ecmascript::kungfu { 244514f5e3Sopenharmony_civoid PostSchedule::Run(ControlFlowGraph &cfg) 254514f5e3Sopenharmony_ci{ 264514f5e3Sopenharmony_ci GenerateExtraBB(cfg); 274514f5e3Sopenharmony_ci 284514f5e3Sopenharmony_ci if (IsLogEnabled()) { 294514f5e3Sopenharmony_ci LOG_COMPILER(INFO) << ""; 304514f5e3Sopenharmony_ci LOG_COMPILER(INFO) << "\033[34m" 314514f5e3Sopenharmony_ci << "====================" 324514f5e3Sopenharmony_ci << " After post schedule " 334514f5e3Sopenharmony_ci << "[" << GetMethodName() << "]" 344514f5e3Sopenharmony_ci << "====================" 354514f5e3Sopenharmony_ci << "\033[0m"; 364514f5e3Sopenharmony_ci PrintGraph("Build extra basic block for scheduled gates", cfg); 374514f5e3Sopenharmony_ci LOG_COMPILER(INFO) << "\033[34m" << "========================= End ==========================" << "\033[0m"; 384514f5e3Sopenharmony_ci } 394514f5e3Sopenharmony_ci} 404514f5e3Sopenharmony_ci 414514f5e3Sopenharmony_civoid PostSchedule::GenerateExtraBB(ControlFlowGraph &cfg) 424514f5e3Sopenharmony_ci{ 434514f5e3Sopenharmony_ci size_t bbNum = cfg.size(); 444514f5e3Sopenharmony_ci size_t bbIdx = 0; 454514f5e3Sopenharmony_ci while (bbIdx < bbNum) { 464514f5e3Sopenharmony_ci const std::vector<GateRef>& bb = cfg.at(bbIdx); 474514f5e3Sopenharmony_ci size_t instNum = bb.size(); 484514f5e3Sopenharmony_ci size_t instIdx = 0; 494514f5e3Sopenharmony_ci while (instIdx < instNum) { 504514f5e3Sopenharmony_ci const std::vector<GateRef>& currentBB = cfg.at(bbIdx); 514514f5e3Sopenharmony_ci GateRef current = currentBB[instIdx]; 524514f5e3Sopenharmony_ci OpCode opcode = acc_.GetOpCode(current); 534514f5e3Sopenharmony_ci bool needRetraverse = false; 544514f5e3Sopenharmony_ci switch (opcode) { 554514f5e3Sopenharmony_ci case OpCode::HEAP_ALLOC: { 564514f5e3Sopenharmony_ci needRetraverse = VisitHeapAlloc(current, cfg, bbIdx, instIdx); 574514f5e3Sopenharmony_ci break; 584514f5e3Sopenharmony_ci } 594514f5e3Sopenharmony_ci case OpCode::STORE: { 604514f5e3Sopenharmony_ci needRetraverse = VisitStore(current, cfg, bbIdx, instIdx); 614514f5e3Sopenharmony_ci break; 624514f5e3Sopenharmony_ci } 634514f5e3Sopenharmony_ci default: { 644514f5e3Sopenharmony_ci break; 654514f5e3Sopenharmony_ci } 664514f5e3Sopenharmony_ci } 674514f5e3Sopenharmony_ci const std::vector<GateRef>& refreshedBB = cfg.at(bbIdx); 684514f5e3Sopenharmony_ci instNum = refreshedBB.size(); 694514f5e3Sopenharmony_ci instIdx = needRetraverse ? 0 : (instIdx + 1); 704514f5e3Sopenharmony_ci } 714514f5e3Sopenharmony_ci bbNum = cfg.size(); 724514f5e3Sopenharmony_ci bbIdx++; 734514f5e3Sopenharmony_ci } 744514f5e3Sopenharmony_ci} 754514f5e3Sopenharmony_ci 764514f5e3Sopenharmony_cibool PostSchedule::VisitHeapAlloc(GateRef gate, ControlFlowGraph &cfg, size_t bbIdx, size_t instIdx) 774514f5e3Sopenharmony_ci{ 784514f5e3Sopenharmony_ci int64_t flag = static_cast<int64_t>(acc_.TryGetValue(gate)); 794514f5e3Sopenharmony_ci ASSERT(flag == RegionSpaceFlag::IN_YOUNG_SPACE || 804514f5e3Sopenharmony_ci flag == RegionSpaceFlag::IN_SHARED_OLD_SPACE || 814514f5e3Sopenharmony_ci flag == RegionSpaceFlag::IN_SHARED_NON_MOVABLE || 824514f5e3Sopenharmony_ci flag == RegionSpaceFlag::IN_OLD_SPACE); 834514f5e3Sopenharmony_ci std::vector<GateRef> currentBBGates; 844514f5e3Sopenharmony_ci std::vector<GateRef> successBBGates; 854514f5e3Sopenharmony_ci std::vector<GateRef> failBBGates; 864514f5e3Sopenharmony_ci std::vector<GateRef> endBBGates; 874514f5e3Sopenharmony_ci if (flag == RegionSpaceFlag::IN_OLD_SPACE) { 884514f5e3Sopenharmony_ci LoweringHeapAllocate(gate, currentBBGates, successBBGates, failBBGates, endBBGates, flag); 894514f5e3Sopenharmony_ci ReplaceGateDirectly(currentBBGates, cfg, bbIdx, instIdx); 904514f5e3Sopenharmony_ci return false; 914514f5e3Sopenharmony_ci } else { 924514f5e3Sopenharmony_ci LoweringHeapAllocAndPrepareScheduleGate(gate, currentBBGates, successBBGates, failBBGates, endBBGates, flag); 934514f5e3Sopenharmony_ci } 944514f5e3Sopenharmony_ci#ifdef ARK_ASAN_ON 954514f5e3Sopenharmony_ci ReplaceGateDirectly(currentBBGates, cfg, bbIdx, instIdx); 964514f5e3Sopenharmony_ci return false; 974514f5e3Sopenharmony_ci#else 984514f5e3Sopenharmony_ci ReplaceBBState(cfg, bbIdx, currentBBGates, endBBGates); 994514f5e3Sopenharmony_ci ScheduleEndBB(endBBGates, cfg, bbIdx, instIdx); 1004514f5e3Sopenharmony_ci ScheduleNewBB(successBBGates, cfg, bbIdx); 1014514f5e3Sopenharmony_ci ScheduleNewBB(failBBGates, cfg, bbIdx); 1024514f5e3Sopenharmony_ci ScheduleCurrentBB(currentBBGates, cfg, bbIdx, instIdx); 1034514f5e3Sopenharmony_ci return true; 1044514f5e3Sopenharmony_ci#endif 1054514f5e3Sopenharmony_ci} 1064514f5e3Sopenharmony_ci 1074514f5e3Sopenharmony_civoid PostSchedule::ReplaceGateDirectly(std::vector<GateRef> &gates, ControlFlowGraph &cfg, size_t bbIdx, size_t instIdx) 1084514f5e3Sopenharmony_ci{ 1094514f5e3Sopenharmony_ci std::vector<GateRef>& bb = cfg.at(bbIdx); 1104514f5e3Sopenharmony_ci bb.insert(bb.begin() + instIdx, gates.begin(), gates.end()); 1114514f5e3Sopenharmony_ci bb.erase(bb.begin() + instIdx + gates.size()); 1124514f5e3Sopenharmony_ci} 1134514f5e3Sopenharmony_ci 1144514f5e3Sopenharmony_civoid PostSchedule::ScheduleEndBB(std::vector<GateRef> &gates, ControlFlowGraph &cfg, size_t bbIdx, size_t instIdx) 1154514f5e3Sopenharmony_ci{ 1164514f5e3Sopenharmony_ci std::vector<GateRef>& bb = cfg.at(bbIdx); 1174514f5e3Sopenharmony_ci if (instIdx > 0) { 1184514f5e3Sopenharmony_ci gates.insert(gates.begin() + 1, bb.begin(), bb.begin() + instIdx); // 1: after state gate 1194514f5e3Sopenharmony_ci } 1204514f5e3Sopenharmony_ci cfg.insert(cfg.begin() + bbIdx + 1, std::move(gates)); // 1: after current bb 1214514f5e3Sopenharmony_ci} 1224514f5e3Sopenharmony_ci 1234514f5e3Sopenharmony_civoid PostSchedule::ScheduleNewBB(std::vector<GateRef> &gates, ControlFlowGraph &cfg, size_t bbIdx) 1244514f5e3Sopenharmony_ci{ 1254514f5e3Sopenharmony_ci if (!gates.empty()) { 1264514f5e3Sopenharmony_ci cfg.insert(cfg.begin() + bbIdx + 1, std::move(gates)); 1274514f5e3Sopenharmony_ci } 1284514f5e3Sopenharmony_ci} 1294514f5e3Sopenharmony_ci 1304514f5e3Sopenharmony_civoid PostSchedule::ScheduleCurrentBB(const std::vector<GateRef> &gates, ControlFlowGraph &cfg, size_t bbIdx, 1314514f5e3Sopenharmony_ci size_t instIdx) 1324514f5e3Sopenharmony_ci{ 1334514f5e3Sopenharmony_ci std::vector<GateRef>& bb = cfg.at(bbIdx); 1344514f5e3Sopenharmony_ci if (instIdx == 0) { 1354514f5e3Sopenharmony_ci bb.erase(bb.begin()); 1364514f5e3Sopenharmony_ci } else { 1374514f5e3Sopenharmony_ci bb.erase(bb.begin(), bb.begin() + instIdx + 1); // 1: include current gate 1384514f5e3Sopenharmony_ci } 1394514f5e3Sopenharmony_ci bb.insert(bb.begin(), gates.begin(), gates.end()); 1404514f5e3Sopenharmony_ci} 1414514f5e3Sopenharmony_ci 1424514f5e3Sopenharmony_civoid PostSchedule::PrepareToScheduleNewGate(GateRef gate, std::vector<GateRef> &gates) 1434514f5e3Sopenharmony_ci{ 1444514f5e3Sopenharmony_ci gates.emplace_back(gate); 1454514f5e3Sopenharmony_ci} 1464514f5e3Sopenharmony_ci 1474514f5e3Sopenharmony_civoid PostSchedule::ReplaceBBState(ControlFlowGraph &cfg, size_t bbIdx, std::vector<GateRef> ¤tBBGates, 1484514f5e3Sopenharmony_ci std::vector<GateRef> &endBBGates) 1494514f5e3Sopenharmony_ci{ 1504514f5e3Sopenharmony_ci GateRef floatBranch = currentBBGates[0]; 1514514f5e3Sopenharmony_ci ASSERT(acc_.GetOpCode(floatBranch) == OpCode::IF_BRANCH); 1524514f5e3Sopenharmony_ci GateRef endBBState = endBBGates[0]; 1534514f5e3Sopenharmony_ci ASSERT(acc_.GetOpCode(endBBState) == OpCode::MERGE); 1544514f5e3Sopenharmony_ci std::vector<GateRef>& bb = cfg.at(bbIdx); 1554514f5e3Sopenharmony_ci GateRef currentBBState = bb[0]; 1564514f5e3Sopenharmony_ci ASSERT(acc_.IsState(currentBBState)); 1574514f5e3Sopenharmony_ci 1584514f5e3Sopenharmony_ci OpCode opcode = acc_.GetOpCode(currentBBState); 1594514f5e3Sopenharmony_ci switch (opcode) { 1604514f5e3Sopenharmony_ci case OpCode::DEOPT_CHECK: 1614514f5e3Sopenharmony_ci case OpCode::RETURN: 1624514f5e3Sopenharmony_ci case OpCode::RETURN_VOID: 1634514f5e3Sopenharmony_ci case OpCode::IF_BRANCH: 1644514f5e3Sopenharmony_ci case OpCode::SWITCH_BRANCH: { 1654514f5e3Sopenharmony_ci GateRef stateIn = acc_.GetState(currentBBState, 0); 1664514f5e3Sopenharmony_ci acc_.ReplaceStateIn(floatBranch, stateIn); 1674514f5e3Sopenharmony_ci acc_.ReplaceStateIn(currentBBState, endBBState); 1684514f5e3Sopenharmony_ci break; 1694514f5e3Sopenharmony_ci } 1704514f5e3Sopenharmony_ci case OpCode::STATE_ENTRY: 1714514f5e3Sopenharmony_ci case OpCode::ORDINARY_BLOCK: 1724514f5e3Sopenharmony_ci case OpCode::IF_TRUE: 1734514f5e3Sopenharmony_ci case OpCode::IF_FALSE: 1744514f5e3Sopenharmony_ci case OpCode::SWITCH_CASE: 1754514f5e3Sopenharmony_ci case OpCode::DEFAULT_CASE: 1764514f5e3Sopenharmony_ci case OpCode::MERGE: 1774514f5e3Sopenharmony_ci case OpCode::LOOP_BEGIN: 1784514f5e3Sopenharmony_ci case OpCode::LOOP_BACK: { 1794514f5e3Sopenharmony_ci acc_.ReplaceControlGate(currentBBState, endBBState); 1804514f5e3Sopenharmony_ci acc_.ReplaceStateIn(floatBranch, currentBBState); 1814514f5e3Sopenharmony_ci currentBBGates.insert(currentBBGates.begin(), currentBBState); 1824514f5e3Sopenharmony_ci bb[0] = builder_.Nop(); 1834514f5e3Sopenharmony_ci break; 1844514f5e3Sopenharmony_ci } 1854514f5e3Sopenharmony_ci default: { 1864514f5e3Sopenharmony_ci LOG_ECMA(FATAL) << "this branch is unreachable with opcode:" << opcode; 1874514f5e3Sopenharmony_ci UNREACHABLE(); 1884514f5e3Sopenharmony_ci } 1894514f5e3Sopenharmony_ci } 1904514f5e3Sopenharmony_ci} 1914514f5e3Sopenharmony_ci 1924514f5e3Sopenharmony_civoid PostSchedule::LoweringHeapAllocAndPrepareScheduleGate(GateRef gate, 1934514f5e3Sopenharmony_ci std::vector<GateRef> ¤tBBGates, 1944514f5e3Sopenharmony_ci std::vector<GateRef> &successBBGates, 1954514f5e3Sopenharmony_ci std::vector<GateRef> &failBBGates, 1964514f5e3Sopenharmony_ci std::vector<GateRef> &endBBGates, 1974514f5e3Sopenharmony_ci [[maybe_unused]] int64_t flag) 1984514f5e3Sopenharmony_ci{ 1994514f5e3Sopenharmony_ci#ifdef ARK_ASAN_ON 2004514f5e3Sopenharmony_ci LoweringHeapAllocate(gate, currentBBGates, successBBGates, failBBGates, endBBGates, flag); 2014514f5e3Sopenharmony_ci#else 2024514f5e3Sopenharmony_ci Environment env(gate, circuit_, &builder_); 2034514f5e3Sopenharmony_ci Label exit(&builder_); 2044514f5e3Sopenharmony_ci GateRef glue = acc_.GetValueIn(gate, 0); 2054514f5e3Sopenharmony_ci GateRef size = acc_.GetValueIn(gate, 1); 2064514f5e3Sopenharmony_ci GateRef hole = circuit_->GetConstantGateWithoutCache( 2074514f5e3Sopenharmony_ci MachineType::I64, JSTaggedValue::VALUE_HOLE, GateType::TaggedValue()); 2084514f5e3Sopenharmony_ci DEFVALUE(result, (&builder_), VariableType::JS_ANY(), hole); 2094514f5e3Sopenharmony_ci Label success(&builder_); 2104514f5e3Sopenharmony_ci Label callRuntime(&builder_); 2114514f5e3Sopenharmony_ci size_t topOffset; 2124514f5e3Sopenharmony_ci size_t endOffset; 2134514f5e3Sopenharmony_ci if (flag == RegionSpaceFlag::IN_SHARED_OLD_SPACE) { 2144514f5e3Sopenharmony_ci topOffset = JSThread::GlueData::GetSOldSpaceAllocationTopAddressOffset(false); 2154514f5e3Sopenharmony_ci endOffset = JSThread::GlueData::GetSOldSpaceAllocationEndAddressOffset(false); 2164514f5e3Sopenharmony_ci } else if (flag == RegionSpaceFlag::IN_SHARED_NON_MOVABLE) { 2174514f5e3Sopenharmony_ci topOffset = JSThread::GlueData::GetSNonMovableSpaceAllocationTopAddressOffset(false); 2184514f5e3Sopenharmony_ci endOffset = JSThread::GlueData::GetSNonMovableSpaceAllocationEndAddressOffset(false); 2194514f5e3Sopenharmony_ci } else { 2204514f5e3Sopenharmony_ci ASSERT(flag == RegionSpaceFlag::IN_YOUNG_SPACE); 2214514f5e3Sopenharmony_ci topOffset = JSThread::GlueData::GetNewSpaceAllocationTopAddressOffset(false); 2224514f5e3Sopenharmony_ci endOffset = JSThread::GlueData::GetNewSpaceAllocationEndAddressOffset(false); 2234514f5e3Sopenharmony_ci } 2244514f5e3Sopenharmony_ci GateRef topAddrOffset = circuit_->GetConstantGateWithoutCache(MachineType::I64, topOffset, GateType::NJSValue()); 2254514f5e3Sopenharmony_ci GateRef endAddrOffset = circuit_->GetConstantGateWithoutCache(MachineType::I64, endOffset, GateType::NJSValue()); 2264514f5e3Sopenharmony_ci GateRef topAddrAddr = builder_.PtrAdd(glue, topAddrOffset); 2274514f5e3Sopenharmony_ci GateRef endAddrAddr = builder_.PtrAdd(glue, endAddrOffset); 2284514f5e3Sopenharmony_ci GateRef topAddress = builder_.Load(VariableType::NATIVE_POINTER(), topAddrAddr); 2294514f5e3Sopenharmony_ci GateRef endAddress = builder_.Load(VariableType::NATIVE_POINTER(), endAddrAddr); 2304514f5e3Sopenharmony_ci GateRef addrOffset = circuit_->GetConstantGateWithoutCache(MachineType::I64, 0, GateType::NJSValue()); 2314514f5e3Sopenharmony_ci GateRef rawTopAddr = builder_.PtrAdd(topAddress, addrOffset); 2324514f5e3Sopenharmony_ci GateRef rawEndAddr = builder_.PtrAdd(endAddress, addrOffset); 2334514f5e3Sopenharmony_ci GateRef top = builder_.Load(VariableType::JS_POINTER(), rawTopAddr); 2344514f5e3Sopenharmony_ci GateRef end = builder_.Load(VariableType::JS_POINTER(), rawEndAddr); 2354514f5e3Sopenharmony_ci 2364514f5e3Sopenharmony_ci GateRef newTop = builder_.PtrAdd(top, size); 2374514f5e3Sopenharmony_ci GateRef condition = builder_.Int64GreaterThan(newTop, end); 2384514f5e3Sopenharmony_ci Label *currentLabel = env.GetCurrentLabel(); 2394514f5e3Sopenharmony_ci BRANCH_CIR(condition, &callRuntime, &success); 2404514f5e3Sopenharmony_ci { 2414514f5e3Sopenharmony_ci GateRef ifBranch = currentLabel->GetControl(); 2424514f5e3Sopenharmony_ci PrepareToScheduleNewGate(ifBranch, currentBBGates); 2434514f5e3Sopenharmony_ci PrepareToScheduleNewGate(condition, currentBBGates); 2444514f5e3Sopenharmony_ci PrepareToScheduleNewGate(newTop, currentBBGates); 2454514f5e3Sopenharmony_ci PrepareToScheduleNewGate(end, currentBBGates); 2464514f5e3Sopenharmony_ci PrepareToScheduleNewGate(top, currentBBGates); 2474514f5e3Sopenharmony_ci PrepareToScheduleNewGate(rawEndAddr, currentBBGates); 2484514f5e3Sopenharmony_ci PrepareToScheduleNewGate(rawTopAddr, currentBBGates); 2494514f5e3Sopenharmony_ci PrepareToScheduleNewGate(topAddress, currentBBGates); 2504514f5e3Sopenharmony_ci PrepareToScheduleNewGate(endAddress, currentBBGates); 2514514f5e3Sopenharmony_ci PrepareToScheduleNewGate(addrOffset, currentBBGates); 2524514f5e3Sopenharmony_ci PrepareToScheduleNewGate(topAddrAddr, currentBBGates); 2534514f5e3Sopenharmony_ci PrepareToScheduleNewGate(endAddrAddr, currentBBGates); 2544514f5e3Sopenharmony_ci PrepareToScheduleNewGate(topAddrOffset, currentBBGates); 2554514f5e3Sopenharmony_ci PrepareToScheduleNewGate(endAddrOffset, currentBBGates); 2564514f5e3Sopenharmony_ci PrepareToScheduleNewGate(hole, currentBBGates); 2574514f5e3Sopenharmony_ci } 2584514f5e3Sopenharmony_ci builder_.Bind(&success); 2594514f5e3Sopenharmony_ci { 2604514f5e3Sopenharmony_ci GateRef ifFalse = builder_.GetState(); 2614514f5e3Sopenharmony_ci GateRef addr = builder_.PtrAdd(topAddress, addrOffset); 2624514f5e3Sopenharmony_ci builder_.StoreWithoutBarrier(VariableType::NATIVE_POINTER(), addr, newTop); 2634514f5e3Sopenharmony_ci GateRef store = builder_.GetDepend(); 2644514f5e3Sopenharmony_ci result = top; 2654514f5e3Sopenharmony_ci builder_.Jump(&exit); 2664514f5e3Sopenharmony_ci { 2674514f5e3Sopenharmony_ci GateRef ordinaryBlock = success.GetControl(); 2684514f5e3Sopenharmony_ci PrepareToScheduleNewGate(ordinaryBlock, successBBGates); 2694514f5e3Sopenharmony_ci PrepareToScheduleNewGate(store, successBBGates); 2704514f5e3Sopenharmony_ci PrepareToScheduleNewGate(addr, successBBGates); 2714514f5e3Sopenharmony_ci PrepareToScheduleNewGate(ifFalse, successBBGates); 2724514f5e3Sopenharmony_ci } 2734514f5e3Sopenharmony_ci } 2744514f5e3Sopenharmony_ci builder_.Bind(&callRuntime); 2754514f5e3Sopenharmony_ci { 2764514f5e3Sopenharmony_ci GateRef ifTrue = builder_.GetState(); 2774514f5e3Sopenharmony_ci GateRef taggedIntMask = circuit_->GetConstantGateWithoutCache( 2784514f5e3Sopenharmony_ci MachineType::I64, JSTaggedValue::TAG_INT, GateType::NJSValue()); 2794514f5e3Sopenharmony_ci GateRef taggedSize = builder_.Int64Or(size, taggedIntMask); 2804514f5e3Sopenharmony_ci GateRef target = Circuit::NullGate(); 2814514f5e3Sopenharmony_ci if (flag == RegionSpaceFlag::IN_SHARED_OLD_SPACE) { 2824514f5e3Sopenharmony_ci target = circuit_->GetConstantGateWithoutCache(MachineType::ARCH, RTSTUB_ID(AllocateInSOld), 2834514f5e3Sopenharmony_ci GateType::NJSValue()); 2844514f5e3Sopenharmony_ci } else if (flag == RegionSpaceFlag::IN_SHARED_NON_MOVABLE) { 2854514f5e3Sopenharmony_ci target = circuit_->GetConstantGateWithoutCache(MachineType::ARCH, RTSTUB_ID(AllocateInSNonMovable), 2864514f5e3Sopenharmony_ci GateType::NJSValue()); 2874514f5e3Sopenharmony_ci } else { 2884514f5e3Sopenharmony_ci ASSERT(flag == RegionSpaceFlag::IN_YOUNG_SPACE); 2894514f5e3Sopenharmony_ci target = circuit_->GetConstantGateWithoutCache(MachineType::ARCH, RTSTUB_ID(AllocateInYoung), 2904514f5e3Sopenharmony_ci GateType::NJSValue()); 2914514f5e3Sopenharmony_ci } 2924514f5e3Sopenharmony_ci const CallSignature *cs = RuntimeStubCSigns::Get(RTSTUB_ID(CallRuntime)); 2934514f5e3Sopenharmony_ci ASSERT(cs->IsRuntimeStub()); 2944514f5e3Sopenharmony_ci GateRef reseverdFrameArgs = circuit_->GetConstantGateWithoutCache(MachineType::I64, 0, GateType::NJSValue()); 2954514f5e3Sopenharmony_ci GateRef reseverdPc = circuit_->GetConstantGateWithoutCache(MachineType::I64, 0, GateType::NJSValue()); 2964514f5e3Sopenharmony_ci GateRef slowResult = builder_.Call(cs, glue, target, builder_.GetDepend(), 2974514f5e3Sopenharmony_ci { taggedSize, reseverdFrameArgs, reseverdPc }, Circuit::NullGate(), 2984514f5e3Sopenharmony_ci "Heap alloc"); 2994514f5e3Sopenharmony_ci result = slowResult; 3004514f5e3Sopenharmony_ci builder_.Jump(&exit); 3014514f5e3Sopenharmony_ci { 3024514f5e3Sopenharmony_ci GateRef ordinaryBlock = callRuntime.GetControl(); 3034514f5e3Sopenharmony_ci PrepareToScheduleNewGate(ordinaryBlock, failBBGates); 3044514f5e3Sopenharmony_ci PrepareToScheduleNewGate(slowResult, failBBGates); 3054514f5e3Sopenharmony_ci PrepareToScheduleNewGate(target, failBBGates); 3064514f5e3Sopenharmony_ci PrepareToScheduleNewGate(taggedSize, failBBGates); 3074514f5e3Sopenharmony_ci PrepareToScheduleNewGate(reseverdFrameArgs, failBBGates); 3084514f5e3Sopenharmony_ci PrepareToScheduleNewGate(reseverdPc, failBBGates); 3094514f5e3Sopenharmony_ci PrepareToScheduleNewGate(taggedIntMask, failBBGates); 3104514f5e3Sopenharmony_ci PrepareToScheduleNewGate(ifTrue, failBBGates); 3114514f5e3Sopenharmony_ci } 3124514f5e3Sopenharmony_ci } 3134514f5e3Sopenharmony_ci builder_.Bind(&exit); 3144514f5e3Sopenharmony_ci { 3154514f5e3Sopenharmony_ci GateRef merge = builder_.GetState(); 3164514f5e3Sopenharmony_ci GateRef phi = *result; 3174514f5e3Sopenharmony_ci PrepareToScheduleNewGate(merge, endBBGates); 3184514f5e3Sopenharmony_ci PrepareToScheduleNewGate(phi, endBBGates); 3194514f5e3Sopenharmony_ci } 3204514f5e3Sopenharmony_ci acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), *result); 3214514f5e3Sopenharmony_ci#endif 3224514f5e3Sopenharmony_ci} 3234514f5e3Sopenharmony_ci 3244514f5e3Sopenharmony_civoid PostSchedule::LoweringHeapAllocate(GateRef gate, 3254514f5e3Sopenharmony_ci std::vector<GateRef> ¤tBBGates, 3264514f5e3Sopenharmony_ci std::vector<GateRef> &successBBGates, 3274514f5e3Sopenharmony_ci std::vector<GateRef> &failBBGates, 3284514f5e3Sopenharmony_ci std::vector<GateRef> &endBBGates, 3294514f5e3Sopenharmony_ci int64_t flag) 3304514f5e3Sopenharmony_ci{ 3314514f5e3Sopenharmony_ci Environment env(gate, circuit_, &builder_); 3324514f5e3Sopenharmony_ci (void)successBBGates; 3334514f5e3Sopenharmony_ci (void)failBBGates; 3344514f5e3Sopenharmony_ci (void)endBBGates; 3354514f5e3Sopenharmony_ci GateRef glue = acc_.GetValueIn(gate, 0); 3364514f5e3Sopenharmony_ci GateRef size = acc_.GetValueIn(gate, 1); 3374514f5e3Sopenharmony_ci GateRef taggedIntMask = circuit_->GetConstantGateWithoutCache( 3384514f5e3Sopenharmony_ci MachineType::I64, JSTaggedValue::TAG_INT, GateType::NJSValue()); 3394514f5e3Sopenharmony_ci GateRef taggedSize = builder_.Int64Or(size, taggedIntMask); 3404514f5e3Sopenharmony_ci auto id = RTSTUB_ID(AllocateInYoung); 3414514f5e3Sopenharmony_ci if (flag == RegionSpaceFlag::IN_SHARED_OLD_SPACE) { 3424514f5e3Sopenharmony_ci id = RTSTUB_ID(AllocateInSOld); 3434514f5e3Sopenharmony_ci } else if (flag == RegionSpaceFlag::IN_SHARED_NON_MOVABLE) { 3444514f5e3Sopenharmony_ci id = RTSTUB_ID(AllocateInSNonMovable); 3454514f5e3Sopenharmony_ci } else if (flag == RegionSpaceFlag::IN_OLD_SPACE) { 3464514f5e3Sopenharmony_ci id = RTSTUB_ID(AllocateInOld); 3474514f5e3Sopenharmony_ci } else { 3484514f5e3Sopenharmony_ci ASSERT(flag == RegionSpaceFlag::IN_YOUNG_SPACE); 3494514f5e3Sopenharmony_ci } 3504514f5e3Sopenharmony_ci GateRef target = circuit_->GetConstantGateWithoutCache(MachineType::ARCH, id, GateType::NJSValue()); 3514514f5e3Sopenharmony_ci const CallSignature *cs = RuntimeStubCSigns::Get(RTSTUB_ID(CallRuntime)); 3524514f5e3Sopenharmony_ci ASSERT(cs->IsRuntimeStub()); 3534514f5e3Sopenharmony_ci GateRef reseverdFrameArgs = circuit_->GetConstantGateWithoutCache(MachineType::I64, 0, GateType::NJSValue()); 3544514f5e3Sopenharmony_ci GateRef reseverdPc = circuit_->GetConstantGateWithoutCache(MachineType::I64, 0, GateType::NJSValue()); 3554514f5e3Sopenharmony_ci GateRef result = builder_.Call(cs, glue, target, builder_.GetDepend(), 3564514f5e3Sopenharmony_ci { taggedSize, reseverdFrameArgs, reseverdPc }, Circuit::NullGate(), "Heap alloc"); 3574514f5e3Sopenharmony_ci acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), result); 3584514f5e3Sopenharmony_ci 3594514f5e3Sopenharmony_ci // Must keep the order of value-in/depend-in 3604514f5e3Sopenharmony_ci PrepareToScheduleNewGate(result, currentBBGates); 3614514f5e3Sopenharmony_ci PrepareToScheduleNewGate(target, currentBBGates); 3624514f5e3Sopenharmony_ci PrepareToScheduleNewGate(taggedSize, currentBBGates); 3634514f5e3Sopenharmony_ci PrepareToScheduleNewGate(reseverdFrameArgs, currentBBGates); 3644514f5e3Sopenharmony_ci PrepareToScheduleNewGate(reseverdPc, currentBBGates); 3654514f5e3Sopenharmony_ci PrepareToScheduleNewGate(taggedIntMask, currentBBGates); 3664514f5e3Sopenharmony_ci return; 3674514f5e3Sopenharmony_ci} 3684514f5e3Sopenharmony_ci 3694514f5e3Sopenharmony_cibool PostSchedule::VisitStore(GateRef gate, ControlFlowGraph &cfg, size_t bbIdx, size_t instIdx) 3704514f5e3Sopenharmony_ci{ 3714514f5e3Sopenharmony_ci std::vector<GateRef> currentBBGates; 3724514f5e3Sopenharmony_ci std::vector<GateRef> barrierBBGates; 3734514f5e3Sopenharmony_ci std::vector<GateRef> endBBGates; 3744514f5e3Sopenharmony_ci MemoryAttribute::Barrier kind = GetWriteBarrierKind(gate); 3754514f5e3Sopenharmony_ci switch (kind) { 3764514f5e3Sopenharmony_ci case MemoryAttribute::Barrier::UNKNOWN_BARRIER: { 3774514f5e3Sopenharmony_ci LoweringStoreUnknownBarrierAndPrepareScheduleGate(gate, currentBBGates, barrierBBGates, endBBGates); 3784514f5e3Sopenharmony_ci ReplaceBBState(cfg, bbIdx, currentBBGates, endBBGates); 3794514f5e3Sopenharmony_ci ScheduleEndBB(endBBGates, cfg, bbIdx, instIdx); 3804514f5e3Sopenharmony_ci ScheduleNewBB(barrierBBGates, cfg, bbIdx); 3814514f5e3Sopenharmony_ci ScheduleCurrentBB(currentBBGates, cfg, bbIdx, instIdx); 3824514f5e3Sopenharmony_ci return true; 3834514f5e3Sopenharmony_ci } 3844514f5e3Sopenharmony_ci case MemoryAttribute::Barrier::NEED_BARRIER: { 3854514f5e3Sopenharmony_ci LoweringStoreWithBarrierAndPrepareScheduleGate(gate, currentBBGates); 3864514f5e3Sopenharmony_ci ReplaceGateDirectly(currentBBGates, cfg, bbIdx, instIdx); 3874514f5e3Sopenharmony_ci return false; 3884514f5e3Sopenharmony_ci } 3894514f5e3Sopenharmony_ci case MemoryAttribute::Barrier::NO_BARRIER: { 3904514f5e3Sopenharmony_ci LoweringStoreNoBarrierAndPrepareScheduleGate(gate, currentBBGates); 3914514f5e3Sopenharmony_ci ReplaceGateDirectly(currentBBGates, cfg, bbIdx, instIdx); 3924514f5e3Sopenharmony_ci return false; 3934514f5e3Sopenharmony_ci } 3944514f5e3Sopenharmony_ci default: { 3954514f5e3Sopenharmony_ci UNREACHABLE(); 3964514f5e3Sopenharmony_ci return false; 3974514f5e3Sopenharmony_ci } 3984514f5e3Sopenharmony_ci } 3994514f5e3Sopenharmony_ci return false; 4004514f5e3Sopenharmony_ci} 4014514f5e3Sopenharmony_ci 4024514f5e3Sopenharmony_ciMemoryAttribute::Barrier PostSchedule::GetWriteBarrierKind(GateRef gate) 4034514f5e3Sopenharmony_ci{ 4044514f5e3Sopenharmony_ci MemoryAttribute mAttr = acc_.GetMemoryAttribute(gate); 4054514f5e3Sopenharmony_ci if (!acc_.IsGCRelated(gate)) { 4064514f5e3Sopenharmony_ci return MemoryAttribute::Barrier::NO_BARRIER; 4074514f5e3Sopenharmony_ci } 4084514f5e3Sopenharmony_ci return mAttr.GetBarrier(); 4094514f5e3Sopenharmony_ci} 4104514f5e3Sopenharmony_ci 4114514f5e3Sopenharmony_ciint PostSchedule::SelectBarrier(MemoryAttribute::ShareFlag share, const CallSignature*& cs, std::string_view& comment) 4124514f5e3Sopenharmony_ci{ 4134514f5e3Sopenharmony_ci int index = 0; 4144514f5e3Sopenharmony_ci switch (share) { 4154514f5e3Sopenharmony_ci case MemoryAttribute::UNKNOWN: 4164514f5e3Sopenharmony_ci if (fastBarrier_) { 4174514f5e3Sopenharmony_ci index = RuntimeStubCSigns::ID_ASMFastWriteBarrier; 4184514f5e3Sopenharmony_ci cs = RuntimeStubCSigns::Get(index); 4194514f5e3Sopenharmony_ci comment = "asm store barrier\0"; 4204514f5e3Sopenharmony_ci } else { 4214514f5e3Sopenharmony_ci index = CommonStubCSigns::SetValueWithBarrier; 4224514f5e3Sopenharmony_ci cs = CommonStubCSigns::Get(index); 4234514f5e3Sopenharmony_ci comment = "store barrier\0"; 4244514f5e3Sopenharmony_ci } 4254514f5e3Sopenharmony_ci break; 4264514f5e3Sopenharmony_ci case MemoryAttribute::SHARED: 4274514f5e3Sopenharmony_ci index = CommonStubCSigns::SetSValueWithBarrier; 4284514f5e3Sopenharmony_ci cs = CommonStubCSigns::Get(index); 4294514f5e3Sopenharmony_ci comment = "store share barrier\0"; 4304514f5e3Sopenharmony_ci break; 4314514f5e3Sopenharmony_ci case MemoryAttribute::NON_SHARE: 4324514f5e3Sopenharmony_ci index = CommonStubCSigns::SetNonSValueWithBarrier; 4334514f5e3Sopenharmony_ci cs = CommonStubCSigns::Get(index); 4344514f5e3Sopenharmony_ci comment = "store not share barrier\0"; 4354514f5e3Sopenharmony_ci break; 4364514f5e3Sopenharmony_ci default: 4374514f5e3Sopenharmony_ci UNREACHABLE(); 4384514f5e3Sopenharmony_ci } 4394514f5e3Sopenharmony_ci return index; 4404514f5e3Sopenharmony_ci} 4414514f5e3Sopenharmony_ci 4424514f5e3Sopenharmony_civoid PostSchedule::LoweringStoreNoBarrierAndPrepareScheduleGate(GateRef gate, std::vector<GateRef> ¤tBBGates) 4434514f5e3Sopenharmony_ci{ 4444514f5e3Sopenharmony_ci Environment env(gate, circuit_, &builder_); 4454514f5e3Sopenharmony_ci 4464514f5e3Sopenharmony_ci GateRef base = acc_.GetValueIn(gate, 1); // 1: object 4474514f5e3Sopenharmony_ci GateRef offset = acc_.GetValueIn(gate, 2); // 2: offset 4484514f5e3Sopenharmony_ci GateRef value = acc_.GetValueIn(gate, 3); // 3: value 4494514f5e3Sopenharmony_ci GateRef addr = builder_.PtrAdd(base, offset); 4504514f5e3Sopenharmony_ci VariableType type = VariableType(acc_.GetMachineType(gate), acc_.GetGateType(gate)); 4514514f5e3Sopenharmony_ci builder_.StoreWithoutBarrier(type, addr, value, acc_.GetMemoryAttribute(gate)); 4524514f5e3Sopenharmony_ci GateRef store = builder_.GetDepend(); 4534514f5e3Sopenharmony_ci { 4544514f5e3Sopenharmony_ci PrepareToScheduleNewGate(store, currentBBGates); 4554514f5e3Sopenharmony_ci PrepareToScheduleNewGate(addr, currentBBGates); 4564514f5e3Sopenharmony_ci } 4574514f5e3Sopenharmony_ci acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), Circuit::NullGate()); 4584514f5e3Sopenharmony_ci} 4594514f5e3Sopenharmony_ci 4604514f5e3Sopenharmony_ciMemoryAttribute::ShareFlag PostSchedule::GetShareKind(panda::ecmascript::kungfu::GateRef gate) 4614514f5e3Sopenharmony_ci{ 4624514f5e3Sopenharmony_ci MemoryAttribute mAttr = acc_.GetMemoryAttribute(gate); 4634514f5e3Sopenharmony_ci return mAttr.GetShare(); 4644514f5e3Sopenharmony_ci} 4654514f5e3Sopenharmony_ci 4664514f5e3Sopenharmony_civoid PostSchedule::LoweringStoreWithBarrierAndPrepareScheduleGate(GateRef gate, std::vector<GateRef> ¤tBBGates) 4674514f5e3Sopenharmony_ci{ 4684514f5e3Sopenharmony_ci Environment env(gate, circuit_, &builder_); 4694514f5e3Sopenharmony_ci 4704514f5e3Sopenharmony_ci GateRef glue = acc_.GetValueIn(gate, 0); 4714514f5e3Sopenharmony_ci GateRef base = acc_.GetValueIn(gate, 1); // 1: object 4724514f5e3Sopenharmony_ci GateRef offset = acc_.GetValueIn(gate, 2); // 2: offset 4734514f5e3Sopenharmony_ci GateRef value = acc_.GetValueIn(gate, 3); // 3: value 4744514f5e3Sopenharmony_ci GateRef addr = builder_.PtrAdd(base, offset); 4754514f5e3Sopenharmony_ci VariableType type = VariableType(acc_.GetMachineType(gate), acc_.GetGateType(gate)); 4764514f5e3Sopenharmony_ci builder_.StoreWithoutBarrier(type, addr, value, acc_.GetMemoryAttribute(gate)); 4774514f5e3Sopenharmony_ci GateRef store = builder_.GetDepend(); 4784514f5e3Sopenharmony_ci MemoryAttribute::ShareFlag share = GetShareKind(gate); 4794514f5e3Sopenharmony_ci std::string_view comment; 4804514f5e3Sopenharmony_ci int index; 4814514f5e3Sopenharmony_ci const CallSignature* cs = nullptr; 4824514f5e3Sopenharmony_ci index = SelectBarrier(share, cs, comment); 4834514f5e3Sopenharmony_ci ASSERT(cs && (cs->IsCommonStub() || cs->IsASMCallBarrierStub()) && "Invalid call signature for barrier"); 4844514f5e3Sopenharmony_ci GateRef target = circuit_->GetConstantGateWithoutCache(MachineType::ARCH, index, GateType::NJSValue()); 4854514f5e3Sopenharmony_ci GateRef reseverdFrameArgs = circuit_->GetConstantGateWithoutCache(MachineType::I64, 0, GateType::NJSValue()); 4864514f5e3Sopenharmony_ci GateRef reseverdPc = circuit_->GetConstantGateWithoutCache(MachineType::I64, 0, GateType::NJSValue()); 4874514f5e3Sopenharmony_ci GateRef storeBarrier = builder_.Call(cs, glue, target, builder_.GetDepend(), 4884514f5e3Sopenharmony_ci {glue, base, offset, value, reseverdFrameArgs, reseverdPc}, 4894514f5e3Sopenharmony_ci Circuit::NullGate(), comment.data()); 4904514f5e3Sopenharmony_ci { 4914514f5e3Sopenharmony_ci PrepareToScheduleNewGate(storeBarrier, currentBBGates); 4924514f5e3Sopenharmony_ci PrepareToScheduleNewGate(reseverdPc, currentBBGates); 4934514f5e3Sopenharmony_ci PrepareToScheduleNewGate(reseverdFrameArgs, currentBBGates); 4944514f5e3Sopenharmony_ci PrepareToScheduleNewGate(target, currentBBGates); 4954514f5e3Sopenharmony_ci PrepareToScheduleNewGate(store, currentBBGates); 4964514f5e3Sopenharmony_ci PrepareToScheduleNewGate(addr, currentBBGates); 4974514f5e3Sopenharmony_ci } 4984514f5e3Sopenharmony_ci acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), Circuit::NullGate()); 4994514f5e3Sopenharmony_ci} 5004514f5e3Sopenharmony_ci 5014514f5e3Sopenharmony_civoid PostSchedule::LoweringStoreUnknownBarrierAndPrepareScheduleGate(GateRef gate, 5024514f5e3Sopenharmony_ci std::vector<GateRef> ¤tBBGates, 5034514f5e3Sopenharmony_ci std::vector<GateRef> &barrierBBGates, 5044514f5e3Sopenharmony_ci std::vector<GateRef> &endBBGates) 5054514f5e3Sopenharmony_ci{ 5064514f5e3Sopenharmony_ci Environment env(gate, circuit_, &builder_); 5074514f5e3Sopenharmony_ci 5084514f5e3Sopenharmony_ci GateRef glue = acc_.GetValueIn(gate, 0); 5094514f5e3Sopenharmony_ci GateRef base = acc_.GetValueIn(gate, 1); // 1: object 5104514f5e3Sopenharmony_ci GateRef offset = acc_.GetValueIn(gate, 2); // 2: offset 5114514f5e3Sopenharmony_ci GateRef value = acc_.GetValueIn(gate, 3); // 3: value 5124514f5e3Sopenharmony_ci GateRef addr = builder_.PtrAdd(base, offset); 5134514f5e3Sopenharmony_ci VariableType type = VariableType(acc_.GetMachineType(gate), acc_.GetGateType(gate)); 5144514f5e3Sopenharmony_ci builder_.StoreWithoutBarrier(type, addr, value, acc_.GetMemoryAttribute(gate)); 5154514f5e3Sopenharmony_ci GateRef store = builder_.GetDepend(); 5164514f5e3Sopenharmony_ci 5174514f5e3Sopenharmony_ci GateRef intVal = builder_.ChangeTaggedPointerToInt64(value); 5184514f5e3Sopenharmony_ci GateRef objMask = circuit_->GetConstantGateWithoutCache( 5194514f5e3Sopenharmony_ci MachineType::I64, JSTaggedValue::TAG_HEAPOBJECT_MASK, GateType::NJSValue()); 5204514f5e3Sopenharmony_ci GateRef masked = builder_.Int64And(intVal, objMask, GateType::Empty(), "checkHeapObject"); 5214514f5e3Sopenharmony_ci GateRef falseVal = circuit_->GetConstantGateWithoutCache(MachineType::I64, 0, GateType::NJSValue()); 5224514f5e3Sopenharmony_ci GateRef condition = builder_.Equal(masked, falseVal, "checkHeapObject"); 5234514f5e3Sopenharmony_ci Label exit(&builder_); 5244514f5e3Sopenharmony_ci Label isHeapObject(&builder_); 5254514f5e3Sopenharmony_ci Label *currentLabel = env.GetCurrentLabel(); 5264514f5e3Sopenharmony_ci BRANCH_CIR(condition, &isHeapObject, &exit); 5274514f5e3Sopenharmony_ci { 5284514f5e3Sopenharmony_ci GateRef ifBranch = currentLabel->GetControl(); 5294514f5e3Sopenharmony_ci PrepareToScheduleNewGate(ifBranch, currentBBGates); 5304514f5e3Sopenharmony_ci PrepareToScheduleNewGate(condition, currentBBGates); 5314514f5e3Sopenharmony_ci PrepareToScheduleNewGate(falseVal, currentBBGates); 5324514f5e3Sopenharmony_ci PrepareToScheduleNewGate(masked, currentBBGates); 5334514f5e3Sopenharmony_ci PrepareToScheduleNewGate(intVal, currentBBGates); 5344514f5e3Sopenharmony_ci PrepareToScheduleNewGate(objMask, currentBBGates); 5354514f5e3Sopenharmony_ci PrepareToScheduleNewGate(store, currentBBGates); 5364514f5e3Sopenharmony_ci PrepareToScheduleNewGate(addr, currentBBGates); 5374514f5e3Sopenharmony_ci } 5384514f5e3Sopenharmony_ci GateRef ifTrue = isHeapObject.GetControl(); 5394514f5e3Sopenharmony_ci GateRef ifFalse = exit.GetControl(); 5404514f5e3Sopenharmony_ci builder_.Bind(&isHeapObject); 5414514f5e3Sopenharmony_ci { 5424514f5e3Sopenharmony_ci MemoryAttribute::ShareFlag share = GetShareKind(gate); 5434514f5e3Sopenharmony_ci std::string_view comment; 5444514f5e3Sopenharmony_ci int index; 5454514f5e3Sopenharmony_ci const CallSignature* cs = nullptr; 5464514f5e3Sopenharmony_ci index = SelectBarrier(share, cs, comment); 5474514f5e3Sopenharmony_ci ASSERT(cs && (cs->IsCommonStub() || cs->IsASMCallBarrierStub()) && "Invalid call signature for barrier"); 5484514f5e3Sopenharmony_ci GateRef target = circuit_->GetConstantGateWithoutCache(MachineType::ARCH, index, GateType::NJSValue()); 5494514f5e3Sopenharmony_ci GateRef reseverdFrameArgs = circuit_->GetConstantGateWithoutCache(MachineType::I64, 0, GateType::NJSValue()); 5504514f5e3Sopenharmony_ci GateRef reseverdPc = circuit_->GetConstantGateWithoutCache(MachineType::I64, 0, GateType::NJSValue()); 5514514f5e3Sopenharmony_ci#ifndef NDEBUG 5524514f5e3Sopenharmony_ci GateRef verifyTarget = circuit_->GetConstantGateWithoutCache(MachineType::ARCH, CommonStubCSigns::VerifyBarrier, 5534514f5e3Sopenharmony_ci GateType::NJSValue()); 5544514f5e3Sopenharmony_ci const CallSignature* verifyBarrierCs = CommonStubCSigns::Get(CommonStubCSigns::VerifyBarrier); 5554514f5e3Sopenharmony_ci GateRef verifyBarrier = builder_.Call(verifyBarrierCs, glue, verifyTarget, builder_.GetDepend(), 5564514f5e3Sopenharmony_ci {glue, base, offset, value, reseverdFrameArgs, reseverdPc}, 5574514f5e3Sopenharmony_ci Circuit::NullGate(), "verify barrier"); 5584514f5e3Sopenharmony_ci#endif 5594514f5e3Sopenharmony_ci GateRef storeBarrier = builder_.Call(cs, glue, target, builder_.GetDepend(), 5604514f5e3Sopenharmony_ci { glue, base, offset, value, reseverdFrameArgs, reseverdPc }, 5614514f5e3Sopenharmony_ci Circuit::NullGate(), comment.data()); 5624514f5e3Sopenharmony_ci builder_.Jump(&exit); 5634514f5e3Sopenharmony_ci { 5644514f5e3Sopenharmony_ci GateRef ordinaryBlock = isHeapObject.GetControl(); 5654514f5e3Sopenharmony_ci PrepareToScheduleNewGate(ordinaryBlock, barrierBBGates); 5664514f5e3Sopenharmony_ci PrepareToScheduleNewGate(storeBarrier, barrierBBGates); 5674514f5e3Sopenharmony_ci#ifndef NDEBUG 5684514f5e3Sopenharmony_ci PrepareToScheduleNewGate(verifyBarrier, barrierBBGates); 5694514f5e3Sopenharmony_ci#endif 5704514f5e3Sopenharmony_ci PrepareToScheduleNewGate(reseverdFrameArgs, barrierBBGates); 5714514f5e3Sopenharmony_ci PrepareToScheduleNewGate(reseverdPc, barrierBBGates); 5724514f5e3Sopenharmony_ci PrepareToScheduleNewGate(ifTrue, barrierBBGates); 5734514f5e3Sopenharmony_ci } 5744514f5e3Sopenharmony_ci } 5754514f5e3Sopenharmony_ci builder_.Bind(&exit); 5764514f5e3Sopenharmony_ci { 5774514f5e3Sopenharmony_ci GateRef merge = builder_.GetState(); 5784514f5e3Sopenharmony_ci PrepareToScheduleNewGate(merge, endBBGates); 5794514f5e3Sopenharmony_ci PrepareToScheduleNewGate(ifFalse, endBBGates); 5804514f5e3Sopenharmony_ci } 5814514f5e3Sopenharmony_ci acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), Circuit::NullGate()); 5824514f5e3Sopenharmony_ci} 5834514f5e3Sopenharmony_ci 5844514f5e3Sopenharmony_civoid PostSchedule::PrintGraph(const char* title, ControlFlowGraph &cfg) 5854514f5e3Sopenharmony_ci{ 5864514f5e3Sopenharmony_ci LOG_COMPILER(INFO) << "======================== " << title << " ========================"; 5874514f5e3Sopenharmony_ci for (size_t bbIdx = 0; bbIdx < cfg.size(); bbIdx++) { 5884514f5e3Sopenharmony_ci LOG_COMPILER(INFO) << "B" << bbIdx << ":"; 5894514f5e3Sopenharmony_ci const std::vector<GateRef>& bb = cfg.at(bbIdx); 5904514f5e3Sopenharmony_ci for (size_t instIdx = 0; instIdx < bb.size(); instIdx++) { 5914514f5e3Sopenharmony_ci GateRef gate = bb[instIdx]; 5924514f5e3Sopenharmony_ci acc_.Print(gate); 5934514f5e3Sopenharmony_ci } 5944514f5e3Sopenharmony_ci LOG_COMPILER(INFO) << ""; 5954514f5e3Sopenharmony_ci } 5964514f5e3Sopenharmony_ci} 5974514f5e3Sopenharmony_ci} // namespace panda::ecmascript::kungfu 598