@@ -1202,35 +1202,10 @@ IndexedInstrProfReader::readSummary(IndexedInstrProf::ProfVersion Version,
1202
1202
}
1203
1203
}
1204
1204
1205
- Error IndexedMemProfReader::deserialize (const unsigned char *Start,
1206
- uint64_t MemProfOffset) {
1207
- const unsigned char *Ptr = Start + MemProfOffset;
1208
-
1209
- // Read the first 64-bit word, which may be RecordTableOffset in
1210
- // memprof::MemProfVersion0 or the MemProf version number in
1211
- // memprof::MemProfVersion1 and above.
1212
- const uint64_t FirstWord =
1213
- support::endian::readNext<uint64_t , llvm::endianness::little>(Ptr );
1214
-
1215
- if (FirstWord == memprof::Version1 || FirstWord == memprof::Version2 ||
1216
- FirstWord == memprof::Version3) {
1217
- // Everything is good. We can proceed to deserialize the rest.
1218
- Version = static_cast <memprof::IndexedVersion>(FirstWord);
1219
- } else if (FirstWord >= 24 ) {
1220
- // This is a heuristic/hack to detect memprof::MemProfVersion0,
1221
- // which does not have a version field in the header.
1222
- // In memprof::MemProfVersion0, FirstWord will be RecordTableOffset,
1223
- // which should be at least 24 because of the MemProf header size.
1224
- Version = memprof::Version0;
1225
- } else {
1226
- return make_error<InstrProfError>(
1227
- instrprof_error::unsupported_version,
1228
- formatv (" MemProf version {} not supported; "
1229
- " requires version between {} and {}, inclusive" ,
1230
- FirstWord, memprof::MinimumSupportedVersion,
1231
- memprof::MaximumSupportedVersion));
1232
- }
1233
-
1205
+ Error IndexedMemProfReader::deserializeV012 (const unsigned char *Start,
1206
+ const unsigned char *Ptr ,
1207
+ uint64_t FirstWord,
1208
+ memprof::IndexedVersion Version) {
1234
1209
// The value returned from RecordTableGenerator.Emit.
1235
1210
const uint64_t RecordTableOffset =
1236
1211
Version == memprof::Version0
@@ -1280,6 +1255,97 @@ Error IndexedMemProfReader::deserialize(const unsigned char *Start,
1280
1255
/* Payload=*/ Start + CallStackPayloadOffset,
1281
1256
/* Base=*/ Start));
1282
1257
1258
+ return Error::success ();
1259
+ }
1260
+
1261
+ Error IndexedMemProfReader::deserializeV3 (const unsigned char *Start,
1262
+ const unsigned char *Ptr ,
1263
+ memprof::IndexedVersion Version) {
1264
+ // The value returned from FrameTableGenerator.Emit.
1265
+ const uint64_t FrameTableOffset =
1266
+ support::endian::readNext<uint64_t , llvm::endianness::little>(Ptr );
1267
+ // The offset in the stream right before invoking
1268
+ // CallStackTableGenerator.Emit.
1269
+ const uint64_t CallStackPayloadOffset =
1270
+ support::endian::readNext<uint64_t , llvm::endianness::little>(Ptr );
1271
+ // The value returned from CallStackTableGenerator.Emit.
1272
+ const uint64_t CallStackTableOffset =
1273
+ support::endian::readNext<uint64_t , llvm::endianness::little>(Ptr );
1274
+ // The offset in the stream right before invoking RecordTableGenerator.Emit.
1275
+ const uint64_t RecordPayloadOffset =
1276
+ support::endian::readNext<uint64_t , llvm::endianness::little>(Ptr );
1277
+ // The value returned from RecordTableGenerator.Emit.
1278
+ const uint64_t RecordTableOffset =
1279
+ support::endian::readNext<uint64_t , llvm::endianness::little>(Ptr );
1280
+
1281
+ // Read the schema.
1282
+ auto SchemaOr = memprof::readMemProfSchema (Ptr );
1283
+ if (!SchemaOr)
1284
+ return SchemaOr.takeError ();
1285
+ Schema = SchemaOr.get ();
1286
+
1287
+ // Initialize the frame table reader with the payload and bucket offsets.
1288
+ MemProfFrameTable.reset (MemProfFrameHashTable::Create (
1289
+ /* Buckets=*/ Start + FrameTableOffset,
1290
+ /* Payload=*/ Ptr ,
1291
+ /* Base=*/ Start));
1292
+
1293
+ MemProfCallStackTable.reset (MemProfCallStackHashTable::Create (
1294
+ /* Buckets=*/ Start + CallStackTableOffset,
1295
+ /* Payload=*/ Start + CallStackPayloadOffset,
1296
+ /* Base=*/ Start));
1297
+
1298
+ // Now initialize the table reader with a pointer into data buffer.
1299
+ MemProfRecordTable.reset (MemProfRecordHashTable::Create (
1300
+ /* Buckets=*/ Start + RecordTableOffset,
1301
+ /* Payload=*/ Start + RecordPayloadOffset,
1302
+ /* Base=*/ Start, memprof::RecordLookupTrait (Version, Schema)));
1303
+
1304
+ return Error::success ();
1305
+ }
1306
+
1307
+ Error IndexedMemProfReader::deserialize (const unsigned char *Start,
1308
+ uint64_t MemProfOffset) {
1309
+ const unsigned char *Ptr = Start + MemProfOffset;
1310
+
1311
+ // Read the first 64-bit word, which may be RecordTableOffset in
1312
+ // memprof::MemProfVersion0 or the MemProf version number in
1313
+ // memprof::MemProfVersion1 and above.
1314
+ const uint64_t FirstWord =
1315
+ support::endian::readNext<uint64_t , llvm::endianness::little>(Ptr );
1316
+
1317
+ if (FirstWord == memprof::Version1 || FirstWord == memprof::Version2 ||
1318
+ FirstWord == memprof::Version3) {
1319
+ // Everything is good. We can proceed to deserialize the rest.
1320
+ Version = static_cast <memprof::IndexedVersion>(FirstWord);
1321
+ } else if (FirstWord >= 24 ) {
1322
+ // This is a heuristic/hack to detect memprof::MemProfVersion0,
1323
+ // which does not have a version field in the header.
1324
+ // In memprof::MemProfVersion0, FirstWord will be RecordTableOffset,
1325
+ // which should be at least 24 because of the MemProf header size.
1326
+ Version = memprof::Version0;
1327
+ } else {
1328
+ return make_error<InstrProfError>(
1329
+ instrprof_error::unsupported_version,
1330
+ formatv (" MemProf version {} not supported; "
1331
+ " requires version between {} and {}, inclusive" ,
1332
+ FirstWord, memprof::MinimumSupportedVersion,
1333
+ memprof::MaximumSupportedVersion));
1334
+ }
1335
+
1336
+ switch (Version) {
1337
+ case memprof::Version0:
1338
+ case memprof::Version1:
1339
+ case memprof::Version2:
1340
+ if (Error E = deserializeV012 (Start, Ptr , FirstWord, Version))
1341
+ return E;
1342
+ break ;
1343
+ case memprof::Version3:
1344
+ if (Error E = deserializeV3 (Start, Ptr , Version))
1345
+ return E;
1346
+ break ;
1347
+ }
1348
+
1283
1349
#ifdef EXPENSIVE_CHECKS
1284
1350
// Go through all the records and verify that CSId has been correctly
1285
1351
// populated. Do this only under EXPENSIVE_CHECKS. Otherwise, we
0 commit comments