1 /* 2 * Copyright (c) 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 #ifndef COMMON_COMPONENTS_HEAP_COLLECTOR_REGION_BITMAP_H 17 #define COMMON_COMPONENTS_HEAP_COLLECTOR_REGION_BITMAP_H 18 19 #include "common_components/base/immortal_wrapper.h" 20 #include "common_components/base/mem_utils.h" 21 #include "common_components/base/sys_call.h" 22 #include "common_components/heap/heap.h" 23 #if defined(__linux__) || defined(PANDA_TARGET_OHOS) || defined(__APPLE__) 24 #include <sys/mman.h> 25 #endif 26 27 namespace common { 28 static constexpr size_t kBitsPerByte = 8; 29 static constexpr size_t kMarkedBytesPerBit = 8; 30 static constexpr size_t kBitsPerWord = sizeof(uint64_t) * kBitsPerByte; 31 static constexpr size_t kBytesPerWord = sizeof(uint64_t) / sizeof(uint8_t); 32 struct RegionBitmap { 33 static constexpr uint8_t factor = 16; 34 std::atomic<uint16_t> partLiveBytes[factor]; 35 std::atomic<size_t> liveBytes; 36 37 // 1 bit marks 8 bytes in region, 64 bits per word. 38 // word count = region size / (8 * 64) = region size / 512, should be dynamically decided at runtime. 39 std::atomic<size_t> wordCnt; 40 std::atomic<uint64_t> markWords[0]; 41 GetRegionBitmapSizeRegionBitmap42 static size_t GetRegionBitmapSize(size_t regionSize) 43 { 44 CHECK_CC(regionSize % (kMarkedBytesPerBit * kBitsPerWord) == 0); 45 return sizeof(RegionBitmap) + ((regionSize / (kMarkedBytesPerBit * kBitsPerWord)) * sizeof(uint64_t)); 46 } 47 RegionBitmapRegionBitmap48 explicit RegionBitmap(size_t regionSize) : liveBytes(0), wordCnt(regionSize / (kMarkedBytesPerBit * kBitsPerWord)) 49 {} 50 MarkBitsRegionBitmap51 bool MarkBits(size_t start) 52 { 53 size_t headWordIdx = (start / kMarkedBytesPerBit) / kBitsPerWord; 54 size_t headMaskBitStart = (start / kMarkedBytesPerBit) % kBitsPerWord; 55 uint64_t headMaskBits = static_cast<uint64_t>(1) << headMaskBitStart; 56 uint64_t old = markWords[headWordIdx].load(); 57 bool isMarked = ((old & headMaskBits) != 0); 58 if (!isMarked) { 59 old = markWords[headWordIdx].fetch_or(headMaskBits); 60 isMarked = ((old & headMaskBits) != 0); 61 return isMarked; 62 } 63 return isMarked; 64 } 65 IsMarkedRegionBitmap66 bool IsMarked(size_t start) 67 { 68 size_t headWordIdx = (start / kMarkedBytesPerBit) / kBitsPerWord; 69 size_t headMaskBitStart = (start / kMarkedBytesPerBit) % kBitsPerWord; 70 uint64_t mask = static_cast<uint64_t>(1) << headMaskBitStart; 71 bool ret = ((markWords[headWordIdx].load() & mask) != 0); 72 return ret; 73 } 74 }; 75 } // namespace common 76 77 #endif // COMMON_COMPONENTS_HEAP_COLLECTOR_REGION_BITMAP_H 78