Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

perf annotate: Check annotation lines more efficiently

In some places, it checks annotated (disasm) lines for each byte. But
as it already has a list of disasm lines, it'd be better to traverse the
list entries instead of checking every offset with linear search (by
annotated_source__get_line() helper).

Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Ian Rogers <irogers@google.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: https://lore.kernel.org/r/20240404175716.1225482-5-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Namhyung Kim and committed by
Arnaldo Carvalho de Melo
0c053ed2 6f157d9a

+35 -21
+35 -21
tools/perf/util/annotate.c
··· 383 383 384 384 static unsigned annotation__count_insn(struct annotation *notes, u64 start, u64 end) 385 385 { 386 + struct annotation_line *al; 386 387 unsigned n_insn = 0; 387 - u64 offset; 388 388 389 - for (offset = start; offset <= end; offset++) { 390 - if (annotated_source__get_line(notes->src, offset)) 391 - n_insn++; 389 + al = annotated_source__get_line(notes->src, start); 390 + if (al == NULL) 391 + return 0; 392 + 393 + list_for_each_entry_from(al, &notes->src->source, node) { 394 + if (al->offset == -1) 395 + continue; 396 + if ((u64)al->offset > end) 397 + break; 398 + n_insn++; 392 399 } 393 400 return n_insn; 394 401 } ··· 412 405 { 413 406 unsigned n_insn; 414 407 unsigned int cover_insn = 0; 415 - u64 offset; 416 408 417 409 n_insn = annotation__count_insn(notes, start, end); 418 410 if (n_insn && ch->num && ch->cycles) { 411 + struct annotation_line *al; 419 412 struct annotated_branch *branch; 420 413 float ipc = n_insn / ((double)ch->cycles / (double)ch->num); 421 414 ··· 423 416 if (ch->reset >= 0x7fff) 424 417 return; 425 418 426 - for (offset = start; offset <= end; offset++) { 427 - struct annotation_line *al; 419 + al = annotated_source__get_line(notes->src, start); 420 + if (al == NULL) 421 + return; 428 422 429 - al = annotated_source__get_line(notes->src, offset); 430 - if (al && al->cycles && al->cycles->ipc == 0.0) { 423 + list_for_each_entry_from(al, &notes->src->source, node) { 424 + if (al->offset == -1) 425 + continue; 426 + if ((u64)al->offset > end) 427 + break; 428 + if (al->cycles && al->cycles->ipc == 0.0) { 431 429 al->cycles->ipc = ipc; 432 430 cover_insn++; 433 431 } ··· 1280 1268 { 1281 1269 struct annotation *notes = symbol__annotation(sym); 1282 1270 struct sym_hist *h = annotation__histogram(notes, evidx); 1283 - int len = symbol__size(sym), offset; 1271 + struct annotation_line *al; 1284 1272 1285 1273 h->nr_samples = 0; 1286 - for (offset = 0; offset < len; ++offset) { 1274 + list_for_each_entry(al, &notes->src->source, node) { 1287 1275 struct sym_hist_entry *entry; 1288 1276 1289 - entry = annotated_source__hist_entry(notes->src, evidx, offset); 1277 + if (al->offset == -1) 1278 + continue; 1279 + 1280 + entry = annotated_source__hist_entry(notes->src, evidx, al->offset); 1290 1281 if (entry == NULL) 1291 1282 continue; 1292 1283 ··· 1349 1334 static void 1350 1335 annotation__mark_jump_targets(struct annotation *notes, struct symbol *sym) 1351 1336 { 1352 - u64 offset, size = symbol__size(sym); 1337 + struct annotation_line *al; 1353 1338 1354 1339 /* PLT symbols contain external offsets */ 1355 1340 if (strstr(sym->name, "@plt")) 1356 1341 return; 1357 1342 1358 - for (offset = 0; offset < size; ++offset) { 1359 - struct annotation_line *al; 1343 + list_for_each_entry(al, &notes->src->source, node) { 1360 1344 struct disasm_line *dl; 1345 + struct annotation_line *target; 1361 1346 1362 - al = annotated_source__get_line(notes->src, offset); 1363 1347 dl = disasm_line(al); 1364 1348 1365 1349 if (!disasm_line__is_valid_local_jump(dl, sym)) 1366 1350 continue; 1367 1351 1368 - al = notes->src->offsets[dl->ops.target.offset]; 1369 - 1352 + target = annotated_source__get_line(notes->src, 1353 + dl->ops.target.offset); 1370 1354 /* 1371 1355 * FIXME: Oops, no jump target? Buggy disassembler? Or do we 1372 1356 * have to adjust to the previous offset? 1373 1357 */ 1374 - if (al == NULL) 1358 + if (target == NULL) 1375 1359 continue; 1376 1360 1377 - if (++al->jump_sources > notes->max_jump_sources) 1378 - notes->max_jump_sources = al->jump_sources; 1361 + if (++target->jump_sources > notes->max_jump_sources) 1362 + notes->max_jump_sources = target->jump_sources; 1379 1363 } 1380 1364 } 1381 1365