Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(224)

Side by Side Diff: third_party/WebKit/Source/platform/wtf/text/StringImpl.cpp

Issue 2856123004: Fix some m_instVar instances in wtf/ (Closed)
Patch Set: . Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/WebKit/Source/platform/wtf/text/StringImpl.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) 3 * (C) 1999 Antti Koivisto (koivisto@kde.org)
4 * (C) 2001 Dirk Mueller ( mueller@kde.org ) 4 * (C) 2001 Dirk Mueller ( mueller@kde.org )
5 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2013 Apple Inc. All 5 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2013 Apple Inc. All
6 * rights reserved. 6 * rights reserved.
7 * Copyright (C) 2006 Andrew Wellington (proton@wiretapped.net) 7 * Copyright (C) 2006 Andrew Wellington (proton@wiretapped.net)
8 * 8 *
9 * This library is free software; you can redistribute it and/or 9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public 10 * modify it under the terms of the GNU Library General Public
(...skipping 23 matching lines...) Expand all
34 #include "platform/wtf/text/AtomicString.h" 34 #include "platform/wtf/text/AtomicString.h"
35 #include "platform/wtf/text/AtomicStringTable.h" 35 #include "platform/wtf/text/AtomicStringTable.h"
36 #include "platform/wtf/text/CString.h" 36 #include "platform/wtf/text/CString.h"
37 #include "platform/wtf/text/CharacterNames.h" 37 #include "platform/wtf/text/CharacterNames.h"
38 #include "platform/wtf/text/StringBuffer.h" 38 #include "platform/wtf/text/StringBuffer.h"
39 #include "platform/wtf/text/StringHash.h" 39 #include "platform/wtf/text/StringHash.h"
40 #include "platform/wtf/text/StringToNumber.h" 40 #include "platform/wtf/text/StringToNumber.h"
41 #include <algorithm> 41 #include <algorithm>
42 #include <memory> 42 #include <memory>
43 43
44 #ifdef STRING_STATS
45 #include "platform/wtf/DataLog.h"
46 #include "platform/wtf/HashMap.h"
47 #include "platform/wtf/HashSet.h"
48 #include "platform/wtf/RefCounted.h"
49 #include "platform/wtf/ThreadingPrimitives.h"
50 #include <unistd.h>
51 #endif
52
53 using namespace std; 44 using namespace std;
54 45
55 namespace WTF { 46 namespace WTF {
56 47
57 using namespace Unicode; 48 using namespace Unicode;
58 49
59 // As of Jan 2017, StringImpl needs 2 * sizeof(int) + 29 bits of data, and 50 // As of Jan 2017, StringImpl needs 2 * sizeof(int) + 29 bits of data, and
60 // sizeof(ThreadRestrictionVerifier) is 16 bytes. Thus, in DCHECK mode the 51 // sizeof(ThreadRestrictionVerifier) is 16 bytes. Thus, in DCHECK mode the
61 // class may be padded to 32 bytes. 52 // class may be padded to 32 bytes.
62 #if DCHECK_IS_ON() 53 #if DCHECK_IS_ON()
63 static_assert(sizeof(StringImpl) <= 8 * sizeof(int), 54 static_assert(sizeof(StringImpl) <= 8 * sizeof(int),
64 "StringImpl should stay small"); 55 "StringImpl should stay small");
65 #else 56 #else
66 static_assert(sizeof(StringImpl) <= 3 * sizeof(int), 57 static_assert(sizeof(StringImpl) <= 3 * sizeof(int),
67 "StringImpl should stay small"); 58 "StringImpl should stay small");
68 #endif 59 #endif
69 60
70 #ifdef STRING_STATS
dcheng 2017/05/03 19:44:40 Hmm... FWIW, the last time I asked about removing
71
72 static Mutex& statsMutex() {
73 DEFINE_STATIC_LOCAL(Mutex, mutex, ());
74 return mutex;
75 }
76
77 static HashSet<void*>& liveStrings() {
78 // Notice that we can't use HashSet<StringImpl*> because then HashSet would
79 // dedup identical strings.
80 DEFINE_STATIC_LOCAL(HashSet<void*>, strings, ());
81 return strings;
82 }
83
84 void addStringForStats(StringImpl* string) {
85 MutexLocker locker(statsMutex());
86 liveStrings().add(string);
87 }
88
89 void removeStringForStats(StringImpl* string) {
90 MutexLocker locker(statsMutex());
91 liveStrings().remove(string);
92 }
93
94 static void fillWithSnippet(const StringImpl* string, Vector<char>& snippet) {
95 const unsigned kMaxSnippetLength = 64;
96 snippet.clear();
97
98 size_t expectedLength = std::min(string->length(), kMaxSnippetLength);
99 if (expectedLength == kMaxSnippetLength)
100 expectedLength += 3; // For the "...".
101 ++expectedLength; // For the terminating '\0'.
102 snippet.reserveCapacity(expectedLength);
103
104 size_t i;
105 for (i = 0; i < string->length() && i < kMaxSnippetLength; ++i) {
106 UChar c = (*string)[i];
107 if (IsASCIIPrintable(c))
108 snippet.append(c);
109 else
110 snippet.append('?');
111 }
112 if (i < string->length()) {
113 snippet.append('.');
114 snippet.append('.');
115 snippet.append('.');
116 }
117 snippet.append('\0');
118 }
119
120 static bool isUnnecessarilyWide(const StringImpl* string) {
121 if (string->is8Bit())
122 return false;
123 UChar c = 0;
124 for (unsigned i = 0; i < string->length(); ++i)
125 c |= (*string)[i] >> 8;
126 return !c;
127 }
128
129 class PerStringStats : public RefCounted<PerStringStats> {
130 public:
131 static PassRefPtr<PerStringStats> create() {
132 return adoptRef(new PerStringStats);
133 }
134
135 void add(const StringImpl* string) {
136 ++m_numberOfCopies;
137 if (!m_length) {
138 m_length = string->length();
139 fillWithSnippet(string, m_snippet);
140 }
141 if (string->isAtomic())
142 ++m_numberOfAtomicCopies;
143 if (isUnnecessarilyWide(string))
144 m_unnecessarilyWide = true;
145 }
146
147 size_t totalCharacters() const { return m_numberOfCopies * m_length; }
148
149 void print() {
150 const char* status = "ok";
151 if (m_unnecessarilyWide)
152 status = "16";
153 dataLogF("%8u copies (%s) of length %8u %s\n", m_numberOfCopies, status,
154 m_length, m_snippet.data());
155 }
156
157 bool m_unnecessarilyWide;
158 unsigned m_numberOfCopies;
159 unsigned m_length;
160 unsigned m_numberOfAtomicCopies;
161 Vector<char> m_snippet;
162
163 private:
164 PerStringStats()
165 : m_unnecessarilyWide(false),
166 m_numberOfCopies(0),
167 m_length(0),
168 m_numberOfAtomicCopies(0) {}
169 };
170
171 bool operator<(const RefPtr<PerStringStats>& a,
172 const RefPtr<PerStringStats>& b) {
173 if (a->m_unnecessarilyWide != b->m_unnecessarilyWide)
174 return !a->m_unnecessarilyWide && b->m_unnecessarilyWide;
175 if (a->totalCharacters() != b->totalCharacters())
176 return a->totalCharacters() < b->totalCharacters();
177 if (a->m_numberOfCopies != b->m_numberOfCopies)
178 return a->m_numberOfCopies < b->m_numberOfCopies;
179 if (a->m_length != b->m_length)
180 return a->m_length < b->m_length;
181 return a->m_numberOfAtomicCopies < b->m_numberOfAtomicCopies;
182 }
183
184 static void printLiveStringStats(void*) {
185 MutexLocker locker(statsMutex());
186 HashSet<void*>& strings = liveStrings();
187
188 HashMap<StringImpl*, RefPtr<PerStringStats>> stats;
189 for (HashSet<void*>::iterator iter = strings.begin(); iter != strings.end();
190 ++iter) {
191 StringImpl* string = static_cast<StringImpl*>(*iter);
192 HashMap<StringImpl*, RefPtr<PerStringStats>>::iterator entry =
193 stats.find(string);
194 RefPtr<PerStringStats> value =
195 entry == stats.end() ? RefPtr<PerStringStats>(PerStringStats::create())
196 : entry->value;
197 value->add(string);
198 stats.set(string, value.release());
199 }
200
201 Vector<RefPtr<PerStringStats>> all;
202 for (HashMap<StringImpl*, RefPtr<PerStringStats>>::iterator iter =
203 stats.begin();
204 iter != stats.end(); ++iter)
205 all.append(iter->value);
206
207 std::sort(all.begin(), all.end());
208 std::reverse(all.begin(), all.end());
209 for (size_t i = 0; i < 20 && i < all.size(); ++i)
210 all[i]->print();
211 }
212
213 StringStats StringImpl::m_stringStats;
214
215 unsigned StringStats::s_stringRemovesTillPrintStats =
216 StringStats::s_printStringStatsFrequency;
217
218 void StringStats::removeString(StringImpl* string) {
219 unsigned length = string->length();
220 --m_totalNumberStrings;
221
222 if (string->is8Bit()) {
223 --m_number8BitStrings;
224 m_total8BitData -= length;
225 } else {
226 --m_number16BitStrings;
227 m_total16BitData -= length;
228 }
229
230 if (!--s_stringRemovesTillPrintStats) {
231 s_stringRemovesTillPrintStats = s_printStringStatsFrequency;
232 printStats();
233 }
234 }
235
236 void StringStats::printStats() {
237 dataLogF("String stats for process id %d:\n", getpid());
238
239 unsigned long long totalNumberCharacters = m_total8BitData + m_total16BitData;
240 double percent8Bit =
241 m_totalNumberStrings
242 ? ((double)m_number8BitStrings * 100) / (double)m_totalNumberStrings
243 : 0.0;
244 double average8bitLength =
245 m_number8BitStrings
246 ? (double)m_total8BitData / (double)m_number8BitStrings
247 : 0.0;
248 dataLogF(
249 "%8u (%5.2f%%) 8 bit %12llu chars %12llu bytes avg length "
250 "%6.1f\n",
251 m_number8BitStrings, percent8Bit, m_total8BitData, m_total8BitData,
252 average8bitLength);
253
254 double percent16Bit =
255 m_totalNumberStrings
256 ? ((double)m_number16BitStrings * 100) / (double)m_totalNumberStrings
257 : 0.0;
258 double average16bitLength =
259 m_number16BitStrings
260 ? (double)m_total16BitData / (double)m_number16BitStrings
261 : 0.0;
262 dataLogF(
263 "%8u (%5.2f%%) 16 bit %12llu chars %12llu bytes avg length "
264 "%6.1f\n",
265 m_number16BitStrings, percent16Bit, m_total16BitData,
266 m_total16BitData * 2, average16bitLength);
267
268 double averageLength =
269 m_totalNumberStrings
270 ? (double)totalNumberCharacters / (double)m_totalNumberStrings
271 : 0.0;
272 unsigned long long totalDataBytes = m_total8BitData + m_total16BitData * 2;
273 dataLogF(
274 "%8u Total %12llu chars %12llu bytes avg length "
275 "%6.1f\n",
276 m_totalNumberStrings, totalNumberCharacters, totalDataBytes,
277 averageLength);
278 unsigned long long totalSavedBytes = m_total8BitData;
279 double percentSavings = totalSavedBytes
280 ? ((double)totalSavedBytes * 100) /
281 (double)(totalDataBytes + totalSavedBytes)
282 : 0.0;
283 dataLogF(" Total savings %12llu bytes (%5.2f%%)\n", totalSavedBytes,
284 percentSavings);
285
286 unsigned totalOverhead = m_totalNumberStrings * sizeof(StringImpl);
287 double overheadPercent = (double)totalOverhead / (double)totalDataBytes * 100;
288 dataLogF(" StringImpl overheader: %8u (%5.2f%%)\n", totalOverhead,
289 overheadPercent);
290
291 internal::callOnMainThread(&printLiveStringStats, nullptr);
292 }
293 #endif
294
295 void* StringImpl::operator new(size_t size) { 61 void* StringImpl::operator new(size_t size) {
296 DCHECK_EQ(size, sizeof(StringImpl)); 62 DCHECK_EQ(size, sizeof(StringImpl));
297 return Partitions::BufferMalloc(size, "WTF::StringImpl"); 63 return Partitions::BufferMalloc(size, "WTF::StringImpl");
298 } 64 }
299 65
300 void StringImpl::operator delete(void* ptr) { 66 void StringImpl::operator delete(void* ptr) {
301 Partitions::BufferFree(ptr); 67 Partitions::BufferFree(ptr);
302 } 68 }
303 69
304 inline StringImpl::~StringImpl() { 70 inline StringImpl::~StringImpl() {
305 DCHECK(!IsStatic()); 71 DCHECK(!IsStatic());
306 72
307 STRING_STATS_REMOVE_STRING(this);
308
309 if (IsAtomic()) 73 if (IsAtomic())
310 AtomicStringTable::Instance().Remove(this); 74 AtomicStringTable::Instance().Remove(this);
311 } 75 }
312 76
313 void StringImpl::DestroyIfNotStatic() const { 77 void StringImpl::DestroyIfNotStatic() const {
314 if (!IsStatic()) 78 if (!IsStatic())
315 delete this; 79 delete this;
316 } 80 }
317 81
318 void StringImpl::UpdateContainsOnlyASCII() const { 82 void StringImpl::UpdateContainsOnlyASCII() const {
(...skipping 1931 matching lines...) Expand 10 before | Expand all | Expand 10 after
2250 } else if (LocaleIdMatchesLang(locale_identifier, "lt")) { 2014 } else if (LocaleIdMatchesLang(locale_identifier, "lt")) {
2251 // TODO(rob.buis) implement upper-casing rules for lt 2015 // TODO(rob.buis) implement upper-casing rules for lt
2252 // like in StringImpl::upper(locale). 2016 // like in StringImpl::upper(locale).
2253 } 2017 }
2254 } 2018 }
2255 2019
2256 return ToUpper(c); 2020 return ToUpper(c);
2257 } 2021 }
2258 2022
2259 } // namespace WTF 2023 } // namespace WTF
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/platform/wtf/text/StringImpl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698