OLD | NEW |
| (Empty) |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "platform/text/CompressibleString.h" | |
6 | |
7 #include "platform/Histogram.h" | |
8 #include "wtf/Assertions.h" | |
9 #include "wtf/WTFThreadData.h" | |
10 #include "wtf/text/WTFString.h" | |
11 | |
12 namespace blink { | |
13 | |
14 class CompressibleStringTable { | |
15 WTF_MAKE_NONCOPYABLE(CompressibleStringTable); | |
16 public: | |
17 static CompressibleStringTable* create(WTFThreadData& data) | |
18 { | |
19 data.m_compressibleStringTable = new CompressibleStringTable; | |
20 data.m_compressibleStringTableDestructor = CompressibleStringTable::dest
roy; | |
21 return data.m_compressibleStringTable; | |
22 } | |
23 | |
24 void add(CompressibleStringImpl* string) | |
25 { | |
26 ASSERT(!m_table.contains(string)); | |
27 m_table.add(string); | |
28 } | |
29 | |
30 bool contains(CompressibleStringImpl* string) const | |
31 { | |
32 return m_table.contains(string); | |
33 } | |
34 | |
35 void remove(CompressibleStringImpl* string) | |
36 { | |
37 ASSERT(m_table.contains(string)); | |
38 m_table.remove(string); | |
39 } | |
40 | |
41 void compressAll() | |
42 { | |
43 HashSet<CompressibleStringImpl*>::iterator end = m_table.end(); | |
44 for (HashSet<CompressibleStringImpl*>::iterator iter = m_table.begin();
iter != end; ++iter) { | |
45 CompressibleStringImpl* string = *iter; | |
46 if (!string->isCompressed()) | |
47 string->compressString(); | |
48 } | |
49 } | |
50 | |
51 private: | |
52 CompressibleStringTable() { } | |
53 | |
54 static void destroy(CompressibleStringTable* table) | |
55 { | |
56 delete table; | |
57 } | |
58 | |
59 HashSet<CompressibleStringImpl*> m_table; | |
60 }; | |
61 | |
62 static inline CompressibleStringTable& compressibleStringTable() | |
63 { | |
64 WTFThreadData& data = wtfThreadData(); | |
65 CompressibleStringTable* table = data.compressibleStringTable(); | |
66 if (UNLIKELY(!table)) | |
67 table = CompressibleStringTable::create(data); | |
68 return *table; | |
69 } | |
70 | |
71 static const unsigned CompressibleStringImplSizeThrehold = 100000; | |
72 | |
73 void CompressibleStringImpl::compressAll() | |
74 { | |
75 compressibleStringTable().compressAll(); | |
76 } | |
77 | |
78 CompressibleStringImpl::CompressibleStringImpl(PassRefPtr<StringImpl> impl) | |
79 : m_string(impl) | |
80 , m_isCompressed(false) | |
81 { | |
82 if (originalContentSizeInBytes() > CompressibleStringImplSizeThrehold) | |
83 compressibleStringTable().add(this); | |
84 } | |
85 | |
86 CompressibleStringImpl::~CompressibleStringImpl() | |
87 { | |
88 if (originalContentSizeInBytes() > CompressibleStringImplSizeThrehold) | |
89 compressibleStringTable().remove(this); | |
90 } | |
91 | |
92 enum CompressibleStringCountType { | |
93 StringWasCompressedInBackgroundTab, | |
94 StringWasDecompressed, | |
95 CompressibleStringCountTypeMax = StringWasDecompressed, | |
96 }; | |
97 | |
98 static void recordCompressibleStringCount(CompressibleStringCountType type) | |
99 { | |
100 DEFINE_THREAD_SAFE_STATIC_LOCAL(EnumerationHistogram, sringTypeHistogram, ne
w EnumerationHistogram("Memory.CompressibleStringCount", CompressibleStringCount
TypeMax + 1)); | |
101 sringTypeHistogram.count(type); | |
102 } | |
103 | |
104 // compressString does nothing but collect UMA so far. | |
105 // TODO(hajimehoshi): Implement this. | |
106 void CompressibleStringImpl::compressString() | |
107 { | |
108 recordCompressibleStringCount(StringWasCompressedInBackgroundTab); | |
109 ASSERT(!isCompressed()); | |
110 m_isCompressed = true; | |
111 } | |
112 | |
113 // decompressString does nothing but collect UMA so far. | |
114 // TODO(hajimehoshi): Implement this. | |
115 void CompressibleStringImpl::decompressString() | |
116 { | |
117 // TODO(hajimehoshi): We wanted to tell whether decompressing in a | |
118 // background tab or a foreground tab, but this was impossible. For example, | |
119 // one renderer process of a new tab page is used for multiple tabs. | |
120 // Another example is that reloading a page will re-use the process with a | |
121 // new Page object and updating a static variable along with reloading will | |
122 // be complex. See also crbug/581266. We will revisit when the situation | |
123 // changes. | |
124 recordCompressibleStringCount(StringWasDecompressed); | |
125 ASSERT(isCompressed()); | |
126 m_isCompressed = false; | |
127 } | |
128 | |
129 } // namespace blink | |
OLD | NEW |