Ignore:
Timestamp:
Aug 22, 2011, 4:41:20 PM (14 years ago)
Author:
[email protected]
Message:

Sampling counter support is in the bytecode directory
https://bugs.webkit.org/show_bug.cgi?id=66724

Reviewed by Darin Adler.

Moved SamplingCounter to a separate header in runtime/.

  • GNUmakefile.list.am:
  • JavaScriptCore.pro:
  • JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
  • JavaScriptCore.xcodeproj/project.pbxproj:
  • bytecode/SamplingTool.cpp:
  • bytecode/SamplingTool.h:
  • runtime/SamplingCounter.cpp: Added.

(JSC::AbstractSamplingCounter::dump):

  • runtime/SamplingCounter.h: Added.

(JSC::AbstractSamplingCounter::count):
(JSC::AbstractSamplingCounter::addressOfCounter):
(JSC::AbstractSamplingCounter::init):
(JSC::SamplingCounter::SamplingCounter):
(JSC::GlobalSamplingCounter::name):
(JSC::DeletableSamplingCounter::DeletableSamplingCounter):
(JSC::DeletableSamplingCounter::~DeletableSamplingCounter):

Location:
trunk/Source/JavaScriptCore/bytecode
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/bytecode/SamplingTool.cpp

    r89973 r93560  
    388388#endif
    389389
    390 void AbstractSamplingCounter::dump()
    391 {
    392 #if ENABLE(SAMPLING_COUNTERS)
    393     if (s_abstractSamplingCounterChain != &s_abstractSamplingCounterChainEnd) {
    394         printf("\nSampling Counter Values:\n");
    395         for (AbstractSamplingCounter* currCounter = s_abstractSamplingCounterChain; (currCounter != &s_abstractSamplingCounterChainEnd); currCounter = currCounter->m_next)
    396             printf("\t%s\t: %lld\n", currCounter->m_name, currCounter->m_counter);
    397         printf("\n\n");
    398     }
    399     s_completed = true;
    400 #endif
    401 }
    402 
    403 AbstractSamplingCounter AbstractSamplingCounter::s_abstractSamplingCounterChainEnd;
    404 AbstractSamplingCounter* AbstractSamplingCounter::s_abstractSamplingCounterChain = &s_abstractSamplingCounterChainEnd;
    405 bool AbstractSamplingCounter::s_completed = false;
    406 
    407390} // namespace JSC
  • trunk/Source/JavaScriptCore/bytecode/SamplingTool.h

    r89973 r93560  
    3333#include "Nodes.h"
    3434#include "Opcode.h"
     35#include "SamplingCounter.h"
    3536#include <wtf/Assertions.h>
    3637#include <wtf/HashMap.h>
     
    280281    };
    281282
    282     // AbstractSamplingCounter:
    283     //
    284     // Implements a named set of counters, printed on exit if ENABLE(SAMPLING_COUNTERS).
    285     // See subclasses below, SamplingCounter, GlobalSamplingCounter and DeletableSamplingCounter.
    286     class AbstractSamplingCounter {
    287         friend class DeletableSamplingCounter;
    288     public:
    289         void count(uint32_t count = 1)
    290         {
    291             m_counter += count;
    292         }
    293 
    294         static void dump();
    295 
    296         int64_t* addressOfCounter() { return &m_counter; }
    297 
    298     protected:
    299         // Effectively the contructor, however called lazily in the case of GlobalSamplingCounter.
    300         void init(const char* name)
    301         {
    302             m_counter = 0;
    303             m_name = name;
    304 
    305             // Set m_next to point to the head of the chain, and inform whatever is
    306             // currently at the head that this node will now hold the pointer to it.
    307             m_next = s_abstractSamplingCounterChain;
    308             s_abstractSamplingCounterChain->m_referer = &m_next;
    309             // Add this node to the head of the list.
    310             s_abstractSamplingCounterChain = this;
    311             m_referer = &s_abstractSamplingCounterChain;
    312         }
    313 
    314         int64_t m_counter;
    315         const char* m_name;
    316         AbstractSamplingCounter* m_next;
    317         // This is a pointer to the pointer to this node in the chain; used to
    318         // allow fast linked list deletion.
    319         AbstractSamplingCounter** m_referer;
    320         // Null object used to detect end of static chain.
    321         static AbstractSamplingCounter s_abstractSamplingCounterChainEnd;
    322         static AbstractSamplingCounter* s_abstractSamplingCounterChain;
    323         static bool s_completed;
    324     };
    325 
    326 #if ENABLE(SAMPLING_COUNTERS)
    327     // SamplingCounter:
    328     //
    329     // This class is suitable and (hopefully!) convenient for cases where a counter is
    330     // required within the scope of a single function.  It can be instantiated as a
    331     // static variable since it contains a constructor but not a destructor (static
    332     // variables in WebKit cannot have destructors).
    333     //
    334     // For example:
    335     //
    336     // void someFunction()
    337     // {
    338     //     static SamplingCounter countMe("This is my counter.  There are many like it, but this one is mine.");
    339     //     countMe.count();
    340     //     // ...
    341     // }
    342     //
    343     class SamplingCounter : public AbstractSamplingCounter {
    344     public:
    345         SamplingCounter(const char* name) { init(name); }
    346     };
    347 
    348     // GlobalSamplingCounter:
    349     //
    350     // This class is suitable for use where a counter is to be declared globally,
    351     // since it contains neither a constructor nor destructor.  Instead, ensure
    352     // that 'name()' is called to provide the counter with a name (and also to
    353     // allow it to be printed out on exit).
    354     //
    355     // GlobalSamplingCounter globalCounter;
    356     //
    357     // void firstFunction()
    358     // {
    359     //     // Put this within a function that is definitely called!
    360     //     // (Or alternatively alongside all calls to 'count()').
    361     //     globalCounter.name("I Name You Destroyer.");
    362     //     globalCounter.count();
    363     //     // ...
    364     // }
    365     //
    366     // void secondFunction()
    367     // {
    368     //     globalCounter.count();
    369     //     // ...
    370     // }
    371     //
    372     class GlobalSamplingCounter : public AbstractSamplingCounter {
    373     public:
    374         void name(const char* name)
    375         {
    376             // Global objects should be mapped in zero filled memory, so this should
    377             // be a safe (albeit not necessarily threadsafe) check for 'first call'.
    378             if (!m_next)
    379                 init(name);
    380         }
    381     };
    382 
    383     // DeletableSamplingCounter:
    384     //
    385     // The above classes (SamplingCounter, GlobalSamplingCounter), are intended for
    386     // use within a global or static scope, and as such cannot have a destructor.
    387     // This means there is no convenient way for them to remove themselves from the
    388     // static list of counters, and should an instance of either class be freed
    389     // before 'dump()' has walked over the list it will potentially walk over an
    390     // invalid pointer.
    391     //
    392     // This class is intended for use where the counter may possibly be deleted before
    393     // the program exits.  Should this occur, the counter will print it's value to
    394     // stderr, and remove itself from the static list.  Example:
    395     //
    396     // DeletableSamplingCounter* counter = new DeletableSamplingCounter("The Counter With No Name");
    397     // counter->count();
    398     // delete counter;
    399     //
    400     class DeletableSamplingCounter : public AbstractSamplingCounter {
    401     public:
    402         DeletableSamplingCounter(const char* name) { init(name); }
    403 
    404         ~DeletableSamplingCounter()
    405         {
    406             if (!s_completed)
    407                 fprintf(stderr, "DeletableSamplingCounter \"%s\" deleted early (with count %lld)\n", m_name, m_counter);
    408             // Our m_referer pointer should know where the pointer to this node is,
    409             // and m_next should know that this node is the previous node in the list.
    410             ASSERT(*m_referer == this);
    411             ASSERT(m_next->m_referer == &m_next);
    412             // Remove this node from the list, and inform m_next that we have done so.
    413             m_next->m_referer = m_referer;
    414             *m_referer = m_next;
    415         }
    416     };
    417 #endif
    418 
    419283} // namespace JSC
    420284
Note: See TracChangeset for help on using the changeset viewer.