1 /* 2 * Copyright (c) 2021-2025 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #include "ecmascript/dfx/hprof/heap_marker.h" 17 18 namespace panda::ecmascript { Mark(JSTaggedType addr)19bool HeapMarker::Mark(JSTaggedType addr) 20 { 21 if (g_isEnableCMCGC) { 22 return CMCMark(addr); 23 } 24 25 auto index = (addr & DEFAULT_REGION_MASK) >> TAGGED_TYPE_SIZE_LOG; 26 Region *region = Region::ObjectAddressToRange(addr); 27 auto it = regionBitsetMap_.find(region); 28 if (it != regionBitsetMap_.end()) { 29 if (it->second.test(index)) { 30 return false; 31 } 32 it->second.set(index); 33 ++count_; 34 return true; 35 } 36 37 std::bitset<BITSET_SIZE> bitset; 38 bitset.set(index); 39 ++count_; 40 regionBitsetMap_.emplace(region, bitset); 41 return true; 42 } 43 CMCMark(JSTaggedType addr)44bool HeapMarker::CMCMark(JSTaggedType addr) 45 { 46 auto index = (addr & common::RegionDesc::DEFAULT_REGION_UNIT_MASK) >> TAGGED_TYPE_SIZE_LOG; 47 JSTaggedType region = addr & ~common::RegionDesc::DEFAULT_REGION_UNIT_MASK; 48 auto it = cmcRegionBitsetMap_.find(region); 49 if (it != cmcRegionBitsetMap_.end()) { 50 if (it->second.test(index)) { 51 return false; 52 } 53 it->second.set(index); 54 ++count_; 55 return true; 56 } 57 58 std::bitset<CMC_BITSET_SIZE> bitset; 59 bitset.set(index); 60 ++count_; 61 cmcRegionBitsetMap_.emplace(region, bitset); 62 return true; 63 } 64 IsMarked(JSTaggedType addr)65bool HeapMarker::IsMarked(JSTaggedType addr) 66 { 67 if (g_isEnableCMCGC) { 68 return IsCMCMarked(addr); 69 } 70 auto index = (addr & DEFAULT_REGION_MASK) >> TAGGED_TYPE_SIZE_LOG; 71 Region *region = Region::ObjectAddressToRange(addr); 72 auto bitsetIt = regionBitsetMap_.find(region); 73 if (bitsetIt != regionBitsetMap_.end() && bitsetIt->second.test(index)) { 74 return true; 75 } 76 return false; 77 } 78 IsCMCMarked(JSTaggedType addr)79bool HeapMarker::IsCMCMarked(JSTaggedType addr) 80 { 81 auto index = (addr & common::RegionDesc::DEFAULT_REGION_UNIT_MASK) >> TAGGED_TYPE_SIZE_LOG; 82 JSTaggedType region = 83 reinterpret_cast<JSTaggedType>(common::RegionDesc::InlinedRegionMetaData::GetInlinedRegionMetaData(addr)); 84 auto bitsetIt = cmcRegionBitsetMap_.find(region); 85 if (bitsetIt != cmcRegionBitsetMap_.end() && bitsetIt->second.test(index)) { 86 return true; 87 } 88 return false; 89 } 90 Clear()91void HeapMarker::Clear() 92 { 93 if (g_isEnableCMCGC) { 94 cmcRegionBitsetMap_.clear(); 95 } 96 regionBitsetMap_.clear(); 97 } 98 IterateMarked(const std::function<void (JSTaggedType)> & cb)99void HeapMarker::IterateMarked(const std::function<void(JSTaggedType)> &cb) 100 { 101 if (g_isEnableCMCGC) { 102 IterateCMCMarked(cb); 103 return; 104 } 105 106 for (const auto &[region, bitset] : regionBitsetMap_) { 107 for (size_t index = 0; index < bitset.size(); ++index) { 108 if (bitset.test(index)) { 109 JSTaggedType addr = reinterpret_cast<JSTaggedType>(region) + (index << TAGGED_TYPE_SIZE_LOG); 110 cb(addr); 111 } 112 } 113 } 114 } 115 IterateCMCMarked(const std::function<void (JSTaggedType)> & cb)116void HeapMarker::IterateCMCMarked(const std::function<void(JSTaggedType)> &cb) 117 { 118 for (const auto &[region, bitset] : cmcRegionBitsetMap_) { 119 for (size_t index = 0; index < bitset.size(); ++index) { 120 if (bitset.test(index)) { 121 JSTaggedType addr = reinterpret_cast<JSTaggedType>(region) + (index << TAGGED_TYPE_SIZE_LOG); 122 cb(addr); 123 } 124 } 125 } 126 } 127 } // namespace panda::ecmascript