GCC Code Coverage Report


Directory: ./
File: src/utilities/object.cpp
Date: 2023-04-27 00:55:30
Exec Total Coverage
Lines: 42 52 80.8%
Functions: 7 11 63.6%
Branches: 35 51 68.6%

Line Branch Exec Source
1 #include "object.h"
2 #include "logging/logging.h"
3
4 namespace lython {
5
6 void GCObject::remove_child(GCObject* child, bool dofree) {
7
8 439 GCObject* result = nullptr;
9 439 int i = int(children.size()) - 1;
10
11
1/2
✓ Branch 0 taken 1018 times.
✗ Branch 1 not taken.
1018 for (; i >= 0; i--) {
12
2/2
✓ Branch 1 taken 439 times.
✓ Branch 2 taken 579 times.
1018 if (children[i] == child) {
13 439 break;
14 }
15 }
16
17 // FIXME: this should never happen
18
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 439 times.
439 if (i == -1) {
19 kwerror("Trying to remove (child: {}) from (parent: {}), (child->parent: {});"
20 "but the child was not found",
21 (void*)child,
22 (void*)this,
23 (void*)child->parent);
24 return;
25 } else {
26 kwinfo("Removed (child: {}) from (parent: {})", (void*)child, (void*)this);
27 }
28 // assert(i != -1, "Should find child");
29
30 439 Array<GCObject*>::iterator data = children.begin() + i;
31
1/1
✓ Branch 2 taken 439 times.
439 children.erase(data);
32 439 child->parent = nullptr;
33
34 /*
35 auto elem = std::find(children.rbegin(), children.rend(), child);
36 assert(elem == children.rend(), "Should be a child");
37 // This is why people hate C++
38 //
39 // This removes the element found by the reverse iterator.
40 // Reverse iterator do not point to the found element
41 // but the element before it.
42 // erase is not specialized to take reverse iterator
43 // so we need to convert ifreet ourselves and KNOW that this is what is
44 // expected but nobody could have guessed that
45 auto n = children.size();
46 auto found = std::next(elem).base();
47
48 assert(*found == child, "Child should match");
49 children.erase(found);
50 assert(n > children.size(), "Child was not removed");
51 */
52
53
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 439 times.
439 if (dofree) {
54 free(child);
55 }
56 }
57
58 void GCObject::remove_child_if_parent(GCObject* child, bool dofree) {
59 if (child->parent == this) {
60 remove_child(child, dofree);
61 }
62 }
63
64 void GCObject::dump(std::ostream& out) {
65 88 Array<GCObject*> visited;
66
67
1/1
✓ Branch 1 taken 88 times.
88 dump_recursive(out, visited, -1, 0);
68 88 }
69
70 int in(GCObject* obj, Array<GCObject*>& visited) {
71 480 int i = 0;
72
73
2/2
✓ Branch 4 taken 3317 times.
✓ Branch 5 taken 480 times.
3797 for (auto* item: visited) {
74
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3317 times.
3317 if (item == obj)
75 return true;
76
77 3317 i += 1;
78 }
79
80 480 return -1;
81 }
82
83 void GCObject::dump_recursive(std::ostream& out, Array<GCObject*>& visited, int prev, int depth) {
84 // Cycles should be impossible here
85
1/2
✓ Branch 0 taken 568 times.
✗ Branch 1 not taken.
568 int index = prev < 0 ? int(visited.size()) : prev;
86
2/3
✗ Branch 1 not taken.
✓ Branch 2 taken 568 times.
✓ Branch 4 taken 568 times.
568 String warning = prev >= 0 ? "DUPLICATE" : "";
87
88
7/7
✓ Branch 2 taken 568 times.
✓ Branch 5 taken 568 times.
✓ Branch 8 taken 568 times.
✓ Branch 11 taken 568 times.
✓ Branch 14 taken 568 times.
✓ Branch 17 taken 568 times.
✓ Branch 20 taken 568 times.
1136 out << String(depth * 2, ' ') << index << ". " << meta::type_name(class_id) << warning
89
1/1
✓ Branch 1 taken 568 times.
568 << std::endl;
90
91
2/2
✓ Branch 5 taken 480 times.
✓ Branch 6 taken 568 times.
1048 for (auto obj: children) {
92 480 int found = in(obj, visited);
93
94
1/2
✓ Branch 0 taken 480 times.
✗ Branch 1 not taken.
480 if (found < 0) {
95
1/1
✓ Branch 1 taken 480 times.
480 visited.push_back(obj);
96 }
97
98
1/1
✓ Branch 1 taken 480 times.
480 obj->dump_recursive(out, visited, found, depth + 1);
99 }
100 568 }
101
102 void GCObject::private_free(GCObject* child) {
103 9801 int cclass_id = child->class_id;
104
105 9801 child->~GCObject();
106
107 9801 manual_free(cclass_id, 1);
108 9801 device::CPU().free((void*)child, 1);
109 9801 }
110
111 void GCObject::free(GCObject* child) {
112 // Remove from parent right away
113 if (child->parent != nullptr) {
114 child->parent->remove_child(child, false);
115 assert(child->parent == nullptr, "parent should be null");
116 }
117
118 private_free(child);
119 }
120
121 GCObject::~GCObject() {
122 COZ_BEGIN("T::GCObject::delete");
123
124 // free children
125 22836 int n = int(children.size());
126
127
2/2
✓ Branch 0 taken 9801 times.
✓ Branch 1 taken 11418 times.
42438 while (n > 0) {
128 19602 n -= 1;
129
130 19602 GCObject* obj = children[n];
131 19602 obj->parent = nullptr;
132 19602 children.pop_back();
133
134 19602 private_free(obj);
135 }
136
137 COZ_PROGRESS_NAMED("GCObject::delete");
138 COZ_END("T::GCObject::delete");
139
140
7/10
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 11403 times.
✓ Branch 3 taken 15 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 15 times.
✓ Branch 11 taken 15 times.
✓ Branch 15 taken 15 times.
✓ Branch 18 taken 15 times.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
34254 assert(children.size() == 0,
141 "Makes sure nobody added more nodes while we were busy destroying them");
142 22836 }
143
144 } // namespace lython
145