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 "public/platform/Platform.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 const int CompressibleStringImplSizeThrehold = 100000; | |
63 | |
64 void initializeCompressibleStringTable() | |
65 { | |
66 WTFThreadData& data = wtfThreadData(); | |
67 ASSERT(!data.compressibleStringTable()); | |
68 CompressibleStringTable::create(data); | |
69 } | |
70 | |
71 static inline CompressibleStringTable& compressibleStringTable() | |
72 { | |
73 WTFThreadData& data = wtfThreadData(); | |
74 ASSERT(data.compressibleStringTable()); | |
75 return *data.compressibleStringTable(); | |
76 } | |
77 | |
78 bool CompressibleStringImpl::s_isPageBackground = false; | |
79 | |
80 void CompressibleStringImpl::compressAll() | |
81 { | |
82 compressibleStringTable().compressAll(); | |
83 } | |
84 | |
85 void CompressibleStringImpl::setPageBackground(bool isPageBackground) | |
86 { | |
87 s_isPageBackground = isPageBackground; | |
88 } | |
89 | |
90 CompressibleStringImpl::CompressibleStringImpl() | |
haraken
2016/01/19 07:43:35
For performance reasons, I'd suggest inlining most
hajimehoshi
2016/01/19 10:19:20
Done.
| |
91 : m_string() | |
92 , m_isCompressed(false) | |
93 { | |
94 } | |
95 | |
96 CompressibleStringImpl::CompressibleStringImpl(PassRefPtr<StringImpl> impl) | |
haraken
2016/01/19 07:43:35
Inline.
hajimehoshi
2016/01/19 10:19:21
Hmm, I don't want to expose compressibleStringTabl
| |
97 : m_string(impl) | |
98 , m_isCompressed(false) | |
99 { | |
100 ASSERT(impl); | |
101 if (originalContentSizeInBytes() > CompressibleStringImplSizeThrehold) | |
102 compressibleStringTable().add(this); | |
103 } | |
104 | |
105 CompressibleStringImpl::~CompressibleStringImpl() | |
106 { | |
107 if (compressibleStringTable().contains(this)) | |
haraken
2016/01/19 07:43:35
A better condition would be:
if (originalConten
hajimehoshi
2016/01/19 10:19:20
Done.
| |
108 compressibleStringTable().remove(this); | |
109 } | |
110 | |
111 unsigned CompressibleStringImpl::originalContentSizeInBytes() const | |
haraken
2016/01/19 07:43:35
Inline.
hajimehoshi
2016/01/19 10:19:21
Done.
| |
112 { | |
113 if (is8Bit()) | |
114 return originalLength() * sizeof(LChar); | |
115 return originalLength() * sizeof(UChar); | |
116 } | |
117 | |
118 // TODO(hajimehoshi): Update this once we implement compression. | |
119 unsigned CompressibleStringImpl::currentSizeInBytes() const | |
haraken
2016/01/19 07:43:35
Inline.
hajimehoshi
2016/01/19 10:19:21
Done.
| |
120 { | |
121 return originalContentSizeInBytes(); | |
122 } | |
123 | |
124 const String& CompressibleStringImpl::toString() | |
haraken
2016/01/19 07:43:35
It would be better to inline this.
hajimehoshi
2016/01/19 10:19:21
Done.
| |
125 { | |
126 if (UNLIKELY(isCompressed())) | |
127 decompressString(); | |
128 return m_string; | |
129 } | |
130 | |
131 const LChar* CompressibleStringImpl::characters8() | |
haraken
2016/01/19 07:43:35
Inline.
hajimehoshi
2016/01/19 10:19:21
Done.
| |
132 { | |
133 return toString().characters8(); | |
134 } | |
135 | |
136 const UChar* CompressibleStringImpl::characters16() | |
haraken
2016/01/19 07:43:35
Inline.
hajimehoshi
2016/01/19 10:19:21
Done.
| |
137 { | |
138 return toString().characters16(); | |
139 } | |
140 | |
141 enum { | |
142 CompressingInBackgroundTab, | |
haraken
2016/01/19 07:43:35
StringWasCompressedInBackgroundTab
StringWasDecomp
hajimehoshi
2016/01/19 10:19:21
Done.
| |
143 DecompressingInBackgroundTab, | |
144 DecompressingInForegroundTab, | |
145 }; | |
146 | |
147 static const char* histogramName() | |
148 { | |
149 return "Memory.CompressibleStringCount"; | |
150 } | |
151 | |
152 // compressString does nothing but collect UMA so far. | |
153 // TODO(hajimehoshi): Implement this. | |
154 void CompressibleStringImpl::compressString() | |
155 { | |
156 if (s_isPageBackground) | |
haraken
2016/01/19 07:43:35
Shouldn't this be:
ASSERT(s_isPageBackground);
hajimehoshi
2016/01/19 10:19:21
Done.
| |
157 Platform::current()->histogramCustomCounts(histogramName(), CompressingI nBackgroundTab, 0, 10000, 50); | |
158 | |
159 ASSERT(!isCompressed()); | |
160 m_isCompressed = true; | |
161 } | |
162 | |
163 // decompressString does nothing but collect UMA so far. | |
164 // TODO(hajimehoshi): Implement this. | |
165 void CompressibleStringImpl::decompressString() | |
166 { | |
167 if (s_isPageBackground) | |
168 Platform::current()->histogramCustomCounts(histogramName(), Decompressin gInBackgroundTab, 0, 10000, 50); | |
169 else | |
170 Platform::current()->histogramCustomCounts(histogramName(), Decompressin gInForegroundTab, 0, 10000, 50); | |
171 | |
172 ASSERT(isCompressed()); | |
173 m_isCompressed = false; | |
174 } | |
175 | |
176 CompressibleString::CompressibleString() | |
haraken
2016/01/19 07:43:35
Inline these methods.
hajimehoshi
2016/01/19 10:19:21
Done.
| |
177 : m_impl(nullptr) | |
178 { | |
179 } | |
180 | |
181 CompressibleString::CompressibleString(const CompressibleString& rhs) | |
182 : m_impl(rhs.m_impl) | |
183 { | |
184 } | |
185 | |
186 CompressibleString::CompressibleString(PassRefPtr<StringImpl> impl) | |
187 : m_impl(impl ? adoptRef(new CompressibleStringImpl(impl)) : nullptr) | |
188 { | |
189 } | |
190 | |
191 void CompressibleString::compressString() const | |
192 { | |
193 m_impl->compressString(); | |
194 } | |
195 | |
196 void CompressibleString::decompressString() const | |
197 { | |
198 m_impl->decompressString(); | |
199 } | |
200 | |
201 } // namespace blink | |
OLD | NEW |