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> &currentBBGates,
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> &currentBBGates,
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> &currentBBGates,
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> &currentBBGates)
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> &currentBBGates)
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> &currentBBGates,
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