• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2021-2022 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 #ifndef PANDA_MEM_HEAP_VERIFIER_H
16 #define PANDA_MEM_HEAP_VERIFIER_H
17 
18 #include "libpandabase/utils/bit_utils.h"
19 #include "libpandabase/utils/logger.h"
20 #include "runtime/mem/object_helpers.h"
21 #include "runtime/mem/rendezvous.h"
22 
23 namespace panda::mem {
24 
25 class HeapManager;
26 class GCRoot;
27 
28 /**
29  * HeapReferenceVerifier checks reference checks if the referent is with the heap and it is live.
30  */
31 template <LangTypeT LangType = LANG_TYPE_STATIC>
32 class HeapReferenceVerifier {
33 public:
HeapReferenceVerifier(HeapManager * heap,size_t * count)34     explicit HeapReferenceVerifier(HeapManager *heap, size_t *count) : HEAP(heap), FAIL_COUNT(count) {}
35 
36     void operator()(ObjectHeader *object_header, ObjectHeader *referent);
37 
38     void operator()(const GCRoot &root);
39 
40 private:
41     HeapManager *const HEAP {nullptr};
42     size_t *const FAIL_COUNT {nullptr};
43 };
44 
45 /**
46  * HeapObjectVerifier iterates over HeapManager's allocated objects. If an object contains reference, it checks if the
47  * referent is with the heap and it is live.
48  */
49 template <LangTypeT LangType = LANG_TYPE_STATIC>
50 class HeapObjectVerifier {
51 public:
52     HeapObjectVerifier() = delete;
53 
HeapObjectVerifier(HeapManager * heap,size_t * count)54     HeapObjectVerifier(HeapManager *heap, size_t *count) : HEAP(heap), FAIL_COUNT(count) {}
55 
56     void operator()(ObjectHeader *obj);
57 
GetFailCount()58     size_t GetFailCount() const
59     {
60         return *FAIL_COUNT;
61     }
62 
63 private:
64     HeapManager *const HEAP {nullptr};
65     size_t *const FAIL_COUNT {nullptr};
66 };
67 
68 class HeapVerifierBase {
69 public:
HeapVerifierBase(HeapManager * heap)70     explicit HeapVerifierBase(HeapManager *heap) : heap_(heap) {}
71     DEFAULT_COPY_SEMANTIC(HeapVerifierBase);
72     DEFAULT_MOVE_SEMANTIC(HeapVerifierBase);
73     ~HeapVerifierBase() = default;
74 
75 protected:
76     HeapManager *heap_ = nullptr;  // NOLINT(misc-non-private-member-variables-in-classes)
77 };
78 
79 /**
80  * A class to query address validity.
81  */
82 template <class LanguageConfig>
83 class HeapVerifier : public HeapVerifierBase {
84 public:
HeapVerifier(HeapManager * heap)85     explicit HeapVerifier(HeapManager *heap) : HeapVerifierBase(heap) {}
86     DEFAULT_COPY_SEMANTIC(HeapVerifier);
87     DEFAULT_MOVE_SEMANTIC(HeapVerifier);
88     ~HeapVerifier() = default;
89 
90     bool IsValidObjectAddress(void *addr) const;
91 
92     bool IsHeapAddress(void *addr) const;
93 
94     size_t VerifyRoot() const;
95 
96     size_t VerifyHeap() const;
97 
VerifyAll()98     size_t VerifyAll() const
99     {
100         return VerifyRoot() + VerifyHeap();
101     }
102 
103     size_t VerifyAllPaused() const;
104 };
105 
106 /**
107  * Fast heap verifier for check heap and stack
108  */
109 template <class LanguageConfig>
110 class FastHeapVerifier : public HeapVerifierBase {
111 public:
FastHeapVerifier(HeapManager * heap)112     explicit FastHeapVerifier(HeapManager *heap) : HeapVerifierBase(heap) {}
113     DEFAULT_COPY_SEMANTIC(FastHeapVerifier);
114     DEFAULT_MOVE_SEMANTIC(FastHeapVerifier);
115     ~FastHeapVerifier() = default;
116 
117     size_t VerifyAll() const;
118 
119 private:
120     struct ObjectCache {
121         const ObjectHeader *heap_object;
122         const ObjectHeader *referent;
123     };
124 };
125 
126 class ObjectVerificationInfo {
127 public:
128     explicit ObjectVerificationInfo(ObjectHeader *referent);
129     DEFAULT_COPY_SEMANTIC(ObjectVerificationInfo);
130     DEFAULT_NOEXCEPT_MOVE_SEMANTIC(ObjectVerificationInfo);
131     ~ObjectVerificationInfo() = default;
132 
133     /**
134      * Check that updated reference \p updated_ref from \p object has same state as before
135      * collecting and refs updating
136      *
137      * @param object the object which contains verifying reference
138      * @param updated_ref new referent position after moving
139      * @param in_alive_space whether the object places in space which was not moved (region promotion, for example)
140      * @return true if reference is correct and false otherwise
141      */
142     bool VerifyUpdatedRef(ObjectHeader *object, ObjectHeader *updated_ref, bool in_alive_space) const;
143 
144 private:
145     void *class_address_ = nullptr;
146     ObjectHeader *old_address_ = nullptr;
147 };
148 
149 template <class LanguageConfig>
150 class HeapVerifierIntoGC : public HeapVerifierBase {
151 public:
HeapVerifierIntoGC(HeapManager * heap)152     explicit HeapVerifierIntoGC(HeapManager *heap) : HeapVerifierBase(heap) {}
153     DEFAULT_COPY_SEMANTIC(HeapVerifierIntoGC);
154     DEFAULT_MOVE_SEMANTIC(HeapVerifierIntoGC);
155     ~HeapVerifierIntoGC() = default;
156 
157     void CollectVerificationInfo(PandaVector<MemRange> &&collectable_mem_ranges);
158 
159     size_t VerifyAll(PandaVector<MemRange> &&alive_mem_ranges = PandaVector<MemRange>());
160 
161 private:
162     using VerifyingRefs = PandaUnorderedMap<size_t, ObjectVerificationInfo>;
163     using RefsVerificationInfo = PandaUnorderedMap<ObjectHeader *, VerifyingRefs>;
164 
165     bool InCollectableSpace(const ObjectHeader *object) const;
166     bool InAliveSpace(const ObjectHeader *object) const;
167     void AddToVerificationInfo(RefsVerificationInfo &verification_info, size_t ref_number, ObjectHeader *object_header,
168                                ObjectHeader *referent);
169 
170     RefsVerificationInfo collectable_verification_info_;
171     RefsVerificationInfo permanent_verification_info_;
172     PandaVector<MemRange> collectable_mem_ranges_;
173     PandaVector<MemRange> alive_mem_ranges_;
174 };
175 }  // namespace panda::mem
176 
177 #endif  // PANDA_MEM_HEAP_VERIFIER_H
178