Home | History | Annotate | Download | only in src
      1 // Copyright 2012 the V8 project authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef V8_COUNTERS_H_
      6 #define V8_COUNTERS_H_
      7 
      8 #include "include/v8.h"
      9 #include "src/allocation.h"
     10 #include "src/globals.h"
     11 #include "src/objects.h"
     12 #include "src/platform/elapsed-timer.h"
     13 
     14 namespace v8 {
     15 namespace internal {
     16 
     17 // StatsCounters is an interface for plugging into external
     18 // counters for monitoring.  Counters can be looked up and
     19 // manipulated by name.
     20 
     21 class StatsTable {
     22  public:
     23   // Register an application-defined function where
     24   // counters can be looked up.
     25   void SetCounterFunction(CounterLookupCallback f) {
     26     lookup_function_ = f;
     27   }
     28 
     29   // Register an application-defined function to create
     30   // a histogram for passing to the AddHistogramSample function
     31   void SetCreateHistogramFunction(CreateHistogramCallback f) {
     32     create_histogram_function_ = f;
     33   }
     34 
     35   // Register an application-defined function to add a sample
     36   // to a histogram created with CreateHistogram function
     37   void SetAddHistogramSampleFunction(AddHistogramSampleCallback f) {
     38     add_histogram_sample_function_ = f;
     39   }
     40 
     41   bool HasCounterFunction() const {
     42     return lookup_function_ != NULL;
     43   }
     44 
     45   // Lookup the location of a counter by name.  If the lookup
     46   // is successful, returns a non-NULL pointer for writing the
     47   // value of the counter.  Each thread calling this function
     48   // may receive a different location to store it's counter.
     49   // The return value must not be cached and re-used across
     50   // threads, although a single thread is free to cache it.
     51   int* FindLocation(const char* name) {
     52     if (!lookup_function_) return NULL;
     53     return lookup_function_(name);
     54   }
     55 
     56   // Create a histogram by name. If the create is successful,
     57   // returns a non-NULL pointer for use with AddHistogramSample
     58   // function. min and max define the expected minimum and maximum
     59   // sample values. buckets is the maximum number of buckets
     60   // that the samples will be grouped into.
     61   void* CreateHistogram(const char* name,
     62                         int min,
     63                         int max,
     64                         size_t buckets) {
     65     if (!create_histogram_function_) return NULL;
     66     return create_histogram_function_(name, min, max, buckets);
     67   }
     68 
     69   // Add a sample to a histogram created with the CreateHistogram
     70   // function.
     71   void AddHistogramSample(void* histogram, int sample) {
     72     if (!add_histogram_sample_function_) return;
     73     return add_histogram_sample_function_(histogram, sample);
     74   }
     75 
     76  private:
     77   StatsTable();
     78 
     79   CounterLookupCallback lookup_function_;
     80   CreateHistogramCallback create_histogram_function_;
     81   AddHistogramSampleCallback add_histogram_sample_function_;
     82 
     83   friend class Isolate;
     84 
     85   DISALLOW_COPY_AND_ASSIGN(StatsTable);
     86 };
     87 
     88 // StatsCounters are dynamically created values which can be tracked in
     89 // the StatsTable.  They are designed to be lightweight to create and
     90 // easy to use.
     91 //
     92 // Internally, a counter represents a value in a row of a StatsTable.
     93 // The row has a 32bit value for each process/thread in the table and also
     94 // a name (stored in the table metadata).  Since the storage location can be
     95 // thread-specific, this class cannot be shared across threads.
     96 class StatsCounter {
     97  public:
     98   StatsCounter() { }
     99   explicit StatsCounter(Isolate* isolate, const char* name)
    100       : isolate_(isolate), name_(name), ptr_(NULL), lookup_done_(false) { }
    101 
    102   // Sets the counter to a specific value.
    103   void Set(int value) {
    104     int* loc = GetPtr();
    105     if (loc) *loc = value;
    106   }
    107 
    108   // Increments the counter.
    109   void Increment() {
    110     int* loc = GetPtr();
    111     if (loc) (*loc)++;
    112   }
    113 
    114   void Increment(int value) {
    115     int* loc = GetPtr();
    116     if (loc)
    117       (*loc) += value;
    118   }
    119 
    120   // Decrements the counter.
    121   void Decrement() {
    122     int* loc = GetPtr();
    123     if (loc) (*loc)--;
    124   }
    125 
    126   void Decrement(int value) {
    127     int* loc = GetPtr();
    128     if (loc) (*loc) -= value;
    129   }
    130 
    131   // Is this counter enabled?
    132   // Returns false if table is full.
    133   bool Enabled() {
    134     return GetPtr() != NULL;
    135   }
    136 
    137   // Get the internal pointer to the counter. This is used
    138   // by the code generator to emit code that manipulates a
    139   // given counter without calling the runtime system.
    140   int* GetInternalPointer() {
    141     int* loc = GetPtr();
    142     ASSERT(loc != NULL);
    143     return loc;
    144   }
    145 
    146   // Reset the cached internal pointer.
    147   void Reset() { lookup_done_ = false; }
    148 
    149  protected:
    150   // Returns the cached address of this counter location.
    151   int* GetPtr() {
    152     if (lookup_done_) return ptr_;
    153     lookup_done_ = true;
    154     ptr_ = FindLocationInStatsTable();
    155     return ptr_;
    156   }
    157 
    158  private:
    159   int* FindLocationInStatsTable() const;
    160 
    161   Isolate* isolate_;
    162   const char* name_;
    163   int* ptr_;
    164   bool lookup_done_;
    165 };
    166 
    167 // A Histogram represents a dynamically created histogram in the StatsTable.
    168 // It will be registered with the histogram system on first use.
    169 class Histogram {
    170  public:
    171   Histogram() { }
    172   Histogram(const char* name,
    173             int min,
    174             int max,
    175             int num_buckets,
    176             Isolate* isolate)
    177       : name_(name),
    178         min_(min),
    179         max_(max),
    180         num_buckets_(num_buckets),
    181         histogram_(NULL),
    182         lookup_done_(false),
    183         isolate_(isolate) { }
    184 
    185   // Add a single sample to this histogram.
    186   void AddSample(int sample);
    187 
    188   // Returns true if this histogram is enabled.
    189   bool Enabled() {
    190     return GetHistogram() != NULL;
    191   }
    192 
    193   // Reset the cached internal pointer.
    194   void Reset() {
    195     lookup_done_ = false;
    196   }
    197 
    198  protected:
    199   // Returns the handle to the histogram.
    200   void* GetHistogram() {
    201     if (!lookup_done_) {
    202       lookup_done_ = true;
    203       histogram_ = CreateHistogram();
    204     }
    205     return histogram_;
    206   }
    207 
    208   const char* name() { return name_; }
    209   Isolate* isolate() const { return isolate_; }
    210 
    211  private:
    212   void* CreateHistogram() const;
    213 
    214   const char* name_;
    215   int min_;
    216   int max_;
    217   int num_buckets_;
    218   void* histogram_;
    219   bool lookup_done_;
    220   Isolate* isolate_;
    221 };
    222 
    223 // A HistogramTimer allows distributions of results to be created.
    224 class HistogramTimer : public Histogram {
    225  public:
    226   HistogramTimer() { }
    227   HistogramTimer(const char* name,
    228                  int min,
    229                  int max,
    230                  int num_buckets,
    231                  Isolate* isolate)
    232       : Histogram(name, min, max, num_buckets, isolate) {}
    233 
    234   // Start the timer.
    235   void Start();
    236 
    237   // Stop the timer and record the results.
    238   void Stop();
    239 
    240   // Returns true if the timer is running.
    241   bool Running() {
    242     return Enabled() && timer_.IsStarted();
    243   }
    244 
    245   // TODO(bmeurer): Remove this when HistogramTimerScope is fixed.
    246 #ifdef DEBUG
    247   ElapsedTimer* timer() { return &timer_; }
    248 #endif
    249 
    250  private:
    251   ElapsedTimer timer_;
    252 };
    253 
    254 // Helper class for scoping a HistogramTimer.
    255 // TODO(bmeurer): The ifdeffery is an ugly hack around the fact that the
    256 // Parser is currently reentrant (when it throws an error, we call back
    257 // into JavaScript and all bets are off), but ElapsedTimer is not
    258 // reentry-safe. Fix this properly and remove |allow_nesting|.
    259 class HistogramTimerScope BASE_EMBEDDED {
    260  public:
    261   explicit HistogramTimerScope(HistogramTimer* timer,
    262                                bool allow_nesting = false)
    263 #ifdef DEBUG
    264       : timer_(timer),
    265         skipped_timer_start_(false) {
    266     if (timer_->timer()->IsStarted() && allow_nesting) {
    267       skipped_timer_start_ = true;
    268     } else {
    269       timer_->Start();
    270     }
    271   }
    272 #else
    273       : timer_(timer) {
    274     timer_->Start();
    275   }
    276 #endif
    277   ~HistogramTimerScope() {
    278 #ifdef DEBUG
    279     if (!skipped_timer_start_) {
    280       timer_->Stop();
    281     }
    282 #else
    283     timer_->Stop();
    284 #endif
    285   }
    286 
    287  private:
    288   HistogramTimer* timer_;
    289 #ifdef DEBUG
    290   bool skipped_timer_start_;
    291 #endif
    292 };
    293 
    294 
    295 #define HISTOGRAM_TIMER_LIST(HT)                                      \
    296   /* Garbage collection timers. */                                    \
    297   HT(gc_compactor, V8.GCCompactor)                                    \
    298   HT(gc_scavenger, V8.GCScavenger)                                    \
    299   HT(gc_context, V8.GCContext) /* GC context cleanup time */          \
    300   /* Parsing timers. */                                               \
    301   HT(parse, V8.Parse)                                                 \
    302   HT(parse_lazy, V8.ParseLazy)                                        \
    303   HT(pre_parse, V8.PreParse)                                          \
    304   /* Total compilation times. */                                      \
    305   HT(compile, V8.Compile)                                             \
    306   HT(compile_eval, V8.CompileEval)                                    \
    307   HT(compile_lazy, V8.CompileLazy)
    308 
    309 #define HISTOGRAM_PERCENTAGE_LIST(HP)                                 \
    310   /* Heap fragmentation. */                                           \
    311   HP(external_fragmentation_total,                                    \
    312      V8.MemoryExternalFragmentationTotal)                             \
    313   HP(external_fragmentation_old_pointer_space,                        \
    314      V8.MemoryExternalFragmentationOldPointerSpace)                   \
    315   HP(external_fragmentation_old_data_space,                           \
    316      V8.MemoryExternalFragmentationOldDataSpace)                      \
    317   HP(external_fragmentation_code_space,                               \
    318      V8.MemoryExternalFragmentationCodeSpace)                         \
    319   HP(external_fragmentation_map_space,                                \
    320      V8.MemoryExternalFragmentationMapSpace)                          \
    321   HP(external_fragmentation_cell_space,                               \
    322      V8.MemoryExternalFragmentationCellSpace)                         \
    323   HP(external_fragmentation_property_cell_space,                      \
    324      V8.MemoryExternalFragmentationPropertyCellSpace)                 \
    325   HP(external_fragmentation_lo_space,                                 \
    326      V8.MemoryExternalFragmentationLoSpace)                           \
    327   /* Percentages of heap committed to each space. */                  \
    328   HP(heap_fraction_new_space,                                         \
    329      V8.MemoryHeapFractionNewSpace)                                   \
    330   HP(heap_fraction_old_pointer_space,                                 \
    331      V8.MemoryHeapFractionOldPointerSpace)                            \
    332   HP(heap_fraction_old_data_space,                                    \
    333      V8.MemoryHeapFractionOldDataSpace)                               \
    334   HP(heap_fraction_code_space,                                        \
    335      V8.MemoryHeapFractionCodeSpace)                                  \
    336   HP(heap_fraction_map_space,                                         \
    337      V8.MemoryHeapFractionMapSpace)                                   \
    338   HP(heap_fraction_cell_space,                                        \
    339      V8.MemoryHeapFractionCellSpace)                                  \
    340   HP(heap_fraction_property_cell_space,                               \
    341      V8.MemoryHeapFractionPropertyCellSpace)                          \
    342   HP(heap_fraction_lo_space,                                          \
    343      V8.MemoryHeapFractionLoSpace)                                    \
    344   /* Percentage of crankshafted codegen. */                           \
    345   HP(codegen_fraction_crankshaft,                                     \
    346      V8.CodegenFractionCrankshaft)                                    \
    347 
    348 
    349 #define HISTOGRAM_MEMORY_LIST(HM)                                     \
    350   HM(heap_sample_total_committed, V8.MemoryHeapSampleTotalCommitted)  \
    351   HM(heap_sample_total_used, V8.MemoryHeapSampleTotalUsed)            \
    352   HM(heap_sample_map_space_committed,                                 \
    353      V8.MemoryHeapSampleMapSpaceCommitted)                            \
    354   HM(heap_sample_cell_space_committed,                                \
    355      V8.MemoryHeapSampleCellSpaceCommitted)                           \
    356   HM(heap_sample_property_cell_space_committed,                       \
    357      V8.MemoryHeapSamplePropertyCellSpaceCommitted)                   \
    358   HM(heap_sample_code_space_committed,                                \
    359      V8.MemoryHeapSampleCodeSpaceCommitted)                           \
    360   HM(heap_sample_maximum_committed,                                   \
    361      V8.MemoryHeapSampleMaximumCommitted)                             \
    362 
    363 
    364 // WARNING: STATS_COUNTER_LIST_* is a very large macro that is causing MSVC
    365 // Intellisense to crash.  It was broken into two macros (each of length 40
    366 // lines) rather than one macro (of length about 80 lines) to work around
    367 // this problem.  Please avoid using recursive macros of this length when
    368 // possible.
    369 #define STATS_COUNTER_LIST_1(SC)                                      \
    370   /* Global Handle Count*/                                            \
    371   SC(global_handles, V8.GlobalHandles)                                \
    372   /* OS Memory allocated */                                           \
    373   SC(memory_allocated, V8.OsMemoryAllocated)                          \
    374   SC(normalized_maps, V8.NormalizedMaps)                              \
    375   SC(props_to_dictionary, V8.ObjectPropertiesToDictionary)            \
    376   SC(elements_to_dictionary, V8.ObjectElementsToDictionary)           \
    377   SC(alive_after_last_gc, V8.AliveAfterLastGC)                        \
    378   SC(objs_since_last_young, V8.ObjsSinceLastYoung)                    \
    379   SC(objs_since_last_full, V8.ObjsSinceLastFull)                      \
    380   SC(string_table_capacity, V8.StringTableCapacity)                   \
    381   SC(number_of_symbols, V8.NumberOfSymbols)                           \
    382   SC(script_wrappers, V8.ScriptWrappers)                              \
    383   SC(call_initialize_stubs, V8.CallInitializeStubs)                   \
    384   SC(call_premonomorphic_stubs, V8.CallPreMonomorphicStubs)           \
    385   SC(call_normal_stubs, V8.CallNormalStubs)                           \
    386   SC(call_megamorphic_stubs, V8.CallMegamorphicStubs)                 \
    387   SC(inlined_copied_elements, V8.InlinedCopiedElements)              \
    388   SC(arguments_adaptors, V8.ArgumentsAdaptors)                        \
    389   SC(compilation_cache_hits, V8.CompilationCacheHits)                 \
    390   SC(compilation_cache_misses, V8.CompilationCacheMisses)             \
    391   SC(string_ctor_calls, V8.StringConstructorCalls)                    \
    392   SC(string_ctor_conversions, V8.StringConstructorConversions)        \
    393   SC(string_ctor_cached_number, V8.StringConstructorCachedNumber)     \
    394   SC(string_ctor_string_value, V8.StringConstructorStringValue)       \
    395   SC(string_ctor_gc_required, V8.StringConstructorGCRequired)         \
    396   /* Amount of evaled source code. */                                 \
    397   SC(total_eval_size, V8.TotalEvalSize)                               \
    398   /* Amount of loaded source code. */                                 \
    399   SC(total_load_size, V8.TotalLoadSize)                               \
    400   /* Amount of parsed source code. */                                 \
    401   SC(total_parse_size, V8.TotalParseSize)                             \
    402   /* Amount of source code skipped over using preparsing. */          \
    403   SC(total_preparse_skipped, V8.TotalPreparseSkipped)                 \
    404   /* Number of symbol lookups skipped using preparsing */             \
    405   SC(total_preparse_symbols_skipped, V8.TotalPreparseSymbolSkipped)   \
    406   /* Amount of compiled source code. */                               \
    407   SC(total_compile_size, V8.TotalCompileSize)                         \
    408   /* Amount of source code compiled with the full codegen. */         \
    409   SC(total_full_codegen_source_size, V8.TotalFullCodegenSourceSize)   \
    410   /* Number of contexts created from scratch. */                      \
    411   SC(contexts_created_from_scratch, V8.ContextsCreatedFromScratch)    \
    412   /* Number of contexts created by partial snapshot. */               \
    413   SC(contexts_created_by_snapshot, V8.ContextsCreatedBySnapshot)      \
    414   /* Number of code objects found from pc. */                         \
    415   SC(pc_to_code, V8.PcToCode)                                         \
    416   SC(pc_to_code_cached, V8.PcToCodeCached)                            \
    417   /* The store-buffer implementation of the write barrier. */         \
    418   SC(store_buffer_compactions, V8.StoreBufferCompactions)             \
    419   SC(store_buffer_overflows, V8.StoreBufferOverflows)
    420 
    421 
    422 #define STATS_COUNTER_LIST_2(SC)                                      \
    423   /* Number of code stubs. */                                         \
    424   SC(code_stubs, V8.CodeStubs)                                        \
    425   /* Amount of stub code. */                                          \
    426   SC(total_stubs_code_size, V8.TotalStubsCodeSize)                    \
    427   /* Amount of (JS) compiled code. */                                 \
    428   SC(total_compiled_code_size, V8.TotalCompiledCodeSize)              \
    429   SC(gc_compactor_caused_by_request, V8.GCCompactorCausedByRequest)   \
    430   SC(gc_compactor_caused_by_promoted_data,                            \
    431      V8.GCCompactorCausedByPromotedData)                              \
    432   SC(gc_compactor_caused_by_oldspace_exhaustion,                      \
    433      V8.GCCompactorCausedByOldspaceExhaustion)                        \
    434   SC(gc_last_resort_from_js, V8.GCLastResortFromJS)                   \
    435   SC(gc_last_resort_from_handles, V8.GCLastResortFromHandles)         \
    436   /* How is the generic keyed-load stub used? */                      \
    437   SC(keyed_load_generic_smi, V8.KeyedLoadGenericSmi)                  \
    438   SC(keyed_load_generic_symbol, V8.KeyedLoadGenericSymbol)            \
    439   SC(keyed_load_generic_lookup_cache, V8.KeyedLoadGenericLookupCache) \
    440   SC(keyed_load_generic_slow, V8.KeyedLoadGenericSlow)                \
    441   SC(keyed_load_polymorphic_stubs, V8.KeyedLoadPolymorphicStubs)      \
    442   SC(keyed_load_external_array_slow, V8.KeyedLoadExternalArraySlow)   \
    443   /* How is the generic keyed-call stub used? */                      \
    444   SC(keyed_call_generic_smi_fast, V8.KeyedCallGenericSmiFast)         \
    445   SC(keyed_call_generic_smi_dict, V8.KeyedCallGenericSmiDict)         \
    446   SC(keyed_call_generic_lookup_cache, V8.KeyedCallGenericLookupCache) \
    447   SC(keyed_call_generic_lookup_dict, V8.KeyedCallGenericLookupDict)   \
    448   SC(keyed_call_generic_slow, V8.KeyedCallGenericSlow)                \
    449   SC(keyed_call_generic_slow_load, V8.KeyedCallGenericSlowLoad)       \
    450   SC(named_load_global_stub, V8.NamedLoadGlobalStub)                  \
    451   SC(named_store_global_inline, V8.NamedStoreGlobalInline)            \
    452   SC(named_store_global_inline_miss, V8.NamedStoreGlobalInlineMiss)   \
    453   SC(keyed_store_polymorphic_stubs, V8.KeyedStorePolymorphicStubs)    \
    454   SC(keyed_store_external_array_slow, V8.KeyedStoreExternalArraySlow) \
    455   SC(store_normal_miss, V8.StoreNormalMiss)                           \
    456   SC(store_normal_hit, V8.StoreNormalHit)                             \
    457   SC(cow_arrays_created_stub, V8.COWArraysCreatedStub)                \
    458   SC(cow_arrays_created_runtime, V8.COWArraysCreatedRuntime)          \
    459   SC(cow_arrays_converted, V8.COWArraysConverted)                     \
    460   SC(call_miss, V8.CallMiss)                                          \
    461   SC(keyed_call_miss, V8.KeyedCallMiss)                               \
    462   SC(load_miss, V8.LoadMiss)                                          \
    463   SC(keyed_load_miss, V8.KeyedLoadMiss)                               \
    464   SC(call_const, V8.CallConst)                                        \
    465   SC(call_const_fast_api, V8.CallConstFastApi)                        \
    466   SC(call_const_interceptor, V8.CallConstInterceptor)                 \
    467   SC(call_const_interceptor_fast_api, V8.CallConstInterceptorFastApi) \
    468   SC(call_global_inline, V8.CallGlobalInline)                         \
    469   SC(call_global_inline_miss, V8.CallGlobalInlineMiss)                \
    470   SC(constructed_objects, V8.ConstructedObjects)                      \
    471   SC(constructed_objects_runtime, V8.ConstructedObjectsRuntime)       \
    472   SC(negative_lookups, V8.NegativeLookups)                            \
    473   SC(negative_lookups_miss, V8.NegativeLookupsMiss)                   \
    474   SC(megamorphic_stub_cache_probes, V8.MegamorphicStubCacheProbes)    \
    475   SC(megamorphic_stub_cache_misses, V8.MegamorphicStubCacheMisses)    \
    476   SC(megamorphic_stub_cache_updates, V8.MegamorphicStubCacheUpdates)  \
    477   SC(array_function_runtime, V8.ArrayFunctionRuntime)                 \
    478   SC(array_function_native, V8.ArrayFunctionNative)                   \
    479   SC(for_in, V8.ForIn)                                                \
    480   SC(enum_cache_hits, V8.EnumCacheHits)                               \
    481   SC(enum_cache_misses, V8.EnumCacheMisses)                           \
    482   SC(zone_segment_bytes, V8.ZoneSegmentBytes)                         \
    483   SC(fast_new_closure_total, V8.FastNewClosureTotal)                  \
    484   SC(fast_new_closure_try_optimized, V8.FastNewClosureTryOptimized)   \
    485   SC(fast_new_closure_install_optimized, V8.FastNewClosureInstallOptimized) \
    486   SC(string_add_runtime, V8.StringAddRuntime)                         \
    487   SC(string_add_native, V8.StringAddNative)                           \
    488   SC(string_add_runtime_ext_to_ascii, V8.StringAddRuntimeExtToAscii)  \
    489   SC(sub_string_runtime, V8.SubStringRuntime)                         \
    490   SC(sub_string_native, V8.SubStringNative)                           \
    491   SC(string_add_make_two_char, V8.StringAddMakeTwoChar)               \
    492   SC(string_compare_native, V8.StringCompareNative)                   \
    493   SC(string_compare_runtime, V8.StringCompareRuntime)                 \
    494   SC(regexp_entry_runtime, V8.RegExpEntryRuntime)                     \
    495   SC(regexp_entry_native, V8.RegExpEntryNative)                       \
    496   SC(number_to_string_native, V8.NumberToStringNative)                \
    497   SC(number_to_string_runtime, V8.NumberToStringRuntime)              \
    498   SC(math_acos, V8.MathAcos)                                          \
    499   SC(math_asin, V8.MathAsin)                                          \
    500   SC(math_atan, V8.MathAtan)                                          \
    501   SC(math_atan2, V8.MathAtan2)                                        \
    502   SC(math_exp, V8.MathExp)                                            \
    503   SC(math_floor, V8.MathFloor)                                        \
    504   SC(math_log, V8.MathLog)                                            \
    505   SC(math_pow, V8.MathPow)                                            \
    506   SC(math_round, V8.MathRound)                                        \
    507   SC(math_sqrt, V8.MathSqrt)                                          \
    508   SC(stack_interrupts, V8.StackInterrupts)                            \
    509   SC(runtime_profiler_ticks, V8.RuntimeProfilerTicks)                 \
    510   SC(bounds_checks_eliminated, V8.BoundsChecksEliminated)             \
    511   SC(bounds_checks_hoisted, V8.BoundsChecksHoisted)                   \
    512   SC(soft_deopts_requested, V8.SoftDeoptsRequested)                   \
    513   SC(soft_deopts_inserted, V8.SoftDeoptsInserted)                     \
    514   SC(soft_deopts_executed, V8.SoftDeoptsExecuted)                     \
    515   /* Number of write barriers in generated code. */                   \
    516   SC(write_barriers_dynamic, V8.WriteBarriersDynamic)                 \
    517   SC(write_barriers_static, V8.WriteBarriersStatic)                   \
    518   SC(new_space_bytes_available, V8.MemoryNewSpaceBytesAvailable)      \
    519   SC(new_space_bytes_committed, V8.MemoryNewSpaceBytesCommitted)      \
    520   SC(new_space_bytes_used, V8.MemoryNewSpaceBytesUsed)                \
    521   SC(old_pointer_space_bytes_available,                               \
    522      V8.MemoryOldPointerSpaceBytesAvailable)                          \
    523   SC(old_pointer_space_bytes_committed,                               \
    524      V8.MemoryOldPointerSpaceBytesCommitted)                          \
    525   SC(old_pointer_space_bytes_used, V8.MemoryOldPointerSpaceBytesUsed) \
    526   SC(old_data_space_bytes_available, V8.MemoryOldDataSpaceBytesAvailable) \
    527   SC(old_data_space_bytes_committed, V8.MemoryOldDataSpaceBytesCommitted) \
    528   SC(old_data_space_bytes_used, V8.MemoryOldDataSpaceBytesUsed)       \
    529   SC(code_space_bytes_available, V8.MemoryCodeSpaceBytesAvailable)    \
    530   SC(code_space_bytes_committed, V8.MemoryCodeSpaceBytesCommitted)    \
    531   SC(code_space_bytes_used, V8.MemoryCodeSpaceBytesUsed)              \
    532   SC(map_space_bytes_available, V8.MemoryMapSpaceBytesAvailable)      \
    533   SC(map_space_bytes_committed, V8.MemoryMapSpaceBytesCommitted)      \
    534   SC(map_space_bytes_used, V8.MemoryMapSpaceBytesUsed)                \
    535   SC(cell_space_bytes_available, V8.MemoryCellSpaceBytesAvailable)    \
    536   SC(cell_space_bytes_committed, V8.MemoryCellSpaceBytesCommitted)    \
    537   SC(cell_space_bytes_used, V8.MemoryCellSpaceBytesUsed)              \
    538   SC(property_cell_space_bytes_available,                             \
    539      V8.MemoryPropertyCellSpaceBytesAvailable)                        \
    540   SC(property_cell_space_bytes_committed,                             \
    541      V8.MemoryPropertyCellSpaceBytesCommitted)                        \
    542   SC(property_cell_space_bytes_used,                                  \
    543      V8.MemoryPropertyCellSpaceBytesUsed)                             \
    544   SC(lo_space_bytes_available, V8.MemoryLoSpaceBytesAvailable)        \
    545   SC(lo_space_bytes_committed, V8.MemoryLoSpaceBytesCommitted)        \
    546   SC(lo_space_bytes_used, V8.MemoryLoSpaceBytesUsed)
    547 
    548 
    549 // This file contains all the v8 counters that are in use.
    550 class Counters {
    551  public:
    552 #define HT(name, caption) \
    553   HistogramTimer* name() { return &name##_; }
    554   HISTOGRAM_TIMER_LIST(HT)
    555 #undef HT
    556 
    557 #define HP(name, caption) \
    558   Histogram* name() { return &name##_; }
    559   HISTOGRAM_PERCENTAGE_LIST(HP)
    560 #undef HP
    561 
    562 #define HM(name, caption) \
    563   Histogram* name() { return &name##_; }
    564   HISTOGRAM_MEMORY_LIST(HM)
    565 #undef HM
    566 
    567 #define SC(name, caption) \
    568   StatsCounter* name() { return &name##_; }
    569   STATS_COUNTER_LIST_1(SC)
    570   STATS_COUNTER_LIST_2(SC)
    571 #undef SC
    572 
    573 #define SC(name) \
    574   StatsCounter* count_of_##name() { return &count_of_##name##_; } \
    575   StatsCounter* size_of_##name() { return &size_of_##name##_; }
    576   INSTANCE_TYPE_LIST(SC)
    577 #undef SC
    578 
    579 #define SC(name) \
    580   StatsCounter* count_of_CODE_TYPE_##name() \
    581     { return &count_of_CODE_TYPE_##name##_; } \
    582   StatsCounter* size_of_CODE_TYPE_##name() \
    583     { return &size_of_CODE_TYPE_##name##_; }
    584   CODE_KIND_LIST(SC)
    585 #undef SC
    586 
    587 #define SC(name) \
    588   StatsCounter* count_of_FIXED_ARRAY_##name() \
    589     { return &count_of_FIXED_ARRAY_##name##_; } \
    590   StatsCounter* size_of_FIXED_ARRAY_##name() \
    591     { return &size_of_FIXED_ARRAY_##name##_; }
    592   FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(SC)
    593 #undef SC
    594 
    595 #define SC(name) \
    596   StatsCounter* count_of_CODE_AGE_##name() \
    597     { return &count_of_CODE_AGE_##name##_; } \
    598   StatsCounter* size_of_CODE_AGE_##name() \
    599     { return &size_of_CODE_AGE_##name##_; }
    600   CODE_AGE_LIST_COMPLETE(SC)
    601 #undef SC
    602 
    603   enum Id {
    604 #define RATE_ID(name, caption) k_##name,
    605     HISTOGRAM_TIMER_LIST(RATE_ID)
    606 #undef RATE_ID
    607 #define PERCENTAGE_ID(name, caption) k_##name,
    608     HISTOGRAM_PERCENTAGE_LIST(PERCENTAGE_ID)
    609 #undef PERCENTAGE_ID
    610 #define MEMORY_ID(name, caption) k_##name,
    611     HISTOGRAM_MEMORY_LIST(MEMORY_ID)
    612 #undef MEMORY_ID
    613 #define COUNTER_ID(name, caption) k_##name,
    614     STATS_COUNTER_LIST_1(COUNTER_ID)
    615     STATS_COUNTER_LIST_2(COUNTER_ID)
    616 #undef COUNTER_ID
    617 #define COUNTER_ID(name) kCountOf##name, kSizeOf##name,
    618     INSTANCE_TYPE_LIST(COUNTER_ID)
    619 #undef COUNTER_ID
    620 #define COUNTER_ID(name) kCountOfCODE_TYPE_##name, \
    621     kSizeOfCODE_TYPE_##name,
    622     CODE_KIND_LIST(COUNTER_ID)
    623 #undef COUNTER_ID
    624 #define COUNTER_ID(name) kCountOfFIXED_ARRAY__##name, \
    625     kSizeOfFIXED_ARRAY__##name,
    626     FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(COUNTER_ID)
    627 #undef COUNTER_ID
    628 #define COUNTER_ID(name) kCountOfCODE_AGE__##name, \
    629     kSizeOfCODE_AGE__##name,
    630     CODE_AGE_LIST_COMPLETE(COUNTER_ID)
    631 #undef COUNTER_ID
    632     stats_counter_count
    633   };
    634 
    635   void ResetCounters();
    636   void ResetHistograms();
    637 
    638  private:
    639 #define HT(name, caption) \
    640   HistogramTimer name##_;
    641   HISTOGRAM_TIMER_LIST(HT)
    642 #undef HT
    643 
    644 #define HP(name, caption) \
    645   Histogram name##_;
    646   HISTOGRAM_PERCENTAGE_LIST(HP)
    647 #undef HP
    648 
    649 #define HM(name, caption) \
    650   Histogram name##_;
    651   HISTOGRAM_MEMORY_LIST(HM)
    652 #undef HM
    653 
    654 #define SC(name, caption) \
    655   StatsCounter name##_;
    656   STATS_COUNTER_LIST_1(SC)
    657   STATS_COUNTER_LIST_2(SC)
    658 #undef SC
    659 
    660 #define SC(name) \
    661   StatsCounter size_of_##name##_; \
    662   StatsCounter count_of_##name##_;
    663   INSTANCE_TYPE_LIST(SC)
    664 #undef SC
    665 
    666 #define SC(name) \
    667   StatsCounter size_of_CODE_TYPE_##name##_; \
    668   StatsCounter count_of_CODE_TYPE_##name##_;
    669   CODE_KIND_LIST(SC)
    670 #undef SC
    671 
    672 #define SC(name) \
    673   StatsCounter size_of_FIXED_ARRAY_##name##_; \
    674   StatsCounter count_of_FIXED_ARRAY_##name##_;
    675   FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(SC)
    676 #undef SC
    677 
    678 #define SC(name) \
    679   StatsCounter size_of_CODE_AGE_##name##_; \
    680   StatsCounter count_of_CODE_AGE_##name##_;
    681   CODE_AGE_LIST_COMPLETE(SC)
    682 #undef SC
    683 
    684   friend class Isolate;
    685 
    686   explicit Counters(Isolate* isolate);
    687 
    688   DISALLOW_IMPLICIT_CONSTRUCTORS(Counters);
    689 };
    690 
    691 } }  // namespace v8::internal
    692 
    693 #endif  // V8_COUNTERS_H_
    694