Index: compiler-rt/trunk/lib/profile/InstrProfilingBuffer.c =================================================================== --- compiler-rt/trunk/lib/profile/InstrProfilingBuffer.c +++ compiler-rt/trunk/lib/profile/InstrProfilingBuffer.c @@ -41,24 +41,31 @@ PROFILE_RANGE_SIZE(Counters) * sizeof(uint64_t) + NamesSize + Padding; } -static size_t bufferWriter(const void *Data, size_t ElmSize, size_t NumElm, - void **Buffer) { - size_t Length = ElmSize * NumElm; - memcpy(*Buffer, Data, Length); - *(char **)Buffer += Length; - return NumElm; +/* The buffer writer is reponsponsible in keeping writer state + * across the call. + */ +static uint32_t bufferWriter(ProfDataIOVec *IOVecs, uint32_t NumIOVecs, + void **WriterCtx) { + uint32_t I; + char **Buffer = (char **)WriterCtx; + for (I = 0; I < NumIOVecs; I++) { + size_t Length = IOVecs[I].ElmSize * IOVecs[I].NumElm; + memcpy(*Buffer, IOVecs[I].Data, Length); + *Buffer += Length; + } + return 0; } __attribute__((visibility("hidden"))) int __llvm_profile_write_buffer(char *Buffer) { - return llvmWriteProfData(Buffer, bufferWriter, 0, 0); + return llvmWriteProfData(bufferWriter, Buffer, 0, 0); } __attribute__((visibility("hidden"))) int __llvm_profile_write_buffer_internal( char *Buffer, const __llvm_profile_data *DataBegin, const __llvm_profile_data *DataEnd, const uint64_t *CountersBegin, const uint64_t *CountersEnd, const char *NamesBegin, const char *NamesEnd) { - return llvmWriteProfDataImpl(Buffer, bufferWriter, DataBegin, DataEnd, + return llvmWriteProfDataImpl(bufferWriter, Buffer, DataBegin, DataEnd, CountersBegin, CountersEnd, 0, 0, NamesBegin, NamesEnd); } Index: compiler-rt/trunk/lib/profile/InstrProfilingFile.c =================================================================== --- compiler-rt/trunk/lib/profile/InstrProfilingFile.c +++ compiler-rt/trunk/lib/profile/InstrProfilingFile.c @@ -17,17 +17,24 @@ #define UNCONST(ptr) ((void *)(uintptr_t)(ptr)) -static size_t fileWriter(const void *Data, size_t ElmSize, size_t NumElm, - void **File) { - return fwrite(Data, ElmSize, NumElm, (FILE *)*File); +/* Return 1 if there is an error, otherwise return 0. */ +static uint32_t fileWriter(ProfDataIOVec *IOVecs, uint32_t NumIOVecs, + void **WriterCtx) { + uint32_t I; + FILE *File = (FILE *)*WriterCtx; + for (I = 0; I < NumIOVecs; I++) { + if (fwrite(IOVecs[I].Data, IOVecs[I].ElmSize, IOVecs[I].NumElm, File) != + IOVecs[I].NumElm) + return 1; + } + return 0; } -uint8_t *ValueDataBegin = NULL; static int writeFile(FILE *File) { uint8_t *ValueDataBegin = NULL; const uint64_t ValueDataSize = __llvm_profile_gather_value_data(&ValueDataBegin); - int r = llvmWriteProfData(File, fileWriter, ValueDataBegin, ValueDataSize); + int r = llvmWriteProfData(fileWriter, File, ValueDataBegin, ValueDataSize); free(ValueDataBegin); return r; } Index: compiler-rt/trunk/lib/profile/InstrProfilingInternal.h =================================================================== --- compiler-rt/trunk/lib/profile/InstrProfilingInternal.h +++ compiler-rt/trunk/lib/profile/InstrProfilingInternal.h @@ -41,12 +41,18 @@ /*! * This is an internal function not intended to be used externally. */ -typedef size_t (*WriterCallback)(const void *Data, size_t ElmS, size_t NumElm, - void **BufferOrFile); -int llvmWriteProfData(void *WriterCtx, WriterCallback Writer, +typedef struct ProfDataIOVec { + const char *Data; + size_t ElmSize; + size_t NumElm; +} ProfDataIOVec; + +typedef uint32_t (*WriterCallback)(ProfDataIOVec *, uint32_t NumIOVecs, + void **WriterCtx); +int llvmWriteProfData(WriterCallback Writer, void *WriterCtx, const uint8_t *ValueDataBegin, const uint64_t ValueDataSize); -int llvmWriteProfDataImpl(void *WriterCtx, WriterCallback Writer, +int llvmWriteProfDataImpl(WriterCallback Writer, void *WriterCtx, const __llvm_profile_data *DataBegin, const __llvm_profile_data *DataEnd, const uint64_t *CountersBegin, Index: compiler-rt/trunk/lib/profile/InstrProfilingWriter.c =================================================================== --- compiler-rt/trunk/lib/profile/InstrProfilingWriter.c +++ compiler-rt/trunk/lib/profile/InstrProfilingWriter.c @@ -11,7 +11,7 @@ #include "InstrProfilingInternal.h" __attribute__((visibility("hidden"))) int -llvmWriteProfData(void *WriterCtx, WriterCallback Writer, +llvmWriteProfData(WriterCallback Writer, void *WriterCtx, const uint8_t *ValueDataBegin, const uint64_t ValueDataSize) { /* Match logic in __llvm_profile_write_buffer(). */ const __llvm_profile_data *DataBegin = __llvm_profile_begin_data(); @@ -20,13 +20,13 @@ const uint64_t *CountersEnd = __llvm_profile_end_counters(); const char *NamesBegin = __llvm_profile_begin_names(); const char *NamesEnd = __llvm_profile_end_names(); - return llvmWriteProfDataImpl(WriterCtx, Writer, DataBegin, DataEnd, + return llvmWriteProfDataImpl(Writer, WriterCtx, DataBegin, DataEnd, CountersBegin, CountersEnd, ValueDataBegin, ValueDataSize, NamesBegin, NamesEnd); } __attribute__((visibility("hidden"))) int llvmWriteProfDataImpl( - void *WriterCtx, WriterCallback Writer, + WriterCallback Writer, void *WriterCtx, const __llvm_profile_data *DataBegin, const __llvm_profile_data *DataEnd, const uint64_t *CountersBegin, const uint64_t *CountersEnd, const uint8_t *ValueDataBegin, const uint64_t ValueDataSize, @@ -58,19 +58,19 @@ Header.ValueDataSize = ValueDataSize; Header.ValueDataDelta = (uintptr_t)ValueDataBegin; -/* Write the data. */ -#define CHECK_write(Data, Size, Length, BuffOrFile) \ - do { \ - if (Writer(Data, Size, Length, &BuffOrFile) != Length) \ - return -1; \ - } while (0) - CHECK_write(&Header, sizeof(__llvm_profile_header), 1, WriterCtx); - CHECK_write(DataBegin, sizeof(__llvm_profile_data), DataSize, WriterCtx); - CHECK_write(CountersBegin, sizeof(uint64_t), CountersSize, WriterCtx); - CHECK_write(NamesBegin, sizeof(char), NamesSize, WriterCtx); - CHECK_write(Zeroes, sizeof(char), Padding, WriterCtx); - if (ValueDataBegin) - CHECK_write(ValueDataBegin, sizeof(char), ValueDataSize, WriterCtx); -#undef CHECK_write + /* Write the data. */ + ProfDataIOVec IOVec[] = { + {(const char *)&Header, sizeof(__llvm_profile_header), 1}, + {(const char *)DataBegin, sizeof(__llvm_profile_data), DataSize}, + {(const char *)CountersBegin, sizeof(uint64_t), CountersSize}, + {(const char *)NamesBegin, sizeof(char), NamesSize}, + {(const char *)Zeroes, sizeof(char), Padding}}; + if (Writer(IOVec, sizeof(IOVec) / sizeof(ProfDataIOVec), &WriterCtx)) + return -1; + if (ValueDataBegin) { + ProfDataIOVec IOVec[1] = {{ValueDataBegin, sizeof(char), ValueDataSize}}; + if (Writer(IOVec, 1, &WriterCtx)) + return -1; + } return 0; }