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