jsperf.h 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
  2. /* This Source Code Form is subject to the terms of the Mozilla Public
  3. * License, v. 2.0. If a copy of the MPL was not distributed with this
  4. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  5. #ifndef perf_jsperf_h
  6. #define perf_jsperf_h
  7. #include "jstypes.h"
  8. #include "js/TypeDecls.h"
  9. #include "js/Utility.h"
  10. namespace JS {
  11. /*
  12. * JS::PerfMeasurement is a generic way to access detailed performance
  13. * measurement APIs provided by your operating system. The details of
  14. * exactly how this works and what can be measured are highly
  15. * system-specific, but this interface is (one hopes) implementable
  16. * on top of all of them.
  17. *
  18. * To use this API, create a PerfMeasurement object, passing its
  19. * constructor a bitmask indicating which events you are interested
  20. * in. Thereafter, Start() zeroes all counters and starts timing;
  21. * Stop() stops timing again; and the counters for the events you
  22. * requested are available as data values after calling Stop(). The
  23. * object may be reused for many measurements.
  24. */
  25. class JS_FRIEND_API(PerfMeasurement)
  26. {
  27. protected:
  28. // Implementation-specific data, if any.
  29. void* impl;
  30. public:
  31. /*
  32. * Events that may be measured. Taken directly from the list of
  33. * "generalized hardware performance event types" in the Linux
  34. * perf_event API, plus some of the "software events".
  35. */
  36. enum EventMask {
  37. CPU_CYCLES = 0x00000001,
  38. INSTRUCTIONS = 0x00000002,
  39. CACHE_REFERENCES = 0x00000004,
  40. CACHE_MISSES = 0x00000008,
  41. BRANCH_INSTRUCTIONS = 0x00000010,
  42. BRANCH_MISSES = 0x00000020,
  43. BUS_CYCLES = 0x00000040,
  44. PAGE_FAULTS = 0x00000080,
  45. MAJOR_PAGE_FAULTS = 0x00000100,
  46. CONTEXT_SWITCHES = 0x00000200,
  47. CPU_MIGRATIONS = 0x00000400,
  48. ALL = 0x000007ff,
  49. NUM_MEASURABLE_EVENTS = 11
  50. };
  51. /*
  52. * Bitmask of events that will be measured when this object is
  53. * active (between Start() and Stop()). This may differ from the
  54. * bitmask passed to the constructor if the platform does not
  55. * support measuring all of the requested events.
  56. */
  57. const EventMask eventsMeasured;
  58. /*
  59. * Counters for each measurable event.
  60. * Immediately after one of these objects is created, all of the
  61. * counters for enabled events will be zero, and all of the
  62. * counters for disabled events will be uint64_t(-1).
  63. */
  64. uint64_t cpu_cycles;
  65. uint64_t instructions;
  66. uint64_t cache_references;
  67. uint64_t cache_misses;
  68. uint64_t branch_instructions;
  69. uint64_t branch_misses;
  70. uint64_t bus_cycles;
  71. uint64_t page_faults;
  72. uint64_t major_page_faults;
  73. uint64_t context_switches;
  74. uint64_t cpu_migrations;
  75. /*
  76. * Prepare to measure the indicated set of events. If not all of
  77. * the requested events can be measured on the current platform,
  78. * then the eventsMeasured bitmask will only include the subset of
  79. * |toMeasure| corresponding to the events that can be measured.
  80. */
  81. explicit PerfMeasurement(EventMask toMeasure);
  82. /* Done with this set of measurements, tear down OS-level state. */
  83. ~PerfMeasurement();
  84. /* Start a measurement cycle. */
  85. void start();
  86. /*
  87. * End a measurement cycle, and for each enabled counter, add the
  88. * number of measured events of that type to the appropriate
  89. * visible variable.
  90. */
  91. void stop();
  92. /* Reset all enabled counters to zero. */
  93. void reset();
  94. /*
  95. * True if this platform supports measuring _something_, i.e. it's
  96. * not using the stub implementation.
  97. */
  98. static bool canMeasureSomething();
  99. };
  100. /* Inject a Javascript wrapper around the above C++ class into the
  101. * Javascript object passed as an argument (this will normally be a
  102. * global object). The JS-visible API is identical to the C++ API.
  103. */
  104. extern JS_FRIEND_API(JSObject*)
  105. RegisterPerfMeasurement(JSContext* cx, JS::HandleObject global);
  106. /*
  107. * Given a Value which contains an instance of the aforementioned
  108. * wrapper class, extract the C++ object. Returns nullptr if the
  109. * Value is not an instance of the wrapper.
  110. */
  111. extern JS_FRIEND_API(PerfMeasurement*)
  112. ExtractPerfMeasurement(const Value& wrapper);
  113. } // namespace JS
  114. #endif /* perf_jsperf_h */