Home | History | Annotate | Download | only in chromium
      1 /*
      2  * Copyright (C) 2011 Google Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  *
      8  * 1.  Redistributions of source code must retain the above copyright
      9  *     notice, this list of conditions and the following disclaimer.
     10  * 2.  Redistributions in binary form must reproduce the above copyright
     11  *     notice, this list of conditions and the following disclaimer in the
     12  *     documentation and/or other materials provided with the distribution.
     13  *
     14  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
     15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     16  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     17  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
     18  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     19  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     20  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
     21  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     23  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     24  */
     25 
     26 // Trace events are for tracking application performance and resource usage.
     27 // Macros are provided to track:
     28 //    Begin and end of function calls
     29 //    Counters
     30 //
     31 // Events are issued against categories. Whereas LOG's
     32 // categories are statically defined, TRACE categories are created
     33 // implicitly with a string. For example:
     34 //   TRACE_EVENT_INSTANT0("MY_SUBSYSTEM", "SomeImportantEvent")
     35 //
     36 // Events can be INSTANT, or can be pairs of BEGIN and END in the same scope:
     37 //   TRACE_EVENT_BEGIN0("MY_SUBSYSTEM", "SomethingCostly")
     38 //   doSomethingCostly()
     39 //   TRACE_EVENT_END0("MY_SUBSYSTEM", "SomethingCostly")
     40 // Note: our tools can't always determine the correct BEGIN/END pairs unless
     41 // these are used in the same scope. Use ASYNC_BEGIN/ASYNC_END macros if you need them
     42 // to be in separate scopes.
     43 //
     44 // A common use case is to trace entire function scopes. This
     45 // issues a trace BEGIN and END automatically:
     46 //   void doSomethingCostly() {
     47 //     TRACE_EVENT0("MY_SUBSYSTEM", "doSomethingCostly");
     48 //     ...
     49 //   }
     50 //
     51 // Additional parameters can be associated with an event:
     52 //   void doSomethingCostly2(int howMuch) {
     53 //     TRACE_EVENT1("MY_SUBSYSTEM", "doSomethingCostly",
     54 //         "howMuch", howMuch);
     55 //     ...
     56 //   }
     57 //
     58 // The trace system will automatically add to this information the
     59 // current process id, thread id, and a timestamp in microseconds.
     60 //
     61 // To trace an asynchronous procedure such as an IPC send/receive, use ASYNC_BEGIN and
     62 // ASYNC_END:
     63 //   [single threaded sender code]
     64 //     static int send_count = 0;
     65 //     ++send_count;
     66 //     TRACE_EVENT_ASYNC_BEGIN0("ipc", "message", send_count);
     67 //     Send(new MyMessage(send_count));
     68 //   [receive code]
     69 //     void OnMyMessage(send_count) {
     70 //       TRACE_EVENT_ASYNC_END0("ipc", "message", send_count);
     71 //     }
     72 // The third parameter is a unique ID to match ASYNC_BEGIN/ASYNC_END pairs.
     73 // ASYNC_BEGIN and ASYNC_END can occur on any thread of any traced process. Pointers can
     74 // be used for the ID parameter, and they will be mangled internally so that
     75 // the same pointer on two different processes will not match. For example:
     76 //   class MyTracedClass {
     77 //    public:
     78 //     MyTracedClass() {
     79 //       TRACE_EVENT_ASYNC_BEGIN0("category", "MyTracedClass", this);
     80 //     }
     81 //     ~MyTracedClass() {
     82 //       TRACE_EVENT_ASYNC_END0("category", "MyTracedClass", this);
     83 //     }
     84 //   }
     85 //
     86 // Trace event also supports counters, which is a way to track a quantity
     87 // as it varies over time. Counters are created with the following macro:
     88 //   TRACE_COUNTER1("MY_SUBSYSTEM", "myCounter", g_myCounterValue);
     89 //
     90 // Counters are process-specific. The macro itself can be issued from any
     91 // thread, however.
     92 //
     93 // Sometimes, you want to track two counters at once. You can do this with two
     94 // counter macros:
     95 //   TRACE_COUNTER1("MY_SUBSYSTEM", "myCounter0", g_myCounterValue[0]);
     96 //   TRACE_COUNTER1("MY_SUBSYSTEM", "myCounter1", g_myCounterValue[1]);
     97 // Or you can do it with a combined macro:
     98 //   TRACE_COUNTER2("MY_SUBSYSTEM", "myCounter",
     99 //       "bytesPinned", g_myCounterValue[0],
    100 //       "bytesAllocated", g_myCounterValue[1]);
    101 // This indicates to the tracing UI that these counters should be displayed
    102 // in a single graph, as a summed area chart.
    103 //
    104 // Since counters are in a global namespace, you may want to disembiguate with a
    105 // unique ID, by using the TRACE_COUNTER_ID* variations.
    106 //
    107 // By default, trace collection is compiled in, but turned off at runtime.
    108 // Collecting trace data is the responsibility of the embedding
    109 // application. In Chrome's case, navigating to about:tracing will turn on
    110 // tracing and display data collected across all active processes.
    111 //
    112 //
    113 // Memory scoping note:
    114 // Tracing copies the pointers, not the string content, of the strings passed
    115 // in for category, name, and arg_names. Thus, the following code will
    116 // cause problems:
    117 //     char* str = strdup("impprtantName");
    118 //     TRACE_EVENT_INSTANT0("SUBSYSTEM", str);  // BAD!
    119 //     free(str);                   // Trace system now has dangling pointer
    120 //
    121 // To avoid this issue with the |name| and |arg_name| parameters, use the
    122 // TRACE_EVENT_COPY_XXX overloads of the macros at additional runtime overhead.
    123 // Notes: The category must always be in a long-lived char* (i.e. static const).
    124 //        The |arg_values|, when used, are always deep copied with the _COPY
    125 //        macros.
    126 //
    127 // When are string argument values copied:
    128 // const char* arg_values are only referenced by default:
    129 //     TRACE_EVENT1("category", "name",
    130 //                  "arg1", "literal string is only referenced");
    131 // Use TRACE_STR_COPY to force copying of a const char*:
    132 //     TRACE_EVENT1("category", "name",
    133 //                  "arg1", TRACE_STR_COPY("string will be copied"));
    134 // std::string arg_values are always copied:
    135 //     TRACE_EVENT1("category", "name",
    136 //                  "arg1", std::string("string will be copied"));
    137 //
    138 //
    139 // Thread Safety:
    140 // A thread safe singleton and mutex are used for thread safety. Category
    141 // enabled flags are used to limit the performance impact when the system
    142 // is not enabled.
    143 //
    144 // TRACE_EVENT macros first cache a pointer to a category. The categories are
    145 // statically allocated and safe at all times, even after exit. Fetching a
    146 // category is protected by the TraceLog::lock_. Multiple threads initializing
    147 // the static variable is safe, as they will be serialized by the lock and
    148 // multiple calls will return the same pointer to the category.
    149 //
    150 // Then the category_enabled flag is checked. This is a unsigned char, and
    151 // not intended to be multithread safe. It optimizes access to addTraceEvent
    152 // which is threadsafe internally via TraceLog::lock_. The enabled flag may
    153 // cause some threads to incorrectly call or skip calling addTraceEvent near
    154 // the time of the system being enabled or disabled. This is acceptable as
    155 // we tolerate some data loss while the system is being enabled/disabled and
    156 // because addTraceEvent is threadsafe internally and checks the enabled state
    157 // again under lock.
    158 //
    159 // Without the use of these static category pointers and enabled flags all
    160 // trace points would carry a significant performance cost of aquiring a lock
    161 // and resolving the category.
    162 
    163 #ifndef TraceEvent_h
    164 #define TraceEvent_h
    165 
    166 #include "core/platform/EventTracer.h"
    167 
    168 #include "wtf/DynamicAnnotations.h"
    169 #include "wtf/text/CString.h"
    170 
    171 // By default, const char* argument values are assumed to have long-lived scope
    172 // and will not be copied. Use this macro to force a const char* to be copied.
    173 #define TRACE_STR_COPY(str) \
    174     WebCore::TraceEvent::TraceStringWithCopy(str)
    175 
    176 // Records a pair of begin and end events called "name" for the current
    177 // scope, with 0, 1 or 2 associated arguments. If the category is not
    178 // enabled, then this does nothing.
    179 // - category and name strings must have application lifetime (statics or
    180 //   literals). They may not include " chars.
    181 #define TRACE_EVENT0(category, name) \
    182     INTERNAL_TRACE_EVENT_ADD_SCOPED(category, name)
    183 #define TRACE_EVENT1(category, name, arg1_name, arg1_val) \
    184     INTERNAL_TRACE_EVENT_ADD_SCOPED(category, name, arg1_name, arg1_val)
    185 #define TRACE_EVENT2(category, name, arg1_name, arg1_val, arg2_name, arg2_val) \
    186     INTERNAL_TRACE_EVENT_ADD_SCOPED(category, name, arg1_name, arg1_val, \
    187         arg2_name, arg2_val)
    188 
    189 // Records a single event called "name" immediately, with 0, 1 or 2
    190 // associated arguments. If the category is not enabled, then this
    191 // does nothing.
    192 // - category and name strings must have application lifetime (statics or
    193 //   literals). They may not include " chars.
    194 #define TRACE_EVENT_INSTANT0(category, name) \
    195     INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, \
    196         category, name, TRACE_EVENT_FLAG_NONE)
    197 #define TRACE_EVENT_INSTANT1(category, name, arg1_name, arg1_val) \
    198     INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, \
    199         category, name, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
    200 #define TRACE_EVENT_INSTANT2(category, name, arg1_name, arg1_val, \
    201         arg2_name, arg2_val) \
    202     INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, \
    203         category, name, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, \
    204         arg2_name, arg2_val)
    205 #define TRACE_EVENT_COPY_INSTANT0(category, name) \
    206     INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, \
    207         category, name, TRACE_EVENT_FLAG_COPY)
    208 #define TRACE_EVENT_COPY_INSTANT1(category, name, arg1_name, arg1_val) \
    209     INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, \
    210         category, name, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val)
    211 #define TRACE_EVENT_COPY_INSTANT2(category, name, arg1_name, arg1_val, \
    212         arg2_name, arg2_val) \
    213     INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, \
    214         category, name, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, \
    215         arg2_name, arg2_val)
    216 
    217 // Records a single BEGIN event called "name" immediately, with 0, 1 or 2
    218 // associated arguments. If the category is not enabled, then this
    219 // does nothing.
    220 // - category and name strings must have application lifetime (statics or
    221 //   literals). They may not include " chars.
    222 #define TRACE_EVENT_BEGIN0(category, name) \
    223     INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, \
    224         category, name, TRACE_EVENT_FLAG_NONE)
    225 #define TRACE_EVENT_BEGIN1(category, name, arg1_name, arg1_val) \
    226     INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, \
    227         category, name, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
    228 #define TRACE_EVENT_BEGIN2(category, name, arg1_name, arg1_val, \
    229         arg2_name, arg2_val) \
    230     INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, \
    231         category, name, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, \
    232         arg2_name, arg2_val)
    233 #define TRACE_EVENT_COPY_BEGIN0(category, name) \
    234     INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, \
    235         category, name, TRACE_EVENT_FLAG_COPY)
    236 #define TRACE_EVENT_COPY_BEGIN1(category, name, arg1_name, arg1_val) \
    237     INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, \
    238         category, name, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val)
    239 #define TRACE_EVENT_COPY_BEGIN2(category, name, arg1_name, arg1_val, \
    240         arg2_name, arg2_val) \
    241     INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, \
    242         category, name, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, \
    243         arg2_name, arg2_val)
    244 
    245 // Records a single END event for "name" immediately. If the category
    246 // is not enabled, then this does nothing.
    247 // - category and name strings must have application lifetime (statics or
    248 //   literals). They may not include " chars.
    249 #define TRACE_EVENT_END0(category, name) \
    250     INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, \
    251         category, name, TRACE_EVENT_FLAG_NONE)
    252 #define TRACE_EVENT_END1(category, name, arg1_name, arg1_val) \
    253     INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, \
    254         category, name, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
    255 #define TRACE_EVENT_END2(category, name, arg1_name, arg1_val, \
    256         arg2_name, arg2_val) \
    257     INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, \
    258         category, name, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, \
    259         arg2_name, arg2_val)
    260 #define TRACE_EVENT_COPY_END0(category, name) \
    261     INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, \
    262         category, name, TRACE_EVENT_FLAG_COPY)
    263 #define TRACE_EVENT_COPY_END1(category, name, arg1_name, arg1_val) \
    264     INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, \
    265         category, name, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val)
    266 #define TRACE_EVENT_COPY_END2(category, name, arg1_name, arg1_val, \
    267         arg2_name, arg2_val) \
    268     INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, \
    269         category, name, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, \
    270         arg2_name, arg2_val)
    271 
    272 // Records the value of a counter called "name" immediately. Value
    273 // must be representable as a 32 bit integer.
    274 // - category and name strings must have application lifetime (statics or
    275 //   literals). They may not include " chars.
    276 #define TRACE_COUNTER1(category, name, value) \
    277     INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, \
    278         category, name, TRACE_EVENT_FLAG_NONE, \
    279         "value", static_cast<int>(value))
    280 #define TRACE_COPY_COUNTER1(category, name, value) \
    281     INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, \
    282         category, name, TRACE_EVENT_FLAG_COPY, \
    283         "value", static_cast<int>(value))
    284 
    285 // Records the values of a multi-parted counter called "name" immediately.
    286 // The UI will treat value1 and value2 as parts of a whole, displaying their
    287 // values as a stacked-bar chart.
    288 // - category and name strings must have application lifetime (statics or
    289 //   literals). They may not include " chars.
    290 #define TRACE_COUNTER2(category, name, value1_name, value1_val, \
    291         value2_name, value2_val) \
    292     INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, \
    293         category, name, TRACE_EVENT_FLAG_NONE, \
    294         value1_name, static_cast<int>(value1_val), \
    295         value2_name, static_cast<int>(value2_val))
    296 #define TRACE_COPY_COUNTER2(category, name, value1_name, value1_val, \
    297         value2_name, value2_val) \
    298     INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, \
    299         category, name, TRACE_EVENT_FLAG_COPY, \
    300         value1_name, static_cast<int>(value1_val), \
    301         value2_name, static_cast<int>(value2_val))
    302 
    303 // Records the value of a counter called "name" immediately. Value
    304 // must be representable as a 32 bit integer.
    305 // - category and name strings must have application lifetime (statics or
    306 //   literals). They may not include " chars.
    307 // - |id| is used to disambiguate counters with the same name. It must either
    308 //   be a pointer or an integer value up to 64 bits. If it's a pointer, the bits
    309 //   will be xored with a hash of the process ID so that the same pointer on
    310 //   two different processes will not collide.
    311 #define TRACE_COUNTER_ID1(category, name, id, value) \
    312     INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_COUNTER, \
    313         category, name, id, TRACE_EVENT_FLAG_NONE, \
    314         "value", static_cast<int>(value))
    315 #define TRACE_COPY_COUNTER_ID1(category, name, id, value) \
    316     INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_COUNTER, \
    317         category, name, id, TRACE_EVENT_FLAG_COPY, \
    318         "value", static_cast<int>(value))
    319 
    320 // Records the values of a multi-parted counter called "name" immediately.
    321 // The UI will treat value1 and value2 as parts of a whole, displaying their
    322 // values as a stacked-bar chart.
    323 // - category and name strings must have application lifetime (statics or
    324 //   literals). They may not include " chars.
    325 // - |id| is used to disambiguate counters with the same name. It must either
    326 //   be a pointer or an integer value up to 64 bits. If it's a pointer, the bits
    327 //   will be xored with a hash of the process ID so that the same pointer on
    328 //   two different processes will not collide.
    329 #define TRACE_COUNTER_ID2(category, name, id, value1_name, value1_val, \
    330         value2_name, value2_val) \
    331     INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_COUNTER, \
    332         category, name, id, TRACE_EVENT_FLAG_NONE, \
    333         value1_name, static_cast<int>(value1_val), \
    334         value2_name, static_cast<int>(value2_val))
    335 #define TRACE_COPY_COUNTER_ID2(category, name, id, value1_name, value1_val, \
    336         value2_name, value2_val) \
    337     INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_COUNTER, \
    338         category, name, id, TRACE_EVENT_FLAG_COPY, \
    339         value1_name, static_cast<int>(value1_val), \
    340         value2_name, static_cast<int>(value2_val))
    341 
    342 // Records a single ASYNC_BEGIN event called "name" immediately, with 0, 1 or 2
    343 // associated arguments. If the category is not enabled, then this
    344 // does nothing.
    345 // - category and name strings must have application lifetime (statics or
    346 //   literals). They may not include " chars.
    347 // - |id| is used to match the ASYNC_BEGIN event with the ASYNC_END event. ASYNC
    348 //   events are considered to match if their category, name and id values all
    349 //   match. |id| must either be a pointer or an integer value up to 64 bits. If
    350 //   it's a pointer, the bits will be xored with a hash of the process ID so
    351 //   that the same pointer on two different processes will not collide.
    352 // An asynchronous operation can consist of multiple phases. The first phase is
    353 // defined by the ASYNC_BEGIN calls. Additional phases can be defined using the
    354 // ASYNC_STEP_BEGIN macros. When the operation completes, call ASYNC_END.
    355 // An async operation can span threads and processes, but all events in that
    356 // operation must use the same |name| and |id|. Each event can have its own
    357 // args.
    358 #define TRACE_EVENT_ASYNC_BEGIN0(category, name, id) \
    359     INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \
    360         category, name, id, TRACE_EVENT_FLAG_NONE)
    361 #define TRACE_EVENT_ASYNC_BEGIN1(category, name, id, arg1_name, arg1_val) \
    362     INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \
    363         category, name, id, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
    364 #define TRACE_EVENT_ASYNC_BEGIN2(category, name, id, arg1_name, arg1_val, \
    365         arg2_name, arg2_val) \
    366     INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \
    367         category, name, id, TRACE_EVENT_FLAG_NONE, \
    368         arg1_name, arg1_val, arg2_name, arg2_val)
    369 #define TRACE_EVENT_COPY_ASYNC_BEGIN0(category, name, id) \
    370     INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \
    371         category, name, id, TRACE_EVENT_FLAG_COPY)
    372 #define TRACE_EVENT_COPY_ASYNC_BEGIN1(category, name, id, arg1_name, arg1_val) \
    373     INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \
    374         category, name, id, TRACE_EVENT_FLAG_COPY, \
    375         arg1_name, arg1_val)
    376 #define TRACE_EVENT_COPY_ASYNC_BEGIN2(category, name, id, arg1_name, arg1_val, \
    377         arg2_name, arg2_val) \
    378     INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \
    379         category, name, id, TRACE_EVENT_FLAG_COPY, \
    380         arg1_name, arg1_val, arg2_name, arg2_val)
    381 
    382 // Records a single ASYNC_STEP event for |step| immediately. If the category
    383 // is not enabled, then this does nothing. The |name| and |id| must match the
    384 // ASYNC_BEGIN event above. The |step| param identifies this step within the
    385 // async event. This should be called at the beginning of the next phase of an
    386 // asynchronous operation.
    387 #define TRACE_EVENT_ASYNC_STEP0(category, name, id, step) \
    388     INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_STEP, \
    389         category, name, id, TRACE_EVENT_FLAG_NONE, "step", step)
    390 #define TRACE_EVENT_ASYNC_STEP1(category, name, id, step, \
    391                                       arg1_name, arg1_val) \
    392     INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_STEP, \
    393         category, name, id, TRACE_EVENT_FLAG_NONE, "step", step, \
    394         arg1_name, arg1_val)
    395 #define TRACE_EVENT_COPY_ASYNC_STEP0(category, name, id, step) \
    396     INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_STEP, \
    397         category, name, id, TRACE_EVENT_FLAG_COPY, "step", step)
    398 #define TRACE_EVENT_COPY_ASYNC_STEP1(category, name, id, step, \
    399         arg1_name, arg1_val) \
    400     INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_STEP, \
    401         category, name, id, TRACE_EVENT_FLAG_COPY, "step", step, \
    402         arg1_name, arg1_val)
    403 
    404 // Records a single ASYNC_END event for "name" immediately. If the category
    405 // is not enabled, then this does nothing.
    406 #define TRACE_EVENT_ASYNC_END0(category, name, id) \
    407     INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \
    408         category, name, id, TRACE_EVENT_FLAG_NONE)
    409 #define TRACE_EVENT_ASYNC_END1(category, name, id, arg1_name, arg1_val) \
    410     INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \
    411         category, name, id, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
    412 #define TRACE_EVENT_ASYNC_END2(category, name, id, arg1_name, arg1_val, \
    413         arg2_name, arg2_val) \
    414     INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \
    415         category, name, id, TRACE_EVENT_FLAG_NONE, \
    416         arg1_name, arg1_val, arg2_name, arg2_val)
    417 #define TRACE_EVENT_COPY_ASYNC_END0(category, name, id) \
    418     INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \
    419         category, name, id, TRACE_EVENT_FLAG_COPY)
    420 #define TRACE_EVENT_COPY_ASYNC_END1(category, name, id, arg1_name, arg1_val) \
    421     INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \
    422         category, name, id, TRACE_EVENT_FLAG_COPY, \
    423         arg1_name, arg1_val)
    424 #define TRACE_EVENT_COPY_ASYNC_END2(category, name, id, arg1_name, arg1_val, \
    425         arg2_name, arg2_val) \
    426     INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \
    427         category, name, id, TRACE_EVENT_FLAG_COPY, \
    428         arg1_name, arg1_val, arg2_name, arg2_val)
    429 
    430 // Creates a scope of a sampling state with the given category and name (both must
    431 // be constant strings). These states are intended for a sampling profiler.
    432 // Implementation note: we store category and name together because we don't
    433 // want the inconsistency/expense of storing two pointers.
    434 // |thread_bucket| is [0..2] and is used to statically isolate samples in one
    435 // thread from others.
    436 //
    437 // {  // The sampling state is set within this scope.
    438 //    TRACE_EVENT_SAMPLING_STATE_SCOPE_FOR_BUCKET(0, "category", "name");
    439 //    ...;
    440 // }
    441 #define TRACE_EVENT_SCOPED_SAMPLING_STATE_FOR_BUCKET(bucket_number, category, name) \
    442     TraceEvent::SamplingStateScope<bucket_number> traceEventSamplingScope(category "\0" name);
    443 
    444 // Returns a current sampling state of the given bucket.
    445 // The format of the returned string is "category\0name".
    446 #define TRACE_EVENT_GET_SAMPLING_STATE_FOR_BUCKET(bucket_number) \
    447     TraceEvent::SamplingStateScope<bucket_number>::current()
    448 
    449 // Sets a current sampling state of the given bucket.
    450 // |category| and |name| have to be constant strings.
    451 #define TRACE_EVENT_SET_SAMPLING_STATE_FOR_BUCKET(bucket_number, category, name) \
    452     TraceEvent::SamplingStateScope<bucket_number>::set(category "\0" name)
    453 
    454 // Sets a current sampling state of the given bucket.
    455 // |categoryAndName| doesn't need to be a constant string.
    456 // The format of the string is "category\0name".
    457 #define TRACE_EVENT_SET_NONCONST_SAMPLING_STATE_FOR_BUCKET(bucket_number, categoryAndName) \
    458     TraceEvent::SamplingStateScope<bucket_number>::set(categoryAndName)
    459 
    460 // Syntactic sugars for the sampling tracing in the main thread.
    461 #define TRACE_EVENT_SCOPED_SAMPLING_STATE(category, name) \
    462     TRACE_EVENT_SCOPED_SAMPLING_STATE_FOR_BUCKET(0, category, name)
    463 #define TRACE_EVENT_GET_SAMPLING_STATE() \
    464     TRACE_EVENT_GET_SAMPLING_STATE_FOR_BUCKET(0)
    465 #define TRACE_EVENT_SET_SAMPLING_STATE(category, name) \
    466     TRACE_EVENT_SET_SAMPLING_STATE_FOR_BUCKET(0, category, name)
    467 #define TRACE_EVENT_SET_NONCONST_SAMPLING_STATE(categoryAndName) \
    468     TRACE_EVENT_SET_NONCONST_SAMPLING_STATE_FOR_BUCKET(0, categoryAndName)
    469 
    470 ////////////////////////////////////////////////////////////////////////////////
    471 // Implementation specific tracing API definitions.
    472 
    473 // Get a pointer to the enabled state of the given trace category. Only
    474 // long-lived literal strings should be given as the category name. The returned
    475 // pointer can be held permanently in a local static for example. If the
    476 // unsigned char is non-zero, tracing is enabled. If tracing is enabled,
    477 // TRACE_EVENT_API_ADD_TRACE_EVENT can be called. It's OK if tracing is disabled
    478 // between the load of the tracing state and the call to
    479 // TRACE_EVENT_API_ADD_TRACE_EVENT, because this flag only provides an early out
    480 // for best performance when tracing is disabled.
    481 // const unsigned char*
    482 //     TRACE_EVENT_API_GET_CATEGORY_ENABLED(const char* category_name)
    483 #define TRACE_EVENT_API_GET_CATEGORY_ENABLED \
    484     WebCore::EventTracer::getTraceCategoryEnabledFlag
    485 
    486 // Add a trace event to the platform tracing system.
    487 // void TRACE_EVENT_API_ADD_TRACE_EVENT(
    488 //                    char phase,
    489 //                    const unsigned char* category_enabled,
    490 //                    const char* name,
    491 //                    unsigned long long id,
    492 //                    int num_args,
    493 //                    const char** arg_names,
    494 //                    const unsigned char* arg_types,
    495 //                    const unsigned long long* arg_values,
    496 //                    unsigned char flags)
    497 #define TRACE_EVENT_API_ADD_TRACE_EVENT \
    498     WebCore::EventTracer::addTraceEvent
    499 
    500 ////////////////////////////////////////////////////////////////////////////////
    501 
    502 // Implementation detail: trace event macros create temporary variables
    503 // to keep instrumentation overhead low. These macros give each temporary
    504 // variable a unique name based on the line number to prevent name collissions.
    505 #define INTERNAL_TRACE_EVENT_UID3(a, b) \
    506     trace_event_unique_##a##b
    507 #define INTERNAL_TRACE_EVENT_UID2(a, b) \
    508     INTERNAL_TRACE_EVENT_UID3(a, b)
    509 #define INTERNALTRACEEVENTUID(name_prefix) \
    510     INTERNAL_TRACE_EVENT_UID2(name_prefix, __LINE__)
    511 
    512 // Implementation detail: internal macro to create static category.
    513 // - WTF_ANNOTATE_BENIGN_RACE, see Thread Safety above.
    514 #define INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category) \
    515     static const unsigned char* INTERNALTRACEEVENTUID(catstatic) = 0; \
    516     WTF_ANNOTATE_BENIGN_RACE(&INTERNALTRACEEVENTUID(catstatic), \
    517                              "trace_event category"); \
    518     if (!INTERNALTRACEEVENTUID(catstatic)) \
    519       INTERNALTRACEEVENTUID(catstatic) = \
    520           TRACE_EVENT_API_GET_CATEGORY_ENABLED(category);
    521 
    522 // Implementation detail: internal macro to create static category and add
    523 // event if the category is enabled.
    524 #define INTERNAL_TRACE_EVENT_ADD(phase, category, name, flags, ...) \
    525     do { \
    526         INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category); \
    527         if (*INTERNALTRACEEVENTUID(catstatic)) { \
    528             WebCore::TraceEvent::addTraceEvent( \
    529                 phase, INTERNALTRACEEVENTUID(catstatic), name, \
    530                 WebCore::TraceEvent::noEventId, flags, ##__VA_ARGS__); \
    531         } \
    532     } while (0)
    533 
    534 // Implementation detail: internal macro to create static category and add begin
    535 // event if the category is enabled. Also adds the end event when the scope
    536 // ends.
    537 #define INTERNAL_TRACE_EVENT_ADD_SCOPED(category, name, ...) \
    538     INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category); \
    539     WebCore::TraceEvent::TraceEndOnScopeClose \
    540         INTERNALTRACEEVENTUID(profileScope); \
    541     if (*INTERNALTRACEEVENTUID(catstatic)) { \
    542       WebCore::TraceEvent::addTraceEvent( \
    543           TRACE_EVENT_PHASE_BEGIN, \
    544           INTERNALTRACEEVENTUID(catstatic), \
    545           name, WebCore::TraceEvent::noEventId, \
    546           TRACE_EVENT_FLAG_NONE, ##__VA_ARGS__); \
    547       INTERNALTRACEEVENTUID(profileScope).initialize( \
    548           INTERNALTRACEEVENTUID(catstatic), name); \
    549     }
    550 
    551 // Implementation detail: internal macro to create static category and add
    552 // event if the category is enabled.
    553 #define INTERNAL_TRACE_EVENT_ADD_WITH_ID(phase, category, name, id, flags, \
    554                                          ...) \
    555     do { \
    556         INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category); \
    557         if (*INTERNALTRACEEVENTUID(catstatic)) { \
    558             unsigned char traceEventFlags = flags | TRACE_EVENT_FLAG_HAS_ID; \
    559             WebCore::TraceEvent::TraceID traceEventTraceID( \
    560                 id, &traceEventFlags); \
    561             WebCore::TraceEvent::addTraceEvent( \
    562                 phase, INTERNALTRACEEVENTUID(catstatic), \
    563                 name, traceEventTraceID.data(), traceEventFlags, \
    564                 ##__VA_ARGS__); \
    565         } \
    566     } while (0)
    567 
    568 // Notes regarding the following definitions:
    569 // New values can be added and propagated to third party libraries, but existing
    570 // definitions must never be changed, because third party libraries may use old
    571 // definitions.
    572 
    573 // Phase indicates the nature of an event entry. E.g. part of a begin/end pair.
    574 #define TRACE_EVENT_PHASE_BEGIN    ('B')
    575 #define TRACE_EVENT_PHASE_END      ('E')
    576 #define TRACE_EVENT_PHASE_INSTANT  ('I')
    577 #define TRACE_EVENT_PHASE_ASYNC_BEGIN ('S')
    578 #define TRACE_EVENT_PHASE_ASYNC_STEP  ('T')
    579 #define TRACE_EVENT_PHASE_ASYNC_END   ('F')
    580 #define TRACE_EVENT_PHASE_METADATA ('M')
    581 #define TRACE_EVENT_PHASE_COUNTER  ('C')
    582 #define TRACE_EVENT_PHASE_SAMPLE  ('P')
    583 
    584 // Flags for changing the behavior of TRACE_EVENT_API_ADD_TRACE_EVENT.
    585 #define TRACE_EVENT_FLAG_NONE        (static_cast<unsigned char>(0))
    586 #define TRACE_EVENT_FLAG_COPY        (static_cast<unsigned char>(1 << 0))
    587 #define TRACE_EVENT_FLAG_HAS_ID      (static_cast<unsigned char>(1 << 1))
    588 #define TRACE_EVENT_FLAG_MANGLE_ID   (static_cast<unsigned char>(1 << 2))
    589 
    590 // Type values for identifying types in the TraceValue union.
    591 #define TRACE_VALUE_TYPE_BOOL         (static_cast<unsigned char>(1))
    592 #define TRACE_VALUE_TYPE_UINT         (static_cast<unsigned char>(2))
    593 #define TRACE_VALUE_TYPE_INT          (static_cast<unsigned char>(3))
    594 #define TRACE_VALUE_TYPE_DOUBLE       (static_cast<unsigned char>(4))
    595 #define TRACE_VALUE_TYPE_POINTER      (static_cast<unsigned char>(5))
    596 #define TRACE_VALUE_TYPE_STRING       (static_cast<unsigned char>(6))
    597 #define TRACE_VALUE_TYPE_COPY_STRING  (static_cast<unsigned char>(7))
    598 
    599 
    600 namespace WebCore {
    601 
    602 namespace TraceEvent {
    603 
    604 // Specify these values when the corresponding argument of addTraceEvent is not
    605 // used.
    606 const int zeroNumArgs = 0;
    607 const unsigned long long noEventId = 0;
    608 
    609 // TraceID encapsulates an ID that can either be an integer or pointer. Pointers
    610 // are mangled with the Process ID so that they are unlikely to collide when the
    611 // same pointer is used on different processes.
    612 class TraceID {
    613 public:
    614     explicit TraceID(const void* id, unsigned char* flags) :
    615         m_data(static_cast<unsigned long long>(reinterpret_cast<unsigned long>(id)))
    616     {
    617         *flags |= TRACE_EVENT_FLAG_MANGLE_ID;
    618     }
    619     explicit TraceID(unsigned long long id, unsigned char* flags) : m_data(id) { (void)flags; }
    620     explicit TraceID(unsigned long id, unsigned char* flags) : m_data(id) { (void)flags; }
    621     explicit TraceID(unsigned int id, unsigned char* flags) : m_data(id) { (void)flags; }
    622     explicit TraceID(unsigned short id, unsigned char* flags) : m_data(id) { (void)flags; }
    623     explicit TraceID(unsigned char id, unsigned char* flags) : m_data(id) { (void)flags; }
    624     explicit TraceID(long long id, unsigned char* flags) :
    625         m_data(static_cast<unsigned long long>(id)) { (void)flags; }
    626     explicit TraceID(long id, unsigned char* flags) :
    627         m_data(static_cast<unsigned long long>(id)) { (void)flags; }
    628     explicit TraceID(int id, unsigned char* flags) :
    629         m_data(static_cast<unsigned long long>(id)) { (void)flags; }
    630     explicit TraceID(short id, unsigned char* flags) :
    631         m_data(static_cast<unsigned long long>(id)) { (void)flags; }
    632     explicit TraceID(signed char id, unsigned char* flags) :
    633         m_data(static_cast<unsigned long long>(id)) { (void)flags; }
    634 
    635     unsigned long long data() const { return m_data; }
    636 
    637 private:
    638     unsigned long long m_data;
    639 };
    640 
    641 // Simple union to store various types as unsigned long long.
    642 union TraceValueUnion {
    643     bool m_bool;
    644     unsigned long long m_uint;
    645     long long m_int;
    646     double m_double;
    647     const void* m_pointer;
    648     const char* m_string;
    649 };
    650 
    651 // Simple container for const char* that should be copied instead of retained.
    652 class TraceStringWithCopy {
    653 public:
    654     explicit TraceStringWithCopy(const char* str) : m_str(str) { }
    655     operator const char* () const { return m_str; }
    656 private:
    657     const char* m_str;
    658 };
    659 
    660 // Define setTraceValue for each allowed type. It stores the type and
    661 // value in the return arguments. This allows this API to avoid declaring any
    662 // structures so that it is portable to third_party libraries.
    663 #define INTERNAL_DECLARE_SET_TRACE_VALUE(actual_type, \
    664                                          union_member, \
    665                                          value_type_id) \
    666     static inline void setTraceValue(actual_type arg, \
    667                                      unsigned char* type, \
    668                                      unsigned long long* value) { \
    669         TraceValueUnion typeValue; \
    670         typeValue.union_member = arg; \
    671         *type = value_type_id; \
    672         *value = typeValue.m_uint; \
    673     }
    674 // Simpler form for int types that can be safely casted.
    675 #define INTERNAL_DECLARE_SET_TRACE_VALUE_INT(actual_type, \
    676                                              value_type_id) \
    677     static inline void setTraceValue(actual_type arg, \
    678                                      unsigned char* type, \
    679                                      unsigned long long* value) { \
    680         *type = value_type_id; \
    681         *value = static_cast<unsigned long long>(arg); \
    682     }
    683 
    684 INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned long long, TRACE_VALUE_TYPE_UINT)
    685 INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned int, TRACE_VALUE_TYPE_UINT)
    686 INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned short, TRACE_VALUE_TYPE_UINT)
    687 INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned char, TRACE_VALUE_TYPE_UINT)
    688 INTERNAL_DECLARE_SET_TRACE_VALUE_INT(long long, TRACE_VALUE_TYPE_INT)
    689 INTERNAL_DECLARE_SET_TRACE_VALUE_INT(int, TRACE_VALUE_TYPE_INT)
    690 INTERNAL_DECLARE_SET_TRACE_VALUE_INT(short, TRACE_VALUE_TYPE_INT)
    691 INTERNAL_DECLARE_SET_TRACE_VALUE_INT(signed char, TRACE_VALUE_TYPE_INT)
    692 INTERNAL_DECLARE_SET_TRACE_VALUE(bool, m_bool, TRACE_VALUE_TYPE_BOOL)
    693 INTERNAL_DECLARE_SET_TRACE_VALUE(double, m_double, TRACE_VALUE_TYPE_DOUBLE)
    694 INTERNAL_DECLARE_SET_TRACE_VALUE(const void*, m_pointer,
    695                                  TRACE_VALUE_TYPE_POINTER)
    696 INTERNAL_DECLARE_SET_TRACE_VALUE(const char*, m_string,
    697                                  TRACE_VALUE_TYPE_STRING)
    698 INTERNAL_DECLARE_SET_TRACE_VALUE(const TraceStringWithCopy&, m_string,
    699                                  TRACE_VALUE_TYPE_COPY_STRING)
    700 
    701 #undef INTERNAL_DECLARE_SET_TRACE_VALUE
    702 #undef INTERNAL_DECLARE_SET_TRACE_VALUE_INT
    703 
    704 // WTF::String version of setTraceValue so that trace arguments can be strings.
    705 static inline void setTraceValue(const WTF::CString& arg,
    706                                  unsigned char* type,
    707                                  unsigned long long* value) {
    708     TraceValueUnion typeValue;
    709     typeValue.m_string = arg.data();
    710     *type = TRACE_VALUE_TYPE_COPY_STRING;
    711     *value = typeValue.m_uint;
    712 }
    713 
    714 // These addTraceEvent template functions are defined here instead of in the
    715 // macro, because the arg values could be temporary string objects. In order to
    716 // store pointers to the internal c_str and pass through to the tracing API, the
    717 // arg values must live throughout these procedures.
    718 
    719 static inline void addTraceEvent(char phase,
    720                                 const unsigned char* categoryEnabled,
    721                                 const char* name,
    722                                 unsigned long long id,
    723                                 unsigned char flags) {
    724     TRACE_EVENT_API_ADD_TRACE_EVENT(
    725         phase, categoryEnabled, name, id,
    726         zeroNumArgs, 0, 0, 0,
    727         flags);
    728 }
    729 
    730 template<class ARG1_TYPE>
    731 static inline void addTraceEvent(char phase,
    732                                 const unsigned char* categoryEnabled,
    733                                 const char* name,
    734                                 unsigned long long id,
    735                                 unsigned char flags,
    736                                 const char* arg1Name,
    737                                 const ARG1_TYPE& arg1Val) {
    738     const int numArgs = 1;
    739     unsigned char argTypes[1];
    740     unsigned long long argValues[1];
    741     setTraceValue(arg1Val, &argTypes[0], &argValues[0]);
    742     TRACE_EVENT_API_ADD_TRACE_EVENT(
    743         phase, categoryEnabled, name, id,
    744         numArgs, &arg1Name, argTypes, argValues,
    745         flags);
    746 }
    747 
    748 template<class ARG1_TYPE, class ARG2_TYPE>
    749 static inline void addTraceEvent(char phase,
    750                                 const unsigned char* categoryEnabled,
    751                                 const char* name,
    752                                 unsigned long long id,
    753                                 unsigned char flags,
    754                                 const char* arg1Name,
    755                                 const ARG1_TYPE& arg1Val,
    756                                 const char* arg2Name,
    757                                 const ARG2_TYPE& arg2Val) {
    758     const int numArgs = 2;
    759     const char* argNames[2] = { arg1Name, arg2Name };
    760     unsigned char argTypes[2];
    761     unsigned long long argValues[2];
    762     setTraceValue(arg1Val, &argTypes[0], &argValues[0]);
    763     setTraceValue(arg2Val, &argTypes[1], &argValues[1]);
    764     return TRACE_EVENT_API_ADD_TRACE_EVENT(
    765         phase, categoryEnabled, name, id,
    766         numArgs, argNames, argTypes, argValues,
    767         flags);
    768 }
    769 
    770 // Used by TRACE_EVENTx macro. Do not use directly.
    771 class TraceEndOnScopeClose {
    772 public:
    773     // Note: members of m_data intentionally left uninitialized. See initialize.
    774     TraceEndOnScopeClose() : m_pdata(0) { }
    775     ~TraceEndOnScopeClose()
    776     {
    777         if (m_pdata)
    778             addEventIfEnabled();
    779     }
    780 
    781     void initialize(const unsigned char* categoryEnabled,
    782                     const char* name)
    783     {
    784         m_data.categoryEnabled = categoryEnabled;
    785         m_data.name = name;
    786         m_pdata = &m_data;
    787     }
    788 
    789 private:
    790     // Add the end event if the category is still enabled.
    791     void addEventIfEnabled()
    792     {
    793         // Only called when m_pdata is non-null.
    794         if (*m_pdata->categoryEnabled) {
    795             TRACE_EVENT_API_ADD_TRACE_EVENT(
    796                 TRACE_EVENT_PHASE_END,
    797                 m_pdata->categoryEnabled,
    798                 m_pdata->name, noEventId,
    799                 zeroNumArgs, 0, 0, 0,
    800                 TRACE_EVENT_FLAG_NONE);
    801         }
    802     }
    803 
    804     // This Data struct workaround is to avoid initializing all the members
    805     // in Data during construction of this object, since this object is always
    806     // constructed, even when tracing is disabled. If the members of Data were
    807     // members of this class instead, compiler warnings occur about potential
    808     // uninitialized accesses.
    809     struct Data {
    810         const unsigned char* categoryEnabled;
    811         const char* name;
    812     };
    813     Data* m_pdata;
    814     Data m_data;
    815 };
    816 
    817 // TraceEventSamplingStateScope records the current sampling state
    818 // and sets a new sampling state. When the scope exists, it restores
    819 // the sampling state having recorded.
    820 template<size_t BucketNumber>
    821 class SamplingStateScope {
    822     WTF_MAKE_FAST_ALLOCATED;
    823 public:
    824     SamplingStateScope(const char* categoryAndName)
    825     {
    826         m_previousState = SamplingStateScope<BucketNumber>::current();
    827         SamplingStateScope<BucketNumber>::set(categoryAndName);
    828     }
    829 
    830     ~SamplingStateScope()
    831     {
    832         SamplingStateScope<BucketNumber>::set(m_previousState);
    833     }
    834 
    835     // FIXME: Make load/store to traceSamplingState[] thread-safe and atomic.
    836     static inline const char* current()
    837     {
    838         return reinterpret_cast<const char*>(*WebCore::traceSamplingState[BucketNumber]);
    839     }
    840     static inline void set(const char* categoryAndName)
    841     {
    842         *WebCore::traceSamplingState[BucketNumber] = reinterpret_cast<long>(const_cast<char*>(categoryAndName));
    843     }
    844 
    845 private:
    846     const char* m_previousState;
    847 };
    848 
    849 } // namespace TraceEvent
    850 
    851 } // namespace WebCore
    852 
    853 #endif
    854