Home | History | Annotate | Download | only in inspector
      1 /*
      2 * Copyright (C) 2013 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 are
      6 * met:
      7 *
      8 *     * Redistributions of source code must retain the above copyright
      9 * notice, this list of conditions and the following disclaimer.
     10 *     * Redistributions in binary form must reproduce the above
     11 * copyright notice, this list of conditions and the following disclaimer
     12 * in the documentation and/or other materials provided with the
     13 * distribution.
     14 *     * Neither the name of Google Inc. nor the names of its
     15 * contributors may be used to endorse or promote products derived from
     16 * this software without specific prior written permission.
     17 *
     18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29 */
     30 
     31 #ifndef TraceEventDispatcher_h
     32 #define TraceEventDispatcher_h
     33 
     34 #include "platform/TraceEvent.h"
     35 #include "platform/heap/Handle.h"
     36 #include "wtf/HashMap.h"
     37 #include "wtf/Threading.h"
     38 #include "wtf/ThreadingPrimitives.h"
     39 #include "wtf/Vector.h"
     40 #include "wtf/text/StringHash.h"
     41 #include "wtf/text/WTFString.h"
     42 
     43 namespace blink {
     44 
     45 class InspectorClient;
     46 
     47 class TraceEventDispatcher {
     48     WTF_MAKE_NONCOPYABLE(TraceEventDispatcher);
     49 public:
     50     class TraceEvent {
     51     public:
     52         TraceEvent()
     53             : m_name(0)
     54             , m_argumentCount(0)
     55         {
     56         }
     57 
     58         TraceEvent(double timestamp, char phase, const char* name, unsigned long long id, ThreadIdentifier threadIdentifier,
     59             int argumentCount, const char* const* argumentNames, const unsigned char* argumentTypes, const unsigned long long* argumentValues)
     60             : m_timestamp(timestamp)
     61             , m_phase(phase)
     62             , m_name(name)
     63             , m_id(id)
     64             , m_threadIdentifier(threadIdentifier)
     65             , m_argumentCount(argumentCount)
     66         {
     67             if (m_argumentCount > MaxArguments) {
     68                 ASSERT_NOT_REACHED();
     69                 m_argumentCount = MaxArguments;
     70             }
     71             for (int i = 0; i < m_argumentCount; ++i) {
     72                 m_argumentNames[i] = argumentNames[i];
     73                 if (argumentTypes[i] == TRACE_VALUE_TYPE_COPY_STRING) {
     74                     m_stringArguments[i] = reinterpret_cast<const char*>(argumentValues[i]);
     75                     m_argumentValues[i].m_string = reinterpret_cast<const char*>(m_stringArguments[i].characters8());
     76                     m_argumentTypes[i] = TRACE_VALUE_TYPE_STRING;
     77                 } else {
     78                     m_argumentValues[i].m_int = argumentValues[i];
     79                     m_argumentTypes[i] = argumentTypes[i];
     80                 }
     81             }
     82         }
     83 
     84         double timestamp() const { return m_timestamp; }
     85         char phase() const { return m_phase; }
     86         const char* name() const { return m_name; }
     87         unsigned long long id() const { return m_id; }
     88         ThreadIdentifier threadIdentifier() const { return m_threadIdentifier; }
     89         int argumentCount() const { return m_argumentCount; }
     90         bool isNull() const { return !m_name; }
     91 
     92         bool asBool(const char* name) const
     93         {
     94             return parameter(name, TRACE_VALUE_TYPE_BOOL).m_bool;
     95         }
     96         long long asInt(const char* name) const
     97         {
     98             size_t index = findParameter(name);
     99             if (index == kNotFound || (m_argumentTypes[index] != TRACE_VALUE_TYPE_INT && m_argumentTypes[index] != TRACE_VALUE_TYPE_UINT)) {
    100                 ASSERT_NOT_REACHED();
    101                 return 0;
    102             }
    103             return reinterpret_cast<const blink::TraceEvent::TraceValueUnion*>(m_argumentValues + index)->m_int;
    104         }
    105         unsigned long long asUInt(const char* name) const
    106         {
    107             return asInt(name);
    108         }
    109         double asDouble(const char* name) const
    110         {
    111             return parameter(name, TRACE_VALUE_TYPE_DOUBLE).m_double;
    112         }
    113         const char* asString(const char* name) const
    114         {
    115             return parameter(name, TRACE_VALUE_TYPE_STRING).m_string;
    116         }
    117 
    118     private:
    119         enum { MaxArguments = 2 };
    120 
    121         size_t findParameter(const char*) const;
    122         const blink::TraceEvent::TraceValueUnion& parameter(const char* name, unsigned char expectedType) const;
    123 
    124         double m_timestamp;
    125         char m_phase;
    126         const char* m_name;
    127         unsigned long long m_id;
    128         ThreadIdentifier m_threadIdentifier;
    129         int m_argumentCount;
    130         const char* m_argumentNames[MaxArguments];
    131         unsigned char m_argumentTypes[MaxArguments];
    132         blink::TraceEvent::TraceValueUnion m_argumentValues[MaxArguments];
    133         // These are only used as buffers for TRACE_VALUE_TYPE_COPY_STRING.
    134         // Consider allocating the entire vector of buffered trace events and their copied arguments out of a special arena
    135         // to make things more compact.
    136         String m_stringArguments[MaxArguments];
    137     };
    138 
    139     class TraceEventListener : public NoBaseWillBeGarbageCollected<TraceEventListener> {
    140     public:
    141 #if !ENABLE(OILPAN)
    142         virtual ~TraceEventListener() { }
    143 #endif
    144         virtual void call(const TraceEventDispatcher::TraceEvent&) = 0;
    145         virtual void* target() = 0;
    146         virtual void trace(Visitor*) { }
    147     };
    148 
    149     static TraceEventDispatcher* instance()
    150     {
    151         DEFINE_STATIC_LOCAL(TraceEventDispatcher, instance, ());
    152         return &instance;
    153     }
    154 
    155     void addListener(const char* name, char phase, PassOwnPtrWillBeRawPtr<TraceEventListener>, InspectorClient*);
    156 
    157     void removeAllListeners(void*, InspectorClient*);
    158     void processBackgroundEvents();
    159 
    160 private:
    161     typedef std::pair<String, int> EventSelector;
    162     typedef WillBeHeapHashMap<EventSelector, OwnPtrWillBeMember<WillBeHeapVector<OwnPtrWillBeMember<TraceEventListener> > > > ListenersMap;
    163 
    164     TraceEventDispatcher()
    165         : m_listeners(adoptPtrWillBeNoop(new ListenersMap()))
    166         , m_processEventsTaskInFlight(false)
    167         , m_lastEventProcessingTime(0)
    168     {
    169     }
    170 
    171     static void dispatchEventOnAnyThread(char phase, const unsigned char*, const char* name, unsigned long long id,
    172         int numArgs, const char* const* argNames, const unsigned char* argTypes, const unsigned long long* argValues,
    173         unsigned char flags, double timestamp);
    174 
    175     void enqueueEvent(double timestamp, char phase, const char* name, unsigned long long id, ThreadIdentifier,
    176         int argumentCount, const char* const* argumentNames, const unsigned char* argumentTypes, const unsigned long long* argumentValues);
    177     void processBackgroundEventsTask();
    178 
    179     Mutex m_mutex;
    180     OwnPtrWillBePersistent<ListenersMap> m_listeners;
    181     Vector<TraceEvent> m_backgroundEvents;
    182     bool m_processEventsTaskInFlight;
    183     double m_lastEventProcessingTime;
    184 };
    185 
    186 } // namespace blink
    187 
    188 #endif // TraceEventDispatcher_h
    189