LCOV - code coverage report
Current view: top level - js/src/jit - ICState.h (source / functions) Hit Total Coverage
Test: output.info Lines: 54 55 98.2 %
Date: 2017-07-14 16:53:18 Functions: 13 14 92.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
       2             :  * vim: set ts=8 sts=4 et sw=4 tw=99:
       3             :  * This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #ifndef jit_ICState_h
       8             : #define jit_ICState_h
       9             : 
      10             : #include "jit/JitOptions.h"
      11             : 
      12             : namespace js {
      13             : namespace jit {
      14             : 
      15             : // ICState stores information about a Baseline or Ion IC.
      16             : class ICState
      17             : {
      18             :   public:
      19             :     // When we attach the maximum number of stubs, we discard all stubs and
      20             :     // transition the IC to Megamorphic to attach stubs that are more generic
      21             :     // (handle more cases). If we again attach the maximum number of stubs, we
      22             :     // transition to Generic and (depending on the IC) will either attach a
      23             :     // single stub that handles everything or stop attaching new stubs.
      24             :     //
      25             :     // We also transition to Generic when we repeatedly fail to attach a stub,
      26             :     // to avoid wasting time trying.
      27             :     enum class Mode : uint8_t { Specialized = 0, Megamorphic, Generic };
      28             : 
      29             :   private:
      30             :     Mode mode_;
      31             : 
      32             :     // Number of optimized stubs currently attached to this IC.
      33             :     uint8_t numOptimizedStubs_;
      34             : 
      35             :     // Number of times we failed to attach a stub.
      36             :     uint8_t numFailures_;
      37             : 
      38             :     // This is only used for shared Baseline ICs and stored here to save space.
      39             :     bool invalid_ : 1;
      40             : 
      41             :     static const size_t MaxOptimizedStubs = 6;
      42             : 
      43         204 :     void transition(Mode mode) {
      44         204 :         MOZ_ASSERT(mode > mode_);
      45         204 :         mode_ = mode;
      46         204 :         numFailures_ = 0;
      47         204 :     }
      48             : 
      49        7263 :     MOZ_ALWAYS_INLINE size_t maxFailures() const {
      50             :         // Allow more failures if we attached stubs.
      51             :         static_assert(MaxOptimizedStubs == 6,
      52             :                       "numFailures_/maxFailures should fit in uint8_t");
      53        7263 :         size_t res = 5 + size_t(40) * numOptimizedStubs_;
      54        7263 :         MOZ_ASSERT(res <= UINT8_MAX, "numFailures_ should not overflow");
      55        7263 :         return res;
      56             :     }
      57             : 
      58             :   public:
      59       17243 :     ICState()
      60       17243 :       : invalid_(false)
      61             :     {
      62       17243 :         reset();
      63       17243 :     }
      64             : 
      65       12137 :     Mode mode() const { return mode_; }
      66       17083 :     size_t numOptimizedStubs() const { return numOptimizedStubs_; }
      67             : 
      68       12577 :     MOZ_ALWAYS_INLINE bool canAttachStub() const {
      69       12577 :         MOZ_ASSERT(numOptimizedStubs_ <= MaxOptimizedStubs);
      70       12577 :         if (mode_ == Mode::Generic || JitOptions.disableCacheIR)
      71        5442 :             return false;
      72        7135 :         return true;
      73             :     }
      74             : 
      75       10091 :     bool invalid() const { return invalid_; }
      76           0 :     void setInvalid() { invalid_ = true; }
      77             : 
      78             :     // If this returns true, we transitioned to a new mode and the caller
      79             :     // should discard all stubs.
      80       12577 :     MOZ_MUST_USE MOZ_ALWAYS_INLINE bool maybeTransition() {
      81       12577 :         MOZ_ASSERT(numOptimizedStubs_ <= MaxOptimizedStubs);
      82       12577 :         if (mode_ == Mode::Generic)
      83        5366 :             return false;
      84        7211 :         if (numOptimizedStubs_ < MaxOptimizedStubs && numFailures_ < maxFailures())
      85        7007 :             return false;
      86         204 :         if (numFailures_ == maxFailures() || mode_ == Mode::Megamorphic) {
      87          76 :             transition(Mode::Generic);
      88          76 :             return true;
      89             :         }
      90         128 :         MOZ_ASSERT(mode_ == Mode::Specialized);
      91         128 :         transition(Mode::Megamorphic);
      92         128 :         return true;
      93             :     }
      94       17243 :     void reset() {
      95       17243 :         mode_ = Mode::Specialized;
      96       17243 :         numOptimizedStubs_ = 0;
      97       17243 :         numFailures_ = 0;
      98       17243 :     }
      99       10034 :     void trackAttached() {
     100             :         // We'd like to assert numOptimizedStubs_ < MaxOptimizedStubs, but
     101             :         // since this code is also used for non-CacheIR Baseline stubs, assert
     102             :         // < 16 for now. Note that we do have the stronger assert in other
     103             :         // methods, because they are only used by CacheIR ICs.
     104       10034 :         MOZ_ASSERT(numOptimizedStubs_ < 16);
     105       10034 :         numOptimizedStubs_++;
     106       10034 :         numFailures_ = 0;
     107       10034 :     }
     108         648 :     void trackNotAttached() {
     109             :         // Note: we can't assert numFailures_ < maxFailures() because
     110             :         // maxFailures() depends on numOptimizedStubs_ and it's possible a
     111             :         // GC discarded stubs before we got here.
     112         648 :         numFailures_++;
     113         648 :         MOZ_ASSERT(numFailures_ > 0, "numFailures_ should not overflow");
     114         648 :     }
     115        1056 :     void trackUnlinkedStub() {
     116        1056 :         MOZ_ASSERT(numOptimizedStubs_ > 0);
     117        1056 :         numOptimizedStubs_--;
     118        1056 :     }
     119           1 :     void trackUnlinkedAllStubs() {
     120           1 :         numOptimizedStubs_ = 0;
     121           1 :     }
     122             : };
     123             : 
     124             : } // namespace jit
     125             : } // namespace js
     126             : 
     127             : #endif /* jit_ICState_h */

Generated by: LCOV version 1.13