1/*
2 * Copyright (C) 2012 Apple 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
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#pragma once
27
28#include <mutex>
29#include <wtf/ExportMacros.h>
30
31
32// Define this flag to enable Stack stats collection. This feature is useful
33// for getting a sample of native stack usage sizes.
34//
35// Enabling this will cause stats to be collected and written to a log file at
36// various instrumented points in the code. It will result in noticeable
37// performance loss. Hence, this should only be enable when you want to do
38// some stats location in your local build. This code is provided here as a
39// convenience for collecting that data. It is not meant to be enabled by
40// default on release or debug builds.
41
42#define ENABLE_STACK_STATS 0
43
44
45namespace WTF {
46
47#if !ENABLE(STACK_STATS)
48
49class StackStats {
50public:
51 // The CheckPoint class is for marking check points corresponding
52 // each location in code where a stack recursion check is being done.
53
54 class CheckPoint {
55 public:
56 CheckPoint() { }
57 };
58
59 class PerThreadStats {
60 public:
61 PerThreadStats() { }
62 };
63
64 class LayoutCheckPoint {
65 public:
66 LayoutCheckPoint() { }
67 };
68
69 static void probe() { }
70};
71
72#else // ENABLE(STACK_STATS)
73
74class StackStats {
75public:
76 // The CheckPoint class is for marking check points corresponding
77 // each location in code where a stack recursion check is being done.
78
79 class CheckPoint {
80 public:
81 CheckPoint();
82 ~CheckPoint();
83 private:
84 CheckPoint* m_prev;
85 };
86
87 class PerThreadStats {
88 public:
89 PerThreadStats();
90
91 private:
92 int m_reentryDepth;
93 char* m_stackStart;
94 CheckPoint* m_currentCheckPoint;
95
96 friend class CheckPoint;
97 friend class StackStats;
98 };
99
100 class LayoutCheckPoint {
101 public:
102 WTF_EXPORT_PRIVATE LayoutCheckPoint();
103 WTF_EXPORT_PRIVATE ~LayoutCheckPoint();
104
105 private:
106 LayoutCheckPoint* m_prev;
107 int m_depth;
108 };
109
110 // Used for probing the stack at places where we suspect to be high
111 // points of stack usage but are NOT check points where stack recursion
112 // is checked.
113 //
114 // The more places where we add this probe, the more accurate our
115 // stats data will be. However, adding too many probes will also
116 // result in unnecessary performance loss. So, only add these probes
117 // judiciously where appropriate.
118 static void probe();
119
120private:
121 // CheckPoint management:
122 static Lock s_sharedMutex;
123 static CheckPoint* s_topCheckPoint;
124 static LayoutCheckPoint* s_firstLayoutCheckPoint;
125 static LayoutCheckPoint* s_topLayoutCheckPoint;
126
127 // High watermark stats:
128 static int s_maxCheckPointDiff;
129 static int s_maxStackHeight;
130 static int s_maxReentryDepth;
131
132 static int s_maxLayoutCheckPointDiff;
133 static int s_maxTotalLayoutCheckPointDiff;
134 static int s_maxLayoutReentryDepth;
135
136 friend class CheckPoint;
137 friend class LayoutCheckPoint;
138};
139
140#endif // ENABLE(STACK_STATS)
141
142} // namespace WTF
143
144using WTF::StackStats;
145