Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(225)

Side by Side Diff: src/a64/instrument-a64.cc

Issue 148293020: Merge experimental/a64 to bleeding_edge. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Remove ARM from OWNERS Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/a64/instrument-a64.h ('k') | src/a64/lithium-a64.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28 #include "a64/instrument-a64.h"
29
30 namespace v8 {
31 namespace internal {
32
33 Counter::Counter(const char* name, CounterType type)
34 : count_(0), enabled_(false), type_(type) {
35 ASSERT(name != NULL);
36 strncpy(name_, name, kCounterNameMaxLength);
37 }
38
39
40 void Counter::Enable() {
41 enabled_ = true;
42 }
43
44
45 void Counter::Disable() {
46 enabled_ = false;
47 }
48
49
50 bool Counter::IsEnabled() {
51 return enabled_;
52 }
53
54
55 void Counter::Increment() {
56 if (enabled_) {
57 count_++;
58 }
59 }
60
61
62 uint64_t Counter::count() {
63 uint64_t result = count_;
64 if (type_ == Gauge) {
65 // If the counter is a Gauge, reset the count after reading.
66 count_ = 0;
67 }
68 return result;
69 }
70
71
72 const char* Counter::name() {
73 return name_;
74 }
75
76
77 CounterType Counter::type() {
78 return type_;
79 }
80
81
82 typedef struct {
83 const char* name;
84 CounterType type;
85 } CounterDescriptor;
86
87
88 static const CounterDescriptor kCounterList[] = {
89 {"Instruction", Cumulative},
90
91 {"Move Immediate", Gauge},
92 {"Add/Sub DP", Gauge},
93 {"Logical DP", Gauge},
94 {"Other Int DP", Gauge},
95 {"FP DP", Gauge},
96
97 {"Conditional Select", Gauge},
98 {"Conditional Compare", Gauge},
99
100 {"Unconditional Branch", Gauge},
101 {"Compare and Branch", Gauge},
102 {"Test and Branch", Gauge},
103 {"Conditional Branch", Gauge},
104
105 {"Load Integer", Gauge},
106 {"Load FP", Gauge},
107 {"Load Pair", Gauge},
108 {"Load Literal", Gauge},
109
110 {"Store Integer", Gauge},
111 {"Store FP", Gauge},
112 {"Store Pair", Gauge},
113
114 {"PC Addressing", Gauge},
115 {"Other", Gauge},
116 {"SP Adjust", Gauge},
117 };
118
119
120 Instrument::Instrument(const char* datafile, uint64_t sample_period)
121 : output_stream_(stderr), sample_period_(sample_period) {
122
123 // Set up the output stream. If datafile is non-NULL, use that file. If it
124 // can't be opened, or datafile is NULL, use stderr.
125 if (datafile != NULL) {
126 output_stream_ = fopen(datafile, "w");
127 if (output_stream_ == NULL) {
128 fprintf(stderr, "Can't open output file %s. Using stderr.\n", datafile);
129 output_stream_ = stderr;
130 }
131 }
132
133 static const int num_counters =
134 sizeof(kCounterList) / sizeof(CounterDescriptor);
135
136 // Dump an instrumentation description comment at the top of the file.
137 fprintf(output_stream_, "# counters=%d\n", num_counters);
138 fprintf(output_stream_, "# sample_period=%" PRIu64 "\n", sample_period_);
139
140 // Construct Counter objects from counter description array.
141 for (int i = 0; i < num_counters; i++) {
142 Counter* counter = new Counter(kCounterList[i].name, kCounterList[i].type);
143 counters_.push_back(counter);
144 }
145
146 DumpCounterNames();
147 }
148
149
150 Instrument::~Instrument() {
151 // Dump any remaining instruction data to the output file.
152 DumpCounters();
153
154 // Free all the counter objects.
155 std::list<Counter*>::iterator it;
156 for (it = counters_.begin(); it != counters_.end(); it++) {
157 delete *it;
158 }
159
160 if (output_stream_ != stderr) {
161 fclose(output_stream_);
162 }
163 }
164
165
166 void Instrument::Update() {
167 // Increment the instruction counter, and dump all counters if a sample period
168 // has elapsed.
169 static Counter* counter = GetCounter("Instruction");
170 ASSERT(counter->type() == Cumulative);
171 counter->Increment();
172
173 if (counter->IsEnabled() && (counter->count() % sample_period_) == 0) {
174 DumpCounters();
175 }
176 }
177
178
179 void Instrument::DumpCounters() {
180 // Iterate through the counter objects, dumping their values to the output
181 // stream.
182 std::list<Counter*>::const_iterator it;
183 for (it = counters_.begin(); it != counters_.end(); it++) {
184 fprintf(output_stream_, "%" PRIu64 ",", (*it)->count());
185 }
186 fprintf(output_stream_, "\n");
187 fflush(output_stream_);
188 }
189
190
191 void Instrument::DumpCounterNames() {
192 // Iterate through the counter objects, dumping the counter names to the
193 // output stream.
194 std::list<Counter*>::const_iterator it;
195 for (it = counters_.begin(); it != counters_.end(); it++) {
196 fprintf(output_stream_, "%s,", (*it)->name());
197 }
198 fprintf(output_stream_, "\n");
199 fflush(output_stream_);
200 }
201
202
203 void Instrument::HandleInstrumentationEvent(unsigned event) {
204 switch (event) {
205 case InstrumentStateEnable: Enable(); break;
206 case InstrumentStateDisable: Disable(); break;
207 default: DumpEventMarker(event);
208 }
209 }
210
211
212 void Instrument::DumpEventMarker(unsigned marker) {
213 // Dumpan event marker to the output stream as a specially formatted comment
214 // line.
215 static Counter* counter = GetCounter("Instruction");
216
217 fprintf(output_stream_, "# %c%c @ %" PRId64 "\n", marker & 0xff,
218 (marker >> 8) & 0xff, counter->count());
219 }
220
221
222 Counter* Instrument::GetCounter(const char* name) {
223 // Get a Counter object by name from the counter list.
224 std::list<Counter*>::const_iterator it;
225 for (it = counters_.begin(); it != counters_.end(); it++) {
226 if (strcmp((*it)->name(), name) == 0) {
227 return *it;
228 }
229 }
230
231 // A Counter by that name does not exist: print an error message to stderr
232 // and the output file, and exit.
233 static const char* error_message =
234 "# Error: Unknown counter \"%s\". Exiting.\n";
235 fprintf(stderr, error_message, name);
236 fprintf(output_stream_, error_message, name);
237 exit(1);
238 }
239
240
241 void Instrument::Enable() {
242 std::list<Counter*>::iterator it;
243 for (it = counters_.begin(); it != counters_.end(); it++) {
244 (*it)->Enable();
245 }
246 }
247
248
249 void Instrument::Disable() {
250 std::list<Counter*>::iterator it;
251 for (it = counters_.begin(); it != counters_.end(); it++) {
252 (*it)->Disable();
253 }
254 }
255
256
257 void Instrument::VisitPCRelAddressing(Instruction* instr) {
258 Update();
259 static Counter* counter = GetCounter("PC Addressing");
260 counter->Increment();
261 }
262
263
264 void Instrument::VisitAddSubImmediate(Instruction* instr) {
265 Update();
266 static Counter* sp_counter = GetCounter("SP Adjust");
267 static Counter* add_sub_counter = GetCounter("Add/Sub DP");
268 if (((instr->Mask(AddSubOpMask) == SUB) ||
269 (instr->Mask(AddSubOpMask) == ADD)) &&
270 (instr->Rd() == 31) && (instr->Rn() == 31)) {
271 // Count adjustments to the C stack pointer caused by V8 needing two SPs.
272 sp_counter->Increment();
273 } else {
274 add_sub_counter->Increment();
275 }
276 }
277
278
279 void Instrument::VisitLogicalImmediate(Instruction* instr) {
280 Update();
281 static Counter* counter = GetCounter("Logical DP");
282 counter->Increment();
283 }
284
285
286 void Instrument::VisitMoveWideImmediate(Instruction* instr) {
287 Update();
288 static Counter* counter = GetCounter("Move Immediate");
289
290 if (instr->IsMovn() && (instr->Rd() == kZeroRegCode)) {
291 unsigned imm = instr->ImmMoveWide();
292 HandleInstrumentationEvent(imm);
293 } else {
294 counter->Increment();
295 }
296 }
297
298
299 void Instrument::VisitBitfield(Instruction* instr) {
300 Update();
301 static Counter* counter = GetCounter("Other Int DP");
302 counter->Increment();
303 }
304
305
306 void Instrument::VisitExtract(Instruction* instr) {
307 Update();
308 static Counter* counter = GetCounter("Other Int DP");
309 counter->Increment();
310 }
311
312
313 void Instrument::VisitUnconditionalBranch(Instruction* instr) {
314 Update();
315 static Counter* counter = GetCounter("Unconditional Branch");
316 counter->Increment();
317 }
318
319
320 void Instrument::VisitUnconditionalBranchToRegister(Instruction* instr) {
321 Update();
322 static Counter* counter = GetCounter("Unconditional Branch");
323 counter->Increment();
324 }
325
326
327 void Instrument::VisitCompareBranch(Instruction* instr) {
328 Update();
329 static Counter* counter = GetCounter("Compare and Branch");
330 counter->Increment();
331 }
332
333
334 void Instrument::VisitTestBranch(Instruction* instr) {
335 Update();
336 static Counter* counter = GetCounter("Test and Branch");
337 counter->Increment();
338 }
339
340
341 void Instrument::VisitConditionalBranch(Instruction* instr) {
342 Update();
343 static Counter* counter = GetCounter("Conditional Branch");
344 counter->Increment();
345 }
346
347
348 void Instrument::VisitSystem(Instruction* instr) {
349 Update();
350 static Counter* counter = GetCounter("Other");
351 counter->Increment();
352 }
353
354
355 void Instrument::VisitException(Instruction* instr) {
356 Update();
357 static Counter* counter = GetCounter("Other");
358 counter->Increment();
359 }
360
361
362 void Instrument::InstrumentLoadStorePair(Instruction* instr) {
363 static Counter* load_pair_counter = GetCounter("Load Pair");
364 static Counter* store_pair_counter = GetCounter("Store Pair");
365 if (instr->Mask(LoadStorePairLBit) != 0) {
366 load_pair_counter->Increment();
367 } else {
368 store_pair_counter->Increment();
369 }
370 }
371
372
373 void Instrument::VisitLoadStorePairPostIndex(Instruction* instr) {
374 Update();
375 InstrumentLoadStorePair(instr);
376 }
377
378
379 void Instrument::VisitLoadStorePairOffset(Instruction* instr) {
380 Update();
381 InstrumentLoadStorePair(instr);
382 }
383
384
385 void Instrument::VisitLoadStorePairPreIndex(Instruction* instr) {
386 Update();
387 InstrumentLoadStorePair(instr);
388 }
389
390
391 void Instrument::VisitLoadStorePairNonTemporal(Instruction* instr) {
392 Update();
393 InstrumentLoadStorePair(instr);
394 }
395
396
397 void Instrument::VisitLoadLiteral(Instruction* instr) {
398 Update();
399 static Counter* counter = GetCounter("Load Literal");
400 counter->Increment();
401 }
402
403
404 void Instrument::InstrumentLoadStore(Instruction* instr) {
405 static Counter* load_int_counter = GetCounter("Load Integer");
406 static Counter* store_int_counter = GetCounter("Store Integer");
407 static Counter* load_fp_counter = GetCounter("Load FP");
408 static Counter* store_fp_counter = GetCounter("Store FP");
409
410 switch (instr->Mask(LoadStoreOpMask)) {
411 case STRB_w: // Fall through.
412 case STRH_w: // Fall through.
413 case STR_w: // Fall through.
414 case STR_x: store_int_counter->Increment(); break;
415 case STR_s: // Fall through.
416 case STR_d: store_fp_counter->Increment(); break;
417 case LDRB_w: // Fall through.
418 case LDRH_w: // Fall through.
419 case LDR_w: // Fall through.
420 case LDR_x: // Fall through.
421 case LDRSB_x: // Fall through.
422 case LDRSH_x: // Fall through.
423 case LDRSW_x: // Fall through.
424 case LDRSB_w: // Fall through.
425 case LDRSH_w: load_int_counter->Increment(); break;
426 case LDR_s: // Fall through.
427 case LDR_d: load_fp_counter->Increment(); break;
428 default: UNREACHABLE();
429 }
430 }
431
432
433 void Instrument::VisitLoadStoreUnscaledOffset(Instruction* instr) {
434 Update();
435 InstrumentLoadStore(instr);
436 }
437
438
439 void Instrument::VisitLoadStorePostIndex(Instruction* instr) {
440 Update();
441 InstrumentLoadStore(instr);
442 }
443
444
445 void Instrument::VisitLoadStorePreIndex(Instruction* instr) {
446 Update();
447 InstrumentLoadStore(instr);
448 }
449
450
451 void Instrument::VisitLoadStoreRegisterOffset(Instruction* instr) {
452 Update();
453 InstrumentLoadStore(instr);
454 }
455
456
457 void Instrument::VisitLoadStoreUnsignedOffset(Instruction* instr) {
458 Update();
459 InstrumentLoadStore(instr);
460 }
461
462
463 void Instrument::VisitLogicalShifted(Instruction* instr) {
464 Update();
465 static Counter* counter = GetCounter("Logical DP");
466 counter->Increment();
467 }
468
469
470 void Instrument::VisitAddSubShifted(Instruction* instr) {
471 Update();
472 static Counter* counter = GetCounter("Add/Sub DP");
473 counter->Increment();
474 }
475
476
477 void Instrument::VisitAddSubExtended(Instruction* instr) {
478 Update();
479 static Counter* sp_counter = GetCounter("SP Adjust");
480 static Counter* add_sub_counter = GetCounter("Add/Sub DP");
481 if (((instr->Mask(AddSubOpMask) == SUB) ||
482 (instr->Mask(AddSubOpMask) == ADD)) &&
483 (instr->Rd() == 31) && (instr->Rn() == 31)) {
484 // Count adjustments to the C stack pointer caused by V8 needing two SPs.
485 sp_counter->Increment();
486 } else {
487 add_sub_counter->Increment();
488 }
489 }
490
491
492 void Instrument::VisitAddSubWithCarry(Instruction* instr) {
493 Update();
494 static Counter* counter = GetCounter("Add/Sub DP");
495 counter->Increment();
496 }
497
498
499 void Instrument::VisitConditionalCompareRegister(Instruction* instr) {
500 Update();
501 static Counter* counter = GetCounter("Conditional Compare");
502 counter->Increment();
503 }
504
505
506 void Instrument::VisitConditionalCompareImmediate(Instruction* instr) {
507 Update();
508 static Counter* counter = GetCounter("Conditional Compare");
509 counter->Increment();
510 }
511
512
513 void Instrument::VisitConditionalSelect(Instruction* instr) {
514 Update();
515 static Counter* counter = GetCounter("Conditional Select");
516 counter->Increment();
517 }
518
519
520 void Instrument::VisitDataProcessing1Source(Instruction* instr) {
521 Update();
522 static Counter* counter = GetCounter("Other Int DP");
523 counter->Increment();
524 }
525
526
527 void Instrument::VisitDataProcessing2Source(Instruction* instr) {
528 Update();
529 static Counter* counter = GetCounter("Other Int DP");
530 counter->Increment();
531 }
532
533
534 void Instrument::VisitDataProcessing3Source(Instruction* instr) {
535 Update();
536 static Counter* counter = GetCounter("Other Int DP");
537 counter->Increment();
538 }
539
540
541 void Instrument::VisitFPCompare(Instruction* instr) {
542 Update();
543 static Counter* counter = GetCounter("FP DP");
544 counter->Increment();
545 }
546
547
548 void Instrument::VisitFPConditionalCompare(Instruction* instr) {
549 Update();
550 static Counter* counter = GetCounter("Conditional Compare");
551 counter->Increment();
552 }
553
554
555 void Instrument::VisitFPConditionalSelect(Instruction* instr) {
556 Update();
557 static Counter* counter = GetCounter("Conditional Select");
558 counter->Increment();
559 }
560
561
562 void Instrument::VisitFPImmediate(Instruction* instr) {
563 Update();
564 static Counter* counter = GetCounter("FP DP");
565 counter->Increment();
566 }
567
568
569 void Instrument::VisitFPDataProcessing1Source(Instruction* instr) {
570 Update();
571 static Counter* counter = GetCounter("FP DP");
572 counter->Increment();
573 }
574
575
576 void Instrument::VisitFPDataProcessing2Source(Instruction* instr) {
577 Update();
578 static Counter* counter = GetCounter("FP DP");
579 counter->Increment();
580 }
581
582
583 void Instrument::VisitFPDataProcessing3Source(Instruction* instr) {
584 Update();
585 static Counter* counter = GetCounter("FP DP");
586 counter->Increment();
587 }
588
589
590 void Instrument::VisitFPIntegerConvert(Instruction* instr) {
591 Update();
592 static Counter* counter = GetCounter("FP DP");
593 counter->Increment();
594 }
595
596
597 void Instrument::VisitFPFixedPointConvert(Instruction* instr) {
598 Update();
599 static Counter* counter = GetCounter("FP DP");
600 counter->Increment();
601 }
602
603
604 void Instrument::VisitUnallocated(Instruction* instr) {
605 Update();
606 static Counter* counter = GetCounter("Other");
607 counter->Increment();
608 }
609
610
611 void Instrument::VisitUnimplemented(Instruction* instr) {
612 Update();
613 static Counter* counter = GetCounter("Other");
614 counter->Increment();
615 }
616
617
618 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/a64/instrument-a64.h ('k') | src/a64/lithium-a64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698