Changeset 52795 in webkit
- Timestamp:
- Jan 5, 2010 7:14:00 AM (14 years ago)
- Location:
- trunk/WebCore
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebCore/ChangeLog
r52793 r52795 1 2010-01-04 Yong Li <yoli@rim.com> 2 3 Reviewed by Darin Adler. 4 5 Let SharedBuffer use a group of memory segments internally. 6 It will merge the segments into a flat consecutive buffer only when 7 necessary. 8 https://bugs.webkit.org/show_bug.cgi?id=33178 9 10 * platform/SharedBuffer.cpp: 11 (WebCore::allocateSegment): 12 (WebCore::freeSegment): 13 (WebCore::SharedBuffer::SharedBuffer): 14 (WebCore::SharedBuffer::~SharedBuffer): 15 (WebCore::SharedBuffer::adoptVector): 16 (WebCore::SharedBuffer::size): 17 (WebCore::SharedBuffer::data): 18 (WebCore::SharedBuffer::append): 19 (WebCore::SharedBuffer::clear): 20 (WebCore::SharedBuffer::copy): 21 (WebCore::SharedBuffer::buffer): 22 (WebCore::SharedBuffer::getSomeData): 23 * platform/SharedBuffer.h: 24 * platform/cf/SharedBufferCF.cpp: 25 (WebCore::SharedBuffer::maybeTransferPlatformData): 26 * platform/haiku/SharedBufferHaiku.cpp: 27 (WebCore::SharedBuffer::createWithContentsOfFile): 28 * platform/qt/SharedBufferQt.cpp: 29 (WebCore::SharedBuffer::createWithContentsOfFile): 30 * platform/win/SharedBufferWin.cpp: 31 (WebCore::SharedBuffer::createWithContentsOfFile): 32 1 33 2010-01-05 Simon Hausmann <simon.hausmann@nokia.com> 2 34 -
trunk/WebCore/platform/SharedBuffer.cpp
r51875 r52795 1 1 /* 2 2 * Copyright (C) 2006, 2008 Apple Inc. All rights reserved. 3 * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved. 3 4 * 4 5 * Redistribution and use in source and binary forms, with or without … … 31 32 namespace WebCore { 32 33 34 static const unsigned segmentSize = 0x1000; 35 static const unsigned segmentPositionMask = 0x0FFF; 36 37 static inline unsigned segmentIndex(unsigned position) 38 { 39 return position / segmentSize; 40 } 41 42 static inline unsigned offsetInSegment(unsigned position) 43 { 44 return position & segmentPositionMask; 45 } 46 47 static inline char* allocateSegment() 48 { 49 return static_cast<char*>(fastMalloc(segmentSize)); 50 } 51 52 static inline void freeSegment(char* p) 53 { 54 fastFree(p); 55 } 56 33 57 SharedBuffer::SharedBuffer() 58 : m_size(0) 34 59 { 35 60 } 36 61 37 62 SharedBuffer::SharedBuffer(const char* data, int size) 38 { 39 m_buffer.append(data, size); 63 : m_size(0) 64 { 65 append(data, size); 40 66 } 41 67 42 68 SharedBuffer::SharedBuffer(const unsigned char* data, int size) 43 { 44 m_buffer.append(data, size); 69 : m_size(0) 70 { 71 append(reinterpret_cast<const char*>(data), size); 45 72 } 46 73 47 74 SharedBuffer::~SharedBuffer() 48 75 { 76 clear(); 49 77 } 50 78 … … 53 81 RefPtr<SharedBuffer> buffer = create(); 54 82 buffer->m_buffer.swap(vector); 83 buffer->m_size = buffer->m_buffer.size(); 55 84 return buffer.release(); 56 85 } … … 72 101 return m_purgeableBuffer->size(); 73 102 74 return m_ buffer.size();103 return m_size; 75 104 } 76 105 … … 83 112 return m_purgeableBuffer->data(); 84 113 85 return m_buffer.data();86 } 87 88 void SharedBuffer::append(const char* data, int len )114 return buffer().data(); 115 } 116 117 void SharedBuffer::append(const char* data, int length) 89 118 { 90 119 ASSERT(!m_purgeableBuffer); … … 92 121 maybeTransferPlatformData(); 93 122 94 m_buffer.append(data, len); 123 unsigned positionInSegment = offsetInSegment(m_size - m_buffer.size()); 124 m_size += length; 125 126 if (m_size <= segmentSize) { 127 // No need to use segments for small resource data 128 m_buffer.append(data, length); 129 return; 130 } 131 132 char* segment; 133 if (!positionInSegment) { 134 segment = allocateSegment(); 135 m_segments.append(segment); 136 } else 137 segment = m_segments.last() + positionInSegment; 138 139 unsigned segmentFreeSpace = segmentSize - positionInSegment; 140 unsigned bytesToCopy = length < segmentFreeSpace ? length : segmentFreeSpace; 141 142 for (;;) { 143 memcpy(segment, data, bytesToCopy); 144 if (length == bytesToCopy) 145 break; 146 147 length -= bytesToCopy; 148 data += bytesToCopy; 149 segment = allocateSegment(); 150 m_segments.append(segment); 151 bytesToCopy = length < segmentSize ? length : segmentSize; 152 } 95 153 } 96 154 … … 99 157 clearPlatformData(); 100 158 159 for (unsigned i = 0; i < m_segments.size(); ++i) 160 freeSegment(m_segments[i]); 161 162 m_segments.clear(); 163 m_size = 0; 164 101 165 m_buffer.clear(); 102 166 m_purgeableBuffer.clear(); … … 105 169 PassRefPtr<SharedBuffer> SharedBuffer::copy() const 106 170 { 107 return SharedBuffer::create(data(), size()); 171 RefPtr<SharedBuffer> clone(adoptRef(new SharedBuffer)); 172 if (m_purgeableBuffer || hasPlatformData()) { 173 clone->append(data(), size()); 174 return clone; 175 } 176 177 clone->m_size = m_size; 178 clone->m_buffer.reserveCapacity(m_size); 179 clone->m_buffer.append(m_buffer.data(), m_buffer.size()); 180 for (unsigned i = 0; i < m_segments.size(); ++i) 181 clone->m_buffer.append(m_segments[i], segmentSize); 182 return clone; 108 183 } 109 184 … … 114 189 } 115 190 191 const Vector<char>& SharedBuffer::buffer() const 192 { 193 unsigned bufferSize = m_buffer.size(); 194 if (m_size > bufferSize) { 195 m_buffer.resize(m_size); 196 char* destination = m_buffer.data() + bufferSize; 197 unsigned bytesLeft = m_size - bufferSize; 198 for (unsigned i = 0; i < m_segments.size(); ++i) { 199 unsigned bytesToCopy = bytesLeft < segmentSize ? bytesLeft : segmentSize; 200 memcpy(destination, m_segments[i], bytesToCopy); 201 destination += bytesToCopy; 202 bytesLeft -= bytesToCopy; 203 freeSegment(m_segments[i]); 204 } 205 m_segments.clear(); 206 } 207 return m_buffer; 208 } 209 210 unsigned SharedBuffer::getSomeData(const char*& someData, unsigned position) const 211 { 212 if (hasPlatformData() || m_purgeableBuffer) { 213 someData = data() + position; 214 return size() - position; 215 } 216 217 if (position >= m_size) { 218 someData = 0; 219 return 0; 220 } 221 222 unsigned consecutiveSize = m_buffer.size(); 223 if (position < consecutiveSize) { 224 someData = m_buffer.data() + position; 225 return consecutiveSize - position; 226 } 227 228 position -= consecutiveSize; 229 unsigned segmentedSize = m_size - consecutiveSize; 230 unsigned segments = m_segments.size(); 231 unsigned segment = segmentIndex(position); 232 ASSERT(segment < segments); 233 234 unsigned positionInSegment = offsetInSegment(position); 235 someData = m_segments[segment] + positionInSegment; 236 return segment == segments - 1 ? segmentedSize - position : segmentSize - positionInSegment; 237 } 238 116 239 #if !PLATFORM(CF) 117 240 -
trunk/WebCore/platform/SharedBuffer.h
r42463 r52795 1 1 /* 2 2 * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. 3 * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved. 3 4 * 4 5 * Redistribution and use in source and binary forms, with or without … … 74 75 #endif 75 76 77 // Calling this function will force internal segmented buffers 78 // to be merged into a flat buffer. Use getSomeData() whenever possible 79 // for better performance. 76 80 const char* data() const; 81 77 82 unsigned size() const; 78 const Vector<char> &buffer() { return m_buffer; }79 83 80 bool isEmpty() const { return size() == 0; } 84 // Calling this function will force internal segmented buffers 85 // to be merged into a flat buffer. Use getSomeData() whenever possible 86 // for better performance. 87 const Vector<char>& buffer() const; 88 89 bool isEmpty() const { return size(); } 81 90 82 91 void append(const char*, int); … … 91 100 // Ensure this buffer has no other clients before calling this. 92 101 PurgeableBuffer* releasePurgeableBuffer(); 93 102 103 // Return the number of consecutive bytes after "position". "data" 104 // points to the first byte. 105 // Return 0 when no more data left. 106 // When extracting all data with getSomeData(), the caller should 107 // repeat calling it until it returns 0. 108 // Usage: 109 // const char* segment; 110 // unsigned pos = 0; 111 // while (unsigned length = sharedBuffer->getSomeData(segment, pos)) { 112 // // Use the data. for example: decoder->decode(segment, length); 113 // pos += length; 114 // } 115 unsigned getSomeData(const char*& data, unsigned position = 0) const; 116 94 117 private: 95 118 SharedBuffer(); … … 101 124 bool hasPlatformData() const; 102 125 103 Vector<char> m_buffer; 126 unsigned m_size; 127 mutable Vector<char> m_buffer; 128 mutable Vector<char*> m_segments; 104 129 OwnPtr<PurgeableBuffer> m_purgeableBuffer; 105 130 #if PLATFORM(CF) … … 111 136 } 112 137 113 #endif 138 #endif // SharedBuffer_h -
trunk/WebCore/platform/cf/SharedBufferCF.cpp
r42463 r52795 77 77 return; 78 78 79 ASSERT(m_ buffer.size()== 0);79 ASSERT(m_size == 0); 80 80 81 m_buffer.append((const char*)CFDataGetBytePtr(m_cfData.get()), CFDataGetLength(m_cfData.get()));81 append((const char*)CFDataGetBytePtr(m_cfData.get()), CFDataGetLength(m_cfData.get())); 82 82 83 83 m_cfData = 0; -
trunk/WebCore/platform/haiku/SharedBufferHaiku.cpp
r47295 r52795 48 48 if (result->m_buffer.size() != size) 49 49 return 0; 50 result->m_size = size; 50 51 51 52 file.Read(result->m_buffer.data(), result->m_buffer.size()); -
trunk/WebCore/platform/qt/SharedBufferQt.cpp
r46170 r52795 46 46 return 0; 47 47 48 result->m_size = result->m_buffer.size(); 49 48 50 file.read(result->m_buffer.data(), result->m_buffer.size()); 49 51 return result.release(); -
trunk/WebCore/platform/win/SharedBufferWin.cpp
r47663 r52795 58 58 } 59 59 60 result->m_size = result->m_buffer.size(); 61 60 62 if (fread(result->m_buffer.data(), 1, fileStat.st_size, fileDescriptor) != fileStat.st_size) 61 63 LOG_ERROR("Failed to fully read contents of file %s - errno(%i)", filePath.ascii().data(), errno);
Note: See TracChangeset
for help on using the changeset viewer.