blob: 4f50647ff8c5284951ee59060e213a008975bcee [file] [log] [blame]
/*
* Copyright (C) 2012 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.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``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 INC. 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.
*/
#pragma once
#include <mutex>
#include <wtf/ExportMacros.h>
// Define this flag to enable Stack stats collection. This feature is useful
// for getting a sample of native stack usage sizes.
//
// Enabling this will cause stats to be collected and written to a log file at
// various instrumented points in the code. It will result in noticeable
// performance loss. Hence, this should only be enable when you want to do
// some stats location in your local build. This code is provided here as a
// convenience for collecting that data. It is not meant to be enabled by
// default on release or debug builds.
#define ENABLE_STACK_STATS 0
namespace WTF {
#if !ENABLE(STACK_STATS)
class StackStats {
WTF_MAKE_FAST_ALLOCATED;
public:
// The CheckPoint class is for marking check points corresponding
// each location in code where a stack recursion check is being done.
class CheckPoint {
public:
CheckPoint() { }
};
class PerThreadStats {
public:
PerThreadStats() { }
};
class LayoutCheckPoint {
public:
LayoutCheckPoint() { }
};
static void probe() { }
};
#else // ENABLE(STACK_STATS)
class StackStats {
WTF_MAKE_FAST_ALLOCATED;
public:
// The CheckPoint class is for marking check points corresponding
// each location in code where a stack recursion check is being done.
class CheckPoint {
public:
CheckPoint();
~CheckPoint();
private:
CheckPoint* m_prev;
};
class PerThreadStats {
public:
PerThreadStats();
private:
int m_reentryDepth;
char* m_stackStart;
CheckPoint* m_currentCheckPoint;
friend class CheckPoint;
friend class StackStats;
};
class LayoutCheckPoint {
public:
WTF_EXPORT_PRIVATE LayoutCheckPoint();
WTF_EXPORT_PRIVATE ~LayoutCheckPoint();
private:
LayoutCheckPoint* m_prev;
int m_depth;
};
// Used for probing the stack at places where we suspect to be high
// points of stack usage but are NOT check points where stack recursion
// is checked.
//
// The more places where we add this probe, the more accurate our
// stats data will be. However, adding too many probes will also
// result in unnecessary performance loss. So, only add these probes
// judiciously where appropriate.
static void probe();
private:
// CheckPoint management:
static Lock s_sharedMutex;
static CheckPoint* s_topCheckPoint;
static LayoutCheckPoint* s_firstLayoutCheckPoint;
static LayoutCheckPoint* s_topLayoutCheckPoint;
// High watermark stats:
static int s_maxCheckPointDiff;
static int s_maxStackHeight;
static int s_maxReentryDepth;
static int s_maxLayoutCheckPointDiff;
static int s_maxTotalLayoutCheckPointDiff;
static int s_maxLayoutReentryDepth;
friend class CheckPoint;
friend class LayoutCheckPoint;
};
#endif // ENABLE(STACK_STATS)
} // namespace WTF
using WTF::StackStats;