TEST_F(SampleProfTest, sample_overflow_saturation) { const uint64_t Max = std::numeric_limits<uint64_t>::max(); sampleprof_error Result; StringRef FooName("_Z3fooi"); FunctionSamples FooSamples; Result = FooSamples.addTotalSamples(1); ASSERT_EQ(Result, sampleprof_error::success); Result = FooSamples.addHeadSamples(1); ASSERT_EQ(Result, sampleprof_error::success); Result = FooSamples.addBodySamples(10, 0, 1); ASSERT_EQ(Result, sampleprof_error::success); Result = FooSamples.addTotalSamples(Max); ASSERT_EQ(Result, sampleprof_error::counter_overflow); ASSERT_EQ(FooSamples.getTotalSamples(), Max); Result = FooSamples.addHeadSamples(Max); ASSERT_EQ(Result, sampleprof_error::counter_overflow); ASSERT_EQ(FooSamples.getHeadSamples(), Max); Result = FooSamples.addBodySamples(10, 0, Max); ASSERT_EQ(Result, sampleprof_error::counter_overflow); ErrorOr<uint64_t> BodySamples = FooSamples.findSamplesAt(10, 0); ASSERT_FALSE(BodySamples.getError()); ASSERT_EQ(BodySamples.get(), Max); }
std::error_code SampleProfileReaderBinary::readProfile(FunctionSamples &FProfile) { auto NumSamples = readNumber<uint64_t>(); if (std::error_code EC = NumSamples.getError()) return EC; FProfile.addTotalSamples(*NumSamples); // Read the samples in the body. auto NumRecords = readNumber<uint32_t>(); if (std::error_code EC = NumRecords.getError()) return EC; for (uint32_t I = 0; I < *NumRecords; ++I) { auto LineOffset = readNumber<uint64_t>(); if (std::error_code EC = LineOffset.getError()) return EC; if (!isOffsetLegal(*LineOffset)) { return std::error_code(); } auto Discriminator = readNumber<uint64_t>(); if (std::error_code EC = Discriminator.getError()) return EC; auto NumSamples = readNumber<uint64_t>(); if (std::error_code EC = NumSamples.getError()) return EC; auto NumCalls = readNumber<uint32_t>(); if (std::error_code EC = NumCalls.getError()) return EC; for (uint32_t J = 0; J < *NumCalls; ++J) { auto CalledFunction(readStringFromTable()); if (std::error_code EC = CalledFunction.getError()) return EC; auto CalledFunctionSamples = readNumber<uint64_t>(); if (std::error_code EC = CalledFunctionSamples.getError()) return EC; FProfile.addCalledTargetSamples(*LineOffset, *Discriminator, *CalledFunction, *CalledFunctionSamples); } FProfile.addBodySamples(*LineOffset, *Discriminator, *NumSamples); } // Read all the samples for inlined function calls. auto NumCallsites = readNumber<uint32_t>(); if (std::error_code EC = NumCallsites.getError()) return EC; for (uint32_t J = 0; J < *NumCallsites; ++J) { auto LineOffset = readNumber<uint64_t>(); if (std::error_code EC = LineOffset.getError()) return EC; auto Discriminator = readNumber<uint64_t>(); if (std::error_code EC = Discriminator.getError()) return EC; auto FName(readStringFromTable()); if (std::error_code EC = FName.getError()) return EC; FunctionSamples &CalleeProfile = FProfile.functionSamplesAt( LineLocation(*LineOffset, *Discriminator))[*FName]; CalleeProfile.setName(*FName); if (std::error_code EC = readProfile(CalleeProfile)) return EC; } return sampleprof_error::success; }