Skip to content

Commit f0b2753

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 f0b2753

File tree

3 files changed

+24
-2
lines changed

3 files changed

+24
-2
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: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3046,6 +3046,25 @@ TClass *TClass::GetClass(const char *name, Bool_t load, Bool_t silent, size_t hi
30463046
// continue as before ...
30473047
}
30483048

3049+
// Check if this is a fundamental type already in the typesystem to delay
3050+
// as much as possible any lookup
3051+
if (!cl) {
3052+
std::string name_no_std = name;
3053+
TClassEdit::RemoveStd(name_no_std);
3054+
auto lot = reinterpret_cast<THashTable*>(gROOT->GetListOfTypes());
3055+
auto theType = reinterpret_cast<TDataType*>(lot->THashTable::FindObject(name_no_std.c_str()));
3056+
if(theType && -1 != theType->GetType()) {
3057+
return nullptr;
3058+
} else {
3059+
{
3060+
TInterpreter::SuspendAutoLoadingRAII autoloadOff(gInterpreter);
3061+
theType = reinterpret_cast<TDataType*>(lot->FindObject(name));
3062+
}
3063+
// If it is a typedef, check that this is not a class
3064+
if (theType && -1 != theType->GetType()) return nullptr;
3065+
}
3066+
}
3067+
30493068
std::string normalizedName;
30503069
Bool_t checkTable = kFALSE;
30513070

@@ -3054,6 +3073,7 @@ TClass *TClass::GetClass(const char *name, Bool_t load, Bool_t silent, size_t hi
30543073
TInterpreter::SuspendAutoLoadingRAII autoloadOff(gInterpreter);
30553074
TClassEdit::GetNormalizedName(normalizedName, name);
30563075
}
3076+
30573077
// Try the normalized name.
30583078
if (normalizedName != name) {
30593079
cl = (TClass*)gROOT->GetListOfClasses()->FindObject(normalizedName.c_str());

0 commit comments

Comments
 (0)