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