+bool InstrProfLookupTrait::ReadValueProfilingData(
+ const unsigned char *&D, const unsigned char *const End) {
+
+ using namespace support;
+ // Read number of value kinds with value sites.
+ if (D + sizeof(uint64_t) > End)
+ return false;
+ uint64_t ValueKindCount = endian::readNext<uint64_t, little, unaligned>(D);
+
+ for (uint32_t Kind = 0; Kind < ValueKindCount; ++Kind) {
+
+ // Read value kind and number of value sites for kind.
+ if (D + 2 * sizeof(uint64_t) > End)
+ return false;
+ uint64_t ValueKind = endian::readNext<uint64_t, little, unaligned>(D);
+ uint64_t ValueSiteCount = endian::readNext<uint64_t, little, unaligned>(D);
+
+ std::vector<InstrProfValueSiteRecord> &ValueSites =
+ DataBuffer.back().getValueSitesForKind(ValueKind);
+ ValueSites.reserve(ValueSiteCount);
+ for (uint64_t VSite = 0; VSite < ValueSiteCount; ++VSite) {
+ // Read number of value data pairs at value site.
+ if (D + sizeof(uint64_t) > End)
+ return false;
+ uint64_t ValueDataCount =
+ endian::readNext<uint64_t, little, unaligned>(D);
+
+ // Check if there are as many ValueDataPairs as ValueDataCount in memory.
+ if (D + (ValueDataCount << 1) * sizeof(uint64_t) > End)
+ return false;
+
+ InstrProfValueSiteRecord VSiteRecord;
+ for (uint64_t VCount = 0; VCount < ValueDataCount; ++VCount) {
+ uint64_t Value = endian::readNext<uint64_t, little, unaligned>(D);
+ uint64_t NumTaken = endian::readNext<uint64_t, little, unaligned>(D);
+ switch (ValueKind) {
+ case IPVK_IndirectCallTarget: {
+ auto Result =
+ std::lower_bound(HashKeys.begin(), HashKeys.end(), Value,
+ [](const std::pair<uint64_t, const char *> &LHS,
+ uint64_t RHS) { return LHS.first < RHS; });
+ assert(Result != HashKeys.end() &&
+ "Hash does not match any known keys\n");
+ Value = (uint64_t)Result->second;
+ break;
+ }
+ }
+ VSiteRecord.ValueData.push_back(std::make_pair(Value, NumTaken));
+ }
+ ValueSites.push_back(std::move(VSiteRecord));
+ }
+ }
+ return true;
+}
+