• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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