js/src/perf/jsperf.h

changeset 0
6474c204b198
     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 */

mercurial