Skip to content

Commit 01c9573

Browse files
committed
add jit timing feature
1 parent 63ac468 commit 01c9573

File tree

9 files changed

+120
-39
lines changed

9 files changed

+120
-39
lines changed

oi/CodeGen.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,9 @@ void addIncludes(const TypeGraph& typeGraph,
105105
includes.emplace("functional");
106106
includes.emplace("oi/types/st.h");
107107
}
108+
if (features[Feature::JitTiming]) {
109+
includes.emplace("chrono");
110+
}
108111
for (const Type& t : typeGraph.finalTypes) {
109112
if (const auto* c = dynamic_cast<const Container*>(&t)) {
110113
includes.emplace(c->containerInfo_.header);
@@ -684,10 +687,10 @@ void CodeGen::generate(
684687

685688
if (config_.features[Feature::TypedDataSegment]) {
686689
FuncGen::DefineTopLevelGetSizeRefTyped(
687-
code, SymbolService::getTypeName(drgnType));
690+
code, SymbolService::getTypeName(drgnType), config_.features);
688691
} else {
689-
FuncGen::DefineTopLevelGetSizeRef(code,
690-
SymbolService::getTypeName(drgnType));
692+
FuncGen::DefineTopLevelGetSizeRef(
693+
code, SymbolService::getTypeName(drgnType), config_.features);
691694
}
692695

693696
if (VLOG_IS_ON(3)) {

oi/Features.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ std::string_view featureHelp(Feature f) {
4242
return "Log information from the JIT code for debugging.";
4343
case Feature::PolymorphicInheritance:
4444
return "Follow polymorphic inheritance hierarchies in the probed object.";
45+
case Feature::JitTiming:
46+
return "Instrument the JIT code with timing for performance testing.";
4547

4648
case Feature::UnknownFeature:
4749
throw std::runtime_error("should not ask for help for UnknownFeature!");

oi/Features.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
X(TypedDataSegment, "typed-data-segment") \
3131
X(GenJitDebug, "gen-jit-debug") \
3232
X(JitLogging, "jit-logging") \
33+
X(JitTiming, "jit-timing") \
3334
X(PolymorphicInheritance, "polymorphic-inheritance")
3435

3536
namespace ObjectIntrospection {

oi/FuncGen.cpp

Lines changed: 79 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@
2222

2323
#include "oi/ContainerInfo.h"
2424

25+
using ObjectIntrospection::Feature;
26+
using ObjectIntrospection::FeatureSet;
27+
2528
namespace {
2629

2730
const std::string typedValueFunc = R"(
@@ -235,29 +238,47 @@ void FuncGen::DefineTopLevelGetObjectSize(std::string& testCode,
235238
}
236239

237240
void FuncGen::DefineTopLevelGetSizeRef(std::string& testCode,
238-
const std::string& rawType) {
241+
const std::string& rawType,
242+
FeatureSet features) {
239243
std::string func = R"(
240244
#pragma GCC diagnostic push
241245
#pragma GCC diagnostic ignored "-Wunknown-attributes"
242246
/* RawType: %1% */
243247
void __attribute__((used, retain)) getSize_%2$016x(const OIInternal::__ROOT_TYPE__& t)
244248
#pragma GCC diagnostic pop
245249
{
250+
)";
251+
if (features[Feature::JitTiming]) {
252+
func += " const auto startTime = std::chrono::steady_clock::now();\n";
253+
}
254+
func += R"(
246255
pointers.initialize();
247256
pointers.add((uintptr_t)&t);
248257
auto data = reinterpret_cast<uintptr_t*>(dataBase);
249-
data[0] = oidMagicId;
250-
data[1] = cookieValue;
251-
data[2] = 0;
252258
253-
size_t dataSegOffset = 3 * sizeof(uintptr_t);
259+
size_t dataSegOffset = 0;
260+
data[dataSegOffset++] = oidMagicId;
261+
data[dataSegOffset++] = cookieValue;
262+
uintptr_t& writtenSize = data[dataSegOffset++];
263+
writtenSize = 0;
264+
uintptr_t& timeTakenNs = data[dataSegOffset++];
265+
266+
dataSegOffset *= sizeof(uintptr_t);
254267
JLOG("%1% @");
255268
JLOGPTR(&t);
256269
OIInternal::getSizeType(t, dataSegOffset);
257270
OIInternal::StoreData((uintptr_t)123456789, dataSegOffset);
258271
OIInternal::StoreData((uintptr_t)123456789, dataSegOffset);
259-
data[2] = dataSegOffset;
272+
writtenSize = dataSegOffset;
260273
dataBase += dataSegOffset;
274+
)";
275+
if (features[Feature::JitTiming]) {
276+
func += R"(
277+
timeTakenNs = std::chrono::duration_cast<std::chrono::nanoseconds>(
278+
std::chrono::steady_clock::now() - startTime).count();
279+
)";
280+
}
281+
func += R"(
261282
}
262283
)";
263284

@@ -267,25 +288,34 @@ void FuncGen::DefineTopLevelGetSizeRef(std::string& testCode,
267288
}
268289

269290
void FuncGen::DefineTopLevelGetSizeRefTyped(std::string& testCode,
270-
const std::string& rawType) {
291+
const std::string& rawType,
292+
FeatureSet features) {
271293
std::string func = R"(
272294
#pragma GCC diagnostic push
273295
#pragma GCC diagnostic ignored "-Wunknown-attributes"
274296
/* RawType: %1% */
275297
void __attribute__((used, retain)) getSize_%2$016x(const OIInternal::__ROOT_TYPE__& t)
276298
#pragma GCC diagnostic pop
277299
{
300+
)";
301+
if (features[Feature::JitTiming]) {
302+
func += " const auto startTime = std::chrono::steady_clock::now();\n";
303+
}
304+
func += R"(
278305
pointers.initialize();
279306
pointers.add((uintptr_t)&t);
280307
auto data = reinterpret_cast<uintptr_t*>(dataBase);
281308
282309
// TODO: Replace these with types::st::Uint64 once the VarInt decoding
283310
// logic is moved out of OIDebugger and into new TreeBuilder.
284-
data[0] = oidMagicId;
285-
data[1] = cookieValue;
286-
data[2] = 0;
287-
288-
size_t dataSegOffset = 3 * sizeof(uintptr_t);
311+
size_t dataSegOffset = 0;
312+
data[dataSegOffset++] = oidMagicId;
313+
data[dataSegOffset++] = cookieValue;
314+
uintptr_t& writtenSize = data[dataSegOffset++];
315+
writtenSize = 0;
316+
uintptr_t& timeTakenNs = data[dataSegOffset++];
317+
318+
dataSegOffset *= sizeof(uintptr_t);
289319
JLOG("%1% @");
290320
JLOGPTR(&t);
291321
@@ -310,8 +340,16 @@ void FuncGen::DefineTopLevelGetSizeRefTyped(std::string& testCode,
310340
.write(123456789);
311341
312342
dataSegOffset = end.offset();
313-
data[2] = dataSegOffset;
343+
writtenSize = dataSegOffset;
314344
dataBase += dataSegOffset;
345+
)";
346+
if (features[Feature::JitTiming]) {
347+
func += R"(
348+
timeTakenNs = std::chrono::duration_cast<std::chrono::nanoseconds>(
349+
std::chrono::steady_clock::now() - startTime).count();
350+
)";
351+
}
352+
func += R"(
315353
}
316354
)";
317355

@@ -342,27 +380,45 @@ void FuncGen::DefineTopLevelGetSizeRefRet(std::string& testCode,
342380
}
343381

344382
void FuncGen::DefineTopLevelGetSizeSmartPtr(std::string& testCode,
345-
const std::string& rawType) {
383+
const std::string& rawType,
384+
FeatureSet features) {
346385
std::string func = R"(
347386
#pragma GCC diagnostic push
348387
#pragma GCC diagnostic ignored "-Wunknown-attributes"
349388
/* RawType: %1% */
350389
void __attribute__((used, retain)) getSize_%2$016x(const OIInternal::__ROOT_TYPE__& t)
351390
#pragma GCC diagnostic pop
352391
{
392+
)";
393+
if (features[Feature::JitTiming]) {
394+
func += " const auto startTime = std::chrono::steady_clock::now();\n";
395+
}
396+
func += R"(
353397
pointers.initialize();
354398
auto data = reinterpret_cast<uintptr_t*>(dataBase);
355-
data[0] = oidMagicId;
356-
data[1] = cookieValue;
357-
data[2] = 0;
358399
359-
size_t dataSegOffset = 3 * sizeof(uintptr_t);
400+
size_t dataSegOffset = 0;
401+
data[dataSegOffset++] = oidMagicId;
402+
data[dataSegOffset++] = cookieValue;
403+
uintptr_t& writtenSize = data[dataSegOffset++];
404+
writtenSize = 0;
405+
uintptr_t& timeTakenNs = data[dataSegOffset++];
406+
407+
dataSegOffset *= sizeof(uintptr_t);
360408
361409
OIInternal::getSizeType(t, dataSegOffset);
362410
OIInternal::StoreData((uintptr_t)123456789, dataSegOffset);
363411
OIInternal::StoreData((uintptr_t)123456789, dataSegOffset);
364-
data[2] = dataSegOffset;
412+
writtenSize = dataSegOffset;
365413
dataBase += dataSegOffset;
414+
)";
415+
if (features[Feature::JitTiming]) {
416+
func += R"(
417+
timeTakenNs = std::chrono::duration_cast<std::chrono::nanoseconds>(
418+
std::chrono::steady_clock::now() - startTime).count();
419+
)";
420+
}
421+
func += R"(
366422
}
367423
)";
368424

@@ -373,7 +429,7 @@ void FuncGen::DefineTopLevelGetSizeSmartPtr(std::string& testCode,
373429

374430
bool FuncGen::DeclareGetSizeFuncs(std::string& testCode,
375431
const ContainerInfoRefSet& containerInfo,
376-
bool chaseRawPointers) {
432+
FeatureSet features) {
377433
for (const ContainerInfo& cInfo : containerInfo) {
378434
std::string ctype = cInfo.typeName;
379435
ctype = ctype.substr(0, ctype.find("<", 0));
@@ -383,7 +439,7 @@ bool FuncGen::DeclareGetSizeFuncs(std::string& testCode,
383439
testCode.append(fmt.str());
384440
}
385441

386-
if (chaseRawPointers) {
442+
if (features[Feature::ChaseRawPointers]) {
387443
testCode.append(
388444
"template<typename T, typename = "
389445
"std::enable_if_t<!std::is_pointer_v<std::decay_t<T>>>>\n");
@@ -397,7 +453,7 @@ bool FuncGen::DeclareGetSizeFuncs(std::string& testCode,
397453

398454
bool FuncGen::DefineGetSizeFuncs(std::string& testCode,
399455
const ContainerInfoRefSet& containerInfo,
400-
bool chaseRawPointers) {
456+
FeatureSet features) {
401457
for (const ContainerInfo& cInfo : containerInfo) {
402458
std::string ctype = cInfo.typeName;
403459
ctype = ctype.substr(0, ctype.find("<", 0));
@@ -407,7 +463,7 @@ bool FuncGen::DefineGetSizeFuncs(std::string& testCode,
407463
testCode.append(fmt.str());
408464
}
409465

410-
if (chaseRawPointers) {
466+
if (features[Feature::ChaseRawPointers]) {
411467
testCode.append("template<typename T, typename C>\n");
412468
} else {
413469
testCode.append("template<typename T>\n");

oi/FuncGen.h

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <string>
2121

2222
#include "oi/ContainerInfo.h"
23+
#include "oi/Features.h"
2324

2425
namespace fs = std::filesystem;
2526

@@ -39,10 +40,10 @@ class FuncGen {
3940

4041
bool DeclareGetSizeFuncs(std::string& testCode,
4142
const ContainerInfoRefSet& containerInfo,
42-
bool chaseRawPointers);
43+
ObjectIntrospection::FeatureSet features);
4344
bool DefineGetSizeFuncs(std::string& testCode,
4445
const ContainerInfoRefSet& containerInfo,
45-
bool chaseRawPointers);
46+
ObjectIntrospection::FeatureSet features);
4647

4748
static void DeclareGetContainer(std::string& testCode);
4849

@@ -54,16 +55,22 @@ class FuncGen {
5455
const std::string& type,
5556
const std::string& linkageName);
5657

57-
static void DefineTopLevelGetSizeRef(std::string& testCode,
58-
const std::string& rawType);
59-
static void DefineTopLevelGetSizeRefTyped(std::string& testCode,
60-
const std::string& rawType);
58+
static void DefineTopLevelGetSizeRef(
59+
std::string& testCode,
60+
const std::string& rawType,
61+
ObjectIntrospection::FeatureSet features);
62+
static void DefineTopLevelGetSizeRefTyped(
63+
std::string& testCode,
64+
const std::string& rawType,
65+
ObjectIntrospection::FeatureSet features);
6166

6267
static void DefineTopLevelGetSizeRefRet(std::string& testCode,
6368
const std::string& type);
6469

65-
static void DefineTopLevelGetSizeSmartPtr(std::string& testCode,
66-
const std::string& rawType);
70+
static void DefineTopLevelGetSizeSmartPtr(
71+
std::string& testCode,
72+
const std::string& rawType,
73+
ObjectIntrospection::FeatureSet features);
6774

6875
static void DefineGetSizeTypedValueFunc(std::string& testCode,
6976
const std::string& ctype);

oi/OICodeGen.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3038,6 +3038,10 @@ bool OICodeGen::generateJitCode(std::string& code) {
30383038
// Required for the offsetof() macro
30393039
includedHeaders.insert("cstddef");
30403040

3041+
if (config.features[Feature::JitTiming]) {
3042+
includedHeaders.emplace("chrono");
3043+
}
3044+
30413045
for (const auto& e : includedHeaders) {
30423046
code.append("#include <");
30433047
code.append(e);
@@ -3254,7 +3258,7 @@ bool OICodeGen::generateJitCode(std::string& code) {
32543258
functionsCode.append("namespace OIInternal {\nnamespace {\n");
32553259
functionsCode.append("// functions -----\n");
32563260
if (!funcGen.DeclareGetSizeFuncs(functionsCode, containerTypesFuncDef,
3257-
feature(Feature::ChaseRawPointers))) {
3261+
config.features)) {
32583262
LOG(ERROR) << "declaring get size for containers failed";
32593263
return false;
32603264
}
@@ -3292,7 +3296,7 @@ bool OICodeGen::generateJitCode(std::string& code) {
32923296
}
32933297

32943298
if (!funcGen.DefineGetSizeFuncs(functionsCode, containerTypesFuncDef,
3295-
feature(Feature::ChaseRawPointers))) {
3299+
config.features)) {
32963300
LOG(ERROR) << "defining get size for containers failed";
32973301
return false;
32983302
}
@@ -3389,9 +3393,11 @@ bool OICodeGen::generateJitCode(std::string& code) {
33893393
if (rootTypeStr.starts_with("unique_ptr") ||
33903394
rootTypeStr.starts_with("LowPtr") ||
33913395
rootTypeStr.starts_with("shared_ptr")) {
3392-
funcGen.DefineTopLevelGetSizeSmartPtr(functionsCode, rawTypeName);
3396+
funcGen.DefineTopLevelGetSizeSmartPtr(functionsCode, rawTypeName,
3397+
config.features);
33933398
} else {
3394-
funcGen.DefineTopLevelGetSizeRef(functionsCode, rawTypeName);
3399+
funcGen.DefineTopLevelGetSizeRef(functionsCode, rawTypeName,
3400+
config.features);
33953401
}
33963402
} else {
33973403
if (linkageName.empty()) {

oi/OIDebugger.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2734,6 +2734,10 @@ bool OIDebugger::decodeTargetData(const DataHeader& dataHeader,
27342734
return false;
27352735
}
27362736

2737+
if (generatorConfig.features[Feature::JitTiming]) {
2738+
LOG(INFO) << "JIT Timing: " << dataHeader.timeTakenNs << "ns";
2739+
}
2740+
27372741
/*
27382742
* Currently we use MAX_INT to indicate two things:
27392743
* - a single MAX_INT indicates the end of results for the current object
@@ -2744,6 +2748,7 @@ bool OIDebugger::decodeTargetData(const DataHeader& dataHeader,
27442748
outVec.push_back(0);
27452749
outVec.push_back(0);
27462750
outVec.push_back(0);
2751+
outVec.push_back(0);
27472752
uint64_t prevVal = 0;
27482753

27492754
while (true) {

oi/OIDebugger.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,7 @@ class OIDebugger {
265265
uintptr_t magicId;
266266
uintptr_t cookie;
267267
uintptr_t size;
268+
uintptr_t timeTakenNs;
268269

269270
/*
270271
* Flexible Array Member are not standard in C++, but this is

oi/TreeBuilder.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ void TreeBuilder::build(const std::vector<uint64_t>& data,
227227
th = &typeHierarchy;
228228
oidData = &data;
229229

230-
oidDataIndex = 3; // HACK: OID's first 3 outputs are dummy 0s
230+
oidDataIndex = 4; // HACK: OID's first 4 outputs are dummy 0s
231231

232232
ObjectIntrospection::Metrics::Tracing _("build_tree");
233233
VLOG(1) << "Building tree...";

0 commit comments

Comments
 (0)