1 /*
2  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3  * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc.
4  * All rights reserved.
5  * Copyright (C) 2013 Google Inc. All rights reserved.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public License
18  * along with this library; see the file COPYING.LIB.  If not, write to
19  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20  * Boston, MA 02110-1301, USA.
21  *
22  */
23 
24 #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_CSS_RESOLVER_MATCHED_PROPERTIES_CACHE_H_
25 #define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_RESOLVER_MATCHED_PROPERTIES_CACHE_H_
26 
27 #include "third_party/blink/renderer/core/css/css_property_value_set.h"
28 #include "third_party/blink/renderer/core/css/resolver/match_result.h"
29 #include "third_party/blink/renderer/platform/heap/handle.h"
30 #include "third_party/blink/renderer/platform/wtf/forward.h"
31 #include "third_party/blink/renderer/platform/wtf/hash_map.h"
32 
33 namespace blink {
34 
35 class ComputedStyle;
36 class StyleResolverState;
37 
38 class CORE_EXPORT CachedMatchedProperties final
39     : public GarbageCollected<CachedMatchedProperties> {
40  public:
41   // Caches data of MatchedProperties. See |MatchedPropertiesCache::Cache| for
42   // semantics.
43   // We use UntracedMember<> here because WeakMember<> would require using a
44   // HeapHashSet which is slower to iterate.
45   Vector<UntracedMember<CSSPropertyValueSet>> matched_properties;
46   Vector<MatchedProperties::Data> matched_properties_types;
47 
48   scoped_refptr<ComputedStyle> computed_style;
49   scoped_refptr<ComputedStyle> parent_computed_style;
50 
51   // g_null_atom-terminated array of property names.
52   //
53   // Note that this stores AtomicString for both standard and custom
54   // properties, for memory saving purposes. (CSSPropertyName is twice as
55   // big).
56   std::unique_ptr<AtomicString[]> dependencies;
57 
58   void Set(const ComputedStyle&,
59            const ComputedStyle& parent_style,
60            const MatchedPropertiesVector&,
61            const HashSet<CSSPropertyName>& new_dependencies);
62   void Clear();
63 
64   // True if the computed value for each dependency is equal for the
65   // cached parent style vs. the incoming parent style.
66   bool DependenciesEqual(const StyleResolverState&);
67 
Trace(Visitor *)68   void Trace(Visitor*) const {}
69 
70   bool operator==(const MatchedPropertiesVector& properties);
71   bool operator!=(const MatchedPropertiesVector& properties);
72 };
73 
74 class CORE_EXPORT MatchedPropertiesCache {
75   DISALLOW_NEW();
76 
77  public:
78   MatchedPropertiesCache();
79   MatchedPropertiesCache(const MatchedPropertiesCache&) = delete;
80   MatchedPropertiesCache& operator=(const MatchedPropertiesCache&) = delete;
~MatchedPropertiesCache()81   ~MatchedPropertiesCache() { DCHECK(cache_.IsEmpty()); }
82 
83   class CORE_EXPORT Key {
84     STACK_ALLOCATED();
85 
86    public:
87     explicit Key(const MatchResult&);
88 
IsValid()89     bool IsValid() const {
90       // If hash_ happens to compute to the empty value or the deleted value,
91       // the corresponding MatchResult can't be cached.
92       return hash_ != HashTraits<unsigned>::EmptyValue() &&
93              !HashTraits<unsigned>::IsDeletedValue(hash_);
94     }
95 
96    private:
97     friend class MatchedPropertiesCache;
98     friend class MatchedPropertiesCacheTestKey;
99 
100     Key(const MatchResult&, unsigned hash);
101 
102     const MatchResult& result_;
103     unsigned hash_;
104   };
105 
106   const CachedMatchedProperties* Find(const Key&, const StyleResolverState&);
107   void Add(const Key&,
108            const ComputedStyle&,
109            const ComputedStyle& parent_style,
110            const HashSet<CSSPropertyName>& dependencies);
111 
112   void Clear();
113   void ClearViewportDependent();
114 
115   static bool IsCacheable(const StyleResolverState&);
116   static bool IsStyleCacheable(const ComputedStyle&);
117 
118   void Trace(Visitor*) const;
119 
120  private:
121   // The cache is mapping a hash to a cached entry where the entry is kept as
122   // long as *all* properties referred to by the entry are alive. This requires
123   // custom weakness which is managed through
124   // |RemoveCachedMatchedPropertiesWithDeadEntries|.
125   using Cache = HeapHashMap<unsigned,
126                             Member<CachedMatchedProperties>,
127                             DefaultHash<unsigned>::Hash,
128                             HashTraits<unsigned>>;
129 
130   void RemoveCachedMatchedPropertiesWithDeadEntries(const LivenessBroker&);
131 
132   Cache cache_;
133 };
134 
135 }  // namespace blink
136 
137 #endif
138