Skip to content

Commit 6112065

Browse files
committed
TClass::GetClass: no interpreter lookups for fundamental types
This commit solves issue #9029 and, more in general, avoid lookups and parsing in some cases. One of the principles of the TClass::GetClass method implementation is to avoid as much as possible. This commit adds yet another fence in TClass::GetClass, checking if the name in input is the name of a known fundamental type or typedef to it. In order to avoid code duplication, a routine previously available within the implementation of TClassEdit has been made available with a public API.
1 parent 8d03a46 commit 6112065

File tree

3 files changed

+29
-5
lines changed

3 files changed

+29
-5
lines changed

core/foundation/inc/TClassEdit.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,8 @@ namespace TClassEdit {
180180
ROOT::ESTLType STLKind(std::string_view type); //Kind of stl container
181181
inline ROOT::ESTLType STLKind(ROOT::Internal::TStringView type) { return STLKind(std::string_view(type)); }
182182
int STLArgs (int kind); //Min number of arguments without allocator
183+
void RemoveStd(std::string &name, size_t pos = 0);
184+
void RemoveStd(std::string_view &name);
183185
std::string ResolveTypedef(const char *tname, bool resolveAll = false);
184186
std::string ShortType (const char *typeDesc, int mode);
185187
std::string InsertStd(const char *tname);

core/foundation/src/TClassEdit.cxx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ static size_t StdLen(const std::string_view name)
112112
/// Remove std:: and any potential inline namespace (well compiler detail
113113
/// namespace.
114114

115-
static void RemoveStd(std::string &name, size_t pos = 0)
115+
void TClassEdit::RemoveStd(std::string &name, size_t pos)
116116
{
117117
size_t len = StdLen({name.data()+pos,name.length()-pos});
118118
if (len) {
@@ -124,7 +124,7 @@ static void RemoveStd(std::string &name, size_t pos = 0)
124124
/// Remove std:: and any potential inline namespace (well compiler detail
125125
/// namespace.
126126

127-
static void RemoveStd(std::string_view &name)
127+
void TClassEdit::RemoveStd(std::string_view &name)
128128
{
129129
size_t len = StdLen(name);
130130
if (len) {

core/meta/src/TClass.cxx

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3047,13 +3047,35 @@ TClass *TClass::GetClass(const char *name, Bool_t load, Bool_t silent, size_t hi
30473047
}
30483048

30493049
std::string normalizedName;
3050-
Bool_t checkTable = kFALSE;
30513050

3051+
// Check if this is a fundamental type already in the typesystem to delay
3052+
// as much as possible any lookup
30523053
if (!cl) {
30533054
{
30543055
TInterpreter::SuspendAutoLoadingRAII autoloadOff(gInterpreter);
30553056
TClassEdit::GetNormalizedName(normalizedName, name);
30563057
}
3058+
std::string name_no_std = name;
3059+
TClassEdit::RemoveStd(name_no_std);
3060+
auto lot = reinterpret_cast<THashTable *>(gROOT->GetListOfTypes());
3061+
auto theType = reinterpret_cast<TDataType *>(lot->THashTable::FindObject(name_no_std.c_str()));
3062+
if (theType && -1 != theType->GetType()) {
3063+
return nullptr;
3064+
} else {
3065+
{
3066+
TInterpreter::SuspendAutoLoadingRAII autoloadOff(gInterpreter);
3067+
TInterpreter::SuspendAutoParsing autoparseOff(gInterpreter);
3068+
theType = reinterpret_cast<TDataType *>(lot->FindObject(name));
3069+
}
3070+
// If it is a typedef, check that this is not a class
3071+
if (theType && -1 != theType->GetType())
3072+
return nullptr;
3073+
}
3074+
}
3075+
3076+
Bool_t checkTable = kFALSE;
3077+
3078+
if (!cl) {
30573079
// Try the normalized name.
30583080
if (normalizedName != name) {
30593081
cl = (TClass*)gROOT->GetListOfClasses()->FindObject(normalizedName.c_str());
@@ -3067,8 +3089,8 @@ TClass *TClass::GetClass(const char *name, Bool_t load, Bool_t silent, size_t hi
30673089
checkTable = kTRUE;
30683090
}
30693091
} else {
3070-
normalizedName = cl->GetName(); // Use the fact that all TClass names are normalized.
3071-
checkTable = load && (normalizedName != name);
3092+
normalizedName = cl->GetName(); // Use the fact that all TClass names are normalized.
3093+
checkTable = load && (normalizedName != name);
30723094
}
30733095

30743096
if (!load) return nullptr;

0 commit comments

Comments
 (0)