[PATCH] D17623: [compiler-rt] Fix entry count for __llvm_prf_data on i386 Darwin

Vedant Kumar via llvm-commits llvm-commits at lists.llvm.org
Thu Feb 25 16:42:39 PST 2016


vsk created this revision.
vsk added a reviewer: davidxl.
vsk added subscribers: lhames, mschifer, llvm-commits.

Compiler-rt miscalculates the number of entries in the __llvm_prf_data section on i386 Darwin. This results in a number of test failures (which we started catching after r261344).

The fix we attempted earlier is insufficient (r261683). It caused some tests to start passing again, but that hid the fact that we drop data entries.

This patch should fix the real problem. It fixes the way we compute `DataSize` by taking into account the way the Darwin linker lays out __llvm_prf_data.

http://reviews.llvm.org/D17623

Files:
  lib/profile/InstrProfiling.h
  lib/profile/InstrProfilingBuffer.c
  lib/profile/InstrProfilingValue.c
  lib/profile/InstrProfilingWriter.c

Index: lib/profile/InstrProfilingWriter.c
===================================================================
--- lib/profile/InstrProfilingWriter.c
+++ lib/profile/InstrProfilingWriter.c
@@ -144,7 +144,7 @@
     const char *NamesBegin, const char *NamesEnd) {
 
   /* Calculate size of sections. */
-  const uint64_t DataSize = DataEnd - DataBegin;
+  const uint64_t DataSize = __llvm_profile_get_data_size(DataBegin, DataEnd);
   const uint64_t CountersSize = CountersEnd - CountersBegin;
   const uint64_t NamesSize = NamesEnd - NamesBegin;
   const uint64_t Padding = __llvm_profile_get_num_padding_bytes(NamesSize);
Index: lib/profile/InstrProfilingValue.c
===================================================================
--- lib/profile/InstrProfilingValue.c
+++ lib/profile/InstrProfilingValue.c
@@ -142,8 +142,8 @@
   if (!ValueDataSize)
     return NULL;
 
-  ValueDataArray =
-      (ValueProfData **)calloc(DataEnd - DataBegin, sizeof(void *));
+  ValueDataArray = (ValueProfData **)calloc(
+      __llvm_profile_get_data_size(DataBegin, DataEnd), sizeof(void *));
   if (!ValueDataArray)
     PROF_OOM_RETURN("Failed to write value profile data ");
 
Index: lib/profile/InstrProfilingBuffer.c
===================================================================
--- lib/profile/InstrProfilingBuffer.c
+++ lib/profile/InstrProfilingBuffer.c
@@ -23,19 +23,30 @@
       DataBegin, DataEnd, CountersBegin, CountersEnd, NamesBegin, NamesEnd);
 }
 
-#define PROFILE_RANGE_SIZE(Range) (Range##End - Range##Begin)
+COMPILER_RT_VISIBILITY
+uint64_t __llvm_profile_get_data_size(const __llvm_profile_data *Begin,
+                                      const __llvm_profile_data *End) {
+  intptr_t BeginI = (intptr_t)Begin, EndI = (intptr_t)End;
+  intptr_t SectionSize = EndI - BeginI;
+  intptr_t SizeOfLastEntry = SectionSize % sizeof(__llvm_profile_data);
+  if (!SizeOfLastEntry)
+    return SectionSize / sizeof(__llvm_profile_data);
+  intptr_t Size = SectionSize - SizeOfLastEntry + sizeof(__llvm_profile_data);
+  return Size / sizeof(__llvm_profile_data);
+}
 
 COMPILER_RT_VISIBILITY
 uint64_t __llvm_profile_get_size_for_buffer_internal(
     const __llvm_profile_data *DataBegin, const __llvm_profile_data *DataEnd,
     const uint64_t *CountersBegin, const uint64_t *CountersEnd,
     const char *NamesBegin, const char *NamesEnd) {
   /* Match logic in __llvm_profile_write_buffer(). */
-  const uint64_t NamesSize = PROFILE_RANGE_SIZE(Names) * sizeof(char);
+  const uint64_t NamesSize = (NamesEnd - NamesBegin) * sizeof(char);
   const uint8_t Padding = __llvm_profile_get_num_padding_bytes(NamesSize);
   return sizeof(__llvm_profile_header) +
-         PROFILE_RANGE_SIZE(Data) * sizeof(__llvm_profile_data) +
-         PROFILE_RANGE_SIZE(Counters) * sizeof(uint64_t) + NamesSize + Padding;
+         (__llvm_profile_get_data_size(DataBegin, DataEnd) *
+          sizeof(__llvm_profile_data)) +
+         (CountersEnd - CountersBegin) * sizeof(uint64_t) + NamesSize + Padding;
 }
 
 COMPILER_RT_VISIBILITY int __llvm_profile_write_buffer(char *Buffer) {
Index: lib/profile/InstrProfiling.h
===================================================================
--- lib/profile/InstrProfiling.h
+++ lib/profile/InstrProfiling.h
@@ -131,4 +131,8 @@
 /*! \brief Get the version of the file format. */
 uint64_t __llvm_profile_get_version(void);
 
+/*! \brief Get the number of entries in the profile data section. */
+uint64_t __llvm_profile_get_data_size(const __llvm_profile_data *Begin,
+                                      const __llvm_profile_data *End);
+
 #endif /* PROFILE_INSTRPROFILING_H_ */


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D17623.49120.patch
Type: text/x-patch
Size: 3621 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160226/4d2c32a4/attachment-0001.bin>


More information about the llvm-commits mailing list