14514f5e3Sopenharmony_ci/*
24514f5e3Sopenharmony_ci * Copyright (c) 2021 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#include "ecmascript/mem/incremental_marker.h"
164514f5e3Sopenharmony_ci#include "ecmascript/mem/parallel_marker-inl.h"
174514f5e3Sopenharmony_ci
184514f5e3Sopenharmony_cinamespace panda::ecmascript {
194514f5e3Sopenharmony_ciMarker::Marker(Heap *heap) : heap_(heap), workManager_(heap->GetWorkManager()) {}
204514f5e3Sopenharmony_ci
214514f5e3Sopenharmony_civoid Marker::MarkRoots(uint32_t threadId, VMRootVisitType type)
224514f5e3Sopenharmony_ci{
234514f5e3Sopenharmony_ci    TRACE_GC(GCStats::Scope::ScopeId::MarkRoots, heap_->GetEcmaVM()->GetEcmaGCStats());
244514f5e3Sopenharmony_ci    ECMA_BYTRACE_NAME(HITRACE_TAG_ARK, "GC::MarkRoots");
254514f5e3Sopenharmony_ci    ObjectXRay::VisitVMRoots(
264514f5e3Sopenharmony_ci        heap_->GetEcmaVM(),
274514f5e3Sopenharmony_ci        [this, threadId](Root type, ObjectSlot slot) {this->HandleRoots(threadId, type, slot);},
284514f5e3Sopenharmony_ci        [this, threadId](Root type, ObjectSlot start, ObjectSlot end) {
294514f5e3Sopenharmony_ci            this->HandleRangeRoots(threadId, type, start, end);
304514f5e3Sopenharmony_ci        },
314514f5e3Sopenharmony_ci        [this](Root type, ObjectSlot base, ObjectSlot derived, uintptr_t baseOldObject) {
324514f5e3Sopenharmony_ci            this->HandleDerivedRoots(type, base, derived, baseOldObject);
334514f5e3Sopenharmony_ci        }, type);
344514f5e3Sopenharmony_ci    workManager_->PushWorkNodeToGlobal(threadId, false);
354514f5e3Sopenharmony_ci}
364514f5e3Sopenharmony_ci
374514f5e3Sopenharmony_civoid Marker::ProcessNewToEden(uint32_t threadId)
384514f5e3Sopenharmony_ci{
394514f5e3Sopenharmony_ci    heap_->EnumerateNewSpaceRegions([this, threadId](Region *region) {this->HandleNewToEdenRSet(threadId, region);});
404514f5e3Sopenharmony_ci    ProcessMarkStack(threadId);
414514f5e3Sopenharmony_ci}
424514f5e3Sopenharmony_ci
434514f5e3Sopenharmony_civoid Marker::ProcessNewToEdenNoMarkStack(uint32_t threadId)
444514f5e3Sopenharmony_ci{
454514f5e3Sopenharmony_ci    heap_->EnumerateNewSpaceRegions([this, threadId](Region *region) {this->HandleNewToEdenRSet(threadId, region);});
464514f5e3Sopenharmony_ci}
474514f5e3Sopenharmony_ci
484514f5e3Sopenharmony_civoid Marker::ProcessOldToNew(uint32_t threadId)
494514f5e3Sopenharmony_ci{
504514f5e3Sopenharmony_ci    heap_->EnumerateOldSpaceRegions([this, threadId](Region *region) {
514514f5e3Sopenharmony_ci        this->HandleOldToNewRSet(threadId, region);
524514f5e3Sopenharmony_ci    });
534514f5e3Sopenharmony_ci    ProcessMarkStack(threadId);
544514f5e3Sopenharmony_ci}
554514f5e3Sopenharmony_ci
564514f5e3Sopenharmony_civoid Marker::ProcessOldToNewNoMarkStack(uint32_t threadId)
574514f5e3Sopenharmony_ci{
584514f5e3Sopenharmony_ci    heap_->EnumerateOldSpaceRegions([this, threadId](Region *region) {
594514f5e3Sopenharmony_ci        this->HandleOldToNewRSet(threadId, region);
604514f5e3Sopenharmony_ci    });
614514f5e3Sopenharmony_ci}
624514f5e3Sopenharmony_ci
634514f5e3Sopenharmony_civoid Marker::ProcessOldToNew(uint32_t threadId, Region *region)
644514f5e3Sopenharmony_ci{
654514f5e3Sopenharmony_ci    heap_->EnumerateOldSpaceRegions([this, threadId](Region *region) {
664514f5e3Sopenharmony_ci        this->HandleOldToNewRSet(threadId, region);
674514f5e3Sopenharmony_ci        }, region);
684514f5e3Sopenharmony_ci    ProcessMarkStack(threadId);
694514f5e3Sopenharmony_ci}
704514f5e3Sopenharmony_ci
714514f5e3Sopenharmony_civoid Marker::ProcessSnapshotRSet(uint32_t threadId)
724514f5e3Sopenharmony_ci{
734514f5e3Sopenharmony_ci    heap_->EnumerateSnapshotSpaceRegions([this, threadId](Region *region) {
744514f5e3Sopenharmony_ci        this->HandleOldToNewRSet(threadId, region);
754514f5e3Sopenharmony_ci    });
764514f5e3Sopenharmony_ci    ProcessMarkStack(threadId);
774514f5e3Sopenharmony_ci}
784514f5e3Sopenharmony_ci
794514f5e3Sopenharmony_civoid Marker::ProcessSnapshotRSetNoMarkStack(uint32_t threadId)
804514f5e3Sopenharmony_ci{
814514f5e3Sopenharmony_ci    heap_->EnumerateSnapshotSpaceRegions([this, threadId](Region *region) {
824514f5e3Sopenharmony_ci        this->HandleOldToNewRSet(threadId, region);
834514f5e3Sopenharmony_ci    });
844514f5e3Sopenharmony_ci}
854514f5e3Sopenharmony_ci
864514f5e3Sopenharmony_civoid NonMovableMarker::MarkJitCodeMap(uint32_t threadId)
874514f5e3Sopenharmony_ci{
884514f5e3Sopenharmony_ci    // To keep MachineCode objects alive (for dump) before JsError object be free, we have to know which JsError is
894514f5e3Sopenharmony_ci    // alive first. So this method must be call after all other mark work finish.
904514f5e3Sopenharmony_ci    TRACE_GC(GCStats::Scope::ScopeId::MarkRoots, heap_->GetEcmaVM()->GetEcmaGCStats());
914514f5e3Sopenharmony_ci    ECMA_BYTRACE_NAME(HITRACE_TAG_ARK, "GC::MarkJitCodeMap");
924514f5e3Sopenharmony_ci    if (!heap_->IsFullMark()) {
934514f5e3Sopenharmony_ci        return;
944514f5e3Sopenharmony_ci    }
954514f5e3Sopenharmony_ci    JitCodeMapVisitor visitor = [this, threadId](std::map<JSTaggedType, JitCodeVector *> &jitCodeMaps) {
964514f5e3Sopenharmony_ci        auto it = jitCodeMaps.begin();
974514f5e3Sopenharmony_ci        while (it != jitCodeMaps.end()) {
984514f5e3Sopenharmony_ci            JSTaggedType jsError = it->first;
994514f5e3Sopenharmony_ci            Region *objectRegion = Region::ObjectAddressToRange(reinterpret_cast<TaggedObject *>(jsError));
1004514f5e3Sopenharmony_ci            if (!objectRegion->Test(reinterpret_cast<TaggedObject *>(jsError))) {
1014514f5e3Sopenharmony_ci                ++it;
1024514f5e3Sopenharmony_ci                continue;
1034514f5e3Sopenharmony_ci            }
1044514f5e3Sopenharmony_ci            for (auto &jitCodeMap : *(it->second)) {
1054514f5e3Sopenharmony_ci                auto &jitCode = std::get<0>(jitCodeMap);
1064514f5e3Sopenharmony_ci                MarkObject(threadId, jitCode);
1074514f5e3Sopenharmony_ci            }
1084514f5e3Sopenharmony_ci            ++it;
1094514f5e3Sopenharmony_ci        }
1104514f5e3Sopenharmony_ci    };
1114514f5e3Sopenharmony_ci    ObjectXRay::VisitJitCodeMap(heap_->GetEcmaVM(), visitor);
1124514f5e3Sopenharmony_ci    ProcessMarkStack(threadId);
1134514f5e3Sopenharmony_ci    heap_->WaitRunningTaskFinished();
1144514f5e3Sopenharmony_ci}
1154514f5e3Sopenharmony_ci
1164514f5e3Sopenharmony_civoid NonMovableMarker::ProcessMarkStack(uint32_t threadId)
1174514f5e3Sopenharmony_ci{
1184514f5e3Sopenharmony_ci    bool isFullMark = heap_->IsConcurrentFullMark();
1194514f5e3Sopenharmony_ci    auto cb = [&](ObjectSlot s, Region *rootRegion, bool needBarrier) {
1204514f5e3Sopenharmony_ci        MarkValue(threadId, s, rootRegion, needBarrier);
1214514f5e3Sopenharmony_ci    };
1224514f5e3Sopenharmony_ci    EcmaObjectRangeVisitor visitor = [this, threadId, isFullMark, cb](TaggedObject *root, ObjectSlot start,
1234514f5e3Sopenharmony_ci                                                                      ObjectSlot end, VisitObjectArea area) {
1244514f5e3Sopenharmony_ci        Region *rootRegion = Region::ObjectAddressToRange(root);
1254514f5e3Sopenharmony_ci        bool needBarrier = isFullMark && !rootRegion->InGeneralNewSpaceOrCSet();
1264514f5e3Sopenharmony_ci        if (area == VisitObjectArea::IN_OBJECT) {
1274514f5e3Sopenharmony_ci            if (VisitBodyInObj(root, start, end, needBarrier, cb)) {
1284514f5e3Sopenharmony_ci                return;
1294514f5e3Sopenharmony_ci            }
1304514f5e3Sopenharmony_ci        }
1314514f5e3Sopenharmony_ci        for (ObjectSlot slot = start; slot < end; slot++) {
1324514f5e3Sopenharmony_ci            MarkValue(threadId, slot, rootRegion, needBarrier);
1334514f5e3Sopenharmony_ci        }
1344514f5e3Sopenharmony_ci    };
1354514f5e3Sopenharmony_ci    SemiSpace *newSpace = heap_->GetNewSpace();
1364514f5e3Sopenharmony_ci    TaggedObject *obj = nullptr;
1374514f5e3Sopenharmony_ci    while (workManager_->Pop(threadId, &obj)) {
1384514f5e3Sopenharmony_ci        Region *region = Region::ObjectAddressToRange(obj);
1394514f5e3Sopenharmony_ci        if (region->IsHalfFreshRegion()) {
1404514f5e3Sopenharmony_ci            ASSERT(region->InYoungSpace());
1414514f5e3Sopenharmony_ci            if (newSpace->IsFreshObjectInHalfFreshRegion(obj)) {
1424514f5e3Sopenharmony_ci                // Fresh object do not need to visit body.
1434514f5e3Sopenharmony_ci                continue;
1444514f5e3Sopenharmony_ci            }
1454514f5e3Sopenharmony_ci        }
1464514f5e3Sopenharmony_ci
1474514f5e3Sopenharmony_ci        JSHClass *jsHclass = obj->SynchronizedGetClass();
1484514f5e3Sopenharmony_ci        ASSERT(!region->IsFreshRegion());
1494514f5e3Sopenharmony_ci        auto size = jsHclass->SizeFromJSHClass(obj);
1504514f5e3Sopenharmony_ci        region->IncreaseAliveObjectSafe(size);
1514514f5e3Sopenharmony_ci        MarkObject(threadId, jsHclass);
1524514f5e3Sopenharmony_ci        ObjectXRay::VisitObjectBody<VisitType::OLD_GC_VISIT>(obj, jsHclass, visitor);
1534514f5e3Sopenharmony_ci    }
1544514f5e3Sopenharmony_ci}
1554514f5e3Sopenharmony_ci
1564514f5e3Sopenharmony_civoid NonMovableMarker::ProcessIncrementalMarkStack(uint32_t threadId, uint32_t markStepSize)
1574514f5e3Sopenharmony_ci{
1584514f5e3Sopenharmony_ci    bool isFullMark = heap_->IsConcurrentFullMark();
1594514f5e3Sopenharmony_ci    uint32_t visitAddrNum = 0;
1604514f5e3Sopenharmony_ci    auto cb = [&](ObjectSlot s, Region *rootRegion, bool needBarrier) {
1614514f5e3Sopenharmony_ci        MarkValue(threadId, s, rootRegion, needBarrier);
1624514f5e3Sopenharmony_ci    };
1634514f5e3Sopenharmony_ci    EcmaObjectRangeVisitor visitor = [this, threadId, isFullMark, &visitAddrNum, cb](TaggedObject *root,
1644514f5e3Sopenharmony_ci                                                                                     ObjectSlot start,
1654514f5e3Sopenharmony_ci                                                                                     ObjectSlot end,
1664514f5e3Sopenharmony_ci                                                                                     VisitObjectArea area) {
1674514f5e3Sopenharmony_ci        Region *rootRegion = Region::ObjectAddressToRange(root);
1684514f5e3Sopenharmony_ci        visitAddrNum += end.SlotAddress() - start.SlotAddress();
1694514f5e3Sopenharmony_ci        bool needBarrier = isFullMark && !rootRegion->InGeneralNewSpaceOrCSet();
1704514f5e3Sopenharmony_ci        if (area == VisitObjectArea::IN_OBJECT) {
1714514f5e3Sopenharmony_ci            if (VisitBodyInObj(root, start, end, needBarrier, cb)) {
1724514f5e3Sopenharmony_ci                return;
1734514f5e3Sopenharmony_ci            }
1744514f5e3Sopenharmony_ci        }
1754514f5e3Sopenharmony_ci        for (ObjectSlot slot = start; slot < end; slot++) {
1764514f5e3Sopenharmony_ci            MarkValue(threadId, slot, rootRegion, needBarrier);
1774514f5e3Sopenharmony_ci        }
1784514f5e3Sopenharmony_ci    };
1794514f5e3Sopenharmony_ci    TaggedObject *obj = nullptr;
1804514f5e3Sopenharmony_ci    double startTime = heap_->GetIncrementalMarker()->GetCurrentTimeInMs();
1814514f5e3Sopenharmony_ci    double costTime = startTime;
1824514f5e3Sopenharmony_ci    while (workManager_->Pop(threadId, &obj)) {
1834514f5e3Sopenharmony_ci        JSHClass *jsHclass = obj->GetClass();
1844514f5e3Sopenharmony_ci        Region *region = Region::ObjectAddressToRange(obj);
1854514f5e3Sopenharmony_ci        auto size = jsHclass->SizeFromJSHClass(obj);
1864514f5e3Sopenharmony_ci        region->IncreaseAliveObjectSafe(size);
1874514f5e3Sopenharmony_ci        MarkObject(threadId, jsHclass);
1884514f5e3Sopenharmony_ci        ObjectXRay::VisitObjectBody<VisitType::OLD_GC_VISIT>(obj, jsHclass, visitor);
1894514f5e3Sopenharmony_ci        if (heap_->GetIncrementalMarker()->IsTriggeredIncrementalMark() && visitAddrNum >= markStepSize) {
1904514f5e3Sopenharmony_ci            costTime = heap_->GetIncrementalMarker()->GetCurrentTimeInMs() - startTime;
1914514f5e3Sopenharmony_ci            heap_->GetIncrementalMarker()->UpdateMarkingSpeed(visitAddrNum, costTime);
1924514f5e3Sopenharmony_ci            return;
1934514f5e3Sopenharmony_ci        }
1944514f5e3Sopenharmony_ci    }
1954514f5e3Sopenharmony_ci    if (heap_->GetJSThread()->IsMarking() && heap_->GetIncrementalMarker()->IsTriggeredIncrementalMark()) {
1964514f5e3Sopenharmony_ci        costTime = heap_->GetIncrementalMarker()->GetCurrentTimeInMs() - startTime;
1974514f5e3Sopenharmony_ci        heap_->GetIncrementalMarker()->UpdateMarkingSpeed(visitAddrNum, costTime);
1984514f5e3Sopenharmony_ci        heap_->GetIncrementalMarker()->SetMarkingFinished(true);
1994514f5e3Sopenharmony_ci    }
2004514f5e3Sopenharmony_ci}
2014514f5e3Sopenharmony_ci
2024514f5e3Sopenharmony_civoid SemiGCMarker::Initialize()
2034514f5e3Sopenharmony_ci{
2044514f5e3Sopenharmony_ci    waterLine_ = heap_->GetNewSpace()->GetWaterLine();
2054514f5e3Sopenharmony_ci}
2064514f5e3Sopenharmony_ci
2074514f5e3Sopenharmony_civoid SemiGCMarker::ProcessMarkStack(uint32_t threadId)
2084514f5e3Sopenharmony_ci{
2094514f5e3Sopenharmony_ci    auto cb = [&](ObjectSlot s, TaggedObject *root) { MarkValue(threadId, root, s); };
2104514f5e3Sopenharmony_ci    EcmaObjectRangeVisitor visitor = [this, threadId, cb](TaggedObject *root, ObjectSlot start,
2114514f5e3Sopenharmony_ci                                                          ObjectSlot end, VisitObjectArea area) {
2124514f5e3Sopenharmony_ci        if (area == VisitObjectArea::IN_OBJECT) {
2134514f5e3Sopenharmony_ci            if (VisitBodyInObj(root, start, end, cb)) {
2144514f5e3Sopenharmony_ci                return;
2154514f5e3Sopenharmony_ci            }
2164514f5e3Sopenharmony_ci        }
2174514f5e3Sopenharmony_ci        for (ObjectSlot slot = start; slot < end; slot++) {
2184514f5e3Sopenharmony_ci            MarkValue(threadId, root, slot);
2194514f5e3Sopenharmony_ci        }
2204514f5e3Sopenharmony_ci    };
2214514f5e3Sopenharmony_ci    TaggedObject *obj = nullptr;
2224514f5e3Sopenharmony_ci    while (workManager_->Pop(threadId, &obj)) {
2234514f5e3Sopenharmony_ci        auto jsHclass = obj->GetClass();
2244514f5e3Sopenharmony_ci        ObjectXRay::VisitObjectBody<VisitType::SEMI_GC_VISIT>(obj, jsHclass, visitor);
2254514f5e3Sopenharmony_ci    }
2264514f5e3Sopenharmony_ci}
2274514f5e3Sopenharmony_ci
2284514f5e3Sopenharmony_civoid CompressGCMarker::ProcessMarkStack(uint32_t threadId)
2294514f5e3Sopenharmony_ci{
2304514f5e3Sopenharmony_ci    auto cb = [&](ObjectSlot s, [[maybe_unused]] TaggedObject *root) { MarkValue(threadId, s); };
2314514f5e3Sopenharmony_ci    EcmaObjectRangeVisitor visitor = [this, threadId, cb](TaggedObject *root, ObjectSlot start,
2324514f5e3Sopenharmony_ci                                                          ObjectSlot end, VisitObjectArea area) {
2334514f5e3Sopenharmony_ci        if (area == VisitObjectArea::IN_OBJECT) {
2344514f5e3Sopenharmony_ci            if (VisitBodyInObj(root, start, end, cb)) {
2354514f5e3Sopenharmony_ci                return;
2364514f5e3Sopenharmony_ci            }
2374514f5e3Sopenharmony_ci        }
2384514f5e3Sopenharmony_ci        for (ObjectSlot slot = start; slot < end; slot++) {
2394514f5e3Sopenharmony_ci            MarkValue(threadId, slot);
2404514f5e3Sopenharmony_ci        }
2414514f5e3Sopenharmony_ci    };
2424514f5e3Sopenharmony_ci    TaggedObject *obj = nullptr;
2434514f5e3Sopenharmony_ci    while (workManager_->Pop(threadId, &obj)) {
2444514f5e3Sopenharmony_ci        auto jsHClass = obj->GetClass();
2454514f5e3Sopenharmony_ci        ObjectSlot objectSlot(ToUintPtr(obj));
2464514f5e3Sopenharmony_ci        MarkObject(threadId, jsHClass, objectSlot);
2474514f5e3Sopenharmony_ci        ObjectXRay::VisitObjectBody<VisitType::OLD_GC_VISIT>(obj, jsHClass, visitor);
2484514f5e3Sopenharmony_ci    }
2494514f5e3Sopenharmony_ci}
2504514f5e3Sopenharmony_ci
2514514f5e3Sopenharmony_civoid CompressGCMarker::MarkJitCodeMap(uint32_t threadId)
2524514f5e3Sopenharmony_ci{
2534514f5e3Sopenharmony_ci    // To keep MachineCode objects alive (for dump) before JsError object be free, we have to know which JsError is
2544514f5e3Sopenharmony_ci    // alive first. So this method must be call after all other mark work finish.
2554514f5e3Sopenharmony_ci    TRACE_GC(GCStats::Scope::ScopeId::MarkRoots, heap_->GetEcmaVM()->GetEcmaGCStats());
2564514f5e3Sopenharmony_ci    ECMA_BYTRACE_NAME(HITRACE_TAG_ARK, "GC::MarkJitCodeMap");
2574514f5e3Sopenharmony_ci    ObjectXRay::VisitJitCodeMap(heap_->GetEcmaVM(),
2584514f5e3Sopenharmony_ci        [this, threadId](std::map<JSTaggedType, JitCodeVector *> &jitCodeMaps) {
2594514f5e3Sopenharmony_ci            this->HandleVisitJitCodeMap(threadId, jitCodeMaps);
2604514f5e3Sopenharmony_ci        });
2614514f5e3Sopenharmony_ci    ProcessMarkStack(threadId);
2624514f5e3Sopenharmony_ci    heap_->WaitRunningTaskFinished();
2634514f5e3Sopenharmony_ci}
2644514f5e3Sopenharmony_ci
2654514f5e3Sopenharmony_civoid CompressGCMarker::HandleVisitJitCodeMap(uint32_t threadId, std::map<JSTaggedType, JitCodeVector *> &jitCodeMaps)
2664514f5e3Sopenharmony_ci{
2674514f5e3Sopenharmony_ci    auto it = jitCodeMaps.begin();
2684514f5e3Sopenharmony_ci    while (it != jitCodeMaps.end()) {
2694514f5e3Sopenharmony_ci        JSTaggedType jsError = it->first;
2704514f5e3Sopenharmony_ci        auto jsErrorObj = reinterpret_cast<TaggedObject *>(jsError);
2714514f5e3Sopenharmony_ci        Region *objectRegion = Region::ObjectAddressToRange(jsErrorObj);
2724514f5e3Sopenharmony_ci        auto jitCodeVec = it->second;
2734514f5e3Sopenharmony_ci        if (!NeedEvacuate(objectRegion)) {
2744514f5e3Sopenharmony_ci            if (!objectRegion->InSharedHeap() && !objectRegion->Test(jsErrorObj)) {
2754514f5e3Sopenharmony_ci                delete it->second;
2764514f5e3Sopenharmony_ci                it = jitCodeMaps.erase(it);
2774514f5e3Sopenharmony_ci                continue;
2784514f5e3Sopenharmony_ci            }
2794514f5e3Sopenharmony_ci        } else {
2804514f5e3Sopenharmony_ci            MarkWord markWord(jsErrorObj);
2814514f5e3Sopenharmony_ci            if (markWord.IsForwardingAddress()) {
2824514f5e3Sopenharmony_ci                TaggedObject *dst = markWord.ToForwardingAddress();
2834514f5e3Sopenharmony_ci                jitCodeMaps.emplace(JSTaggedValue(dst).GetRawData(), it->second);
2844514f5e3Sopenharmony_ci                it = jitCodeMaps.erase(it);
2854514f5e3Sopenharmony_ci            } else {
2864514f5e3Sopenharmony_ci                delete it->second;
2874514f5e3Sopenharmony_ci                it = jitCodeMaps.erase(it);
2884514f5e3Sopenharmony_ci                continue;
2894514f5e3Sopenharmony_ci            }
2904514f5e3Sopenharmony_ci        }
2914514f5e3Sopenharmony_ci        for (auto &jitCodeMap : *jitCodeVec) {
2924514f5e3Sopenharmony_ci            auto &jitCode = std::get<0>(jitCodeMap);
2934514f5e3Sopenharmony_ci            auto obj = static_cast<TaggedObject *>(jitCode);
2944514f5e3Sopenharmony_ci            // jitcode is MachineCode, and MachineCode is in the MachineCode space, will not be evacute.
2954514f5e3Sopenharmony_ci            MarkObject(threadId, obj, ObjectSlot(reinterpret_cast<uintptr_t>(&jitCode)));
2964514f5e3Sopenharmony_ci        }
2974514f5e3Sopenharmony_ci        ++it;
2984514f5e3Sopenharmony_ci    }
2994514f5e3Sopenharmony_ci}
3004514f5e3Sopenharmony_ci
3014514f5e3Sopenharmony_ciuintptr_t CompressGCMarker::AllocateForwardAddress(uint32_t threadId, size_t size, JSHClass *hclass,
3024514f5e3Sopenharmony_ci                                                   TaggedObject *object)
3034514f5e3Sopenharmony_ci{
3044514f5e3Sopenharmony_ci    if (!isAppSpawn_) {
3054514f5e3Sopenharmony_ci        bool isPromoted = true;
3064514f5e3Sopenharmony_ci        return AllocateDstSpace(threadId, size, isPromoted);
3074514f5e3Sopenharmony_ci    }
3084514f5e3Sopenharmony_ci    if (Heap::ShouldMoveToRoSpace(hclass, object)) {
3094514f5e3Sopenharmony_ci        return AllocateReadOnlySpace(size);
3104514f5e3Sopenharmony_ci    } else {
3114514f5e3Sopenharmony_ci        return AllocateAppSpawnSpace(size);
3124514f5e3Sopenharmony_ci    }
3134514f5e3Sopenharmony_ci}
3144514f5e3Sopenharmony_ci}  // namespace panda::ecmascript
315