@@ -51,16 +51,29 @@ uint64_t __llvm_profile_get_size_for_buffer(void) {
51
51
const char * BitmapEnd = __llvm_profile_end_bitmap ();
52
52
const char * NamesBegin = __llvm_profile_begin_names ();
53
53
const char * NamesEnd = __llvm_profile_end_names ();
54
+ const VTableProfData * VTableBegin = __llvm_profile_begin_vtables ();
55
+ const VTableProfData * VTableEnd = __llvm_profile_end_vtables ();
56
+ const char * VNamesBegin = __llvm_profile_begin_vtabnames ();
57
+ const char * VNamesEnd = __llvm_profile_end_vtabnames ();
54
58
55
59
return __llvm_profile_get_size_for_buffer_internal (
56
60
DataBegin , DataEnd , CountersBegin , CountersEnd , BitmapBegin , BitmapEnd ,
57
- NamesBegin , NamesEnd );
61
+ NamesBegin , NamesEnd , VTableBegin , VTableEnd , VNamesBegin , VNamesEnd );
58
62
}
59
63
60
64
COMPILER_RT_VISIBILITY
61
65
uint64_t __llvm_profile_get_num_data (const __llvm_profile_data * Begin ,
62
66
const __llvm_profile_data * End ) {
63
67
intptr_t BeginI = (intptr_t )Begin , EndI = (intptr_t )End ;
68
+ // `sizeof(__llvm_profile_data) - 1` is required in the numerator when
69
+ // [Begin, End] represents an inclusive range.
70
+ // For ELF, [Begin, End) represents the address of linker-inserted
71
+ // symbols `__start__<elf-section>` and `__stop_<elf-section>`.
72
+ // Thereby, `End` is one byte past the inclusive range, and
73
+ // `sizeof(__llvm_profile_data) - 1` is not necessary in the numerator to get
74
+ // the correct number of profile data.
75
+ // FIXME: Consider removing `sizeof(__llvm_profile_data) - 1` if this is true
76
+ // across platforms.
64
77
return ((EndI + sizeof (__llvm_profile_data ) - 1 ) - BeginI ) /
65
78
sizeof (__llvm_profile_data );
66
79
}
@@ -71,6 +84,26 @@ uint64_t __llvm_profile_get_data_size(const __llvm_profile_data *Begin,
71
84
return __llvm_profile_get_num_data (Begin , End ) * sizeof (__llvm_profile_data );
72
85
}
73
86
87
+ // Counts the number of `VTableProfData` elements within the range of [Begin,
88
+ // End). Caller should guarantee that End points to one byte past the inclusive
89
+ // range.
90
+ // FIXME: Add a compiler-rt test to make sure the number of vtables in the
91
+ // raw profile is the same as the number of vtable elements in the instrumented
92
+ // binary.
93
+ COMPILER_RT_VISIBILITY
94
+ uint64_t __llvm_profile_get_num_vtable (const VTableProfData * Begin ,
95
+ const VTableProfData * End ) {
96
+ // Convert pointers to intptr_t to use integer arithmetic.
97
+ intptr_t EndI = (intptr_t )End , BeginI = (intptr_t )Begin ;
98
+ return (EndI - BeginI ) / sizeof (VTableProfData );
99
+ }
100
+
101
+ COMPILER_RT_VISIBILITY
102
+ uint64_t __llvm_profile_get_vtable_section_size (const VTableProfData * Begin ,
103
+ const VTableProfData * End ) {
104
+ return (intptr_t )(End ) - (intptr_t )(Begin );
105
+ }
106
+
74
107
COMPILER_RT_VISIBILITY size_t __llvm_profile_counter_entry_size (void ) {
75
108
if (__llvm_profile_get_version () & VARIANT_MASK_BYTE_COVERAGE )
76
109
return sizeof (uint8_t );
@@ -119,21 +152,33 @@ static int needsCounterPadding(void) {
119
152
}
120
153
121
154
COMPILER_RT_VISIBILITY
122
- void __llvm_profile_get_padding_sizes_for_counters (
155
+ int __llvm_profile_get_padding_sizes_for_counters (
123
156
uint64_t DataSize , uint64_t CountersSize , uint64_t NumBitmapBytes ,
124
- uint64_t NamesSize , uint64_t * PaddingBytesBeforeCounters ,
125
- uint64_t * PaddingBytesAfterCounters , uint64_t * PaddingBytesAfterBitmapBytes ,
126
- uint64_t * PaddingBytesAfterNames ) {
157
+ uint64_t NamesSize , uint64_t VTableSize , uint64_t VNameSize ,
158
+ uint64_t * PaddingBytesBeforeCounters , uint64_t * PaddingBytesAfterCounters ,
159
+ uint64_t * PaddingBytesAfterBitmapBytes , uint64_t * PaddingBytesAfterNames ,
160
+ uint64_t * PaddingBytesAfterVTable , uint64_t * PaddingBytesAfterVName ) {
161
+ // Counter padding is needed only if continuous mode is enabled.
127
162
if (!needsCounterPadding ()) {
128
163
* PaddingBytesBeforeCounters = 0 ;
129
164
* PaddingBytesAfterCounters =
130
165
__llvm_profile_get_num_padding_bytes (CountersSize );
131
166
* PaddingBytesAfterBitmapBytes =
132
167
__llvm_profile_get_num_padding_bytes (NumBitmapBytes );
133
168
* PaddingBytesAfterNames = __llvm_profile_get_num_padding_bytes (NamesSize );
134
- return ;
169
+ if (PaddingBytesAfterVTable != NULL )
170
+ * PaddingBytesAfterVTable =
171
+ __llvm_profile_get_num_padding_bytes (VTableSize );
172
+ if (PaddingBytesAfterVName != NULL )
173
+ * PaddingBytesAfterVName = __llvm_profile_get_num_padding_bytes (VNameSize );
174
+ return 0 ;
135
175
}
136
176
177
+ // Value profiling not supported in continuous mode at profile-write time.
178
+ // Return -1 to alert the incompatibility.
179
+ if (VTableSize != 0 || VNameSize != 0 )
180
+ return -1 ;
181
+
137
182
// In continuous mode, the file offsets for headers and for the start of
138
183
// counter sections need to be page-aligned.
139
184
* PaddingBytesBeforeCounters =
@@ -142,34 +187,52 @@ void __llvm_profile_get_padding_sizes_for_counters(
142
187
* PaddingBytesAfterBitmapBytes =
143
188
calculateBytesNeededToPageAlign (NumBitmapBytes );
144
189
* PaddingBytesAfterNames = calculateBytesNeededToPageAlign (NamesSize );
190
+ // Set these two variables to zero to avoid uninitialized variables
191
+ // even if VTableSize and VNameSize are known to be zero.
192
+ if (PaddingBytesAfterVTable != NULL )
193
+ * PaddingBytesAfterVTable = 0 ;
194
+ if (PaddingBytesAfterVName != NULL )
195
+ * PaddingBytesAfterVName = 0 ;
196
+ return 0 ;
145
197
}
146
198
147
199
COMPILER_RT_VISIBILITY
148
200
uint64_t __llvm_profile_get_size_for_buffer_internal (
149
201
const __llvm_profile_data * DataBegin , const __llvm_profile_data * DataEnd ,
150
202
const char * CountersBegin , const char * CountersEnd , const char * BitmapBegin ,
151
- const char * BitmapEnd , const char * NamesBegin , const char * NamesEnd ) {
203
+ const char * BitmapEnd , const char * NamesBegin , const char * NamesEnd ,
204
+ const VTableProfData * VTableBegin , const VTableProfData * VTableEnd ,
205
+ const char * VNamesBegin , const char * VNamesEnd ) {
152
206
/* Match logic in __llvm_profile_write_buffer(). */
153
207
const uint64_t NamesSize = (NamesEnd - NamesBegin ) * sizeof (char );
154
208
uint64_t DataSize = __llvm_profile_get_data_size (DataBegin , DataEnd );
155
209
uint64_t CountersSize =
156
210
__llvm_profile_get_counters_size (CountersBegin , CountersEnd );
157
211
const uint64_t NumBitmapBytes =
158
212
__llvm_profile_get_num_bitmap_bytes (BitmapBegin , BitmapEnd );
213
+ const uint64_t VTableSize =
214
+ __llvm_profile_get_vtable_section_size (VTableBegin , VTableEnd );
215
+ const uint64_t VNameSize =
216
+ __llvm_profile_get_name_size (VNamesBegin , VNamesEnd );
159
217
160
218
/* Determine how much padding is needed before/after the counters and after
161
219
* the names. */
162
220
uint64_t PaddingBytesBeforeCounters , PaddingBytesAfterCounters ,
163
- PaddingBytesAfterNames , PaddingBytesAfterBitmapBytes ;
221
+ PaddingBytesAfterNames , PaddingBytesAfterBitmapBytes ,
222
+ PaddingBytesAfterVTable , PaddingBytesAfterVNames ;
164
223
__llvm_profile_get_padding_sizes_for_counters (
165
- DataSize , CountersSize , NumBitmapBytes , NamesSize ,
166
- & PaddingBytesBeforeCounters , & PaddingBytesAfterCounters ,
167
- & PaddingBytesAfterBitmapBytes , & PaddingBytesAfterNames );
224
+ DataSize , CountersSize , NumBitmapBytes , NamesSize , 0 /* VTableSize */ ,
225
+ 0 /* VNameSize */ , & PaddingBytesBeforeCounters ,
226
+ & PaddingBytesAfterCounters , & PaddingBytesAfterBitmapBytes ,
227
+ & PaddingBytesAfterNames , & PaddingBytesAfterVTable ,
228
+ & PaddingBytesAfterVNames );
168
229
169
230
return sizeof (__llvm_profile_header ) + __llvm_write_binary_ids (NULL ) +
170
231
DataSize + PaddingBytesBeforeCounters + CountersSize +
171
232
PaddingBytesAfterCounters + NumBitmapBytes +
172
- PaddingBytesAfterBitmapBytes + NamesSize + PaddingBytesAfterNames ;
233
+ PaddingBytesAfterBitmapBytes + NamesSize + PaddingBytesAfterNames +
234
+ VTableSize + PaddingBytesAfterVTable + VNameSize +
235
+ PaddingBytesAfterVNames ;
173
236
}
174
237
175
238
COMPILER_RT_VISIBILITY
@@ -191,7 +254,10 @@ COMPILER_RT_VISIBILITY int __llvm_profile_write_buffer_internal(
191
254
const char * NamesBegin , const char * NamesEnd ) {
192
255
ProfDataWriter BufferWriter ;
193
256
initBufferWriter (& BufferWriter , Buffer );
194
- return lprofWriteDataImpl (& BufferWriter , DataBegin , DataEnd , CountersBegin ,
195
- CountersEnd , BitmapBegin , BitmapEnd , 0 , NamesBegin ,
196
- NamesEnd , 0 );
257
+ // Set virtual table arguments to NULL since they are not supported yet.
258
+ return lprofWriteDataImpl (
259
+ & BufferWriter , DataBegin , DataEnd , CountersBegin , CountersEnd ,
260
+ BitmapBegin , BitmapEnd , /*VPDataReader=*/ 0 , NamesBegin , NamesEnd ,
261
+ /*VTableBegin=*/ NULL , /*VTableEnd=*/ NULL , /*VNamesBegin=*/ NULL ,
262
+ /*VNamesEnd=*/ NULL , /*SkipNameDataWrite=*/ 0 );
197
263
}
0 commit comments