Skip to content

Commit 66ea2cb

Browse files
committed
TypeGraph: Add Node IDs to non-leaf types
These aren't used for anything yet, but should be useful for stable IDs when printing nodes before and after passes and for faster cycle detection than the current map of pointers.
1 parent 8805480 commit 66ea2cb

19 files changed

+286
-234
lines changed

oi/type_graph/AddPadding.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,13 +98,12 @@ void AddPadding::addPadding(const Member& prevMember,
9898

9999
if (paddingBits % 8 == 0) {
100100
// Pad with an array of bytes
101-
auto* primitive = typeGraph_.make_type<Primitive>(Primitive::Kind::Int8);
102-
auto* paddingArray =
103-
typeGraph_.make_type<Array>(primitive, paddingBits / 8);
101+
auto* primitive = typeGraph_.makeType<Primitive>(Primitive::Kind::Int8);
102+
auto* paddingArray = typeGraph_.makeType<Array>(primitive, paddingBits / 8);
104103
paddedMembers.emplace_back(paddingArray, MemberPrefix, prevMemberEndBits);
105104
} else {
106105
// Pad with a bitfield
107-
auto* primitive = typeGraph_.make_type<Primitive>(Primitive::Kind::Int64);
106+
auto* primitive = typeGraph_.makeType<Primitive>(Primitive::Kind::Int64);
108107
paddedMembers.emplace_back(primitive, MemberPrefix, prevMemberEndBits,
109108
paddingBits);
110109
}

oi/type_graph/DrgnParser.cpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ Type* DrgnParser::enumerateType(struct drgn_type* type) {
8686
return it->second;
8787

8888
if (!drgn_utils::isSizeComplete(type)) {
89-
return make_type<Primitive>(nullptr, Primitive::Kind::Void);
89+
return makeType<Primitive>(nullptr, Primitive::Kind::Void);
9090
}
9191

9292
enum drgn_type_kind kind = drgn_type_kind(type);
@@ -135,7 +135,7 @@ Container* DrgnParser::enumerateContainer(struct drgn_type* type,
135135

136136
VLOG(2) << "Matching container `" << containerInfo.typeName << "` from `"
137137
<< fqName << "`" << std::endl;
138-
auto* c = make_type<Container>(type, containerInfo, size);
138+
auto* c = makeType<Container>(type, containerInfo, size);
139139
enumerateClassTemplateParams(type, c->templateParams);
140140
return c;
141141
}
@@ -183,8 +183,8 @@ Type* DrgnParser::enumerateClass(struct drgn_type* type) {
183183
std::to_string(drgn_type_kind(type))};
184184
}
185185

186-
auto c = make_type<Class>(type, kind, std::move(name), std::move(fqName),
187-
size, virtuality);
186+
auto c = makeType<Class>(type, kind, std::move(name), std::move(fqName), size,
187+
virtuality);
188188

189189
enumerateClassTemplateParams(type, c->templateParams);
190190
enumerateClassParents(type, c->parents);
@@ -417,7 +417,7 @@ Enum* DrgnParser::enumerateEnum(struct drgn_type* type) {
417417
std::string name = drgn_type_tag(type);
418418
uint64_t size = get_drgn_type_size(type);
419419
;
420-
return make_type<Enum>(type, name, size);
420+
return makeType<Enum>(type, name, size);
421421
}
422422

423423
Typedef* DrgnParser::enumerateTypedef(struct drgn_type* type) {
@@ -426,28 +426,28 @@ Typedef* DrgnParser::enumerateTypedef(struct drgn_type* type) {
426426

427427
struct drgn_type* underlyingType = drgn_type_type(type).type;
428428
auto t = enumerateType(underlyingType);
429-
return make_type<Typedef>(type, name, t);
429+
return makeType<Typedef>(type, name, t);
430430
}
431431

432432
Type* DrgnParser::enumeratePointer(struct drgn_type* type) {
433433
if (!chasePointer()) {
434434
// TODO dodgy nullptr - primitives should be handled as singletons
435-
return make_type<Primitive>(nullptr, Primitive::Kind::UIntPtr);
435+
return makeType<Primitive>(nullptr, Primitive::Kind::UIntPtr);
436436
}
437437

438438
struct drgn_type* pointeeType = drgn_type_type(type).type;
439439

440440
// TODO why was old CodeGen following funciton pointers?
441441

442442
Type* t = enumerateType(pointeeType);
443-
return make_type<Pointer>(type, t);
443+
return makeType<Pointer>(type, t);
444444
}
445445

446446
Array* DrgnParser::enumerateArray(struct drgn_type* type) {
447447
struct drgn_type* elementType = drgn_type_type(type).type;
448448
uint64_t len = drgn_type_length(type);
449449
auto t = enumerateType(elementType);
450-
return make_type<Array>(type, t, len);
450+
return makeType<Array>(type, t, len);
451451
}
452452

453453
Primitive* DrgnParser::enumeratePrimitive(struct drgn_type* type) {
@@ -469,7 +469,7 @@ Primitive* DrgnParser::enumeratePrimitive(struct drgn_type* type) {
469469
throw DrgnParserError{"Invalid drgn type kind for primitive: " +
470470
std::to_string(drgn_type_kind(type))};
471471
}
472-
return make_type<Primitive>(type, kind);
472+
return makeType<Primitive>(type, kind);
473473
}
474474

475475
bool DrgnParser::chasePointer() const {

oi/type_graph/DrgnParser.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,8 @@ class DrgnParser {
6868
std::unordered_map<struct drgn_type*, Type*> drgn_types_;
6969

7070
template <typename T, typename... Args>
71-
T* make_type(struct drgn_type* type, Args&&... args) {
72-
auto type_unique_ptr = std::make_unique<T>(std::forward<Args>(args)...);
73-
auto type_raw_ptr = type_unique_ptr.get();
74-
typeGraph_.add(std::move(type_unique_ptr));
71+
T* makeType(struct drgn_type* type, Args&&... args) {
72+
auto* type_raw_ptr = typeGraph_.makeType<T>(std::forward<Args>(args)...);
7573
drgn_types_.insert({type, type_raw_ptr});
7674
return type_raw_ptr;
7775
}

oi/type_graph/RemoveIgnored.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,9 @@ void RemoveIgnored::visit(Class& c) {
4444
if (!ignoreMember(c.name(), c.members[i].name)) {
4545
continue;
4646
}
47-
auto* primitive = typeGraph_.make_type<Primitive>(Primitive::Kind::Int8);
47+
auto* primitive = typeGraph_.makeType<Primitive>(Primitive::Kind::Int8);
4848
auto* paddingArray =
49-
typeGraph_.make_type<Array>(primitive, c.members[i].type->size());
49+
typeGraph_.makeType<Array>(primitive, c.members[i].type->size());
5050
c.members[i] =
5151
Member{paddingArray, c.members[i].name, c.members[i].bitOffset};
5252
}

oi/type_graph/TypeGraph.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
namespace type_graph {
1919

2020
template <>
21-
Primitive* TypeGraph::make_type<Primitive>(Primitive::Kind kind) {
21+
Primitive* TypeGraph::makeType<Primitive>(Primitive::Kind kind) {
2222
switch (kind) {
2323
case Primitive::Kind::Int8:
2424
static Primitive pInt8{kind};

oi/type_graph/TypeGraph.h

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,12 @@
2323

2424
namespace type_graph {
2525

26+
/*
27+
* TypeGraph
28+
*
29+
* This class represents a type graph. It stores the nodes and keeps track of
30+
* the roots.
31+
*/
2632
class TypeGraph {
2733
public:
2834
size_t size() const noexcept {
@@ -42,24 +48,33 @@ class TypeGraph {
4248
rootTypes_.push_back(type);
4349
}
4450

45-
// Override of the generic make_type function that returns singleton Primitive
51+
// Override of the generic makeType function that returns singleton Primitive
4652
// objects
4753
template <typename T>
48-
Primitive* make_type(Primitive::Kind kind);
54+
Primitive* makeType(Primitive::Kind kind);
4955

5056
template <typename T, typename... Args>
51-
T* make_type(Args&&... args) {
57+
T* makeType(Args&&... args) {
5258
static_assert(!std::is_same<T, Primitive>::value,
5359
"Primitive singleton override should be used");
54-
55-
auto type_unique_ptr = std::make_unique<T>(std::forward<Args>(args)...);
56-
auto type_raw_ptr = type_unique_ptr.get();
57-
types_.push_back(std::move(type_unique_ptr));
58-
return type_raw_ptr;
59-
}
60-
61-
void add(std::unique_ptr<Type> type) {
62-
types_.push_back(std::move(type));
60+
if constexpr (std::is_same<T, Class>::value ||
61+
std::is_same<T, Container>::value ||
62+
std::is_same<T, Array>::value ||
63+
std::is_same<T, Typedef>::value ||
64+
std::is_same<T, Pointer>::value) {
65+
// Node ID required
66+
auto type_unique_ptr =
67+
std::make_unique<T>(next_id_++, std::forward<Args>(args)...);
68+
auto type_raw_ptr = type_unique_ptr.get();
69+
types_.push_back(std::move(type_unique_ptr));
70+
return type_raw_ptr;
71+
} else {
72+
// No Node ID
73+
auto type_unique_ptr = std::make_unique<T>(std::forward<Args>(args)...);
74+
auto type_raw_ptr = type_unique_ptr.get();
75+
types_.push_back(std::move(type_unique_ptr));
76+
return type_raw_ptr;
77+
}
6378
}
6479

6580
// TODO dodgy (use a getter instead to allow returning a const vector):
@@ -69,6 +84,7 @@ class TypeGraph {
6984
std::vector<std::reference_wrapper<Type>> rootTypes_;
7085
// Store all type objects in vectors for ownership. Order is not significant.
7186
std::vector<std::unique_ptr<Type>> types_;
87+
NodeId next_id_ = 0;
7288
};
7389

7490
} // namespace type_graph

oi/type_graph/TypeIdentifier.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ void TypeIdentifier::visit(Container& c) {
7474
if (std::regex_search(paramClass->fqName(), info.matcher)) {
7575
// Create dummy containers
7676
auto* dummy =
77-
typeGraph_.make_type<Container>(info, param.type->size());
77+
typeGraph_.makeType<Container>(info, param.type->size());
7878
dummy->templateParams = paramClass->templateParams;
7979
c.templateParams[i] = dummy;
8080
replaced = true;
@@ -99,11 +99,11 @@ void TypeIdentifier::visit(Container& c) {
9999
auto* allocator =
100100
dynamic_cast<Class*>(param.type); // TODO please don't do this...
101101
Type& typeToAllocate = *allocator->templateParams.at(0).type;
102-
auto* dummy = typeGraph_.make_type<DummyAllocator>(typeToAllocate, size,
103-
param.type->align());
102+
auto* dummy = typeGraph_.makeType<DummyAllocator>(typeToAllocate, size,
103+
param.type->align());
104104
c.templateParams[i] = dummy;
105105
} else {
106-
auto* dummy = typeGraph_.make_type<Dummy>(size, param.type->align());
106+
auto* dummy = typeGraph_.makeType<Dummy>(size, param.type->align());
107107
c.templateParams[i] = dummy;
108108
}
109109
}

oi/type_graph/Types.h

Lines changed: 50 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ struct ContainerInfo;
3838

3939
namespace type_graph {
4040

41+
using NodeId = int32_t;
42+
4143
enum class Qualifier {
4244
Const,
4345
Max,
@@ -122,20 +124,26 @@ class Class : public Type {
122124
Union,
123125
};
124126

125-
Class(Kind kind,
127+
Class(NodeId id,
128+
Kind kind,
126129
std::string name,
127130
std::string fqName,
128131
size_t size,
129132
int virtuality = 0)
130-
: kind_(kind),
131-
name_(std::move(name)),
133+
: name_(std::move(name)),
132134
fqName_(std::move(fqName)),
133135
size_(size),
134-
virtuality_(virtuality) {
136+
kind_(kind),
137+
virtuality_(virtuality),
138+
id_(id) {
135139
}
136140

137-
Class(Kind kind, const std::string& name, size_t size, int virtuality = 0)
138-
: Class(kind, name, name, size, virtuality) {
141+
Class(NodeId id,
142+
Kind kind,
143+
const std::string& name,
144+
size_t size,
145+
int virtuality = 0)
146+
: Class(id, kind, name, name, size, virtuality) {
139147
}
140148

141149
DECLARE_ACCEPT
@@ -182,6 +190,10 @@ class Class : public Type {
182190

183191
bool isDynamic() const;
184192

193+
NodeId id() const {
194+
return id_;
195+
}
196+
185197
std::vector<TemplateParam> templateParams;
186198
std::vector<Parent> parents; // Sorted by offset
187199
std::vector<Member> members; // Sorted by offset
@@ -190,21 +202,23 @@ class Class : public Type {
190202
children; // Only for dynamic classes
191203

192204
private:
193-
Kind kind_;
194205
std::string name_;
195206
std::string fqName_;
196207
size_t size_;
197-
int virtuality_;
198208
uint64_t align_ = 0;
209+
Kind kind_;
210+
int virtuality_;
211+
NodeId id_ = -1;
199212
bool packed_ = false;
200213
};
201214

202215
class Container : public Type {
203216
public:
204-
Container(const ContainerInfo& containerInfo, size_t size)
217+
Container(NodeId id, const ContainerInfo& containerInfo, size_t size)
205218
: containerInfo_(containerInfo),
206219
name_(containerInfo.typeName),
207-
size_(size) {
220+
size_(size),
221+
id_(id) {
208222
}
209223

210224
DECLARE_ACCEPT
@@ -229,12 +243,17 @@ class Container : public Type {
229243
return 8; // TODO not needed for containers?
230244
}
231245

246+
NodeId id() const {
247+
return id_;
248+
}
249+
232250
std::vector<TemplateParam> templateParams;
233251
const ContainerInfo& containerInfo_;
234252

235253
private:
236254
std::string name_;
237255
size_t size_;
256+
NodeId id_ = -1;
238257
};
239258

240259
class Enum : public Type {
@@ -264,7 +283,8 @@ class Enum : public Type {
264283

265284
class Array : public Type {
266285
public:
267-
Array(Type* elementType, size_t len) : elementType_(elementType), len_(len) {
286+
Array(NodeId id, Type* elementType, size_t len)
287+
: elementType_(elementType), len_(len), id_(id) {
268288
}
269289

270290
DECLARE_ACCEPT
@@ -290,9 +310,14 @@ class Array : public Type {
290310
return len_;
291311
}
292312

313+
NodeId id() const {
314+
return id_;
315+
}
316+
293317
private:
294318
Type* elementType_;
295319
size_t len_;
320+
NodeId id_ = -1;
296321
};
297322

298323
class Primitive : public Type {
@@ -334,8 +359,8 @@ class Primitive : public Type {
334359

335360
class Typedef : public Type {
336361
public:
337-
explicit Typedef(const std::string& name, Type* underlyingType)
338-
: name_(name), underlyingType_(underlyingType) {
362+
explicit Typedef(NodeId id, const std::string& name, Type* underlyingType)
363+
: name_(name), underlyingType_(underlyingType), id_(id) {
339364
}
340365

341366
DECLARE_ACCEPT
@@ -360,14 +385,20 @@ class Typedef : public Type {
360385
return underlyingType_;
361386
}
362387

388+
NodeId id() const {
389+
return id_;
390+
}
391+
363392
private:
364393
std::string name_;
365394
Type* underlyingType_;
395+
NodeId id_ = -1;
366396
};
367397

368398
class Pointer : public Type {
369399
public:
370-
explicit Pointer(Type* pointeeType) : pointeeType_(pointeeType) {
400+
explicit Pointer(NodeId id, Type* pointeeType)
401+
: pointeeType_(pointeeType), id_(id) {
371402
}
372403

373404
DECLARE_ACCEPT
@@ -388,8 +419,13 @@ class Pointer : public Type {
388419
return pointeeType_;
389420
}
390421

422+
NodeId id() const {
423+
return id_;
424+
}
425+
391426
private:
392427
Type* pointeeType_;
428+
NodeId id_ = -1;
393429
};
394430

395431
class Dummy : public Type {

0 commit comments

Comments
 (0)