• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 ECMASCRIPT_MEM_HEAP_VERIFICATION_H
17 #define ECMASCRIPT_MEM_HEAP_VERIFICATION_H
18 
19 #include <cstdint>
20 
21 #include "ecmascript/js_tagged_value.h"
22 #include "ecmascript/mem/heap.h"
23 #include "ecmascript/mem/object_xray.h"
24 #include "ecmascript/mem/mem.h"
25 #include "ecmascript/mem/slots.h"
26 
27 namespace panda::ecmascript {
28 static constexpr uint32_t INVALID_THRESHOLD = 0x40000;
29 
30 class VerifyScope {
31 public:
VerifyScope(BaseHeap * heap)32     VerifyScope(BaseHeap *heap) : heap_(heap)
33     {
34         heap_->SetVerifying(true);
35     }
36 
~VerifyScope()37     ~VerifyScope()
38     {
39         heap_->SetVerifying(false);
40     }
41 private:
42     BaseHeap *heap_ {nullptr};
43 };
44 
45 // Verify the object body
46 // NOLINTNEXTLINE(cppcoreguidelines-special-member-functions, hicpp-special-member-functions)
47 class VerifyObjectVisitor {
48 public:
49     // Only used for verify InactiveSemiSpace
50     static void VerifyInactiveSemiSpaceMarkedObject(const BaseHeap *heap, void *addr);
51 
52     VerifyObjectVisitor(const BaseHeap *heap, size_t *failCount,
53                         VerifyKind verifyKind = VerifyKind::VERIFY_PRE_GC)
heap_(heap)54         : heap_(heap), failCount_(failCount), verifyKind_(verifyKind)
55     {
56     }
57     ~VerifyObjectVisitor() = default;
58 
operator()59     void operator()(TaggedObject *obj)
60     {
61         VisitAllObjects(obj);
62     }
63 
64     void operator()(TaggedObject *obj, JSTaggedValue value);
65 
GetFailedCount()66     size_t GetFailedCount() const
67     {
68         return *failCount_;
69     }
70 
71 private:
72     void VisitAllObjects(TaggedObject *obj);
73     void VerifyObjectSlotLegal(ObjectSlot slot, TaggedObject *obj) const;
74     void VerifyHeapObjectSlotLegal(ObjectSlot slot, JSTaggedValue value, TaggedObject *obj) const;
75     void VerifyMarkYoung(TaggedObject *obj, ObjectSlot slot, TaggedObject *value) const;
76     void VerifyEvacuateYoung(TaggedObject *obj, ObjectSlot slot, TaggedObject *value) const;
77     void VerifyMarkFull(TaggedObject *obj, ObjectSlot slot, TaggedObject *value) const;
78     void VerifyEvacuateOld(TaggedObject *obj, ObjectSlot slot, TaggedObject *value) const;
79     void VerifyEvacuateFull(TaggedObject *obj, ObjectSlot slot, TaggedObject *value) const;
80     void VerifySharedRSetPostFullGC(TaggedObject *obj, ObjectSlot slot, TaggedObject *value) const;
81     void VerifySharedObjectReference(TaggedObject *obj, ObjectSlot slot, TaggedObject *value) const;
82 
83     const BaseHeap* const heap_ {nullptr};
84     size_t* const failCount_ {nullptr};
85     VerifyKind verifyKind_;
86 };
87 
88 class Verification {
89 public:
90     explicit Verification(Heap *heap, VerifyKind verifyKind = VerifyKind::VERIFY_PRE_GC)
heap_(heap)91         : heap_(heap), verifyKind_(verifyKind) {}
92     ~Verification() = default;
93 
94     static void VerifyMark(Heap *heap);
95     static void VerifyEvacuate(Heap *heap);
96     void VerifyAll() const;
97 
98     size_t VerifyRoot() const;
99     size_t VerifyHeap() const;
100     size_t VerifyOldToNewRSet() const;
101 private:
102     class VerificationRootVisitor final : public RootVisitor {
103     public:
VerificationRootVisitor(const Verification * verification,size_t & failCount)104         explicit VerificationRootVisitor(const Verification *verification, size_t &failCount)
105             : verification_(verification), failCount_(failCount) {}
106         ~VerificationRootVisitor() = default;
107 
108         void VisitRoot([[maybe_unused]] Root type, ObjectSlot slot) override;
109         void VisitRangeRoot([[maybe_unused]] Root type, ObjectSlot start, ObjectSlot end) override;
110         void VisitBaseAndDerivedRoot([[maybe_unused]] Root type, ObjectSlot base, ObjectSlot derived,
111                                      uintptr_t baseOldObject) override;
112     private:
113         const Verification *verification_;
114         size_t &failCount_;
115     };
116 
117     void VerifyObjectSlot(const ObjectSlot &slot, size_t *failCount) const;
118 
119     NO_COPY_SEMANTIC(Verification);
120     NO_MOVE_SEMANTIC(Verification);
121 
122     Heap *heap_ {nullptr};
123     VerifyKind verifyKind_;
124 };
125 
126 class SharedHeapVerification {
127 public:
SharedHeapVerification(SharedHeap * heap,VerifyKind verifyKind)128     explicit SharedHeapVerification(SharedHeap *heap, VerifyKind verifyKind)
129         : sHeap_(heap), verifyKind_(verifyKind) {}
130     ~SharedHeapVerification() = default;
131 
132     void VerifyAll() const;
133     void VerifyMark(bool cm) const;
134     void VerifySweep(bool cm) const;
135 
136     size_t VerifyRoot() const;
137     size_t VerifyHeap() const;
138 private:
139     class VerificationRootVisitor final : public RootVisitor {
140     public:
VerificationRootVisitor(const SharedHeapVerification * sVerification,size_t & failCount)141         explicit VerificationRootVisitor(const SharedHeapVerification *sVerification, size_t &failCount)
142             : sVerification_(sVerification), failCount_(failCount) {}
143         ~VerificationRootVisitor() = default;
144 
145         void VisitRoot([[maybe_unused]] Root type, ObjectSlot slot) override;
146         void VisitRangeRoot([[maybe_unused]] Root type, ObjectSlot start, ObjectSlot end) override;
147         void VisitBaseAndDerivedRoot([[maybe_unused]] Root type, ObjectSlot base, ObjectSlot derived,
148                                      uintptr_t baseOldObject) override;
149     private:
150         const SharedHeapVerification *sVerification_;
151         size_t &failCount_;
152     };
153 
154     class VerificationSerializeRootVisitor final : public RootVisitor {
155     public:
VerificationSerializeRootVisitor(SharedHeap * sHeap,size_t & failCount)156         explicit VerificationSerializeRootVisitor(SharedHeap *sHeap, size_t &failCount)
157             : sHeap_(sHeap), failCount_(failCount) {}
158         ~VerificationSerializeRootVisitor() = default;
159 
160         void VisitRoot([[maybe_unused]] Root type, ObjectSlot slot) override;
161         void VisitRangeRoot([[maybe_unused]] Root type, ObjectSlot start, ObjectSlot end) override;
162         void VisitBaseAndDerivedRoot([[maybe_unused]] Root type, ObjectSlot base, ObjectSlot derived,
163                                      uintptr_t baseOldObject) override;
164     private:
165         SharedHeap *sHeap_;
166         size_t &failCount_;
167     };
168 
169     void VerifyObjectSlot(const ObjectSlot &slot, size_t *failCount) const;
170 
171     NO_COPY_SEMANTIC(SharedHeapVerification);
172     NO_MOVE_SEMANTIC(SharedHeapVerification);
173 
174     SharedHeap *sHeap_ {nullptr};
175     VerifyKind verifyKind_;
176 };
177 
178 template <class Callback>
179 class VerifyVisitor final : public EcmaObjectRangeVisitor<VerifyVisitor<Callback>> {
180 public:
VerifyVisitor(Callback & cb)181     explicit VerifyVisitor(Callback &cb) : cb_(cb) {}
182     ~VerifyVisitor() = default;
VisitObjectRangeImpl(TaggedObject * root,ObjectSlot start,ObjectSlot end,VisitObjectArea area)183     void VisitObjectRangeImpl(TaggedObject *root, ObjectSlot start, ObjectSlot end, VisitObjectArea area) override
184     {
185         if (UNLIKELY(area == VisitObjectArea::IN_OBJECT)) {
186             auto hclass = root->GetClass();
187             ASSERT(!hclass->IsAllTaggedProp());
188             int index = 0;
189             for (ObjectSlot slot = start; slot < end; slot++) {
190                 auto layout = LayoutInfo::Cast(hclass->GetLayout().GetTaggedObject());
191                 auto attr = layout->GetAttr(index++);
192                 if (attr.IsTaggedRep()) {
193                     cb_(slot, root);
194                 }
195             }
196             return;
197         }
198         for (ObjectSlot slot = start; slot < end; slot++) {
199             cb_(slot, root);
200         }
201     }
202 private:
203     Callback &cb_;
204 };
205 }  // namespace panda::ecmascript
206 
207 #endif  // ECMASCRIPT_MEM_HEAP_VERIFICATION_H
208