[PGO] Extract VP data integrity check code into a helper function (NFC)
authorXinliang David Li <davidxl@google.com>
Sat, 28 Nov 2015 04:56:07 +0000 (04:56 +0000)
committerXinliang David Li <davidxl@google.com>
Sat, 28 Nov 2015 04:56:07 +0000 (04:56 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@254217 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/ProfileData/InstrProf.h
lib/ProfileData/InstrProf.cpp

index 778fe16c2e6db6acfe4cdff22ae61db5ff4ec178..3a1226662007fce351f5ec55de80384127fcf408 100644 (file)
@@ -506,6 +506,9 @@ typedef struct ValueProfData {
   /// Return a pointer to \c ValueProfData instance ready to be streamed.
   static std::unique_ptr<ValueProfData>
   serializeFrom(const InstrProfRecord &Record);
+  /// Check the integrity of the record. Return the error code when
+  /// an error is detected, otherwise return instrprof_error::success.
+  instrprof_error checkIntegrity();
   /// Return a pointer to \c ValueProfileData instance ready to be read.
   /// All data in the instance are properly byte swapped. The input
   /// data is assumed to be in little endian order.
index 86cd76c9a208c65ef6b459d48fdf59291cad1787..54c37e30dba3f0df39b1fe6918a7886485a88b84 100644 (file)
@@ -442,6 +442,24 @@ static std::unique_ptr<ValueProfData> allocValueProfData(uint32_t TotalSize) {
                                             ValueProfData());
 }
 
+instrprof_error ValueProfData::checkIntegrity() {
+  if (NumValueKinds > IPVK_Last + 1)
+    return instrprof_error::malformed;
+  // Total size needs to be mulltiple of quadword size.
+  if (TotalSize % sizeof(uint64_t))
+    return instrprof_error::malformed;
+
+  ValueProfRecord *VR = getFirstValueProfRecord(this);
+  for (uint32_t K = 0; K < this->NumValueKinds; K++) {
+    if (VR->Kind > IPVK_Last)
+      return instrprof_error::malformed;
+    VR = getValueProfRecordNext(VR);
+    if ((char *)VR - (char *)this > (ptrdiff_t)TotalSize)
+      return instrprof_error::malformed;
+  }
+  return instrprof_error::success;
+}
+
 ErrorOr<std::unique_ptr<ValueProfData>>
 ValueProfData::getValueProfData(const unsigned char *D,
                                 const unsigned char *const BufferEnd,
@@ -452,31 +470,17 @@ ValueProfData::getValueProfData(const unsigned char *D,
 
   const unsigned char *Header = D;
   uint32_t TotalSize = swapToHostOrder<uint32_t>(Header, Endianness);
-  uint32_t NumValueKinds = swapToHostOrder<uint32_t>(Header, Endianness);
-
   if (D + TotalSize > BufferEnd)
     return instrprof_error::too_large;
-  if (NumValueKinds > IPVK_Last + 1)
-    return instrprof_error::malformed;
-  // Total size needs to be mulltiple of quadword size.
-  if (TotalSize % sizeof(uint64_t))
-    return instrprof_error::malformed;
 
   std::unique_ptr<ValueProfData> VPD = allocValueProfData(TotalSize);
-
   memcpy(VPD.get(), D, TotalSize);
   // Byte swap.
   VPD->swapBytesToHost(Endianness);
 
-  // Data integrity check:
-  ValueProfRecord *VR = getFirstValueProfRecord(VPD.get());
-  for (uint32_t K = 0; K < VPD->NumValueKinds; K++) {
-    if (VR->Kind > IPVK_Last)
-      return instrprof_error::malformed;
-    VR = getValueProfRecordNext(VR);
-    if ((char *)VR - (char *)VPD.get() > (ptrdiff_t)TotalSize)
-      return instrprof_error::malformed;
-  }
+  instrprof_error EC = VPD->checkIntegrity();
+  if (EC != instrprof_error::success)
+    return EC;
 
   return std::move(VPD);
 }