/*
 * Copyright (C) 2011 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1.  Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 * 2.  Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
 *     its contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#pragma once

#include <stdint.h>
#include <wtf/Assertions.h>

namespace JSC {

// AbstractSamplingCounter:
//
// Implements a named set of counters, printed on exit if ENABLE(SAMPLING_COUNTERS).
// See subclasses below, SamplingCounter, GlobalSamplingCounter and DeletableSamplingCounter.
class AbstractSamplingCounter {
    friend class DeletableSamplingCounter;
public:
    void count(uint32_t count = 1)
    {
        m_counter += count;
    }

    JS_EXPORT_PRIVATE static void dump();

    int64_t* addressOfCounter() { return &m_counter; }

protected:
    // Effectively the contructor, however called lazily in the case of GlobalSamplingCounter.
    void init(const char* name)
    {
        m_counter = 0;
        m_name = name;

        // Set m_next to point to the head of the chain, and inform whatever is
        // currently at the head that this node will now hold the pointer to it.
        m_next = s_abstractSamplingCounterChain;
        s_abstractSamplingCounterChain->m_referer = &m_next;
        // Add this node to the head of the list.
        s_abstractSamplingCounterChain = this;
        m_referer = &s_abstractSamplingCounterChain;
    }

    int64_t m_counter;
    const char* m_name;
    AbstractSamplingCounter* m_next;
    // This is a pointer to the pointer to this node in the chain; used to
    // allow fast linked list deletion.
    AbstractSamplingCounter** m_referer;
    // Null object used to detect end of static chain.
    static AbstractSamplingCounter s_abstractSamplingCounterChainEnd;
    JS_EXPORTDATA static AbstractSamplingCounter* s_abstractSamplingCounterChain;
    static bool s_completed;
};

#if ENABLE(SAMPLING_COUNTERS)
// SamplingCounter:
//
// This class is suitable and (hopefully!) convenient for cases where a counter is
// required within the scope of a single function. It can be instantiated as a
// static variable since it contains a constructor but not a destructor (static
// variables in WebKit cannot have destructors).
//
// For example:
//
// void someFunction()
// {
//     static SamplingCounter countMe("This is my counter. There are many like it, but this one is mine.");
//     countMe.count();
//     // ...
// }
//
class SamplingCounter : public AbstractSamplingCounter {
public:
    SamplingCounter(const char* name) { init(name); }
};

// GlobalSamplingCounter:
//
// This class is suitable for use where a counter is to be declared globally,
// since it contains neither a constructor nor destructor. Instead, ensure
// that 'name()' is called to provide the counter with a name (and also to
// allow it to be printed out on exit).
//
// GlobalSamplingCounter globalCounter;
//
// void firstFunction()
// {
//     // Put this within a function that is definitely called!
//     // (Or alternatively alongside all calls to 'count()').
//     globalCounter.name("I Name You Destroyer.");
//     globalCounter.count();
//     // ...
// }
//
// void secondFunction()
// {
//     globalCounter.count();
//     // ...
// }
//
class GlobalSamplingCounter : public AbstractSamplingCounter {
public:
    void name(const char* name)
    {
        // Global objects should be mapped in zero filled memory, so this should
        // be a safe (albeit not necessarily threadsafe) check for 'first call'.
        if (!m_next)
            init(name);
    }
};

// DeletableSamplingCounter:
//
// The above classes (SamplingCounter, GlobalSamplingCounter), are intended for
// use within a global or static scope, and as such cannot have a destructor.
// This means there is no convenient way for them to remove themselves from the
// static list of counters, and should an instance of either class be freed
// before 'dump()' has walked over the list it will potentially walk over an
// invalid pointer.
//
// This class is intended for use where the counter may possibly be deleted before
// the program exits. Should this occur, the counter will print it's value to
// stderr, and remove itself from the static list. Example:
//
// DeletableSamplingCounter* counter = new DeletableSamplingCounter("The Counter With No Name");
// counter->count();
// delete counter;
//
class DeletableSamplingCounter : public AbstractSamplingCounter {
public:
    DeletableSamplingCounter(const char* name) { init(name); }

    ~DeletableSamplingCounter()
    {
        if (!s_completed)
            dataFile("DeletableSamplingCounter \"%s\" deleted early (with count %lld)\n", m_name, m_counter);
        // Our m_referer pointer should know where the pointer to this node is,
        // and m_next should know that this node is the previous node in the list.
        ASSERT(*m_referer == this);
        ASSERT(m_next->m_referer == &m_next);
        // Remove this node from the list, and inform m_next that we have done so.
        m_next->m_referer = m_referer;
        *m_referer = m_next;
    }
};
#endif

} // namespace JSC
