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