OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "platform/text/CompressibleString.h" | 5 #include "platform/text/CompressibleString.h" |
6 | 6 |
7 #include "public/platform/Platform.h" | 7 #include "public/platform/Platform.h" |
| 8 #include "third_party/zlib/google/compression_utils.h" |
8 #include "wtf/Assertions.h" | 9 #include "wtf/Assertions.h" |
9 #include "wtf/WTFThreadData.h" | 10 #include "wtf/WTFThreadData.h" |
10 #include "wtf/text/WTFString.h" | 11 #include "wtf/text/WTFString.h" |
11 | 12 |
12 namespace blink { | 13 namespace blink { |
13 | 14 |
14 class CompressibleStringTable { | 15 class CompressibleStringTable { |
15 WTF_MAKE_NONCOPYABLE(CompressibleStringTable); | 16 WTF_MAKE_NONCOPYABLE(CompressibleStringTable); |
16 public: | 17 public: |
17 static CompressibleStringTable* create(WTFThreadData& data) | 18 static CompressibleStringTable* create(WTFThreadData& data) |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
70 | 71 |
71 static const unsigned CompressibleStringImplSizeThrehold = 100000; | 72 static const unsigned CompressibleStringImplSizeThrehold = 100000; |
72 | 73 |
73 void CompressibleStringImpl::compressAll() | 74 void CompressibleStringImpl::compressAll() |
74 { | 75 { |
75 compressibleStringTable().compressAll(); | 76 compressibleStringTable().compressAll(); |
76 } | 77 } |
77 | 78 |
78 CompressibleStringImpl::CompressibleStringImpl(PassRefPtr<StringImpl> impl) | 79 CompressibleStringImpl::CompressibleStringImpl(PassRefPtr<StringImpl> impl) |
79 : m_string(impl) | 80 : m_string(impl) |
80 , m_isCompressed(false) | 81 , m_originalLength(m_string.length()) |
| 82 , m_compressedData(nullptr) |
| 83 , m_compressedDataSize(0) |
81 { | 84 { |
82 if (originalContentSizeInBytes() > CompressibleStringImplSizeThrehold) | 85 if (originalContentSizeInBytes() > CompressibleStringImplSizeThrehold) |
83 compressibleStringTable().add(this); | 86 compressibleStringTable().add(this); |
84 } | 87 } |
85 | 88 |
86 CompressibleStringImpl::~CompressibleStringImpl() | 89 CompressibleStringImpl::~CompressibleStringImpl() |
87 { | 90 { |
88 if (originalContentSizeInBytes() > CompressibleStringImplSizeThrehold) | 91 if (originalContentSizeInBytes() > CompressibleStringImplSizeThrehold) |
89 compressibleStringTable().remove(this); | 92 compressibleStringTable().remove(this); |
90 } | 93 } |
91 | 94 |
92 enum CompressibleStringCountType { | 95 enum CompressibleStringCountType { |
93 StringWasCompressedInBackgroundTab, | 96 StringWasCompressedInBackgroundTab, |
94 StringWasDecompressed, | 97 StringWasDecompressed, |
95 CompressibleStringCountTypeMax = StringWasDecompressed, | 98 CompressibleStringCountTypeMax = StringWasDecompressed, |
96 }; | 99 }; |
97 | 100 |
98 static void recordCompressibleStringCount(CompressibleStringCountType type) | 101 static void recordCompressibleStringCount(CompressibleStringCountType type) |
99 { | 102 { |
100 Platform::current()->histogramEnumeration("Memory.CompressibleStringCount",
type, CompressibleStringCountTypeMax + 1); | 103 Platform::current()->histogramEnumeration("Memory.CompressibleStringCount",
type, CompressibleStringCountTypeMax + 1); |
101 } | 104 } |
102 | 105 |
103 // compressString does nothing but collect UMA so far. | |
104 // TODO(hajimehoshi): Implement this. | |
105 void CompressibleStringImpl::compressString() | 106 void CompressibleStringImpl::compressString() |
106 { | 107 { |
107 recordCompressibleStringCount(StringWasCompressedInBackgroundTab); | 108 recordCompressibleStringCount(StringWasCompressedInBackgroundTab); |
108 ASSERT(!isCompressed()); | 109 ASSERT(!isCompressed()); |
109 m_isCompressed = true; | 110 ASSERT(!m_compressedData); |
| 111 ASSERT(!m_compressedDataSize); |
| 112 |
| 113 // TODO(hajimehoshi): Now components offers funcitons accepting only |
| 114 // std::strings. This is not efficient. We should offer char* version. |
| 115 std::string in, out; |
| 116 if (m_string.is8Bit()) { |
| 117 in = std::string(reinterpret_cast<const char*>(m_string.characters8()),
originalContentSizeInBytes()); |
| 118 m_string = emptyString(); |
| 119 } else { |
| 120 in = std::string(reinterpret_cast<const char*>(m_string.characters16()),
originalContentSizeInBytes()); |
| 121 m_string = emptyString16Bit(); |
| 122 } |
| 123 compression::GzipCompress(in, &out); |
| 124 |
| 125 m_compressedData = WTF::Partitions::fastMalloc(out.size(), "CompressibleStri
ng"); |
| 126 memcpy(m_compressedData, out.c_str(), out.size()); |
| 127 m_compressedDataSize = out.size(); |
110 } | 128 } |
111 | 129 |
112 // decompressString does nothing but collect UMA so far. | |
113 // TODO(hajimehoshi): Implement this. | |
114 void CompressibleStringImpl::decompressString() | 130 void CompressibleStringImpl::decompressString() |
115 { | 131 { |
116 // TODO(hajimehoshi): We wanted to tell whether decompressing in a | 132 // TODO(hajimehoshi): We wanted to tell whether decompressing in a |
117 // background tab or a foreground tab, but this was impossible. For example, | 133 // background tab or a foreground tab, but this was impossible. For example, |
118 // one renderer process of a new tab page is used for multiple tabs. | 134 // one renderer process of a new tab page is used for multiple tabs. |
119 // Another example is that reloading a page will re-use the process with a | 135 // Another example is that reloading a page will re-use the process with a |
120 // new Page object and updating a static variable along with reloading will | 136 // new Page object and updating a static variable along with reloading will |
121 // be complex. See also crbug/581266. We will revisit when the situation | 137 // be complex. See also crbug/581266. We will revisit when the situation |
122 // changes. | 138 // changes. |
123 recordCompressibleStringCount(StringWasDecompressed); | 139 recordCompressibleStringCount(StringWasDecompressed); |
124 ASSERT(isCompressed()); | 140 ASSERT(isCompressed()); |
125 m_isCompressed = false; | 141 ASSERT(m_compressedData); |
| 142 ASSERT(m_compressedDataSize); |
| 143 |
| 144 std::string in(static_cast<const char*>(m_compressedData), m_compressedDataS
ize); |
| 145 std::string out; |
| 146 compression::GzipUncompress(in, &out); |
| 147 |
| 148 if (is8Bit()) { |
| 149 LChar* data = nullptr; |
| 150 m_string = StringImpl::createUninitialized(out.size() / sizeof(LChar), d
ata); |
| 151 memcpy(data, out.c_str(), out.size()); |
| 152 } else { |
| 153 UChar* data = nullptr; |
| 154 m_string = StringImpl::createUninitialized(out.size() / sizeof(UChar), d
ata); |
| 155 memcpy(data, out.c_str(), out.size()); |
| 156 } |
| 157 |
| 158 WTF::Partitions::fastFree(m_compressedData); |
| 159 m_compressedData = nullptr; |
| 160 m_compressedDataSize = 0; |
| 161 ASSERT(m_originalLength == m_string.length()); |
126 } | 162 } |
127 | 163 |
128 } // namespace blink | 164 } // namespace blink |
OLD | NEW |