Home | History | Annotate | Download | only in wtf
      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 #ifndef StackStats_h
     27 #define StackStats_h
     28 
     29 #include "ThreadingPrimitives.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 1
     43 
     44 
     45 namespace WTF {
     46 
     47 #if !ENABLE(STACK_STATS)
     48 
     49 class StackStats {
     50 public:
     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 initialize() { }
     70     static void probe() { }
     71 };
     72 
     73 #else // ENABLE(STACK_STATS)
     74 
     75 class StackStats {
     76 public:
     77     // The CheckPoint class is for marking check points corresponding
     78     // each location in code where a stack recursion check is being done.
     79 
     80     class CheckPoint {
     81     public:
     82         CheckPoint();
     83         ~CheckPoint();
     84     private:
     85         CheckPoint* m_prev;
     86     };
     87 
     88     class PerThreadStats {
     89     public:
     90         PerThreadStats();
     91 
     92     private:
     93         int m_reentryDepth;
     94         char* m_stackStart;
     95         CheckPoint* m_currentCheckPoint;
     96 
     97         friend class CheckPoint;
     98         friend class StackStats;
     99     };
    100 
    101     class LayoutCheckPoint {
    102     public:
    103         LayoutCheckPoint();
    104         ~LayoutCheckPoint();
    105 
    106     private:
    107         LayoutCheckPoint* m_prev;
    108         int m_depth;
    109     };
    110 
    111     // Initializes locks and the log file. Should only be called once.
    112     static void initialize();
    113 
    114     // Used for probing the stack at places where we suspect to be high
    115     // points of stack usage but are NOT check points where stack recursion
    116     // is checked.
    117     //
    118     // The more places where we add this probe, the more accurate our
    119     // stats data will be. However, adding too many probes will also
    120     // result in unnecessary performance loss. So, only add these probes
    121     // judiciously where appropriate.
    122     static void probe();
    123 
    124 private:
    125     // CheckPoint management:
    126     static Mutex* s_sharedLock;
    127     static CheckPoint* s_topCheckPoint;
    128     static LayoutCheckPoint* s_firstLayoutCheckPoint;
    129     static LayoutCheckPoint* s_topLayoutCheckPoint;
    130 
    131     // High watermark stats:
    132     static int s_maxCheckPointDiff;
    133     static int s_maxStackHeight;
    134     static int s_maxReentryDepth;
    135 
    136     static int s_maxLayoutCheckPointDiff;
    137     static int s_maxTotalLayoutCheckPointDiff;
    138     static int s_maxLayoutReentryDepth;
    139 
    140     friend class CheckPoint;
    141     friend class LayoutCheckPoint;
    142 };
    143 
    144 #endif // ENABLE(STACK_STATS)
    145 
    146 } // namespace WTF
    147 
    148 using WTF::StackStats;
    149 
    150 #endif // StackStats_h
    151