DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Implementation

Mercurial (fddffdeab170)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/*
 * an object that stores the result of determining whether a style struct that
 * was computed can be cached in the rule tree, and if so, what the conditions
 * it relies on are
 */

#ifndef RuleNodeCacheConditions_h_
#define RuleNodeCacheConditions_h_

#include "mozilla/Attributes.h"
#include "nsCoord.h"
#include "nsTArray.h"

class nsStyleContext;

namespace mozilla {

/**
 * nsRuleNodeCacheConditions is used to store information about whether
 * we can store a style struct that we're computing in the rule tree.
 *
 * For inherited structs (i.e., structs with inherited properties), we
 * cache the struct in the rule tree if it does not depend on any data
 * in the style context tree, and otherwise store it in the style
 * context tree.  This means that for inherited structs, setting any
 * conditions is equivalent to making the struct uncacheable.
 *
 * For reset structs (i.e., structs with non-inherited properties), we
 * are also able to cache structs in the rule tree conditionally on
 * certain common conditions.  For these structs, setting conditions
 * (SetFontSizeDependency, SetWritingModeDependency) instead causes the
 * struct to be stored, with the condition, in the rule tree.
 */
class RuleNodeCacheConditions
{
public:
  RuleNodeCacheConditions()
    : mFontSize(0), mBits(0) {}
  RuleNodeCacheConditions(const RuleNodeCacheConditions& aOther)
    : mFontSize(aOther.mFontSize), mBits(aOther.mBits) {}
  RuleNodeCacheConditions& operator=(const RuleNodeCacheConditions& aOther)
  {
    mFontSize = aOther.mFontSize;
    mBits = aOther.mBits;
    return *this;
  }
  bool operator==(const RuleNodeCacheConditions& aOther) const
  {
    return mFontSize == aOther.mFontSize &&
           mBits == aOther.mBits;
  }
  bool operator!=(const RuleNodeCacheConditions& aOther) const
  {
    return !(*this == aOther);
  }

  bool Matches(nsStyleContext* aStyleContext) const;

  /**
   * Record that the data being computed depend on the font-size
   * property of the element for which they are being computed.
   *
   * Note that we sometimes actually call this when there is a
   * dependency on the font-size property of the parent element, but we
   * only do so while computing inherited structs (nsStyleFont), and we
   * only store reset structs conditionally.
   */
  void SetFontSizeDependency(nscoord aCoord)
  {
    MOZ_ASSERT(!(mBits & eHaveFontSize) || mFontSize == aCoord);
    mFontSize = aCoord;
    mBits |= eHaveFontSize;
  }

  /**
   * Record that the data being computed depend on the writing mode of
   * the element for which they are being computed, which in turn
   * depends on its 'writing-mode', 'direction', and 'text-orientation'
   * properties.
   */
  void SetWritingModeDependency(uint8_t aWritingMode)
  {
    MOZ_ASSERT(!(mBits & eHaveWritingMode) || GetWritingMode() == aWritingMode);
    mBits |= (static_cast<uint64_t>(aWritingMode) << eWritingModeShift) |
             eHaveWritingMode;
  }

  void SetUncacheable()
  {
    mBits |= eUncacheable;
  }

  bool Cacheable() const
  {
    return !(mBits & eUncacheable);
  }

  bool CacheableWithDependencies() const
  {
    return !(mBits & eUncacheable) &&
           (mBits & eHaveBitsMask) != 0;
  }

  bool CacheableWithoutDependencies() const
  {
    // We're not uncacheable and we have don't have a font-size or
    // writing mode value.
    return (mBits & eHaveBitsMask) == 0;
  }

#ifdef DEBUG
  void List() const;
#endif

private:
  enum {
    eUncacheable      = 0x0001,
    eHaveFontSize     = 0x0002,
    eHaveWritingMode  = 0x0004,
    eHaveBitsMask     = 0x00ff,
    eWritingModeMask  = 0xff00,
    eWritingModeShift = 8,
  };

  uint8_t GetWritingMode() const
  {
    return static_cast<uint8_t>(
        (mBits & eWritingModeMask) >> eWritingModeShift);
  }

  // The font size from which em units are derived.
  nscoord mFontSize;

  // Values in mBits:
  //   bit 0:      are we set to "uncacheable"?
  //   bit 1:      do we have a font size value?
  //   bit 2:      do we have a writing mode value?
  //   bits 2-7:   unused
  //   bits 8-15:  writing mode (uint8_t)
  //   bits 16-31: unused
  uint32_t mBits;
};

} // namespace mozilla

#endif // !defined(RuleNodeCacheConditions_h_)