Commit abcf78c4 authored by oliver@apple.com's avatar oliver@apple.com
Browse files

Support in memory compression of rarely used data

https://bugs.webkit.org/show_bug.cgi?id=120143

Reviewed by Gavin Barraclough.

Source/JavaScriptCore:

Include zlib in LD_FLAGS and make UnlinkedCodeBlock make use of CompressibleVector.  This saves ~200k on google maps.

* Configurations/JavaScriptCore.xcconfig:
* bytecode/UnlinkedCodeBlock.cpp:
(JSC::UnlinkedCodeBlock::expressionRangeForBytecodeOffset):
(JSC::UnlinkedCodeBlock::addExpressionInfo):
* bytecode/UnlinkedCodeBlock.h:

Source/WTF:

Adds a set of utility functions to wrap the use of zlib over a generic
type or a Vector<> as well as adding CompressibleVector that wraps
either a Vector<> or compressed data.

* GNUmakefile.list.am:
* WTF.pro:
* WTF.vcxproj/WTF.vcxproj:
* WTF.xcodeproj/project.pbxproj:
* wtf/CMakeLists.txt:
* wtf/CheckedArithmetic.h:
* wtf/Compression.cpp: Added.
(WTF::zAlloc):
(WTF::zFree):
(WTF::GenericCompressedData::create):
(WTF::GenericCompressedData::decompress):
* wtf/Compression.h: Added.
(WTF::GenericCompressedData::compressedSize):
(WTF::GenericCompressedData::originalSize):
(WTF::GenericCompressedData::GenericCompressedData):
(WTF::CompressedVector::create):
(WTF::CompressedVector::decompress):
(WTF::CompressedVector::size):
(WTF::CompressibleVector::CompressibleVector):
(WTF::CompressibleVector::shrinkToFit):
(WTF::CompressibleVector::size):
(WTF::CompressibleVector::operator[]):
(WTF::CompressibleVector::at):
(WTF::CompressibleVector::begin):
(WTF::CompressibleVector::end):
(WTF::CompressibleVector::data):
(WTF::CompressibleVector::decompressIfNecessary):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@154498 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 058b9ddc
2013-08-23 Oliver Hunt <oliver@apple.com>
Support in memory compression of rarely used data
https://bugs.webkit.org/show_bug.cgi?id=120143
Reviewed by Gavin Barraclough.
Include zlib in LD_FLAGS and make UnlinkedCodeBlock make use of CompressibleVector. This saves ~200k on google maps.
* Configurations/JavaScriptCore.xcconfig:
* bytecode/UnlinkedCodeBlock.cpp:
(JSC::UnlinkedCodeBlock::expressionRangeForBytecodeOffset):
(JSC::UnlinkedCodeBlock::addExpressionInfo):
* bytecode/UnlinkedCodeBlock.h:
2013-08-22 Mark Hahnenberg <mhahnenberg@apple.com>
 
JSObject and JSArray code shouldn't have to tiptoe around garbage collection
......
......@@ -41,7 +41,7 @@ OTHER_LDFLAGS_LLVM_ENABLE_FTL_JIT = -lpthread -lm -lLLVMTableGen -lLLVMDebugInfo
OTHER_LDFLAGS_BASE = -lobjc -Wl,-Y,3 $(OTHER_LDFLAGS_HIDE_SYMBOLS);
OTHER_LDFLAGS_BASE = -lz -lobjc -Wl,-Y,3 $(OTHER_LDFLAGS_HIDE_SYMBOLS);
OTHER_LDFLAGS = $(inherited) $(OTHER_LDFLAGS_$(PLATFORM_NAME));
OTHER_LDFLAGS_iphoneos = $(OTHER_LDFLAGS_BASE);
OTHER_LDFLAGS_iphonesimulator = $(OTHER_LDFLAGS_iphoneos);
......
......@@ -263,7 +263,7 @@ void UnlinkedCodeBlock::expressionRangeForBytecodeOffset(unsigned bytecodeOffset
return;
}
Vector<ExpressionRangeInfo>& expressionInfo = m_expressionInfo;
Vector<ExpressionRangeInfo>& expressionInfo = m_expressionInfo.data();
int low = 0;
int high = expressionInfo.size();
......@@ -351,7 +351,7 @@ void UnlinkedCodeBlock::addExpressionInfo(unsigned instructionOffset,
}
} // switch
m_expressionInfo.append(info);
m_expressionInfo.data().append(info);
}
void UnlinkedProgramCodeBlock::visitChildren(JSCell* cell, SlotVisitor& visitor)
......
......@@ -39,6 +39,7 @@
#include "SpecialPointer.h"
#include "SymbolTable.h"
#include <wtf/Compression.h>
#include <wtf/RefCountedArray.h>
#include <wtf/Vector.h>
......@@ -539,7 +540,7 @@ public:
private:
OwnPtr<RareData> m_rareData;
Vector<ExpressionRangeInfo> m_expressionInfo;
CompressibleVector<ExpressionRangeInfo> m_expressionInfo;
protected:
......
2013-08-23 Oliver Hunt <oliver@apple.com>
Support in memory compression of rarely used data
https://bugs.webkit.org/show_bug.cgi?id=120143
Reviewed by Gavin Barraclough.
Adds a set of utility functions to wrap the use of zlib over a generic
type or a Vector<> as well as adding CompressibleVector that wraps
either a Vector<> or compressed data.
* GNUmakefile.list.am:
* WTF.pro:
* WTF.vcxproj/WTF.vcxproj:
* WTF.xcodeproj/project.pbxproj:
* wtf/CMakeLists.txt:
* wtf/CheckedArithmetic.h:
* wtf/Compression.cpp: Added.
(WTF::zAlloc):
(WTF::zFree):
(WTF::GenericCompressedData::create):
(WTF::GenericCompressedData::decompress):
* wtf/Compression.h: Added.
(WTF::GenericCompressedData::compressedSize):
(WTF::GenericCompressedData::originalSize):
(WTF::GenericCompressedData::GenericCompressedData):
(WTF::CompressedVector::create):
(WTF::CompressedVector::decompress):
(WTF::CompressedVector::size):
(WTF::CompressibleVector::CompressibleVector):
(WTF::CompressibleVector::shrinkToFit):
(WTF::CompressibleVector::size):
(WTF::CompressibleVector::operator[]):
(WTF::CompressibleVector::at):
(WTF::CompressibleVector::begin):
(WTF::CompressibleVector::end):
(WTF::CompressibleVector::data):
(WTF::CompressibleVector::decompressIfNecessary):
2013-08-21 Commit Queue <commit-queue@webkit.org>
 
Unreviewed, rolling out r154416.
......
......@@ -16,7 +16,8 @@ libWTF_la_LIBADD = \
$(UNICODE_LIBS) \
$(GLIB_LIBS) \
$(WINMM_LIBS) \
-lpthread
-lpthread \
-lz
if TARGET_WIN32
# OwnPtrWin.cpp needs the symbols from gdi32 dll
......
......@@ -25,6 +25,8 @@ wtf_sources += \
Source/WTF/wtf/Compiler.h \
Source/WTF/wtf/CompilationThread.cpp \
Source/WTF/wtf/CompilationThread.h \
Source/WTF/wtf/Compression.h \
Source/WTF/wtf/Compression.cpp \
Source/WTF/wtf/CryptographicallyRandomNumber.cpp \
Source/WTF/wtf/CryptographicallyRandomNumber.h \
Source/WTF/wtf/CurrentTime.cpp \
......
......@@ -28,6 +28,8 @@ linux-*:use?(GSTREAMER) {
win32-* {
LIBS += -lwinmm
LIBS += -lgdi32
} else {
LIBS += -lz
}
qnx {
......
......@@ -34,6 +34,7 @@ HEADERS += \
ByteOrder.h \
CheckedArithmetic.h \
Compiler.h \
Compression.h \
CryptographicallyRandomNumber.h \
CurrentTime.h \
DateMath.h \
......@@ -177,6 +178,7 @@ SOURCES += \
Atomics.cpp \
BitVector.cpp \
CompilationThread.cpp \
Compression.cpp \
CryptographicallyRandomNumber.cpp \
CurrentTime.cpp \
DateMath.cpp \
......
......@@ -54,6 +54,7 @@
<ClCompile Include="..\wtf\Assertions.cpp" />
<ClCompile Include="..\wtf\BitVector.cpp" />
<ClCompile Include="..\wtf\CompilationThread.cpp" />
<ClCompile Include="..\wtf\Compression.cpp" />
<ClCompile Include="..\wtf\CryptographicallyRandomNumber.cpp" />
<ClCompile Include="..\wtf\CurrentTime.cpp" />
<ClCompile Include="..\wtf\DataLog.cpp" />
......@@ -135,6 +136,7 @@
<ClInclude Include="..\wtf\CheckedArithmetic.h" />
<ClInclude Include="..\wtf\CheckedBoolean.h" />
<ClInclude Include="..\wtf\Compiler.h" />
<ClInclude Include="..\wtf\Compression.h" />
<ClInclude Include="..\wtf\CryptographicallyRandomNumber.h" />
<ClInclude Include="..\wtf\CurrentTime.h" />
<ClInclude Include="..\wtf\DataLog.h" />
......
......@@ -69,6 +69,8 @@
A748745217A0BDAE00FA04CB /* SixCharacterHash.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A748744F17A0BDAE00FA04CB /* SixCharacterHash.cpp */; };
A748745317A0BDAE00FA04CB /* SixCharacterHash.h in Headers */ = {isa = PBXBuildFile; fileRef = A748745017A0BDAE00FA04CB /* SixCharacterHash.h */; };
A748745417A0BDAE00FA04CB /* StringHashDumpContext.h in Headers */ = {isa = PBXBuildFile; fileRef = A748745117A0BDAE00FA04CB /* StringHashDumpContext.h */; };
A7E643C617C5423B003BB16B /* Compression.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7E643C417C5423B003BB16B /* Compression.cpp */; };
A7E643C717C5423B003BB16B /* Compression.h in Headers */ = {isa = PBXBuildFile; fileRef = A7E643C517C5423B003BB16B /* Compression.h */; };
A876DBD8151816E500DADB95 /* Platform.h in Headers */ = {isa = PBXBuildFile; fileRef = A876DBD7151816E500DADB95 /* Platform.h */; };
A8A4737F151A825B004123FF /* Alignment.h in Headers */ = {isa = PBXBuildFile; fileRef = A8A47254151A825A004123FF /* Alignment.h */; };
A8A47385151A825B004123FF /* ASCIICType.h in Headers */ = {isa = PBXBuildFile; fileRef = A8A4725A151A825A004123FF /* ASCIICType.h */; };
......@@ -340,6 +342,8 @@
A748744F17A0BDAE00FA04CB /* SixCharacterHash.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SixCharacterHash.cpp; sourceTree = "<group>"; };
A748745017A0BDAE00FA04CB /* SixCharacterHash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SixCharacterHash.h; sourceTree = "<group>"; };
A748745117A0BDAE00FA04CB /* StringHashDumpContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StringHashDumpContext.h; sourceTree = "<group>"; };
A7E643C417C5423B003BB16B /* Compression.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Compression.cpp; sourceTree = "<group>"; };
A7E643C517C5423B003BB16B /* Compression.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Compression.h; sourceTree = "<group>"; };
A876DBD7151816E500DADB95 /* Platform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Platform.h; sourceTree = "<group>"; };
A8A47254151A825A004123FF /* Alignment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Alignment.h; sourceTree = "<group>"; };
A8A4725A151A825A004123FF /* ASCIICType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASCIICType.h; sourceTree = "<group>"; };
......@@ -806,6 +810,8 @@
974CFC8D16A4F327006D5404 /* WeakPtr.h */,
A8A4737A151A825B004123FF /* WTFThreadData.cpp */,
A8A4737B151A825B004123FF /* WTFThreadData.h */,
A7E643C417C5423B003BB16B /* Compression.cpp */,
A7E643C517C5423B003BB16B /* Compression.h */,
);
path = wtf;
sourceTree = "<group>";
......@@ -1084,6 +1090,7 @@
A8A4744D151A825B004123FF /* ThreadingPrimitives.h in Headers */,
A8A47450151A825B004123FF /* ThreadRestrictionVerifier.h in Headers */,
A8A47454151A825B004123FF /* ThreadSafeRefCounted.h in Headers */,
A7E643C717C5423B003BB16B /* Compression.h in Headers */,
A8A47455151A825B004123FF /* ThreadSpecific.h in Headers */,
149EF16316BBFE0D000A4331 /* TriState.h in Headers */,
A8A47459151A825B004123FF /* TypeTraits.h in Headers */,
......@@ -1211,6 +1218,7 @@
A8A473F2151A825B004123FF /* NullPtr.cpp in Sources */,
A8A473F4151A825B004123FF /* NumberOfCores.cpp in Sources */,
A8A473F7151A825B004123FF /* OSAllocatorPosix.cpp in Sources */,
A7E643C617C5423B003BB16B /* Compression.cpp in Sources */,
A8A473F9151A825B004123FF /* OSRandomSource.cpp in Sources */,
A8A47400151A825B004123FF /* PageAllocationAligned.cpp in Sources */,
A8A47402151A825B004123FF /* PageBlock.cpp in Sources */,
......
......@@ -12,6 +12,7 @@ set(WTF_HEADERS
ByteOrder.h
CompilationThread.h
Compiler.h
Compression.h
CryptographicallyRandomNumber.h
CurrentTime.h
DateMath.h
......@@ -151,6 +152,7 @@ set(WTF_SOURCES
Atomics.cpp
BitVector.cpp
CompilationThread.cpp
Compression.cpp
CryptographicallyRandomNumber.cpp
CurrentTime.cpp
DateMath.cpp
......
......@@ -721,6 +721,7 @@ typedef Checked<int32_t, RecordOverflow> CheckedInt32;
typedef Checked<uint32_t, RecordOverflow> CheckedUint32;
typedef Checked<int64_t, RecordOverflow> CheckedInt64;
typedef Checked<uint64_t, RecordOverflow> CheckedUint64;
typedef Checked<size_t, RecordOverflow> CheckedSize;
}
......@@ -735,5 +736,6 @@ using WTF::CheckedInt32;
using WTF::CheckedUint32;
using WTF::CheckedInt64;
using WTF::CheckedUint64;
using WTF::CheckedSize;
#endif
/*
* Copyright (C) 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "Compression.h"
#include "CheckedArithmetic.h"
#if USE(ZLIB)
#include <zlib.h>
namespace WTF {
static void* zAlloc(void*, uint32_t count, uint32_t size)
{
CheckedSize allocSize = count;
allocSize *= size;
if (allocSize.hasOverflowed())
return Z_NULL;
void* result = 0;
if (tryFastMalloc(allocSize.unsafeGet()).getValue(result))
return result;
return Z_NULL;
}
static void zFree(void*, void* data)
{
fastFree(data);
}
PassOwnPtr<GenericCompressedData> GenericCompressedData::create(const uint8_t* data, size_t dataLength)
{
enum { MinimumSize = sizeof(GenericCompressedData) * 8 };
if (!data || dataLength < MinimumSize)
return nullptr;
z_stream stream;
memset(&stream, 0, sizeof(stream));
stream.zalloc = zAlloc;
stream.zfree = zFree;
stream.data_type = Z_BINARY;
stream.opaque = Z_NULL;
stream.avail_in = dataLength;
stream.next_in = const_cast<uint8_t*>(data);
size_t currentOffset = OBJECT_OFFSETOF(GenericCompressedData, m_data);
size_t currentCapacity = fastMallocGoodSize(MinimumSize);
Bytef* compressedData = static_cast<Bytef*>(fastMalloc(currentCapacity));
memset(compressedData, 0, currentCapacity);
stream.next_out = compressedData + currentOffset;
stream.avail_out = currentCapacity - currentOffset;
deflateInit(&stream, Z_BEST_COMPRESSION);
while (true) {
int deflateResult = deflate(&stream, Z_FINISH);
if (deflateResult == Z_OK || !stream.avail_out) {
size_t newCapacity = 0;
currentCapacity -= stream.avail_out;
if (!stream.avail_in)
newCapacity = currentCapacity + 8;
else {
// Determine average capacity
size_t compressedContent = stream.next_in - data;
double expectedSize = static_cast<double>(dataLength) * compressedContent / currentCapacity;
// Expand capacity by at least 8 bytes so we're always growing, and to
// compensate for any exaggerated ideas of how effectively we'll compress
// data in the future.
newCapacity = std::max(static_cast<size_t>(expectedSize + 8), currentCapacity + 8);
}
newCapacity = fastMallocGoodSize(newCapacity);
if (newCapacity >= dataLength)
goto fail;
compressedData = static_cast<Bytef*>(fastRealloc(compressedData, newCapacity));
currentOffset = currentCapacity - stream.avail_out;
stream.next_out = compressedData + currentOffset;
stream.avail_out = newCapacity - currentCapacity;
currentCapacity = newCapacity;
continue;
}
if (deflateResult == Z_STREAM_END) {
ASSERT(!stream.avail_in);
break;
}
ASSERT_NOT_REACHED();
fail:
deflateEnd(&stream);
fastFree(compressedData);
return nullptr;
}
deflateEnd(&stream);
static int64_t totalCompressed = 0;
static int64_t totalInput = 0;
totalCompressed += currentCapacity;
totalInput += dataLength;
GenericCompressedData* result = new (compressedData) GenericCompressedData(dataLength, stream.total_out);
return adoptPtr(result);
}
bool GenericCompressedData::decompress(uint8_t* destination, size_t bufferSize)
{
z_stream stream;
memset(&stream, 0, sizeof(stream));
stream.zalloc = zAlloc;
stream.zfree = zFree;
stream.data_type = Z_BINARY;
stream.opaque = Z_NULL;
stream.next_out = destination;
stream.avail_out = bufferSize;
stream.next_in = m_data;
stream.avail_in = compressedSize();
if (inflateInit(&stream) != Z_OK) {
ASSERT_NOT_REACHED();
return false;
}
int inflateResult = inflate(&stream, Z_FINISH);
inflateEnd(&stream);
if (inflateResult != Z_STREAM_END) {
ASSERT_NOT_REACHED();
return false;
}
return true;
}
}
#else
namespace WTF {
PassOwnPtr<GenericCompressedData> GenericCompressedData::create(const uint8_t*, size_t)
{
return nullptr;
}
bool GenericCompressedData::decompress(uint8_t*, size_t)
{
return false;
}
}
#endif
/*
* Copyright (C) 2012 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef Compression_h
#define Compression_h
#include <wtf/PassOwnPtr.h>
#include <wtf/Vector.h>
namespace WTF {
class GenericCompressedData {
WTF_MAKE_NONCOPYABLE(GenericCompressedData)
public:
WTF_EXPORT_PRIVATE static PassOwnPtr<GenericCompressedData> create(const uint8_t*, size_t);
uint32_t compressedSize() const { return m_compressedSize; }
uint32_t originalSize() const { return m_originalSize; }
WTF_EXPORT_PRIVATE bool decompress(uint8_t* destination, size_t bufferSize);
private:
GenericCompressedData(size_t originalSize, size_t compressedSize)
{
UNUSED_PARAM(m_data);
ASSERT(!m_originalSize);
ASSERT(!m_compressedSize);
m_originalSize = originalSize;
m_compressedSize = compressedSize;
}
uint32_t m_originalSize;
uint32_t m_compressedSize;
uint8_t m_data[];
};
template <typename T> class CompressedVector : private GenericCompressedData {
public:
static PassOwnPtr<CompressedVector> create(const Vector<T>& source)
{
OwnPtr<GenericCompressedData> result = GenericCompressedData::create(reinterpret_cast<const uint8_t*>(source.data()), sizeof(T) * source.size());
return adoptPtr(static_cast<CompressedVector<T>*>(result.leakPtr()));
}
void decompress(Vector<T>& destination)
{
Vector<T> output(originalSize() / sizeof(T));
GenericCompressedData::decompress(reinterpret_cast<uint8_t*>(output.data()), originalSize());
destination.swap(output);
}
size_t size() const { return originalSize() / sizeof(T); }
};
template <typename T> class CompressibleVector {
WTF_MAKE_NONCOPYABLE(CompressibleVector)
public:
CompressibleVector(size_t size = 0)
: m_decompressedData(size)
{
}
typedef typename Vector<T>::iterator iterator;
typedef typename Vector<T>::const_iterator const_iterator;
void shrinkToFit()
{
ASSERT(!m_compressedData);
m_compressedData = CompressedVector<T>::create(m_decompressedData);
if (m_compressedData)
m_decompressedData.clear();
else
m_decompressedData.shrinkToFit();
}
size_t size()
{
if (m_compressedData)
return m_compressedData->size();
return m_decompressedData.size();
}
template <typename U> T& operator[](Checked<U> index) { return data().at(index); }
template <typename U> const T& operator[](Checked<U> index) const { return data().at(index); }
template <typename U> T& at(Checked<U> index) { return data().at(index); }
template <typename U> const T& at(Checked<U> index) const { return data().at(index); }
iterator begin() { return data().begin(); }
iterator end() { return data().end(); }
const_iterator begin() const { return data().begin(); }
const_iterator end() const { return data().end(); }
const Vector<T>& data() const
{
decompressIfNecessary();
return m_decompressedData;
}
Vector<T>& data()
{
decompressIfNecessary();
return m_decompressedData;
}
private:
void decompressIfNecessary() const
{
if (!m_compressedData)
return;
m_compressedData->decompress(m_decompressedData);
m_compressedData.clear();
}
mutable Vector<T> m_decompressedData;
mutable OwnPtr<CompressedVector<T> > m_compressedData;
};
}
using WTF::GenericCompressedData;
using WTF::CompressedVector;
using WTF::CompressibleVector;
#endif
......@@ -9,6 +9,7 @@ list(APPEND WTF_SOURCES
list(APPEND WTF_LIBRARIES
pthread
${ZLIB_LIBRARIES}
${GLIB_LIBRARIES}
${GLIB_GIO_LIBRARIES}
${GLIB_GOBJECT_LIBRARIES}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment