34 : count_(0), enabled_(
false), type_(type) {
63 uint64_t result = count_;
91 {
"Move Immediate",
Gauge},
92 {
"Add/Sub DP",
Gauge},
93 {
"Logical DP",
Gauge},
94 {
"Other Int DP",
Gauge},
97 {
"Conditional Select",
Gauge},
98 {
"Conditional Compare",
Gauge},
100 {
"Unconditional Branch",
Gauge},
101 {
"Compare and Branch",
Gauge},
102 {
"Test and Branch",
Gauge},
103 {
"Conditional Branch",
Gauge},
105 {
"Load Integer",
Gauge},
107 {
"Load Pair",
Gauge},
108 {
"Load Literal",
Gauge},
110 {
"Store Integer",
Gauge},
112 {
"Store Pair",
Gauge},
114 {
"PC Addressing",
Gauge},
116 {
"SP Adjust",
Gauge},
121 : output_stream_(stderr), sample_period_(sample_period) {
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;
133 static const int num_counters =
137 fprintf(output_stream_,
"# counters=%d\n", num_counters);
138 fprintf(output_stream_,
"# sample_period=%" PRIu64
"\n", sample_period_);
141 for (
int i = 0; i < num_counters; i++) {
143 counters_.push_back(counter);
155 std::list<Counter*>::iterator it;
156 for (it = counters_.begin(); it != counters_.end(); it++) {
160 if (output_stream_ != stderr) {
161 fclose(output_stream_);
166 void Instrument::Update() {
169 static Counter* counter = GetCounter(
"Instruction");
173 if (counter->
IsEnabled() && (counter->
count() % sample_period_) == 0) {
179 void Instrument::DumpCounters() {
182 std::list<Counter*>::const_iterator it;
183 for (it = counters_.begin(); it != counters_.end(); it++) {
184 fprintf(output_stream_,
"%" PRIu64
",", (*it)->count());
186 fprintf(output_stream_,
"\n");
187 fflush(output_stream_);
191 void Instrument::DumpCounterNames() {
194 std::list<Counter*>::const_iterator it;
195 for (it = counters_.begin(); it != counters_.end(); it++) {
196 fprintf(output_stream_,
"%s,", (*it)->name());
198 fprintf(output_stream_,
"\n");
199 fflush(output_stream_);
203 void Instrument::HandleInstrumentationEvent(
unsigned event) {
207 default: DumpEventMarker(event);
212 void Instrument::DumpEventMarker(
unsigned marker) {
215 static Counter* counter = GetCounter(
"Instruction");
217 fprintf(output_stream_,
"# %c%c @ %" PRId64
"\n", marker & 0xff,
218 (marker >> 8) & 0xff, counter->count());
222 Counter* Instrument::GetCounter(
const char*
name) {
224 std::list<Counter*>::const_iterator it;
225 for (it = counters_.begin(); it != counters_.end(); it++) {
226 if (strcmp((*it)->name(),
name) == 0) {
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);
241 void Instrument::Enable() {
242 std::list<Counter*>::iterator it;
243 for (it = counters_.begin(); it != counters_.end(); it++) {
249 void Instrument::Disable() {
250 std::list<Counter*>::iterator it;
251 for (it = counters_.begin(); it != counters_.end(); it++) {
257 void Instrument::VisitPCRelAddressing(Instruction* instr) {
259 static Counter* counter = GetCounter(
"PC Addressing");
260 counter->Increment();
264 void Instrument::VisitAddSubImmediate(Instruction* instr) {
266 static Counter* sp_counter = GetCounter(
"SP Adjust");
267 static Counter* add_sub_counter = GetCounter(
"Add/Sub DP");
270 (instr->Rd() == 31) && (instr->Rn() == 31)) {
272 sp_counter->Increment();
274 add_sub_counter->Increment();
279 void Instrument::VisitLogicalImmediate(Instruction* instr) {
281 static Counter* counter = GetCounter(
"Logical DP");
282 counter->Increment();
286 void Instrument::VisitMoveWideImmediate(Instruction* instr) {
288 static Counter* counter = GetCounter(
"Move Immediate");
291 unsigned imm = instr->ImmMoveWide();
292 HandleInstrumentationEvent(imm);
294 counter->Increment();
299 void Instrument::VisitBitfield(Instruction* instr) {
301 static Counter* counter = GetCounter(
"Other Int DP");
302 counter->Increment();
306 void Instrument::VisitExtract(Instruction* instr) {
308 static Counter* counter = GetCounter(
"Other Int DP");
309 counter->Increment();
313 void Instrument::VisitUnconditionalBranch(Instruction* instr) {
315 static Counter* counter = GetCounter(
"Unconditional Branch");
316 counter->Increment();
320 void Instrument::VisitUnconditionalBranchToRegister(Instruction* instr) {
322 static Counter* counter = GetCounter(
"Unconditional Branch");
323 counter->Increment();
327 void Instrument::VisitCompareBranch(Instruction* instr) {
329 static Counter* counter = GetCounter(
"Compare and Branch");
330 counter->Increment();
334 void Instrument::VisitTestBranch(Instruction* instr) {
336 static Counter* counter = GetCounter(
"Test and Branch");
337 counter->Increment();
341 void Instrument::VisitConditionalBranch(Instruction* instr) {
343 static Counter* counter = GetCounter(
"Conditional Branch");
344 counter->Increment();
348 void Instrument::VisitSystem(Instruction* instr) {
350 static Counter* counter = GetCounter(
"Other");
351 counter->Increment();
355 void Instrument::VisitException(Instruction* instr) {
357 static Counter* counter = GetCounter(
"Other");
358 counter->Increment();
362 void Instrument::InstrumentLoadStorePair(Instruction* instr) {
363 static Counter* load_pair_counter = GetCounter(
"Load Pair");
364 static Counter* store_pair_counter = GetCounter(
"Store Pair");
366 load_pair_counter->Increment();
368 store_pair_counter->Increment();
373 void Instrument::VisitLoadStorePairPostIndex(Instruction* instr) {
375 InstrumentLoadStorePair(instr);
379 void Instrument::VisitLoadStorePairOffset(Instruction* instr) {
381 InstrumentLoadStorePair(instr);
385 void Instrument::VisitLoadStorePairPreIndex(Instruction* instr) {
387 InstrumentLoadStorePair(instr);
391 void Instrument::VisitLoadStorePairNonTemporal(Instruction* instr) {
393 InstrumentLoadStorePair(instr);
397 void Instrument::VisitLoadLiteral(Instruction* instr) {
399 static Counter* counter = GetCounter(
"Load Literal");
400 counter->Increment();
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");
414 case STR_x: store_int_counter->Increment();
break;
416 case STR_d: store_fp_counter->Increment();
break;
425 case LDRSH_w: load_int_counter->Increment();
break;
427 case LDR_d: load_fp_counter->Increment();
break;
433 void Instrument::VisitLoadStoreUnscaledOffset(Instruction* instr) {
435 InstrumentLoadStore(instr);
439 void Instrument::VisitLoadStorePostIndex(Instruction* instr) {
441 InstrumentLoadStore(instr);
445 void Instrument::VisitLoadStorePreIndex(Instruction* instr) {
447 InstrumentLoadStore(instr);
451 void Instrument::VisitLoadStoreRegisterOffset(Instruction* instr) {
453 InstrumentLoadStore(instr);
457 void Instrument::VisitLoadStoreUnsignedOffset(Instruction* instr) {
459 InstrumentLoadStore(instr);
463 void Instrument::VisitLogicalShifted(Instruction* instr) {
465 static Counter* counter = GetCounter(
"Logical DP");
466 counter->Increment();
470 void Instrument::VisitAddSubShifted(Instruction* instr) {
472 static Counter* counter = GetCounter(
"Add/Sub DP");
473 counter->Increment();
477 void Instrument::VisitAddSubExtended(Instruction* instr) {
479 static Counter* sp_counter = GetCounter(
"SP Adjust");
480 static Counter* add_sub_counter = GetCounter(
"Add/Sub DP");
483 (instr->Rd() == 31) && (instr->Rn() == 31)) {
485 sp_counter->Increment();
487 add_sub_counter->Increment();
492 void Instrument::VisitAddSubWithCarry(Instruction* instr) {
494 static Counter* counter = GetCounter(
"Add/Sub DP");
495 counter->Increment();
499 void Instrument::VisitConditionalCompareRegister(Instruction* instr) {
501 static Counter* counter = GetCounter(
"Conditional Compare");
502 counter->Increment();
506 void Instrument::VisitConditionalCompareImmediate(Instruction* instr) {
508 static Counter* counter = GetCounter(
"Conditional Compare");
509 counter->Increment();
513 void Instrument::VisitConditionalSelect(Instruction* instr) {
515 static Counter* counter = GetCounter(
"Conditional Select");
516 counter->Increment();
520 void Instrument::VisitDataProcessing1Source(Instruction* instr) {
522 static Counter* counter = GetCounter(
"Other Int DP");
523 counter->Increment();
527 void Instrument::VisitDataProcessing2Source(Instruction* instr) {
529 static Counter* counter = GetCounter(
"Other Int DP");
530 counter->Increment();
534 void Instrument::VisitDataProcessing3Source(Instruction* instr) {
536 static Counter* counter = GetCounter(
"Other Int DP");
537 counter->Increment();
541 void Instrument::VisitFPCompare(Instruction* instr) {
543 static Counter* counter = GetCounter(
"FP DP");
544 counter->Increment();
548 void Instrument::VisitFPConditionalCompare(Instruction* instr) {
550 static Counter* counter = GetCounter(
"Conditional Compare");
551 counter->Increment();
555 void Instrument::VisitFPConditionalSelect(Instruction* instr) {
557 static Counter* counter = GetCounter(
"Conditional Select");
558 counter->Increment();
562 void Instrument::VisitFPImmediate(Instruction* instr) {
564 static Counter* counter = GetCounter(
"FP DP");
565 counter->Increment();
569 void Instrument::VisitFPDataProcessing1Source(Instruction* instr) {
571 static Counter* counter = GetCounter(
"FP DP");
572 counter->Increment();
576 void Instrument::VisitFPDataProcessing2Source(Instruction* instr) {
578 static Counter* counter = GetCounter(
"FP DP");
579 counter->Increment();
583 void Instrument::VisitFPDataProcessing3Source(Instruction* instr) {
585 static Counter* counter = GetCounter(
"FP DP");
586 counter->Increment();
590 void Instrument::VisitFPIntegerConvert(Instruction* instr) {
592 static Counter* counter = GetCounter(
"FP DP");
593 counter->Increment();
597 void Instrument::VisitFPFixedPointConvert(Instruction* instr) {
599 static Counter* counter = GetCounter(
"FP DP");
600 counter->Increment();
604 void Instrument::VisitUnallocated(Instruction* instr) {
606 static Counter* counter = GetCounter(
"Other");
607 counter->Increment();
611 void Instrument::VisitUnimplemented(Instruction* instr) {
613 static Counter* counter = GetCounter(
"Other");
614 counter->Increment();
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter NULL
const unsigned kZeroRegCode
#define ASSERT(condition)
const int kCounterNameMaxLength
Counter(const char *name, CounterType type=Gauge)
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter trace hydrogen to given file name trace inlining decisions trace store elimination trace all use positions trace global value numbering trace hydrogen escape analysis trace the tracking of allocation sites trace map generalization environment for every instruction deoptimize every n garbage collections put a break point before deoptimizing deoptimize uncommon cases use on stack replacement trace array bounds check elimination perform array index dehoisting use load elimination use store elimination use constant folding eliminate unreachable code number of stress runs when picking a function to watch for shared function not JSFunction itself flushes the cache of optimized code for closures on every GC functions with arguments object maximum number of escape analysis fix point iterations allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms concurrent on stack replacement do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes number of stack frames inspected by the profiler percentage of ICs that must have type info to allow optimization extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long expose natives in global object expose freeBuffer extension expose gc extension under the specified name expose externalize string extension number of stack frames to capture disable builtin natives files print name of functions for which code is generated use random jit cookie to mask large constants trace lazy optimization use adaptive optimizations always try to OSR functions trace optimize function deoptimization minimum length for automatic enable preparsing maximum number of optimization attempts before giving up cache prototype transitions trace debugging JSON request response trace out of bounds accesses to external arrays trace_js_array_abuse automatically set the debug break flag when debugger commands are in the queue abort by crashing maximum length of function source code printed in a stack trace max size of the new max size of the old max size of executable always perform global GCs print one trace line following each garbage collection do not print trace line after scavenger collection print statistics of the maximum memory committed for the heap in name
Instrument(const char *datafile=NULL, uint64_t sample_period=kDefaultInstrumentationSamplingPeriod)