1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/js/src/perf/jsperf.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,133 @@ 1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#ifndef perf_jsperf_h 1.10 +#define perf_jsperf_h 1.11 + 1.12 +#include "jstypes.h" 1.13 + 1.14 +#include "js/TypeDecls.h" 1.15 +#include "js/Utility.h" 1.16 + 1.17 +namespace JS { 1.18 + 1.19 +/* 1.20 + * JS::PerfMeasurement is a generic way to access detailed performance 1.21 + * measurement APIs provided by your operating system. The details of 1.22 + * exactly how this works and what can be measured are highly 1.23 + * system-specific, but this interface is (one hopes) implementable 1.24 + * on top of all of them. 1.25 + * 1.26 + * To use this API, create a PerfMeasurement object, passing its 1.27 + * constructor a bitmask indicating which events you are interested 1.28 + * in. Thereafter, Start() zeroes all counters and starts timing; 1.29 + * Stop() stops timing again; and the counters for the events you 1.30 + * requested are available as data values after calling Stop(). The 1.31 + * object may be reused for many measurements. 1.32 + */ 1.33 +class JS_FRIEND_API(PerfMeasurement) 1.34 +{ 1.35 + protected: 1.36 + // Implementation-specific data, if any. 1.37 + void* impl; 1.38 + 1.39 + public: 1.40 + /* 1.41 + * Events that may be measured. Taken directly from the list of 1.42 + * "generalized hardware performance event types" in the Linux 1.43 + * perf_event API, plus some of the "software events". 1.44 + */ 1.45 + enum EventMask { 1.46 + CPU_CYCLES = 0x00000001, 1.47 + INSTRUCTIONS = 0x00000002, 1.48 + CACHE_REFERENCES = 0x00000004, 1.49 + CACHE_MISSES = 0x00000008, 1.50 + BRANCH_INSTRUCTIONS = 0x00000010, 1.51 + BRANCH_MISSES = 0x00000020, 1.52 + BUS_CYCLES = 0x00000040, 1.53 + PAGE_FAULTS = 0x00000080, 1.54 + MAJOR_PAGE_FAULTS = 0x00000100, 1.55 + CONTEXT_SWITCHES = 0x00000200, 1.56 + CPU_MIGRATIONS = 0x00000400, 1.57 + 1.58 + ALL = 0x000007ff, 1.59 + NUM_MEASURABLE_EVENTS = 11 1.60 + }; 1.61 + 1.62 + /* 1.63 + * Bitmask of events that will be measured when this object is 1.64 + * active (between Start() and Stop()). This may differ from the 1.65 + * bitmask passed to the constructor if the platform does not 1.66 + * support measuring all of the requested events. 1.67 + */ 1.68 + const EventMask eventsMeasured; 1.69 + 1.70 + /* 1.71 + * Counters for each measurable event. 1.72 + * Immediately after one of these objects is created, all of the 1.73 + * counters for enabled events will be zero, and all of the 1.74 + * counters for disabled events will be uint64_t(-1). 1.75 + */ 1.76 + uint64_t cpu_cycles; 1.77 + uint64_t instructions; 1.78 + uint64_t cache_references; 1.79 + uint64_t cache_misses; 1.80 + uint64_t branch_instructions; 1.81 + uint64_t branch_misses; 1.82 + uint64_t bus_cycles; 1.83 + uint64_t page_faults; 1.84 + uint64_t major_page_faults; 1.85 + uint64_t context_switches; 1.86 + uint64_t cpu_migrations; 1.87 + 1.88 + /* 1.89 + * Prepare to measure the indicated set of events. If not all of 1.90 + * the requested events can be measured on the current platform, 1.91 + * then the eventsMeasured bitmask will only include the subset of 1.92 + * |toMeasure| corresponding to the events that can be measured. 1.93 + */ 1.94 + PerfMeasurement(EventMask toMeasure); 1.95 + 1.96 + /* Done with this set of measurements, tear down OS-level state. */ 1.97 + ~PerfMeasurement(); 1.98 + 1.99 + /* Start a measurement cycle. */ 1.100 + void start(); 1.101 + 1.102 + /* 1.103 + * End a measurement cycle, and for each enabled counter, add the 1.104 + * number of measured events of that type to the appropriate 1.105 + * visible variable. 1.106 + */ 1.107 + void stop(); 1.108 + 1.109 + /* Reset all enabled counters to zero. */ 1.110 + void reset(); 1.111 + 1.112 + /* 1.113 + * True if this platform supports measuring _something_, i.e. it's 1.114 + * not using the stub implementation. 1.115 + */ 1.116 + static bool canMeasureSomething(); 1.117 +}; 1.118 + 1.119 +/* Inject a Javascript wrapper around the above C++ class into the 1.120 + * Javascript object passed as an argument (this will normally be a 1.121 + * global object). The JS-visible API is identical to the C++ API. 1.122 + */ 1.123 +extern JS_FRIEND_API(JSObject*) 1.124 + RegisterPerfMeasurement(JSContext *cx, JS::HandleObject global); 1.125 + 1.126 +/* 1.127 + * Given a Value which contains an instance of the aforementioned 1.128 + * wrapper class, extract the C++ object. Returns nullptr if the 1.129 + * Value is not an instance of the wrapper. 1.130 + */ 1.131 +extern JS_FRIEND_API(PerfMeasurement*) 1.132 + ExtractPerfMeasurement(Value wrapper); 1.133 + 1.134 +} // namespace JS 1.135 + 1.136 +#endif /* perf_jsperf_h */