Skip to content

Commit 43f674c

Browse files
committed
[lldb] Improve memory usage by freeing CTF types (NFC)
Improve memory usage by reducing the lifetime of CTF types. Once a CTF type has been converted to a (complete) LLDB type, there's no need to keep it in memory anymore. For most types, we can free them right after creating the corresponding LLDB types. The only exception is record types, which are only completed lazily. Differential revision: https://reviews.llvm.org/D156606 (cherry picked from commit 6891812)
1 parent 8dc745e commit 43f674c

File tree

3 files changed

+54
-16
lines changed

3 files changed

+54
-16
lines changed

lldb/source/Plugins/SymbolFile/CTF/CTFTypes.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ struct CTFInteger : public CTFType {
4646
uint32_t encoding)
4747
: CTFType(eInteger, uid, name), bits(bits), encoding(encoding) {}
4848

49+
static bool classof(const CTFType *T) { return T->kind == eInteger; }
50+
4951
uint32_t bits;
5052
uint32_t encoding;
5153
};
@@ -55,34 +57,48 @@ struct CTFModifier : public CTFType {
5557
CTFModifier(Kind kind, lldb::user_id_t uid, uint32_t type)
5658
: CTFType(kind, uid, ""), type(type) {}
5759

60+
static bool classof(const CTFType *T) {
61+
return T->kind == ePointer || T->kind == eConst || T->kind == eVolatile ||
62+
T->kind == eRestrict;
63+
}
64+
5865
public:
5966
uint32_t type;
6067
};
6168

6269
struct CTFPointer : public CTFModifier {
6370
CTFPointer(lldb::user_id_t uid, uint32_t type)
6471
: CTFModifier(ePointer, uid, type) {}
72+
73+
static bool classof(const CTFType *T) { return T->kind == ePointer; }
6574
};
6675

6776
struct CTFConst : public CTFModifier {
6877
CTFConst(lldb::user_id_t uid, uint32_t type)
6978
: CTFModifier(eConst, uid, type) {}
79+
80+
static bool classof(const CTFType *T) { return T->kind == eConst; }
7081
};
7182

7283
struct CTFVolatile : public CTFModifier {
7384
CTFVolatile(lldb::user_id_t uid, uint32_t type)
7485
: CTFModifier(eVolatile, uid, type) {}
86+
87+
static bool classof(const CTFType *T) { return T->kind == eVolatile; }
7588
};
7689

7790
struct CTFRestrict : public CTFModifier {
7891
CTFRestrict(lldb::user_id_t uid, uint32_t type)
7992
: CTFModifier(eRestrict, uid, type) {}
93+
static bool classof(const CTFType *T) { return T->kind == eRestrict; }
8094
};
8195

8296
struct CTFTypedef : public CTFType {
8397
CTFTypedef(lldb::user_id_t uid, llvm::StringRef name, uint32_t type)
8498
: CTFType(eTypedef, uid, name), type(type) {}
8599

100+
static bool classof(const CTFType *T) { return T->kind == eTypedef; }
101+
86102
uint32_t type;
87103
};
88104

@@ -91,6 +107,8 @@ struct CTFArray : public CTFType {
91107
uint32_t index, uint32_t nelems)
92108
: CTFType(eArray, uid, name), type(type), index(index), nelems(nelems) {}
93109

110+
static bool classof(const CTFType *T) { return T->kind == eArray; }
111+
94112
uint32_t type;
95113
uint32_t index;
96114
uint32_t nelems;
@@ -110,6 +128,8 @@ struct CTFEnum : public CTFType {
110128
assert(this->values.size() == nelems);
111129
}
112130

131+
static bool classof(const CTFType *T) { return T->kind == eEnum; }
132+
113133
uint32_t nelems;
114134
uint32_t size;
115135
std::vector<Value> values;
@@ -121,6 +141,8 @@ struct CTFFunction : public CTFType {
121141
: CTFType(eFunction, uid, name), nargs(nargs), return_type(return_type),
122142
args(std::move(args)), variadic(variadic) {}
123143

144+
static bool classof(const CTFType *T) { return T->kind == eFunction; }
145+
124146
uint32_t nargs;
125147
uint32_t return_type;
126148

@@ -144,6 +166,10 @@ struct CTFRecord : public CTFType {
144166
: CTFType(kind, uid, name), nfields(nfields), size(size),
145167
fields(std::move(fields)) {}
146168

169+
static bool classof(const CTFType *T) {
170+
return T->kind == eStruct || T->kind == eUnion;
171+
}
172+
147173
uint32_t nfields;
148174
uint32_t size;
149175
std::vector<Field> fields;
@@ -153,17 +179,23 @@ struct CTFStruct : public CTFRecord {
153179
CTFStruct(lldb::user_id_t uid, llvm::StringRef name, uint32_t nfields,
154180
uint32_t size, std::vector<Field> fields)
155181
: CTFRecord(eStruct, uid, name, nfields, size, std::move(fields)){};
182+
183+
static bool classof(const CTFType *T) { return T->kind == eStruct; }
156184
};
157185

158186
struct CTFUnion : public CTFRecord {
159187
CTFUnion(lldb::user_id_t uid, llvm::StringRef name, uint32_t nfields,
160188
uint32_t size, std::vector<Field> fields)
161189
: CTFRecord(eUnion, uid, name, nfields, size, std::move(fields)){};
190+
191+
static bool classof(const CTFType *T) { return T->kind == eUnion; }
162192
};
163193

164194
struct CTFForward : public CTFType {
165195
CTFForward(lldb::user_id_t uid, llvm::StringRef name)
166196
: CTFType(eForward, uid, name) {}
197+
198+
static bool classof(const CTFType *T) { return T->kind == eForward; }
167199
};
168200

169201
} // namespace lldb_private

lldb/source/Plugins/SymbolFile/CTF/SymbolFileCTF.cpp

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -523,8 +523,7 @@ bool SymbolFileCTF::CompleteType(CompilerType &compiler_type) {
523523
assert(ctf_type && "m_compiler_types should only contain valid CTF types");
524524

525525
// We only support resolving record types.
526-
assert(ctf_type->kind == CTFType::Kind::eStruct ||
527-
ctf_type->kind == CTFType::Kind::eUnion);
526+
assert(llvm::isa<CTFRecord>(ctf_type));
528527

529528
// Cast to the appropriate CTF type.
530529
const CTFRecord *ctf_record = static_cast<const CTFRecord *>(ctf_type);
@@ -551,9 +550,10 @@ bool SymbolFileCTF::CompleteType(CompilerType &compiler_type) {
551550
}
552551
m_ast->CompleteTagDeclarationDefinition(compiler_type);
553552

554-
// Now that the compiler type is no longer incomplete we don't need to
555-
// remember it anymore.
553+
// Now that the compiler type is complete, we don't need to remember it
554+
// anymore and can remove the CTF record type.
556555
m_compiler_types.erase(compiler_type.GetOpaqueQualType());
556+
m_ctf_types.erase(ctf_type->uid);
557557

558558
return true;
559559
}
@@ -727,9 +727,8 @@ size_t SymbolFileCTF::ParseTypes(CompileUnit &cu) {
727727
llvm::Expected<std::unique_ptr<CTFType>> type_or_error =
728728
ParseType(type_offset, type_uid);
729729
if (type_or_error) {
730-
m_ctf_types.emplace_back(std::move(*type_or_error));
730+
m_ctf_types[(*type_or_error)->uid] = std::move(*type_or_error);
731731
} else {
732-
m_ctf_types.emplace_back(std::unique_ptr<CTFType>());
733732
LLDB_LOG_ERROR(log, type_or_error.takeError(),
734733
"Failed to parse type {1} at offset {2}: {0}", type_uid,
735734
type_offset);
@@ -982,16 +981,16 @@ void SymbolFileCTF::AddSymbols(Symtab &symtab) {
982981
}
983982

984983
lldb_private::Type *SymbolFileCTF::ResolveTypeUID(lldb::user_id_t type_uid) {
985-
auto find_result = m_types.find(type_uid);
986-
if (find_result != m_types.end())
987-
return find_result->second.get();
984+
auto type_it = m_types.find(type_uid);
985+
if (type_it != m_types.end())
986+
return type_it->second.get();
988987

989-
if (type_uid == 0 || type_uid > m_ctf_types.size())
988+
auto ctf_type_it = m_ctf_types.find(type_uid);
989+
if (ctf_type_it == m_ctf_types.end())
990990
return nullptr;
991991

992-
CTFType *ctf_type = m_ctf_types[type_uid - 1].get();
993-
if (!ctf_type)
994-
return nullptr;
992+
CTFType *ctf_type = ctf_type_it->second.get();
993+
assert(ctf_type && "m_ctf_types should only contain valid CTF types");
995994

996995
Log *log = GetLog(LLDBLog::Symbols);
997996

@@ -1013,6 +1012,11 @@ lldb_private::Type *SymbolFileCTF::ResolveTypeUID(lldb::user_id_t type_uid) {
10131012

10141013
m_types[type_uid] = type_sp;
10151014

1015+
// Except for record types which we'll need to complete later, we don't need
1016+
// the CTF type anymore.
1017+
if (!isa<CTFRecord>(ctf_type))
1018+
m_ctf_types.erase(type_uid);
1019+
10161020
return type_sp.get();
10171021
}
10181022

lldb/source/Plugins/SymbolFile/CTF/SymbolFileCTF.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -241,15 +241,17 @@ class SymbolFileCTF : public lldb_private::SymbolFileCommon {
241241

242242
std::optional<ctf_header_t> m_header;
243243

244-
std::vector<std::unique_ptr<CTFType>> m_ctf_types;
244+
/// Parsed CTF types.
245+
llvm::DenseMap<lldb::user_id_t, std::unique_ptr<CTFType>> m_ctf_types;
246+
247+
/// Parsed LLDB types.
248+
llvm::DenseMap<lldb::user_id_t, lldb::TypeSP> m_types;
245249

246250
/// To complete types, we need a way to map (imcomplete) compiler types back
247251
/// to parsed CTF types.
248252
llvm::DenseMap<lldb::opaque_compiler_type_t, const CTFType *>
249253
m_compiler_types;
250254

251-
llvm::DenseMap<lldb::user_id_t, lldb::TypeSP> m_types;
252-
253255
std::vector<lldb::FunctionSP> m_functions;
254256
std::vector<lldb::VariableSP> m_variables;
255257

0 commit comments

Comments
 (0)