5 #include "src/arm64/instrument-arm64.h" 10 Counter::Counter(
const char* name, CounterType type)
11 : count_(0), enabled_(false), type_(type) {
12 DCHECK_NOT_NULL(name);
13 strncpy(name_, name, kCounterNameMaxLength);
17 void Counter::Enable() {
22 void Counter::Disable() {
27 bool Counter::IsEnabled() {
32 void Counter::Increment() {
39 uint64_t Counter::count() {
40 uint64_t result = count_;
49 const char* Counter::name() {
54 CounterType Counter::type() {
65 {
"Instruction", Cumulative},
67 {
"Move Immediate", Gauge},
68 {
"Add/Sub DP", Gauge},
69 {
"Logical DP", Gauge},
70 {
"Other Int DP", Gauge},
74 {
"Conditional Select", Gauge},
75 {
"Conditional Compare", Gauge},
77 {
"Unconditional Branch", Gauge},
78 {
"Compare and Branch", Gauge},
79 {
"Test and Branch", Gauge},
80 {
"Conditional Branch", Gauge},
82 {
"Load Integer", Gauge},
85 {
"Load Literal", Gauge},
86 {
"Load Acquire", Gauge},
88 {
"Store Integer", Gauge},
90 {
"Store Pair", Gauge},
91 {
"Store Release", Gauge},
93 {
"PC Addressing", Gauge},
97 Instrument::Instrument(
const char* datafile, uint64_t sample_period)
98 : output_stream_(stderr), sample_period_(sample_period) {
101 if (datafile !=
nullptr) {
102 output_stream_ = fopen(datafile,
"w");
103 if (output_stream_ ==
nullptr) {
104 fprintf(stderr,
"Can't open output file %s. Using stderr.\n", datafile);
105 output_stream_ = stderr;
109 static const int num_counters = arraysize(kCounterList);
112 fprintf(output_stream_,
"# counters=%d\n", num_counters);
113 fprintf(output_stream_,
"# sample_period=%" PRIu64
"\n", sample_period_);
116 for (
int i = 0;
i < num_counters;
i++) {
117 Counter* counter =
new Counter(kCounterList[
i].name, kCounterList[
i].type);
118 counters_.push_back(counter);
125 Instrument::~Instrument() {
130 std::list<Counter*>::iterator it;
131 for (it = counters_.begin(); it != counters_.end(); it++) {
135 if (output_stream_ != stderr) {
136 fclose(output_stream_);
141 void Instrument::Update() {
144 static Counter* counter = GetCounter(
"Instruction");
145 DCHECK(counter->type() == Cumulative);
146 counter->Increment();
148 if (counter->IsEnabled() && (counter->count() % sample_period_) == 0) {
154 void Instrument::DumpCounters() {
157 std::list<Counter*>::const_iterator it;
158 for (it = counters_.begin(); it != counters_.end(); it++) {
159 fprintf(output_stream_,
"%" PRIu64
",", (*it)->count());
161 fprintf(output_stream_,
"\n");
162 fflush(output_stream_);
166 void Instrument::DumpCounterNames() {
169 std::list<Counter*>::const_iterator it;
170 for (it = counters_.begin(); it != counters_.end(); it++) {
171 fprintf(output_stream_,
"%s,", (*it)->name());
173 fprintf(output_stream_,
"\n");
174 fflush(output_stream_);
178 void Instrument::HandleInstrumentationEvent(
unsigned event) {
180 case InstrumentStateEnable: Enable();
break;
181 case InstrumentStateDisable: Disable();
break;
182 default: DumpEventMarker(event);
187 void Instrument::DumpEventMarker(
unsigned marker) {
190 static Counter* counter = GetCounter(
"Instruction");
192 fprintf(output_stream_,
"# %c%c @ %" PRId64
"\n", marker & 0xFF,
193 (marker >> 8) & 0xFF, counter->count());
197 Counter* Instrument::GetCounter(
const char* name) {
199 std::list<Counter*>::const_iterator it;
200 for (it = counters_.begin(); it != counters_.end(); it++) {
201 if (strcmp((*it)->name(), name) == 0) {
208 static const char* error_message =
209 "# Error: Unknown counter \"%s\". Exiting.\n";
210 fprintf(stderr, error_message, name);
211 fprintf(output_stream_, error_message, name);
216 void Instrument::Enable() {
217 std::list<Counter*>::iterator it;
218 for (it = counters_.begin(); it != counters_.end(); it++) {
224 void Instrument::Disable() {
225 std::list<Counter*>::iterator it;
226 for (it = counters_.begin(); it != counters_.end(); it++) {
232 void Instrument::VisitPCRelAddressing(Instruction* instr) {
234 static Counter* counter = GetCounter(
"PC Addressing");
235 counter->Increment();
239 void Instrument::VisitAddSubImmediate(Instruction* instr) {
241 static Counter* counter = GetCounter(
"Add/Sub DP");
242 counter->Increment();
246 void Instrument::VisitLogicalImmediate(Instruction* instr) {
248 static Counter* counter = GetCounter(
"Logical DP");
249 counter->Increment();
253 void Instrument::VisitMoveWideImmediate(Instruction* instr) {
255 static Counter* counter = GetCounter(
"Move Immediate");
257 if (instr->IsMovn() && (instr->Rd() == kZeroRegCode)) {
258 unsigned imm = instr->ImmMoveWide();
259 HandleInstrumentationEvent(imm);
261 counter->Increment();
266 void Instrument::VisitBitfield(Instruction* instr) {
268 static Counter* counter = GetCounter(
"Other Int DP");
269 counter->Increment();
273 void Instrument::VisitExtract(Instruction* instr) {
275 static Counter* counter = GetCounter(
"Other Int DP");
276 counter->Increment();
280 void Instrument::VisitUnconditionalBranch(Instruction* instr) {
282 static Counter* counter = GetCounter(
"Unconditional Branch");
283 counter->Increment();
287 void Instrument::VisitUnconditionalBranchToRegister(Instruction* instr) {
289 static Counter* counter = GetCounter(
"Unconditional Branch");
290 counter->Increment();
294 void Instrument::VisitCompareBranch(Instruction* instr) {
296 static Counter* counter = GetCounter(
"Compare and Branch");
297 counter->Increment();
301 void Instrument::VisitTestBranch(Instruction* instr) {
303 static Counter* counter = GetCounter(
"Test and Branch");
304 counter->Increment();
308 void Instrument::VisitConditionalBranch(Instruction* instr) {
310 static Counter* counter = GetCounter(
"Conditional Branch");
311 counter->Increment();
315 void Instrument::VisitSystem(Instruction* instr) {
317 static Counter* counter = GetCounter(
"Other");
318 counter->Increment();
322 void Instrument::VisitException(Instruction* instr) {
324 static Counter* counter = GetCounter(
"Other");
325 counter->Increment();
329 void Instrument::InstrumentLoadStorePair(Instruction* instr) {
330 static Counter* load_pair_counter = GetCounter(
"Load Pair");
331 static Counter* store_pair_counter = GetCounter(
"Store Pair");
332 if (instr->Mask(LoadStorePairLBit) != 0) {
333 load_pair_counter->Increment();
335 store_pair_counter->Increment();
340 void Instrument::VisitLoadStorePairPostIndex(Instruction* instr) {
342 InstrumentLoadStorePair(instr);
346 void Instrument::VisitLoadStorePairOffset(Instruction* instr) {
348 InstrumentLoadStorePair(instr);
352 void Instrument::VisitLoadStorePairPreIndex(Instruction* instr) {
354 InstrumentLoadStorePair(instr);
358 void Instrument::VisitLoadLiteral(Instruction* instr) {
360 static Counter* counter = GetCounter(
"Load Literal");
361 counter->Increment();
365 void Instrument::InstrumentLoadStore(Instruction* instr) {
366 static Counter* load_int_counter = GetCounter(
"Load Integer");
367 static Counter* store_int_counter = GetCounter(
"Store Integer");
368 static Counter* load_fp_counter = GetCounter(
"Load FP");
369 static Counter* store_fp_counter = GetCounter(
"Store FP");
371 switch (instr->Mask(LoadStoreMask)) {
375 case STR_x: store_int_counter->Increment();
break;
377 case STR_d: store_fp_counter->Increment();
break;
386 case LDRSH_w: load_int_counter->Increment();
break;
388 case LDR_d: load_fp_counter->Increment();
break;
389 default: UNREACHABLE();
394 void Instrument::VisitLoadStoreUnscaledOffset(Instruction* instr) {
396 InstrumentLoadStore(instr);
400 void Instrument::VisitLoadStorePostIndex(Instruction* instr) {
402 InstrumentLoadStore(instr);
406 void Instrument::VisitLoadStorePreIndex(Instruction* instr) {
408 InstrumentLoadStore(instr);
412 void Instrument::VisitLoadStoreRegisterOffset(Instruction* instr) {
414 InstrumentLoadStore(instr);
418 void Instrument::VisitLoadStoreUnsignedOffset(Instruction* instr) {
420 InstrumentLoadStore(instr);
423 void Instrument::VisitLoadStoreAcquireRelease(Instruction* instr) {
425 static Counter* load_counter = GetCounter(
"Load Acquire");
426 static Counter* store_counter = GetCounter(
"Store Release");
428 switch (instr->Mask(LoadStoreAcquireReleaseMask)) {
436 case LDAXR_x: load_counter->Increment();
break;
444 case STLXR_x: store_counter->Increment();
break;
445 default: UNREACHABLE();
449 void Instrument::VisitLogicalShifted(Instruction* instr) {
451 static Counter* counter = GetCounter(
"Logical DP");
452 counter->Increment();
456 void Instrument::VisitAddSubShifted(Instruction* instr) {
458 static Counter* counter = GetCounter(
"Add/Sub DP");
459 counter->Increment();
463 void Instrument::VisitAddSubExtended(Instruction* instr) {
465 static Counter* counter = GetCounter(
"Add/Sub DP");
466 counter->Increment();
470 void Instrument::VisitAddSubWithCarry(Instruction* instr) {
472 static Counter* counter = GetCounter(
"Add/Sub DP");
473 counter->Increment();
477 void Instrument::VisitConditionalCompareRegister(Instruction* instr) {
479 static Counter* counter = GetCounter(
"Conditional Compare");
480 counter->Increment();
484 void Instrument::VisitConditionalCompareImmediate(Instruction* instr) {
486 static Counter* counter = GetCounter(
"Conditional Compare");
487 counter->Increment();
491 void Instrument::VisitConditionalSelect(Instruction* instr) {
493 static Counter* counter = GetCounter(
"Conditional Select");
494 counter->Increment();
498 void Instrument::VisitDataProcessing1Source(Instruction* instr) {
500 static Counter* counter = GetCounter(
"Other Int DP");
501 counter->Increment();
505 void Instrument::VisitDataProcessing2Source(Instruction* instr) {
507 static Counter* counter = GetCounter(
"Other Int DP");
508 counter->Increment();
512 void Instrument::VisitDataProcessing3Source(Instruction* instr) {
514 static Counter* counter = GetCounter(
"Other Int DP");
515 counter->Increment();
519 void Instrument::VisitFPCompare(Instruction* instr) {
521 static Counter* counter = GetCounter(
"FP DP");
522 counter->Increment();
526 void Instrument::VisitFPConditionalCompare(Instruction* instr) {
528 static Counter* counter = GetCounter(
"Conditional Compare");
529 counter->Increment();
533 void Instrument::VisitFPConditionalSelect(Instruction* instr) {
535 static Counter* counter = GetCounter(
"Conditional Select");
536 counter->Increment();
540 void Instrument::VisitFPImmediate(Instruction* instr) {
542 static Counter* counter = GetCounter(
"FP DP");
543 counter->Increment();
547 void Instrument::VisitFPDataProcessing1Source(Instruction* instr) {
549 static Counter* counter = GetCounter(
"FP DP");
550 counter->Increment();
554 void Instrument::VisitFPDataProcessing2Source(Instruction* instr) {
556 static Counter* counter = GetCounter(
"FP DP");
557 counter->Increment();
561 void Instrument::VisitFPDataProcessing3Source(Instruction* instr) {
563 static Counter* counter = GetCounter(
"FP DP");
564 counter->Increment();
568 void Instrument::VisitFPIntegerConvert(Instruction* instr) {
570 static Counter* counter = GetCounter(
"FP DP");
571 counter->Increment();
575 void Instrument::VisitFPFixedPointConvert(Instruction* instr) {
577 static Counter* counter = GetCounter(
"FP DP");
578 counter->Increment();
581 void Instrument::VisitNEON2RegMisc(Instruction* instr) {
584 static Counter* counter = GetCounter(
"NEON");
585 counter->Increment();
588 void Instrument::VisitNEON3Different(Instruction* instr) {
591 static Counter* counter = GetCounter(
"NEON");
592 counter->Increment();
595 void Instrument::VisitNEON3Same(Instruction* instr) {
598 static Counter* counter = GetCounter(
"NEON");
599 counter->Increment();
602 void Instrument::VisitNEONAcrossLanes(Instruction* instr) {
605 static Counter* counter = GetCounter(
"NEON");
606 counter->Increment();
609 void Instrument::VisitNEONByIndexedElement(Instruction* instr) {
612 static Counter* counter = GetCounter(
"NEON");
613 counter->Increment();
616 void Instrument::VisitNEONCopy(Instruction* instr) {
619 static Counter* counter = GetCounter(
"NEON");
620 counter->Increment();
623 void Instrument::VisitNEONExtract(Instruction* instr) {
626 static Counter* counter = GetCounter(
"NEON");
627 counter->Increment();
630 void Instrument::VisitNEONLoadStoreMultiStruct(Instruction* instr) {
633 static Counter* counter = GetCounter(
"NEON");
634 counter->Increment();
637 void Instrument::VisitNEONLoadStoreMultiStructPostIndex(Instruction* instr) {
640 static Counter* counter = GetCounter(
"NEON");
641 counter->Increment();
644 void Instrument::VisitNEONLoadStoreSingleStruct(Instruction* instr) {
647 static Counter* counter = GetCounter(
"NEON");
648 counter->Increment();
651 void Instrument::VisitNEONLoadStoreSingleStructPostIndex(Instruction* instr) {
654 static Counter* counter = GetCounter(
"NEON");
655 counter->Increment();
658 void Instrument::VisitNEONModifiedImmediate(Instruction* instr) {
661 static Counter* counter = GetCounter(
"NEON");
662 counter->Increment();
665 void Instrument::VisitNEONPerm(Instruction* instr) {
668 static Counter* counter = GetCounter(
"NEON");
669 counter->Increment();
672 void Instrument::VisitNEONScalar2RegMisc(Instruction* instr) {
675 static Counter* counter = GetCounter(
"NEON");
676 counter->Increment();
679 void Instrument::VisitNEONScalar3Diff(Instruction* instr) {
682 static Counter* counter = GetCounter(
"NEON");
683 counter->Increment();
686 void Instrument::VisitNEONScalar3Same(Instruction* instr) {
689 static Counter* counter = GetCounter(
"NEON");
690 counter->Increment();
693 void Instrument::VisitNEONScalarByIndexedElement(Instruction* instr) {
696 static Counter* counter = GetCounter(
"NEON");
697 counter->Increment();
700 void Instrument::VisitNEONScalarCopy(Instruction* instr) {
703 static Counter* counter = GetCounter(
"NEON");
704 counter->Increment();
707 void Instrument::VisitNEONScalarPairwise(Instruction* instr) {
710 static Counter* counter = GetCounter(
"NEON");
711 counter->Increment();
714 void Instrument::VisitNEONScalarShiftImmediate(Instruction* instr) {
717 static Counter* counter = GetCounter(
"NEON");
718 counter->Increment();
721 void Instrument::VisitNEONShiftImmediate(Instruction* instr) {
724 static Counter* counter = GetCounter(
"NEON");
725 counter->Increment();
728 void Instrument::VisitNEONTable(Instruction* instr) {
731 static Counter* counter = GetCounter(
"NEON");
732 counter->Increment();
735 void Instrument::VisitUnallocated(Instruction* instr) {
737 static Counter* counter = GetCounter(
"Other");
738 counter->Increment();
742 void Instrument::VisitUnimplemented(Instruction* instr) {
744 static Counter* counter = GetCounter(
"Other");
745 counter->Increment();