TypeGraph: Make Primitive types singletons

Should save some memory and improve performance by not having loads of
copies of primitive types.
This commit is contained in:
Alastair Robertson 2023-07-04 11:07:30 -07:00 committed by Alastair Robertson
parent 0330ef8945
commit 8805480653
5 changed files with 85 additions and 2 deletions

View File

@ -10,6 +10,7 @@ add_library(type_graph
RemoveIgnored.cpp
RemoveTopLevelPointer.cpp
TopoSorter.cpp
TypeGraph.cpp
TypeIdentifier.cpp
Types.cpp
)

View File

@ -450,8 +450,6 @@ Array* DrgnParser::enumerateArray(struct drgn_type* type) {
return make_type<Array>(type, t, len);
}
// TODO deduplication of primitive types (also remember they're not only created
// here)
Primitive* DrgnParser::enumeratePrimitive(struct drgn_type* type) {
Primitive::Kind kind;
switch (drgn_type_kind(type)) {

View File

@ -20,6 +20,11 @@
namespace type_graph {
Printer::Printer(std::ostream& out, size_t numTypes) : out_(out) {
if (numTypes == 0) {
baseIndent_ = 0;
return;
}
// Enough space for "[XYZ] ", where XYZ is the largest node number:
baseIndent_ = static_cast<int>(log10(static_cast<double>(numTypes)) + 1) + 3;
}

View File

@ -0,0 +1,71 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "TypeGraph.h"
namespace type_graph {
template <>
Primitive* TypeGraph::make_type<Primitive>(Primitive::Kind kind) {
switch (kind) {
case Primitive::Kind::Int8:
static Primitive pInt8{kind};
return &pInt8;
case Primitive::Kind::Int16:
static Primitive pInt16{kind};
return &pInt16;
case Primitive::Kind::Int32:
static Primitive pInt32{kind};
return &pInt32;
case Primitive::Kind::Int64:
static Primitive pInt64{kind};
return &pInt64;
case Primitive::Kind::UInt8:
static Primitive pUInt8{kind};
return &pUInt8;
case Primitive::Kind::UInt16:
static Primitive pUInt16{kind};
return &pUInt16;
case Primitive::Kind::UInt32:
static Primitive pUInt32{kind};
return &pUInt32;
case Primitive::Kind::UInt64:
static Primitive pUInt64{kind};
return &pUInt64;
case Primitive::Kind::Float32:
static Primitive pFloat32{kind};
return &pFloat32;
case Primitive::Kind::Float64:
static Primitive pFloat64{kind};
return &pFloat64;
case Primitive::Kind::Float80:
static Primitive pFloat80{kind};
return &pFloat80;
case Primitive::Kind::Float128:
static Primitive pFloat128{kind};
return &pFloat128;
case Primitive::Kind::Bool:
static Primitive pBool{kind};
return &pBool;
case Primitive::Kind::UIntPtr:
static Primitive pUIntPtr{kind};
return &pUIntPtr;
case Primitive::Kind::Void:
static Primitive pVoid{kind};
return &pVoid;
}
}
} // namespace type_graph

View File

@ -42,8 +42,16 @@ class TypeGraph {
rootTypes_.push_back(type);
}
// Override of the generic make_type function that returns singleton Primitive
// objects
template <typename T>
Primitive* make_type(Primitive::Kind kind);
template <typename T, typename... Args>
T* make_type(Args&&... args) {
static_assert(!std::is_same<T, Primitive>::value,
"Primitive singleton override should be used");
auto type_unique_ptr = std::make_unique<T>(std::forward<Args>(args)...);
auto type_raw_ptr = type_unique_ptr.get();
types_.push_back(std::move(type_unique_ptr));