• 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 #include "verification.h"
17 
18 #include "ecmascript/js_tagged_value-inl.h"
19 #include "ecmascript/mem/slots.h"
20 #include "ecmascript/mem/visitor.h"
21 
22 namespace panda::ecmascript {
23 // Verify the object body
VisitAllObjects(TaggedObject * obj)24 void VerifyObjectVisitor::VisitAllObjects(TaggedObject *obj)
25 {
26     auto jsHclass = obj->GetClass();
27     objXRay_.VisitObjectBody<VisitType::OLD_GC_VISIT>(
28         obj, jsHclass, [this]([[maybe_unused]] TaggedObject *root, ObjectSlot start, ObjectSlot end,
29                               [[maybe_unused]] bool isNative) {
30             for (ObjectSlot slot = start; slot < end; slot++) {
31                 JSTaggedValue value(slot.GetTaggedType());
32                 if (value.IsWeak()) {
33                     if (!heap_->IsAlive(value.GetTaggedWeakRef())) {
34                         LOG_GC(ERROR) << "Heap verify detected a dead weak object " << value.GetTaggedObject()
35                                             << " at object:" << slot.SlotAddress();
36                         ++(*failCount_);
37                     }
38                 } else if (value.IsHeapObject()) {
39                     if (!heap_->IsAlive(value.GetTaggedObject())) {
40                         LOG_GC(ERROR) << "Heap verify detected a dead object at " << value.GetTaggedObject()
41                                             << " at object:" << slot.SlotAddress();
42                         ++(*failCount_);
43                     }
44                 }
45             }
46         });
47 }
48 
operator ()(TaggedObject * obj,JSTaggedValue value)49 void VerifyObjectVisitor::operator()(TaggedObject *obj, JSTaggedValue value)
50 {
51     ObjectSlot slot(reinterpret_cast<uintptr_t>(obj));
52     if (!value.IsHeapObject()) {
53         LOG_GC(DEBUG) << "Heap object(" << slot.SlotAddress() << ") old to new rset fail: value is "
54                       << slot.GetTaggedType();
55         return;
56     }
57 
58     TaggedObject *object = value.GetRawTaggedObject();
59     auto region = Region::ObjectAddressToRange(object);
60     if (!region->InYoungSpace()) {
61         LOG_GC(ERROR) << "Heap object(" << slot.GetTaggedType() << ") old to new rset fail: value("
62                       << slot.GetTaggedObject() << "/"
63                       << JSHClass::DumpJSType(slot.GetTaggedObject()->GetClass()->GetObjectType())
64                       << ")" << " in " << region->GetSpaceTypeName();
65         ++(*failCount_);
66     }
67 }
68 
VerifyRoot() const69 size_t Verification::VerifyRoot() const
70 {
71     size_t failCount = 0;
72     RootVisitor visitor = [this, &failCount]([[maybe_unused]] Root type, ObjectSlot slot) {
73         VerifyObjectSlot(slot, &failCount);
74     };
75     RootRangeVisitor rangeVisitor = [this, &failCount]([[maybe_unused]] Root type, ObjectSlot start, ObjectSlot end) {
76         for (ObjectSlot slot = start; slot < end; slot++) {
77             VerifyObjectSlot(slot, &failCount);
78         }
79     };
80     RootBaseAndDerivedVisitor derivedVisitor =
81         []([[maybe_unused]] Root type, [[maybe_unused]] ObjectSlot base, [[maybe_unused]] ObjectSlot derived,
82            [[maybe_unused]] uintptr_t baseOldObject) {
83     };
84     objXRay_.VisitVMRoots(visitor, rangeVisitor, derivedVisitor);
85     if (failCount > 0) {
86         LOG_GC(ERROR) << "VerifyRoot detects deadObject count is " << failCount;
87     }
88 
89     return failCount;
90 }
91 
VerifyHeap() const92 size_t Verification::VerifyHeap() const
93 {
94     size_t failCount = heap_->VerifyHeapObjects();
95     if (failCount > 0) {
96         LOG_GC(ERROR) << "VerifyHeap detects deadObject count is " << failCount;
97     }
98     return failCount;
99 }
100 
VerifyOldToNewRSet() const101 size_t Verification::VerifyOldToNewRSet() const
102 {
103     size_t failCount = heap_->VerifyOldToNewRSet();
104     if (failCount > 0) {
105         LOG_GC(ERROR) << "VerifyOldToNewRSet detects non new space count is " << failCount;
106     }
107     return failCount;
108 }
109 
VerifyObjectSlot(const ObjectSlot & slot,size_t * failCount) const110 void Verification::VerifyObjectSlot(const ObjectSlot &slot, size_t *failCount) const
111 {
112     JSTaggedValue value(slot.GetTaggedType());
113     if (value.IsWeak()) {
114         VerifyObjectVisitor(heap_, failCount)(value.GetTaggedWeakRef());
115     } else if (value.IsHeapObject()) {
116         VerifyObjectVisitor(heap_, failCount)(value.GetTaggedObject());
117     }
118 }
119 }  // namespace panda::ecmascript
120