<commit_before>/*
 * Copyright (C) 2012 Google 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:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * 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.
 *     * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
 * OWNER OR 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.
 */

#ifndef MemoryInstrumentation_h
#define MemoryInstrumentation_h

#include <wtf/OwnPtr.h>
#include <wtf/PassOwnPtr.h>
#include <wtf/RefPtr.h>

#define DEBUG_POINTER_INSTRUMENTATION 0

namespace WTF {

class MemoryClassInfo;
class MemoryObjectInfo;
class MemoryInstrumentation;

typedef const char* MemoryObjectType;

enum MemberType {
    PointerMember,
    ReferenceMember,
    RetainingPointer,
    LastMemberTypeEntry
};

template<typename T> void reportMemoryUsage(const T*, MemoryObjectInfo*);

class MemoryInstrumentationClient {
public:
    virtual ~MemoryInstrumentationClient() { }
    virtual void countObjectSize(const void*, MemoryObjectType, size_t) = 0;
    virtual bool visited(const void*) = 0;
    virtual bool checkCountedObject(const void*) = 0;

    virtual void reportNode(const MemoryObjectInfo&) = 0;
    virtual void reportEdge(const void* target, const char* edgeName, MemberType) = 0;
    virtual void reportLeaf(const MemoryObjectInfo&, const char* edgeName) = 0;
    virtual void reportBaseAddress(const void* base, const void* real) = 0;
    virtual int registerString(const char*) = 0;
};

class MemoryInstrumentation {
public:
    WTF_EXPORT_PRIVATE explicit MemoryInstrumentation(MemoryInstrumentationClient*);
    WTF_EXPORT_PRIVATE virtual ~MemoryInstrumentation();

    template <typename T> void addRootObject(const T& t, MemoryObjectType objectType = 0)
    {
        MemberTypeTraits<T>::addRootObject(this, t, objectType);
        processDeferredObjects();
    }

    template <typename T> void addRootObject(const OwnPtr<T>&, MemoryObjectType = 0); // Link time guard.
    template <typename T> void addRootObject(const RefPtr<T>&, MemoryObjectType = 0); // Link time guard.

protected:
    class WrapperBase {
    public:
        WTF_EXPORT_PRIVATE WrapperBase(MemoryObjectType, const void* pointer);
        virtual ~WrapperBase() { }
        WTF_EXPORT_PRIVATE void process(MemoryInstrumentation*);
        WTF_EXPORT_PRIVATE void processPointer(MemoryInstrumentation*, bool isRoot);
        WTF_EXPORT_PRIVATE void processRootObjectRef(MemoryInstrumentation*);

    protected:
        virtual void callReportMemoryUsage(MemoryObjectInfo*) = 0;
        const void* m_pointer;
        const MemoryObjectType m_ownerObjectType;

    private:
#if DEBUG_POINTER_INSTRUMENTATION
        static const int s_maxCallStackSize = 32;
        void* m_callStack[s_maxCallStackSize];
        int m_callStackSize;
#endif
    };

private:
    void countObjectSize(const void* object, MemoryObjectType objectType, size_t size) { m_client->countObjectSize(object, objectType, size); }
    bool visited(const void* pointer) { return m_client->visited(pointer); }
    bool checkCountedObject(const void* pointer) { return m_client->checkCountedObject(pointer); }

    WTF_EXPORT_PRIVATE void reportEdge(const void* target, const char* edgeName, MemberType);

    virtual void deferObject(PassOwnPtr<WrapperBase>) = 0;
    virtual void processDeferredObjects() = 0;

    WTF_EXPORT_PRIVATE static MemoryObjectType getObjectType(MemoryObjectInfo*);

    friend class MemoryObjectInfo;
    friend class MemoryClassInfo;
    template<typename T> friend void reportMemoryUsage(const T*, MemoryObjectInfo*);

    template <typename Type>
    class IsInstrumented {
        class yes {
            char m;
        };

        class no {
            yes m[2];
        };

        struct BaseMixin {
            void reportMemoryUsage(MemoryObjectInfo*) const { }
        };

#if COMPILER(MSVC)
#pragma warning(push)
#pragma warning(disable: 4624) // Disable warning: destructor could not be generated because a base class destructor is inaccessible.
#endif
        struct Base : public Type, public BaseMixin { };
#if COMPILER(MSVC)
#pragma warning(pop)
#endif

        template <typename T, T t> class Helper { };

        template <typename U> static no deduce(U*, Helper<void (BaseMixin::*)(MemoryObjectInfo*) const, &U::reportMemoryUsage>* = 0);
        static yes deduce(...);

    public:
        static const bool result = sizeof(yes) == sizeof(deduce((Base*)(0)));

    };

    template <int>
    struct InstrumentationSelector {
        template <typename T> static void reportObjectMemoryUsage(const T*, MemoryObjectInfo*);
    };
<commit_msg>Make a metaprogramming hack more C++11-compatible<commit_after>/*
 * Copyright (C) 2012 Google 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:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * 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.
 *     * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
 * OWNER OR 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.
 */

#ifndef MemoryInstrumentation_h
#define MemoryInstrumentation_h

#include <wtf/OwnPtr.h>
#include <wtf/PassOwnPtr.h>
#include <wtf/RefPtr.h>

#define DEBUG_POINTER_INSTRUMENTATION 0

namespace WTF {

class MemoryClassInfo;
class MemoryObjectInfo;
class MemoryInstrumentation;

typedef const char* MemoryObjectType;

enum MemberType {
    PointerMember,
    ReferenceMember,
    RetainingPointer,
    LastMemberTypeEntry
};

template<typename T> void reportMemoryUsage(const T*, MemoryObjectInfo*);

class MemoryInstrumentationClient {
public:
    virtual ~MemoryInstrumentationClient() { }
    virtual void countObjectSize(const void*, MemoryObjectType, size_t) = 0;
    virtual bool visited(const void*) = 0;
    virtual bool checkCountedObject(const void*) = 0;

    virtual void reportNode(const MemoryObjectInfo&) = 0;
    virtual void reportEdge(const void* target, const char* edgeName, MemberType) = 0;
    virtual void reportLeaf(const MemoryObjectInfo&, const char* edgeName) = 0;
    virtual void reportBaseAddress(const void* base, const void* real) = 0;
    virtual int registerString(const char*) = 0;
};

class MemoryInstrumentation {
public:
    WTF_EXPORT_PRIVATE explicit MemoryInstrumentation(MemoryInstrumentationClient*);
    WTF_EXPORT_PRIVATE virtual ~MemoryInstrumentation();

    template <typename T> void addRootObject(const T& t, MemoryObjectType objectType = 0)
    {
        MemberTypeTraits<T>::addRootObject(this, t, objectType);
        processDeferredObjects();
    }

    template <typename T> void addRootObject(const OwnPtr<T>&, MemoryObjectType = 0); // Link time guard.
    template <typename T> void addRootObject(const RefPtr<T>&, MemoryObjectType = 0); // Link time guard.

protected:
    class WrapperBase {
    public:
        WTF_EXPORT_PRIVATE WrapperBase(MemoryObjectType, const void* pointer);
        virtual ~WrapperBase() { }
        WTF_EXPORT_PRIVATE void process(MemoryInstrumentation*);
        WTF_EXPORT_PRIVATE void processPointer(MemoryInstrumentation*, bool isRoot);
        WTF_EXPORT_PRIVATE void processRootObjectRef(MemoryInstrumentation*);

    protected:
        virtual void callReportMemoryUsage(MemoryObjectInfo*) = 0;
        const void* m_pointer;
        const MemoryObjectType m_ownerObjectType;

    private:
#if DEBUG_POINTER_INSTRUMENTATION
        static const int s_maxCallStackSize = 32;
        void* m_callStack[s_maxCallStackSize];
        int m_callStackSize;
#endif
    };

private:
    void countObjectSize(const void* object, MemoryObjectType objectType, size_t size) { m_client->countObjectSize(object, objectType, size); }
    bool visited(const void* pointer) { return m_client->visited(pointer); }
    bool checkCountedObject(const void* pointer) { return m_client->checkCountedObject(pointer); }

    WTF_EXPORT_PRIVATE void reportEdge(const void* target, const char* edgeName, MemberType);

    virtual void deferObject(PassOwnPtr<WrapperBase>) = 0;
    virtual void processDeferredObjects() = 0;

    WTF_EXPORT_PRIVATE static MemoryObjectType getObjectType(MemoryObjectInfo*);

    friend class MemoryObjectInfo;
    friend class MemoryClassInfo;
    template<typename T> friend void reportMemoryUsage(const T*, MemoryObjectInfo*);

    template <typename Type>
    class IsInstrumented {
        class yes {
            char m;
        };

        class no {
            yes m[2];
        };

        struct BaseMixin {
            void reportMemoryUsage(MemoryObjectInfo*) const { }
        };

        struct Base : public Type, public BaseMixin {
            // Provide expicit destructor without definition to avoid MSVC warning "destructor could
            // not be generated because a base class destructor is inaccessible."
            ~Base();
        };

        template <typename T, T t> class Helper { };

        template <typename U> static no deduce(U*, Helper<void (BaseMixin::*)(MemoryObjectInfo*) const, &U::reportMemoryUsage>* = 0);
        static yes deduce(...);

    public:
        static const bool result = sizeof(yes) == sizeof(deduce((Base*)(0)));

    };

    template <int>
    struct InstrumentationSelector {
        template <typename T> static void reportObjectMemoryUsage(const T*, MemoryObjectInfo*);
    };

{'fraction_non_alphanumeric': 0.07734995304362674, 'fraction_numerical': 0.0046102621019380174, 'mean_word_length': 3.9783255418614534, 'pattern_counts': {'":': 0, '<': 39, '<?xml version=': 0, '>': 45, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4420457', 'n_tokens_mistral': 3285, 'n_tokens_neox': 3069, 'n_words': 1114}