Diff
Modified: trunk/Source/WebCore/ChangeLog (215660 => 215661)
--- trunk/Source/WebCore/ChangeLog 2017-04-22 02:01:55 UTC (rev 215660)
+++ trunk/Source/WebCore/ChangeLog 2017-04-22 02:23:45 UTC (rev 215661)
@@ -1,3 +1,15 @@
+2017-04-21 Michael Catanzaro <mcatanz...@igalia.com>
+
+ Unreviewed, rolling out r215608.
+
+ Hundreds of test failures on GTK bot
+
+ Reverted changeset:
+
+ "Reduce copies and allocations in SharedBuffer::append"
+ https://bugs.webkit.org/show_bug.cgi?id=170956
+ http://trac.webkit.org/changeset/215608
+
2017-04-21 Zalan Bujtas <za...@apple.com>
REGRESSION(r205374): <li> content inside <ul> should mid-word wrap when word-break: break-word is present.
Modified: trunk/Source/WebCore/editing/cocoa/EditorCocoa.mm (215660 => 215661)
--- trunk/Source/WebCore/editing/cocoa/EditorCocoa.mm 2017-04-22 02:01:55 UTC (rev 215660)
+++ trunk/Source/WebCore/editing/cocoa/EditorCocoa.mm 2017-04-22 02:23:45 UTC (rev 215661)
@@ -157,7 +157,7 @@
if (!attributedString.length)
return nullptr;
- return SharedBuffer::create([NSKeyedArchiver archivedDataWithRootObject:attributedString]);
+ return SharedBuffer::wrapNSData([NSKeyedArchiver archivedDataWithRootObject:attributedString]);
}
void Editor::writeSelectionToPasteboard(Pasteboard& pasteboard)
@@ -205,7 +205,7 @@
RefPtr<LegacyWebArchive> archive = LegacyWebArchive::createFromSelection(&m_frame);
if (!archive)
return nullptr;
- return SharedBuffer::create(archive->rawDataRepresentation().get());
+ return SharedBuffer::wrapCFData(archive->rawDataRepresentation().get());
}
// FIXME: Makes no sense that selectedTextForDataTransfer always includes alt text, but stringSelectionForPasteboard does not.
@@ -276,7 +276,7 @@
return nullptr;
BEGIN_BLOCK_OBJC_EXCEPTIONS;
- return SharedBuffer::create([string RTFDFromRange:NSMakeRange(0, length) documentAttributes:@{ }]);
+ return SharedBuffer::wrapNSData([string RTFDFromRange:NSMakeRange(0, length) documentAttributes:@{ }]);
END_BLOCK_OBJC_EXCEPTIONS;
return nullptr;
@@ -289,7 +289,7 @@
return nullptr;
BEGIN_BLOCK_OBJC_EXCEPTIONS;
- return SharedBuffer::create([string RTFFromRange:NSMakeRange(0, length) documentAttributes:@{ }]);
+ return SharedBuffer::wrapNSData([string RTFFromRange:NSMakeRange(0, length) documentAttributes:@{ }]);
END_BLOCK_OBJC_EXCEPTIONS;
return nullptr;
Modified: trunk/Source/WebCore/editing/ios/EditorIOS.mm (215660 => 215661)
--- trunk/Source/WebCore/editing/ios/EditorIOS.mm 2017-04-22 02:01:55 UTC (rev 215660)
+++ trunk/Source/WebCore/editing/ios/EditorIOS.mm 2017-04-22 02:23:45 UTC (rev 215661)
@@ -339,10 +339,10 @@
RetainPtr<NSString> fileType = adoptNS((NSString *)UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (CFStringRef)[localPath pathExtension], NULL));
NSData *data = "" dataWithContentsOfFile:localPath];
if (UTTypeConformsTo((CFStringRef)fileType.get(), kUTTypePNG)) {
- addFragment(frame.editor().createFragmentForImageResourceAndAddResource(ArchiveResource::create(SharedBuffer::create([[data copy] autorelease]), URL::fakeURLWithRelativePart("image.png"), @"image/png", emptyString(), emptyString())));
+ addFragment(frame.editor().createFragmentForImageResourceAndAddResource(ArchiveResource::create(SharedBuffer::wrapNSData([[data copy] autorelease]), URL::fakeURLWithRelativePart("image.png"), @"image/png", emptyString(), emptyString())));
return fragment;
} else if (UTTypeConformsTo((CFStringRef)fileType.get(), kUTTypeJPEG)) {
- addFragment(frame.editor().createFragmentForImageResourceAndAddResource(ArchiveResource::create(SharedBuffer::create([[data copy] autorelease]), URL::fakeURLWithRelativePart("image.jpg"), @"image/jpg", emptyString(), emptyString())));
+ addFragment(frame.editor().createFragmentForImageResourceAndAddResource(ArchiveResource::create(SharedBuffer::wrapNSData([[data copy] autorelease]), URL::fakeURLWithRelativePart("image.jpg"), @"image/jpg", emptyString(), emptyString())));
return fragment;
}
} else {
Modified: trunk/Source/WebCore/editing/mac/EditorMac.mm (215660 => 215661)
--- trunk/Source/WebCore/editing/mac/EditorMac.mm 2017-04-22 02:01:55 UTC (rev 215660)
+++ trunk/Source/WebCore/editing/mac/EditorMac.mm 2017-04-22 02:23:45 UTC (rev 215661)
@@ -204,7 +204,7 @@
RefPtr<LegacyWebArchive> archive = LegacyWebArchive::create(imageElement);
if (!archive)
return nullptr;
- return SharedBuffer::create(archive->rawDataRepresentation().get());
+ return SharedBuffer::wrapCFData(archive->rawDataRepresentation().get());
}
RefPtr<SharedBuffer> Editor::dataSelectionForPasteboard(const String& pasteboardType)
Modified: trunk/Source/WebCore/loader/TextTrackLoader.cpp (215660 => 215661)
--- trunk/Source/WebCore/loader/TextTrackLoader.cpp 2017-04-22 02:01:55 UTC (rev 215660)
+++ trunk/Source/WebCore/loader/TextTrackLoader.cpp 2017-04-22 02:23:45 UTC (rev 215661)
@@ -91,15 +91,12 @@
if (!m_cueParser)
m_cueParser = std::make_unique<WebVTTParser>(static_cast<WebVTTParserClient*>(this), m_scriptExecutionContext);
- auto bytesToSkip = m_parseOffset;
- for (const auto& segment : *buffer) {
- if (bytesToSkip > segment->size()) {
- bytesToSkip -= segment->size();
- continue;
- }
- m_cueParser->parseBytes(segment->data() + bytesToSkip, segment->size() - bytesToSkip);
- bytesToSkip = 0;
- m_parseOffset += segment->size();
+ const char* data;
+ unsigned length;
+
+ while ((length = buffer->getSomeData(data, m_parseOffset))) {
+ m_cueParser->parseBytes(data, length);
+ m_parseOffset += length;
}
}
Modified: trunk/Source/WebCore/loader/archive/cf/LegacyWebArchive.cpp (215660 => 215661)
--- trunk/Source/WebCore/loader/archive/cf/LegacyWebArchive.cpp 2017-04-22 02:01:55 UTC (rev 215660)
+++ trunk/Source/WebCore/loader/archive/cf/LegacyWebArchive.cpp 2017-04-22 02:23:45 UTC (rev 215661)
@@ -221,7 +221,7 @@
response = createResourceResponseFromPropertyListData(resourceResponseData, resourceResponseVersion);
}
- return ArchiveResource::create(SharedBuffer::create(resourceData), URL(URL(), url), mimeType, textEncoding, frameName, response);
+ return ArchiveResource::create(SharedBuffer::wrapCFData(resourceData), URL(URL(), url), mimeType, textEncoding, frameName, response);
}
Ref<LegacyWebArchive> LegacyWebArchive::create()
Modified: trunk/Source/WebCore/loader/cache/CachedResource.cpp (215660 => 215661)
--- trunk/Source/WebCore/loader/cache/CachedResource.cpp 2017-04-22 02:01:55 UTC (rev 215660)
+++ trunk/Source/WebCore/loader/cache/CachedResource.cpp 2017-04-22 02:23:45 UTC (rev 215661)
@@ -850,9 +850,8 @@
if (m_data->size() != newBuffer.size() || memcmp(m_data->data(), newBuffer.data(), m_data->size()))
return;
- m_data->clear();
- m_data->append(newBuffer);
- didReplaceSharedBufferContents();
+ if (m_data->tryReplaceContentsWithPlatformBuffer(newBuffer))
+ didReplaceSharedBufferContents();
}
#endif
Modified: trunk/Source/WebCore/loader/cocoa/DiskCacheMonitorCocoa.mm (215660 => 215661)
--- trunk/Source/WebCore/loader/cocoa/DiskCacheMonitorCocoa.mm 2017-04-22 02:01:55 UTC (rev 215660)
+++ trunk/Source/WebCore/loader/cocoa/DiskCacheMonitorCocoa.mm 2017-04-22 02:23:45 UTC (rev 215661)
@@ -48,7 +48,7 @@
if (!data)
return nullptr;
- return SharedBuffer::create(data);
+ return SharedBuffer::wrapCFData(data);
}
void DiskCacheMonitor::monitorFileBackingStoreCreation(const ResourceRequest& request, SessionID sessionID, CFCachedURLResponseRef cachedResponse)
Modified: trunk/Source/WebCore/platform/SharedBuffer.cpp (215660 => 215661)
--- trunk/Source/WebCore/platform/SharedBuffer.cpp 2017-04-22 02:01:55 UTC (rev 215660)
+++ trunk/Source/WebCore/platform/SharedBuffer.cpp 2017-04-22 02:23:45 UTC (rev 215661)
@@ -31,31 +31,62 @@
#include <algorithm>
#include <wtf/unicode/UTF8.h>
-#if USE(SOUP)
-#include "GUniquePtrSoup.h"
+namespace WebCore {
+
+#if !USE(NETWORK_CFDATA_ARRAY_CALLBACK)
+
+static const unsigned segmentSize = 0x1000;
+static const unsigned segmentPositionMask = 0x0FFF;
+
+static inline unsigned segmentIndex(unsigned position)
+{
+ return position / segmentSize;
+}
+
+static inline unsigned offsetInSegment(unsigned position)
+{
+ return position & segmentPositionMask;
+}
+
+static inline char* allocateSegment() WARN_UNUSED_RETURN;
+static inline char* allocateSegment()
+{
+ return static_cast<char*>(fastMalloc(segmentSize));
+}
+
+static inline void freeSegment(char* p)
+{
+ fastFree(p);
+}
+
#endif
-namespace WebCore {
+SharedBuffer::SharedBuffer()
+ : m_buffer(adoptRef(*new DataBuffer))
+{
+}
-SharedBuffer::SharedBuffer(const char* data, size_t size)
+SharedBuffer::SharedBuffer(const char* data, unsigned size)
+ : m_buffer(adoptRef(*new DataBuffer))
{
append(data, size);
}
-SharedBuffer::SharedBuffer(const unsigned char* data, size_t size)
+SharedBuffer::SharedBuffer(const unsigned char* data, unsigned size)
+ : m_buffer(adoptRef(*new DataBuffer))
{
append(reinterpret_cast<const char*>(data), size);
}
SharedBuffer::SharedBuffer(MappedFileData&& fileData)
- : m_size(fileData.size())
+ : m_buffer(adoptRef(*new DataBuffer))
+ , m_fileData(WTFMove(fileData))
{
- m_segments.append(DataSegment::create(WTFMove(fileData)));
}
-SharedBuffer::SharedBuffer(Vector<char>&& data)
+SharedBuffer::~SharedBuffer()
{
- append(WTFMove(data));
+ clear();
}
RefPtr<SharedBuffer> SharedBuffer::createWithContentsOfFile(const String& filePath)
@@ -71,30 +102,37 @@
Ref<SharedBuffer> SharedBuffer::create(Vector<char>&& vector)
{
- return adoptRef(*new SharedBuffer(WTFMove(vector)));
+ auto buffer = create();
+ buffer->m_buffer->data = ""
+ buffer->m_size = buffer->m_buffer->data.size();
+ return buffer;
}
-void SharedBuffer::combineToOneSegment() const
+unsigned SharedBuffer::size() const
{
- if (m_segments.size() <= 1)
- return;
+ if (hasPlatformData())
+ return platformDataSize();
+
+ if (m_fileData)
+ return m_fileData.size();
- Vector<char> combinedData;
- combinedData.reserveInitialCapacity(m_size);
- for (const auto& segment : m_segments)
- combinedData.append(segment->data(), segment->size());
- ASSERT(combinedData.size() == m_size);
- m_segments.clear();
- m_segments.append(DataSegment::create(WTFMove(combinedData)));
- ASSERT(m_segments.size() == 1);
+ return m_size;
}
const char* SharedBuffer::data() const
{
- if (!m_segments.size())
- return nullptr;
- combineToOneSegment();
- return m_segments[0]->data();
+ if (hasPlatformData())
+ return platformData();
+
+ if (m_fileData)
+ return static_cast<const char*>(m_fileData.data());
+
+#if USE(NETWORK_CFDATA_ARRAY_CALLBACK)
+ if (const char* buffer = singleDataArrayBuffer())
+ return buffer;
+#endif
+
+ return this->buffer().data();
}
RefPtr<ArrayBuffer> SharedBuffer::createArrayBuffer() const
@@ -105,69 +143,171 @@
return nullptr;
}
- size_t position = 0;
- for (const auto& segment : m_segments) {
- memcpy(static_cast<char*>(arrayBuffer->data()) + position, segment->data(), segment->size());
- position += segment->size();
+ const char* segment = 0;
+ unsigned position = 0;
+ while (unsigned segmentSize = getSomeData(segment, position)) {
+ memcpy(static_cast<char*>(arrayBuffer->data()) + position, segment, segmentSize);
+ position += segmentSize;
}
- ASSERT(position == m_size);
+ if (position != arrayBuffer->byteLength()) {
+ ASSERT_NOT_REACHED();
+ // Don't return the incomplete ArrayBuffer.
+ return nullptr;
+ }
+
return arrayBuffer;
}
-void SharedBuffer::append(const SharedBuffer& data)
+void SharedBuffer::append(SharedBuffer& data)
{
- m_size += data.m_size;
- m_segments.reserveCapacity(m_segments.size() + data.m_segments.size());
- for (const auto& segment : data.m_segments)
- m_segments.uncheckedAppend(segment.copyRef());
+ if (maybeAppendPlatformData(data))
+ return;
+#if USE(NETWORK_CFDATA_ARRAY_CALLBACK)
+ if (maybeAppendDataArray(data))
+ return;
+#endif
+
+ const char* segment;
+ size_t position = 0;
+ while (size_t length = data.getSomeData(segment, position)) {
+ append(segment, length);
+ position += length;
+ }
}
-void SharedBuffer::append(const char* data, size_t length)
+void SharedBuffer::append(const char* data, unsigned length)
{
+ if (!length)
+ return;
+
+ maybeTransferMappedFileData();
+ maybeTransferPlatformData();
+
+#if !USE(NETWORK_CFDATA_ARRAY_CALLBACK)
+ unsigned positionInSegment = offsetInSegment(m_size - m_buffer->data.size());
m_size += length;
- Vector<char> vector;
- vector.append(data, length);
- m_segments.append(DataSegment::create(WTFMove(vector)));
+
+ if (m_size <= segmentSize) {
+ // No need to use segments for small resource data
+ if (m_buffer->data.isEmpty())
+ m_buffer->data.reserveInitialCapacity(length);
+ appendToDataBuffer(data, length);
+ return;
+ }
+
+ char* segment;
+ if (!positionInSegment) {
+ segment = allocateSegment();
+ m_segments.append(segment);
+ } else
+ segment = m_segments.last() + positionInSegment;
+
+ unsigned segmentFreeSpace = segmentSize - positionInSegment;
+ unsigned bytesToCopy = std::min(length, segmentFreeSpace);
+
+ for (;;) {
+ memcpy(segment, data, bytesToCopy);
+ if (static_cast<unsigned>(length) == bytesToCopy)
+ break;
+
+ length -= bytesToCopy;
+ data += bytesToCopy;
+ segment = allocateSegment();
+ m_segments.append(segment);
+ bytesToCopy = std::min(length, segmentSize);
+ }
+#else
+ m_size += length;
+ if (m_buffer->data.isEmpty())
+ m_buffer->data.reserveInitialCapacity(length);
+ appendToDataBuffer(data, length);
+#endif
}
void SharedBuffer::append(Vector<char>&& data)
{
- m_size += data.size();
- m_segments.append(DataSegment::create(WTFMove(data)));
+ // This takes its argument as a rvalue reference because we intend to have a future
+ // version take ownership of the vector rather than copying.
+ append(data.data(), data.size());
}
void SharedBuffer::clear()
{
+ m_fileData = { };
+
+ clearPlatformData();
+
+#if !USE(NETWORK_CFDATA_ARRAY_CALLBACK)
+ for (char* segment : m_segments)
+ freeSegment(segment);
+ m_segments.clear();
+#else
+ m_dataArray.clear();
+#endif
+
m_size = 0;
- m_segments.clear();
+ clearDataBuffer();
}
Ref<SharedBuffer> SharedBuffer::copy() const
{
- Ref<SharedBuffer> clone = adoptRef(*new SharedBuffer);
+ Ref<SharedBuffer> clone { adoptRef(*new SharedBuffer) };
+
+ if (hasPlatformData() || m_fileData) {
+ clone->append(data(), size());
+ return clone;
+ }
+
clone->m_size = m_size;
- clone->m_segments.reserveInitialCapacity(m_segments.size());
- for (const auto& segment : m_segments)
- clone->m_segments.uncheckedAppend(segment.copyRef());
+ clone->m_buffer->data.reserveCapacity(m_size);
+ clone->m_buffer->data.append(m_buffer->data.data(), m_buffer->data.size());
+
+#if !USE(NETWORK_CFDATA_ARRAY_CALLBACK)
+ if (!m_segments.isEmpty()) {
+ unsigned lastIndex = m_segments.size() - 1;
+ for (unsigned i = 0; i < lastIndex; ++i)
+ clone->m_buffer->data.append(m_segments[i], segmentSize);
+
+ unsigned sizeOfLastSegment = m_size - m_buffer->data.size() - lastIndex * segmentSize;
+ clone->m_buffer->data.append(m_segments.last(), sizeOfLastSegment);
+ }
+#else
+ for (auto& data : m_dataArray)
+ clone->m_dataArray.append(data.get());
+#endif
+ ASSERT(clone->size() == size());
+
return clone;
}
-const char* SharedBuffer::DataSegment::data() const
+void SharedBuffer::duplicateDataBufferIfNecessary() const
{
- auto visitor = WTF::makeVisitor(
- [](const Vector<char>& data) { return data.data(); },
-#if USE(CF)
- [](const RetainPtr<CFDataRef>& data) { return reinterpret_cast<const char*>(CFDataGetBytePtr(data.get())); },
-#endif
-#if USE(SOUP)
- [](const GUniquePtr<SoupBuffer>& data) { return data->data; },
-#endif
- [](const MappedFileData& data) { return reinterpret_cast<const char*>(data.data()); }
- );
- return WTF::visit(visitor, m_immutableData);
+ size_t currentCapacity = m_buffer->data.capacity();
+ if (m_buffer->hasOneRef() || m_size <= currentCapacity)
+ return;
+
+ size_t newCapacity = std::max(static_cast<size_t>(m_size), currentCapacity * 2);
+ auto newBuffer = adoptRef(*new DataBuffer);
+ newBuffer->data.reserveInitialCapacity(newCapacity);
+ newBuffer->data = ""
+ m_buffer = WTFMove(newBuffer);
}
+void SharedBuffer::appendToDataBuffer(const char *data, unsigned length) const
+{
+ duplicateDataBufferIfNecessary();
+ m_buffer->data.append(data, length);
+}
+
+void SharedBuffer::clearDataBuffer()
+{
+ if (!m_buffer->hasOneRef())
+ m_buffer = adoptRef(*new DataBuffer);
+ else
+ m_buffer->data.clear();
+}
+
#if !USE(CF)
void SharedBuffer::hintMemoryNotNeededSoon()
{
@@ -174,21 +314,111 @@
}
#endif
-size_t SharedBuffer::DataSegment::size() const
+#if !USE(NETWORK_CFDATA_ARRAY_CALLBACK)
+
+void SharedBuffer::copyBufferAndClear(char* destination, unsigned bytesToCopy) const
{
- auto visitor = WTF::makeVisitor(
- [](const Vector<char>& data) { return data.size(); },
-#if USE(CF)
- [](const RetainPtr<CFDataRef>& data) { return CFDataGetLength(data.get()); },
+ for (char* segment : m_segments) {
+ unsigned effectiveBytesToCopy = std::min(bytesToCopy, segmentSize);
+ memcpy(destination, segment, effectiveBytesToCopy);
+ destination += effectiveBytesToCopy;
+ bytesToCopy -= effectiveBytesToCopy;
+ freeSegment(segment);
+ }
+ m_segments.clear();
+}
+
#endif
-#if USE(SOUP)
- [](const GUniquePtr<SoupBuffer>& data) { return static_cast<size_t>(data->length); },
+
+const Vector<char>& SharedBuffer::buffer() const
+{
+ unsigned bufferSize = m_buffer->data.size();
+ if (m_size > bufferSize) {
+ duplicateDataBufferIfNecessary();
+ m_buffer->data.resize(m_size);
+ copyBufferAndClear(m_buffer->data.data() + bufferSize, m_size - bufferSize);
+ }
+ return m_buffer->data;
+}
+
+unsigned SharedBuffer::getSomeData(const char*& someData, unsigned position) const
+{
+ unsigned totalSize = size();
+ if (position >= totalSize) {
+ someData = 0;
+ return 0;
+ }
+
+ if (hasPlatformData() || m_fileData) {
+ ASSERT_WITH_SECURITY_IMPLICATION(position < size());
+ someData = data() + position;
+ return totalSize - position;
+ }
+
+ ASSERT_WITH_SECURITY_IMPLICATION(position < m_size);
+ unsigned consecutiveSize = m_buffer->data.size();
+ if (position < consecutiveSize) {
+ someData = m_buffer->data.data() + position;
+ return consecutiveSize - position;
+ }
+
+ position -= consecutiveSize;
+#if !USE(NETWORK_CFDATA_ARRAY_CALLBACK)
+ unsigned segments = m_segments.size();
+ unsigned maxSegmentedSize = segments * segmentSize;
+ unsigned segment = segmentIndex(position);
+ if (segment < segments) {
+ unsigned bytesLeft = totalSize - consecutiveSize;
+ unsigned segmentedSize = std::min(maxSegmentedSize, bytesLeft);
+
+ unsigned positionInSegment = offsetInSegment(position);
+ someData = m_segments[segment] + positionInSegment;
+ return segment == segments - 1 ? segmentedSize - position : segmentSize - positionInSegment;
+ }
+ ASSERT_NOT_REACHED();
+ return 0;
+#else
+ return copySomeDataFromDataArray(someData, position);
#endif
- [](const MappedFileData& data) { return data.size(); }
- );
- return WTF::visit(visitor, m_immutableData);
}
+void SharedBuffer::maybeTransferMappedFileData()
+{
+ if (m_fileData) {
+ auto fileData = WTFMove(m_fileData);
+ append(static_cast<const char*>(fileData.data()), fileData.size());
+ }
+}
+
+#if !USE(CF) && !USE(SOUP)
+
+inline void SharedBuffer::clearPlatformData()
+{
+}
+
+inline void SharedBuffer::maybeTransferPlatformData()
+{
+}
+
+inline bool SharedBuffer::hasPlatformData() const
+{
+ return false;
+}
+
+inline const char* SharedBuffer::platformData() const
+{
+ ASSERT_NOT_REACHED();
+
+ return nullptr;
+}
+
+inline bool SharedBuffer::maybeAppendPlatformData(SharedBuffer&)
+{
+ return false;
+}
+
+#endif
+
RefPtr<SharedBuffer> utf8Buffer(const String& string)
{
// Allocate a buffer big enough to hold all the characters.
Modified: trunk/Source/WebCore/platform/SharedBuffer.h (215660 => 215661)
--- trunk/Source/WebCore/platform/SharedBuffer.h 2017-04-22 02:01:55 UTC (rev 215660)
+++ trunk/Source/WebCore/platform/SharedBuffer.h 2017-04-22 02:23:45 UTC (rev 215661)
@@ -31,7 +31,6 @@
#include <wtf/Forward.h>
#include <wtf/RefCounted.h>
#include <wtf/ThreadSafeRefCounted.h>
-#include <wtf/Variant.h>
#include <wtf/Vector.h>
#include <wtf/text/WTFString.h>
@@ -50,24 +49,27 @@
namespace WebCore {
-class WEBCORE_EXPORT SharedBuffer : public RefCounted<SharedBuffer> {
+class SharedBuffer : public RefCounted<SharedBuffer> {
public:
static Ref<SharedBuffer> create() { return adoptRef(*new SharedBuffer); }
- static Ref<SharedBuffer> create(const char* data, size_t size) { return adoptRef(*new SharedBuffer(data, size)); }
- static Ref<SharedBuffer> create(const unsigned char* data, size_t size) { return adoptRef(*new SharedBuffer(data, size)); }
- static RefPtr<SharedBuffer> createWithContentsOfFile(const String& filePath);
+ static Ref<SharedBuffer> create(const char* c, unsigned i) { return adoptRef(*new SharedBuffer(c, i)); }
+ static Ref<SharedBuffer> create(const unsigned char* data, unsigned size) { return adoptRef(*new SharedBuffer(data, size)); }
- static Ref<SharedBuffer> create(Vector<char>&&);
+ WEBCORE_EXPORT static RefPtr<SharedBuffer> createWithContentsOfFile(const String& filePath);
+
+ WEBCORE_EXPORT static Ref<SharedBuffer> create(Vector<char>&&);
+ WEBCORE_EXPORT ~SharedBuffer();
+
#if USE(FOUNDATION)
- RetainPtr<NSData> createNSData();
- RetainPtr<NSArray> createNSDataArray() const;
- static Ref<SharedBuffer> create(NSData *);
+ WEBCORE_EXPORT RetainPtr<NSData> createNSData();
+ WEBCORE_EXPORT RetainPtr<NSArray> createNSDataArray() const;
+ WEBCORE_EXPORT static Ref<SharedBuffer> wrapNSData(NSData *);
#endif
#if USE(CF)
- RetainPtr<CFDataRef> createCFData();
- static Ref<SharedBuffer> create(CFDataRef);
- void append(CFDataRef);
+ WEBCORE_EXPORT RetainPtr<CFDataRef> createCFData();
+ WEBCORE_EXPORT static Ref<SharedBuffer> wrapCFData(CFDataRef);
+ WEBCORE_EXPORT void append(CFDataRef);
#endif
#if USE(SOUP)
@@ -75,93 +77,101 @@
static Ref<SharedBuffer> wrapSoupBuffer(SoupBuffer*);
#endif
- // Calling data() causes all the data segments to be copied into one segment if they are not already.
- // Iterate the segments using begin() and end() instead.
- // FIXME: Audit the call sites of this function and replace them with iteration if possible.
- const char* data() const;
-
+ // Calling this function will force internal segmented buffers
+ // to be merged into a flat buffer. Use getSomeData() whenever possible
+ // for better performance.
+ WEBCORE_EXPORT const char* data() const;
// Creates an ArrayBuffer and copies this SharedBuffer's contents to that
// ArrayBuffer without merging segmented buffers into a flat buffer.
- RefPtr<ArrayBuffer> createArrayBuffer() const;
+ WEBCORE_EXPORT RefPtr<ArrayBuffer> createArrayBuffer() const;
- // FIXME: This should return a size_t.
- unsigned size() const { return m_size; }
+ WEBCORE_EXPORT unsigned size() const;
bool isEmpty() const { return !size(); }
- void append(const SharedBuffer&);
- void append(const char*, size_t);
- void append(Vector<char>&&);
+ WEBCORE_EXPORT void append(SharedBuffer&);
+ WEBCORE_EXPORT void append(const char*, unsigned);
+ WEBCORE_EXPORT void append(Vector<char>&&);
- void clear();
+ WEBCORE_EXPORT void clear();
- Ref<SharedBuffer> copy() const;
+ WEBCORE_EXPORT Ref<SharedBuffer> copy() const;
+
+ // Return the number of consecutive bytes after "position". "data"
+ // points to the first byte.
+ // Return 0 when no more data left.
+ // When extracting all data with getSomeData(), the caller should
+ // repeat calling it until it returns 0.
+ // Usage:
+ // const char* segment;
+ // unsigned pos = 0;
+ // while (unsigned length = sharedBuffer->getSomeData(segment, pos)) {
+ // // Use the data. for example: decoder->decode(segment, length);
+ // pos += length;
+ // }
+ WEBCORE_EXPORT unsigned getSomeData(const char*& data, unsigned position = 0) const;
- // Data wrapped by a DataSegment should be immutable because it can be referenced by other objects.
- // To modify or combine the data, allocate a new DataSegment.
- class DataSegment : public ThreadSafeRefCounted<DataSegment> {
- public:
- const char* data() const;
- size_t size() const;
+ bool tryReplaceContentsWithPlatformBuffer(SharedBuffer&);
+ WEBCORE_EXPORT bool hasPlatformData() const;
- static Ref<DataSegment> create(Vector<char>&& data) { return adoptRef(*new DataSegment(WTFMove(data))); }
-#if USE(CF)
- static Ref<DataSegment> create(RetainPtr<CFDataRef>&& data) { return adoptRef(*new DataSegment(WTFMove(data))); }
-#endif
-#if USE(SOUP)
- static Ref<DataSegment> create(GUniquePtr<SoupBuffer>&& data) { return adoptRef(*new DataSegment(WTFMove(data))); }
-#endif
- static Ref<DataSegment> create(MappedFileData&& data) { return adoptRef(*new DataSegment(WTFMove(data))); }
+ struct DataBuffer : public ThreadSafeRefCounted<DataBuffer> {
+ Vector<char> data;
+ };
- private:
- DataSegment(Vector<char>&& data)
- : m_immutableData(WTFMove(data)) { }
-#if USE(CF)
- DataSegment(RetainPtr<CFDataRef>&& data)
- : m_immutableData(WTFMove(data)) { }
-#endif
-#if USE(SOUP)
- DataSegment(GUniquePtr<SoupBuffer>&& data)
- : m_immutableData(WTFMove(data)) { }
-#endif
- DataSegment(MappedFileData&& data)
- : m_immutableData(WTFMove(data)) { }
+ void hintMemoryNotNeededSoon();
- Variant<Vector<char>,
-#if USE(CF)
- RetainPtr<CFDataRef>,
+private:
+ WEBCORE_EXPORT SharedBuffer();
+ WEBCORE_EXPORT SharedBuffer(const char*, unsigned);
+ WEBCORE_EXPORT SharedBuffer(const unsigned char*, unsigned);
+ explicit SharedBuffer(MappedFileData&&);
+
+ static RefPtr<SharedBuffer> createFromReadingFile(const String& filePath);
+
+ // Calling this function will force internal segmented buffers
+ // to be merged into a flat buffer. Use getSomeData() whenever possible
+ // for better performance.
+ const Vector<char>& buffer() const;
+
+ void clearPlatformData();
+ void maybeTransferPlatformData();
+ bool maybeAppendPlatformData(SharedBuffer&);
+
+ void maybeTransferMappedFileData();
+
+ void copyBufferAndClear(char* destination, unsigned bytesToCopy) const;
+
+ void appendToDataBuffer(const char *, unsigned) const;
+ void duplicateDataBufferIfNecessary() const;
+ void clearDataBuffer();
+
+ unsigned m_size { 0 };
+ mutable Ref<DataBuffer> m_buffer;
+
+#if USE(NETWORK_CFDATA_ARRAY_CALLBACK)
+ mutable Vector<RetainPtr<CFDataRef>> m_dataArray;
+ unsigned copySomeDataFromDataArray(const char*& someData, unsigned position) const;
+ const char *singleDataArrayBuffer() const;
+ bool maybeAppendDataArray(SharedBuffer&);
+#else
+ mutable Vector<char*> m_segments;
#endif
-#if USE(SOUP)
- GUniquePtr<SoupBuffer>,
-#endif
- MappedFileData> m_immutableData;
- friend class SharedBuffer;
- };
- Vector<Ref<const DataSegment>>::const_iterator begin() const { return m_segments.begin(); }
- Vector<Ref<const DataSegment>>::const_iterator end() const { return m_segments.end(); }
+ unsigned platformDataSize() const;
+ const char* platformData() const;
- void hintMemoryNotNeededSoon();
-
-private:
- SharedBuffer() = default;
- SharedBuffer(const char*, size_t);
- SharedBuffer(const unsigned char*, size_t);
- SharedBuffer(Vector<char>&&);
- SharedBuffer(MappedFileData&&);
#if USE(CF)
- SharedBuffer(CFDataRef);
+ explicit SharedBuffer(CFDataRef);
+ RetainPtr<CFDataRef> m_cfData;
+ CFDataRef existingCFData();
#endif
+
#if USE(SOUP)
- SharedBuffer(SoupBuffer*);
+ explicit SharedBuffer(SoupBuffer*);
+ GUniquePtr<SoupBuffer> m_soupBuffer;
#endif
- void combineToOneSegment() const;
-
- static RefPtr<SharedBuffer> createFromReadingFile(const String& filePath);
-
- size_t m_size { 0 };
- mutable Vector<Ref<const DataSegment>> m_segments;
+ MappedFileData m_fileData;
};
RefPtr<SharedBuffer> utf8Buffer(const String&);
Modified: trunk/Source/WebCore/platform/SharedBufferChunkReader.cpp (215660 => 215661)
--- trunk/Source/WebCore/platform/SharedBufferChunkReader.cpp 2017-04-22 02:01:55 UTC (rev 215660)
+++ trunk/Source/WebCore/platform/SharedBufferChunkReader.cpp 2017-04-22 02:23:45 UTC (rev 215661)
@@ -31,11 +31,6 @@
#include "config.h"
#include "SharedBufferChunkReader.h"
-#if ENABLE(MHTML)
-
-// FIXME: This class is overkill. Remove this class and just iterate the segments of a SharedBuffer
-// using the cool new SharedBuffer::begin() and SharedBuffer::end() instead of using this class.
-
#include "SharedBuffer.h"
namespace WebCore {
@@ -105,10 +100,7 @@
// Read the next segment.
m_segmentIndex = 0;
m_bufferPosition += m_segmentLength;
- // Let's pretend all the data is in one block.
- // FIXME: This class should be removed in favor of just iterating the segments of the SharedBuffer.
- m_segment = m_buffer->data() + m_bufferPosition;
- m_segmentLength = m_buffer->size() - m_bufferPosition;
+ m_segmentLength = m_buffer->getSomeData(m_segment, m_bufferPosition);
if (!m_segmentLength) {
m_reachedEndOfFile = true;
if (m_separatorIndex > 0)
@@ -142,14 +134,12 @@
size_t bufferPosition = m_bufferPosition + m_segmentLength;
const char* segment = 0;
-
- // Let's pretend all the data is in one block.
- // FIXME: This class should be removed in favor of just iterating the segments of the SharedBuffer.
- if (bufferPosition != m_buffer->size()) {
- segment = m_buffer->data() + bufferPosition;
- size_t segmentLength = m_buffer->size() - bufferPosition;
- if (segmentLength > requestedSize)
- segmentLength = requestedSize;
+ while (size_t segmentLength = m_buffer->getSomeData(segment, bufferPosition)) {
+ if (requestedSize <= readBytesCount + segmentLength) {
+ data.append(segment, requestedSize - readBytesCount);
+ readBytesCount += (requestedSize - readBytesCount);
+ break;
+ }
data.append(segment, segmentLength);
readBytesCount += segmentLength;
bufferPosition += segmentLength;
@@ -158,5 +148,3 @@
}
}
-
-#endif
Modified: trunk/Source/WebCore/platform/SharedBufferChunkReader.h (215660 => 215661)
--- trunk/Source/WebCore/platform/SharedBufferChunkReader.h 2017-04-22 02:01:55 UTC (rev 215660)
+++ trunk/Source/WebCore/platform/SharedBufferChunkReader.h 2017-04-22 02:23:45 UTC (rev 215661)
@@ -28,10 +28,9 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#pragma once
+#ifndef SharedBufferChunkReader_h
+#define SharedBufferChunkReader_h
-#if ENABLE(MHTML)
-
#include <wtf/Vector.h>
#include <wtf/text/WTFString.h>
Modified: trunk/Source/WebCore/platform/URLParser.cpp (215660 => 215661)
--- trunk/Source/WebCore/platform/URLParser.cpp 2017-04-22 02:01:55 UTC (rev 215660)
+++ trunk/Source/WebCore/platform/URLParser.cpp 2017-04-22 02:23:45 UTC (rev 215661)
@@ -1149,8 +1149,6 @@
URLParser::URLParser(const String& input, const URL& base, const TextEncoding& encoding)
: m_inputString(input)
{
- if (input == "file:///Users/alexchristensen/webkit/LayoutTests/webarchive/archive-empty-frame-source.html")
- WTFLogAlways("HIT");
if (input.isNull()) {
if (base.isValid() && !base.m_cannotBeABaseURL) {
m_url = base;
Modified: trunk/Source/WebCore/platform/cf/KeyedEncoderCF.cpp (215660 => 215661)
--- trunk/Source/WebCore/platform/cf/KeyedEncoderCF.cpp 2017-04-22 02:01:55 UTC (rev 215660)
+++ trunk/Source/WebCore/platform/cf/KeyedEncoderCF.cpp 2017-04-22 02:23:45 UTC (rev 215661)
@@ -145,7 +145,7 @@
auto data = "" m_rootDictionary.get(), kCFPropertyListBinaryFormat_v1_0, 0, nullptr));
if (!data)
return nullptr;
- return SharedBuffer::create(data.get());
+ return SharedBuffer::wrapCFData(data.get());
}
} // namespace WebCore
Modified: trunk/Source/WebCore/platform/cf/SharedBufferCF.cpp (215660 => 215661)
--- trunk/Source/WebCore/platform/cf/SharedBufferCF.cpp 2017-04-22 02:01:55 UTC (rev 215660)
+++ trunk/Source/WebCore/platform/cf/SharedBufferCF.cpp 2017-04-22 02:23:45 UTC (rev 215661)
@@ -33,9 +33,10 @@
namespace WebCore {
-SharedBuffer::SharedBuffer(CFDataRef data)
+SharedBuffer::SharedBuffer(CFDataRef cfData)
+ : m_buffer(adoptRef(*new DataBuffer))
+ , m_cfData(cfData)
{
- append(data);
}
// Using Foundation allows for an even more efficient implementation of this function,
@@ -43,34 +44,144 @@
#if !USE(FOUNDATION)
RetainPtr<CFDataRef> SharedBuffer::createCFData()
{
- if (m_segments.size() == 1) {
- if (auto data = ""
- return *data;
- }
- return adoptCF(CFDataCreate(nullptr, reinterpret_cast<const UInt8*>(data()), size()));
+ if (m_cfData)
+ return m_cfData;
+
+ // Internal data in SharedBuffer can be segmented. We need to get the contiguous buffer.
+ const Vector<char>& contiguousBuffer = buffer();
+ return adoptCF(CFDataCreate(0, reinterpret_cast<const UInt8*>(contiguousBuffer.data()), contiguousBuffer.size()));
}
#endif
-Ref<SharedBuffer> SharedBuffer::create(CFDataRef data)
+Ref<SharedBuffer> SharedBuffer::wrapCFData(CFDataRef data)
{
return adoptRef(*new SharedBuffer(data));
}
+bool SharedBuffer::hasPlatformData() const
+{
+ return m_cfData;
+}
+
+const char* SharedBuffer::platformData() const
+{
+ return reinterpret_cast<const char*>(CFDataGetBytePtr(m_cfData.get()));
+}
+
+unsigned SharedBuffer::platformDataSize() const
+{
+ return CFDataGetLength(m_cfData.get());
+}
+
void SharedBuffer::hintMemoryNotNeededSoon()
{
- for (const auto& segment : m_segments) {
- if (segment->hasOneRef()) {
- if (auto data = ""
- OSAllocator::hintMemoryNotNeededSoon(const_cast<UInt8*>(CFDataGetBytePtr(data->get())), CFDataGetLength(data->get()));
- }
- }
+ if (!hasPlatformData())
+ return;
+ OSAllocator::hintMemoryNotNeededSoon(const_cast<char*>(platformData()), platformDataSize());
}
+void SharedBuffer::maybeTransferPlatformData()
+{
+ if (!m_cfData)
+ return;
+
+ ASSERT(!m_size);
+
+ // Hang on to the m_cfData pointer in a local pointer as append() will re-enter maybeTransferPlatformData()
+ // and we need to make sure to early return when it does.
+ RetainPtr<CFDataRef> cfData = adoptCF(m_cfData.leakRef());
+
+ append(reinterpret_cast<const char*>(CFDataGetBytePtr(cfData.get())), CFDataGetLength(cfData.get()));
+}
+
+void SharedBuffer::clearPlatformData()
+{
+ m_cfData = 0;
+}
+
+bool SharedBuffer::tryReplaceContentsWithPlatformBuffer(SharedBuffer& newContents)
+{
+ if (!newContents.m_cfData)
+ return false;
+
+ clear();
+ m_cfData = newContents.m_cfData;
+ return true;
+}
+
+bool SharedBuffer::maybeAppendPlatformData(SharedBuffer& newContents)
+{
+ if (size() || !newContents.m_cfData)
+ return false;
+ m_cfData = newContents.m_cfData;
+ return true;
+}
+
+#if USE(NETWORK_CFDATA_ARRAY_CALLBACK)
void SharedBuffer::append(CFDataRef data)
{
ASSERT(data);
+ m_dataArray.append(data);
m_size += CFDataGetLength(data);
- m_segments.append(DataSegment::create(data));
}
+void SharedBuffer::copyBufferAndClear(char* destination, unsigned bytesToCopy) const
+{
+ if (m_dataArray.isEmpty())
+ return;
+
+ CFIndex bytesLeft = bytesToCopy;
+ for (auto& cfData : m_dataArray) {
+ CFIndex dataLen = CFDataGetLength(cfData.get());
+ ASSERT(bytesLeft >= dataLen);
+ memcpy(destination, CFDataGetBytePtr(cfData.get()), dataLen);
+ destination += dataLen;
+ bytesLeft -= dataLen;
+ }
+ m_dataArray.clear();
}
+
+unsigned SharedBuffer::copySomeDataFromDataArray(const char*& someData, unsigned position) const
+{
+ unsigned totalOffset = 0;
+ for (auto& cfData : m_dataArray) {
+ unsigned dataLen = static_cast<unsigned>(CFDataGetLength(cfData.get()));
+ ASSERT(totalOffset <= position);
+ unsigned localOffset = position - totalOffset;
+ if (localOffset < dataLen) {
+ someData = reinterpret_cast<const char *>(CFDataGetBytePtr(cfData.get())) + localOffset;
+ return dataLen - localOffset;
+ }
+ totalOffset += dataLen;
+ }
+ return 0;
+}
+
+const char *SharedBuffer::singleDataArrayBuffer() const
+{
+ // If we had previously copied data into m_buffer in copyDataArrayAndClear() or some other
+ // function, then we can't return a pointer to the CFDataRef buffer.
+ if (m_buffer->data.size())
+ return 0;
+
+ if (m_dataArray.size() != 1)
+ return 0;
+
+ return reinterpret_cast<const char*>(CFDataGetBytePtr(m_dataArray.at(0).get()));
+}
+
+bool SharedBuffer::maybeAppendDataArray(SharedBuffer& data)
+{
+ if (m_buffer->data.size() || m_cfData || !data.m_dataArray.size())
+ return false;
+#if !ASSERT_DISABLED
+ unsigned originalSize = size();
+#endif
+ for (auto& cfData : data.m_dataArray)
+ append(cfData.get());
+ ASSERT(size() == originalSize + data.size());
+ return true;
+}
+#endif
+
+}
Modified: trunk/Source/WebCore/platform/cocoa/NetworkExtensionContentFilter.mm (215660 => 215661)
--- trunk/Source/WebCore/platform/cocoa/NetworkExtensionContentFilter.mm 2017-04-22 02:01:55 UTC (rev 215660)
+++ trunk/Source/WebCore/platform/cocoa/NetworkExtensionContentFilter.mm 2017-04-22 02:23:45 UTC (rev 215661)
@@ -197,7 +197,7 @@
Ref<SharedBuffer> NetworkExtensionContentFilter::replacementData() const
{
ASSERT(didBlockData());
- return SharedBuffer::create(m_replacementData.get());
+ return SharedBuffer::wrapNSData(m_replacementData.get());
}
#if ENABLE(CONTENT_FILTERING)
Modified: trunk/Source/WebCore/platform/cocoa/ParentalControlsContentFilter.mm (215660 => 215661)
--- trunk/Source/WebCore/platform/cocoa/ParentalControlsContentFilter.mm 2017-04-22 02:01:55 UTC (rev 215660)
+++ trunk/Source/WebCore/platform/cocoa/ParentalControlsContentFilter.mm 2017-04-22 02:23:45 UTC (rev 215661)
@@ -93,7 +93,7 @@
Ref<SharedBuffer> ParentalControlsContentFilter::replacementData() const
{
ASSERT(didBlockData());
- return SharedBuffer::create(m_replacementData.get());
+ return SharedBuffer::wrapNSData(m_replacementData.get());
}
#if ENABLE(CONTENT_FILTERING)
Modified: trunk/Source/WebCore/platform/cocoa/SharedBufferCocoa.mm (215660 => 215661)
--- trunk/Source/WebCore/platform/cocoa/SharedBufferCocoa.mm 2017-04-22 02:01:55 UTC (rev 215660)
+++ trunk/Source/WebCore/platform/cocoa/SharedBufferCocoa.mm 2017-04-22 02:23:45 UTC (rev 215661)
@@ -35,10 +35,10 @@
@interface WebCoreSharedBufferData : NSData
{
- RefPtr<const SharedBuffer::DataSegment> sharedBufferDataSegment;
+ RefPtr<SharedBuffer::DataBuffer> sharedBufferDataBuffer;
}
-- (id)initWithSharedBufferDataSegment:(const SharedBuffer::DataSegment&)dataSegment;
+- (id)initWithSharedBufferDataBuffer:(SharedBuffer::DataBuffer*)dataBuffer;
@end
@implementation WebCoreSharedBufferData
@@ -59,12 +59,12 @@
[super dealloc];
}
-- (id)initWithSharedBufferDataSegment:(const SharedBuffer::DataSegment&)dataSegment
+- (id)initWithSharedBufferDataBuffer:(SharedBuffer::DataBuffer*)dataBuffer
{
self = [super init];
if (self)
- sharedBufferDataSegment = &dataSegment;
+ sharedBufferDataBuffer = dataBuffer;
return self;
}
@@ -71,12 +71,12 @@
- (NSUInteger)length
{
- return sharedBufferDataSegment->size();
+ return sharedBufferDataBuffer->data.size();
}
- (const void *)bytes
{
- return sharedBufferDataSegment->data();
+ return sharedBufferDataBuffer->data.data();
}
@end
@@ -83,7 +83,7 @@
namespace WebCore {
-Ref<SharedBuffer> SharedBuffer::create(NSData *nsData)
+Ref<SharedBuffer> SharedBuffer::wrapNSData(NSData *nsData)
{
return adoptRef(*new SharedBuffer((CFDataRef)nsData));
}
@@ -93,13 +93,26 @@
return adoptNS((NSData *)createCFData().leakRef());
}
+CFDataRef SharedBuffer::existingCFData()
+{
+ if (m_cfData)
+ return m_cfData.get();
+
+#if USE(NETWORK_CFDATA_ARRAY_CALLBACK)
+ if (m_dataArray.size() == 1)
+ return m_dataArray.at(0).get();
+#endif
+
+ return nullptr;
+}
+
RetainPtr<CFDataRef> SharedBuffer::createCFData()
{
- combineToOneSegment();
- if (!m_segments.size())
- return adoptCF(CFDataCreate(nullptr, nullptr, 0));
- ASSERT(m_segments.size() == 1);
- return adoptCF((CFDataRef)adoptNS([[WebCoreSharedBufferData alloc] initWithSharedBufferDataSegment:m_segments[0]]).leakRef());
+ if (CFDataRef cfData = existingCFData())
+ return cfData;
+
+ data(); // Force data into m_buffer from segments or data array.
+ return adoptCF((CFDataRef)adoptNS([[WebCoreSharedBufferData alloc] initWithSharedBufferDataBuffer:m_buffer.ptr()]).leakRef());
}
RefPtr<SharedBuffer> SharedBuffer::createFromReadingFile(const String& filePath)
@@ -106,15 +119,31 @@
{
NSData *resourceData = [NSData dataWithContentsOfFile:filePath];
if (resourceData)
- return SharedBuffer::create(resourceData);
+ return SharedBuffer::wrapNSData(resourceData);
return nullptr;
}
RetainPtr<NSArray> SharedBuffer::createNSDataArray() const
{
- auto dataArray = adoptNS([[NSMutableArray alloc] initWithCapacity:m_segments.size()]);
- for (const auto& segment : m_segments)
- [dataArray addObject:adoptNS([[WebCoreSharedBufferData alloc] initWithSharedBufferDataSegment:segment]).get()];
+ if (auto platformData = (NSData *)m_cfData.get())
+ return @[ platformData ];
+
+ if (m_fileData)
+ return @[ [NSData dataWithBytes:m_fileData.data() length:m_fileData.size()] ];
+
+ auto dataArray = adoptNS([[NSMutableArray alloc] init]);
+ if (m_buffer->data.size())
+ [dataArray addObject:adoptNS([[WebCoreSharedBufferData alloc] initWithSharedBufferDataBuffer:m_buffer.ptr()]).get()];
+
+#if USE(NETWORK_CFDATA_ARRAY_CALLBACK)
+ for (auto& data : m_dataArray)
+ [dataArray addObject:(NSData *)data.get()];
+#else
+ // Cocoa platforms all currently USE(NETWORK_CFDATA_ARRAY_CALLBACK), so implementing a code path for copying segments would be dead code.
+ // If this ever changes, the following static_assert will detect it.
+ static_assert(false, "FIXME: Copy the segments into an array of NSData objects.");
+#endif
+
return WTFMove(dataArray);
}
Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/WebCoreAVFResourceLoader.mm (215660 => 215661)
--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/WebCoreAVFResourceLoader.mm 2017-04-22 02:01:55 UTC (rev 215660)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/WebCoreAVFResourceLoader.mm 2017-04-22 02:23:45 UTC (rev 215661)
@@ -173,38 +173,27 @@
responseOffset = static_cast<NSUInteger>(contentRange.firstBytePosition());
// Check for possible unsigned overflow.
- ASSERT(dataRequest.currentOffset >= dataRequest.requestedOffset);
- ASSERT(dataRequest.requestedLength >= (dataRequest.currentOffset - dataRequest.requestedOffset));
+ ASSERT([dataRequest currentOffset] >= [dataRequest requestedOffset]);
+ ASSERT([dataRequest requestedLength] >= ([dataRequest currentOffset] - [dataRequest requestedOffset]));
- NSUInteger remainingLength = dataRequest.requestedLength - static_cast<NSUInteger>(dataRequest.currentOffset - dataRequest.requestedOffset);
+ NSUInteger remainingLength = [dataRequest requestedLength] - static_cast<NSUInteger>([dataRequest currentOffset] - [dataRequest requestedOffset]);
+ do {
+ // Check to see if there is any data available in the buffer to fulfill the data request.
+ if (data->size() <= [dataRequest currentOffset] - responseOffset)
+ return;
- auto bytesToSkip = dataRequest.currentOffset - responseOffset;
- RetainPtr<NSArray> array = data->createNSDataArray();
- for (size_t i = 0; i < [array count]; ++i) {
- NSData *segment = [array objectAtIndex:i];
- if (bytesToSkip) {
- if (bytesToSkip > segment.length) {
- bytesToSkip -= segment.length;
- continue;
- }
- auto bytesToUse = segment.length - bytesToSkip;
- [dataRequest respondWithData:[segment subdataWithRange:NSMakeRange(static_cast<NSUInteger>(bytesToSkip), static_cast<NSUInteger>(segment.length - bytesToSkip))]];
- bytesToSkip = 0;
- remainingLength -= bytesToUse;
- continue;
- }
- if (segment.length <= remainingLength) {
- [dataRequest respondWithData:segment];
- remainingLength -= segment.length;
- continue;
- }
- [dataRequest respondWithData:[segment subdataWithRange:NSMakeRange(0, remainingLength)]];
- remainingLength = 0;
- if (!remainingLength)
- break;
- }
+ const char* someData;
+ NSUInteger receivedLength = data->getSomeData(someData, static_cast<unsigned>([dataRequest currentOffset] - responseOffset));
- if (dataRequest.currentOffset + dataRequest.requestedLength >= dataRequest.requestedOffset) {
+ // Create an NSData with only as much of the received data as necessary to fulfill the request.
+ NSUInteger length = MIN(receivedLength, remainingLength);
+ RetainPtr<NSData> nsData = adoptNS([[NSData alloc] initWithBytes:someData length:length]);
+
+ [dataRequest respondWithData:nsData.get()];
+ remainingLength -= length;
+ } while (remainingLength);
+
+ if ([dataRequest currentOffset] + [dataRequest requestedLength] >= [dataRequest requestedOffset]) {
[m_avRequest.get() finishLoading];
stopLoading();
}
Modified: trunk/Source/WebCore/platform/graphics/cocoa/FontPlatformDataCocoa.mm (215660 => 215661)
--- trunk/Source/WebCore/platform/graphics/cocoa/FontPlatformDataCocoa.mm 2017-04-22 02:01:55 UTC (rev 215660)
+++ trunk/Source/WebCore/platform/graphics/cocoa/FontPlatformDataCocoa.mm 2017-04-22 02:23:45 UTC (rev 215661)
@@ -201,7 +201,7 @@
RefPtr<SharedBuffer> FontPlatformData::openTypeTable(uint32_t table) const
{
if (RetainPtr<CFDataRef> data = "" table, kCTFontTableOptionNoOptions)))
- return SharedBuffer::create(data.get());
+ return SharedBuffer::wrapCFData(data.get());
return nullptr;
}
Modified: trunk/Source/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp (215660 => 215661)
--- trunk/Source/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp 2017-04-22 02:01:55 UTC (rev 215660)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp 2017-04-22 02:23:45 UTC (rev 215661)
@@ -1163,8 +1163,13 @@
void ResourceHandleStreamingClient::didReceiveBuffer(ResourceHandle*, Ref<SharedBuffer>&& buffer, int /* encodedLength */)
{
- for (const auto& segment : buffer.get())
- handleDataReceived(segment->data(), segment->size());
+ // This pattern is suggested by SharedBuffer.h.
+ const char* segment;
+ unsigned position = 0;
+ while (unsigned length = buffer->getSomeData(segment, position)) {
+ handleDataReceived(segment, length);
+ position += length;
+ }
}
void ResourceHandleStreamingClient::didFinishLoading(ResourceHandle*)
Modified: trunk/Source/WebCore/platform/graphics/mac/ImageMac.mm (215660 => 215661)
--- trunk/Source/WebCore/platform/graphics/mac/ImageMac.mm 2017-04-22 02:01:55 UTC (rev 215660)
+++ trunk/Source/WebCore/platform/graphics/mac/ImageMac.mm 2017-04-22 02:23:45 UTC (rev 215661)
@@ -63,7 +63,7 @@
NSData *namedImageData = [NSData dataWithContentsOfFile:imagePath];
if (namedImageData) {
auto image = BitmapImage::create();
- image->setData(SharedBuffer::create(namedImageData), true);
+ image->setData(SharedBuffer::wrapNSData(namedImageData), true);
return WTFMove(image);
}
Modified: trunk/Source/WebCore/platform/image-decoders/ImageDecoder.cpp (215660 => 215661)
--- trunk/Source/WebCore/platform/image-decoders/ImageDecoder.cpp 2017-04-22 02:01:55 UTC (rev 215660)
+++ trunk/Source/WebCore/platform/image-decoders/ImageDecoder.cpp 2017-04-22 02:23:45 UTC (rev 215661)
@@ -42,19 +42,17 @@
namespace {
-static unsigned copyFromSharedBuffer(char* buffer, unsigned bufferLength, const SharedBuffer& sharedBuffer)
+unsigned copyFromSharedBuffer(char* buffer, unsigned bufferLength, const SharedBuffer& sharedBuffer, unsigned offset)
{
unsigned bytesExtracted = 0;
- for (const auto& segment : sharedBuffer) {
- if (bytesExtracted + segment->size() <= bufferLength) {
- memcpy(buffer + bytesExtracted, segment->data(), segment->size());
- bytesExtracted += segment->size();
- } else {
- ASSERT(bufferLength - bytesExtracted < segment->size());
- memcpy(buffer + bytesExtracted, segment->data(), bufferLength - bytesExtracted);
- bytesExtracted = bufferLength;
+ const char* moreData;
+ while (unsigned moreDataLength = sharedBuffer.getSomeData(moreData, offset)) {
+ unsigned bytesToCopy = min(bufferLength - bytesExtracted, moreDataLength);
+ memcpy(buffer + bytesExtracted, moreData, bytesToCopy);
+ bytesExtracted += bytesToCopy;
+ if (bytesExtracted == bufferLength)
break;
- }
+ offset += bytesToCopy;
}
return bytesExtracted;
}
@@ -102,7 +100,7 @@
{
static const unsigned lengthOfLongestSignature = 14; // To wit: "RIFF????WEBPVP"
char contents[lengthOfLongestSignature];
- unsigned length = copyFromSharedBuffer(contents, lengthOfLongestSignature, data);
+ unsigned length = copyFromSharedBuffer(contents, lengthOfLongestSignature, data, 0);
if (length < lengthOfLongestSignature)
return nullptr;
Modified: trunk/Source/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp (215660 => 215661)
--- trunk/Source/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp 2017-04-22 02:01:55 UTC (rev 215660)
+++ trunk/Source/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp 2017-04-22 02:23:45 UTC (rev 215661)
@@ -157,10 +157,11 @@
if (setjmp(JMPBUF(m_png)))
return decoder->setFailed();
- for (const auto& segment : data) {
- m_readOffset += segment->size();
+ const char* segment;
+ while (unsigned segmentLength = data.getSomeData(segment, m_readOffset)) {
+ m_readOffset += segmentLength;
m_currentBufferSize = m_readOffset;
- png_process_data(m_png, m_info, reinterpret_cast<png_bytep>(const_cast<char*>(segment->data())), segment->size());
+ png_process_data(m_png, m_info, reinterpret_cast<png_bytep>(const_cast<char*>(segment)), segmentLength);
// We explicitly specify the superclass encodedDataStatus() because we
// merely want to check if we've managed to set the size, not
// (recursively) trigger additional decoding if we haven't.
Modified: trunk/Source/WebCore/platform/ios/PlatformPasteboardIOS.mm (215660 => 215661)
--- trunk/Source/WebCore/platform/ios/PlatformPasteboardIOS.mm 2017-04-22 02:01:55 UTC (rev 215660)
+++ trunk/Source/WebCore/platform/ios/PlatformPasteboardIOS.mm 2017-04-22 02:23:45 UTC (rev 215661)
@@ -308,7 +308,7 @@
if (![pasteboardItem count])
return nullptr;
- return SharedBuffer::create([pasteboardItem.get() objectAtIndex:0]);
+ return SharedBuffer::wrapNSData([pasteboardItem.get() objectAtIndex:0]);
}
String PlatformPasteboard::readString(int index, const String& type)
Modified: trunk/Source/WebCore/platform/mac/PasteboardMac.mm (215660 => 215661)
--- trunk/Source/WebCore/platform/mac/PasteboardMac.mm 2017-04-22 02:01:55 UTC (rev 215660)
+++ trunk/Source/WebCore/platform/mac/PasteboardMac.mm 2017-04-22 02:23:45 UTC (rev 215661)
@@ -261,7 +261,7 @@
if (!RTFDData)
return;
- newChangeCount = platformStrategies()->pasteboardStrategy()->setBufferForType(SharedBuffer::create(RTFDData).ptr(), NSRTFDPboardType, pasteboardName);
+ newChangeCount = platformStrategies()->pasteboardStrategy()->setBufferForType(SharedBuffer::wrapNSData(RTFDData).ptr(), NSRTFDPboardType, pasteboardName);
}
void Pasteboard::write(const PasteboardImage& pasteboardImage)
@@ -278,7 +278,7 @@
types.append(WebArchivePboardType);
m_changeCount = writeURLForTypes(types, m_pasteboardName, pasteboardImage.url);
- m_changeCount = platformStrategies()->pasteboardStrategy()->setBufferForType(SharedBuffer::create(imageData).ptr(), NSTIFFPboardType, m_pasteboardName);
+ m_changeCount = platformStrategies()->pasteboardStrategy()->setBufferForType(SharedBuffer::wrapCFData(imageData).ptr(), NSTIFFPboardType, m_pasteboardName);
if (pasteboardImage.dataInWebArchiveFormat)
m_changeCount = platformStrategies()->pasteboardStrategy()->setBufferForType(pasteboardImage.dataInWebArchiveFormat.get(), WebArchivePboardType, m_pasteboardName);
writeFileWrapperAsRTFDAttachment(fileWrapper(pasteboardImage), m_pasteboardName, m_changeCount);
Modified: trunk/Source/WebCore/platform/mac/PlatformPasteboardMac.mm (215660 => 215661)
--- trunk/Source/WebCore/platform/mac/PlatformPasteboardMac.mm 2017-04-22 02:01:55 UTC (rev 215660)
+++ trunk/Source/WebCore/platform/mac/PlatformPasteboardMac.mm 2017-04-22 02:23:45 UTC (rev 215661)
@@ -50,7 +50,7 @@
NSData *data = "" dataForType:pasteboardType];
if (!data)
return nullptr;
- return SharedBuffer::create([[data copy] autorelease]);
+ return SharedBuffer::wrapNSData([[data copy] autorelease]);
}
int PlatformPasteboard::numberOfFiles()
Modified: trunk/Source/WebCore/platform/network/BlobResourceHandle.cpp (215660 => 215661)
--- trunk/Source/WebCore/platform/network/BlobResourceHandle.cpp 2017-04-22 02:01:55 UTC (rev 215660)
+++ trunk/Source/WebCore/platform/network/BlobResourceHandle.cpp 2017-04-22 02:23:45 UTC (rev 215661)
@@ -604,7 +604,7 @@
void BlobResourceHandle::notifyReceiveData(const char* data, int bytesRead)
{
if (client())
- client()->didReceiveBuffer(this, SharedBuffer::create(reinterpret_cast<const uint8_t*>(data), bytesRead), bytesRead);
+ client()->didReceiveBuffer(this, SharedBuffer::create(data, bytesRead), bytesRead);
}
void BlobResourceHandle::notifyFail(Error errorCode)
Modified: trunk/Source/WebCore/platform/network/MIMEHeader.cpp (215660 => 215661)
--- trunk/Source/WebCore/platform/network/MIMEHeader.cpp 2017-04-22 02:01:55 UTC (rev 215660)
+++ trunk/Source/WebCore/platform/network/MIMEHeader.cpp 2017-04-22 02:23:45 UTC (rev 215661)
@@ -31,8 +31,6 @@
#include "config.h"
#include "MIMEHeader.h"
-#if ENABLE(MHTML)
-
#include "ParsedContentType.h"
#include "SharedBufferChunkReader.h"
#include <wtf/HashMap.h>
@@ -135,5 +133,3 @@
}
}
-
-#endif
Modified: trunk/Source/WebCore/platform/network/MIMEHeader.h (215660 => 215661)
--- trunk/Source/WebCore/platform/network/MIMEHeader.h 2017-04-22 02:01:55 UTC (rev 215660)
+++ trunk/Source/WebCore/platform/network/MIMEHeader.h 2017-04-22 02:23:45 UTC (rev 215661)
@@ -28,10 +28,9 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#pragma once
+#ifndef MIMEHeader_h
+#define MIMEHeader_h
-#if ENABLE(MHTML)
-
#include <wtf/RefCounted.h>
#include <wtf/RefPtr.h>
#include <wtf/text/WTFString.h>
Modified: trunk/Source/WebCore/platform/network/cf/ResourceHandleCFURLConnectionDelegateWithOperationQueue.cpp (215660 => 215661)
--- trunk/Source/WebCore/platform/network/cf/ResourceHandleCFURLConnectionDelegateWithOperationQueue.cpp 2017-04-22 02:01:55 UTC (rev 215660)
+++ trunk/Source/WebCore/platform/network/cf/ResourceHandleCFURLConnectionDelegateWithOperationQueue.cpp 2017-04-22 02:23:45 UTC (rev 215661)
@@ -177,7 +177,7 @@
if (protectedThis->hasHandle() && m_handle->client()) {
LOG(Network, "CFNet - ResourceHandleCFURLConnectionDelegateWithOperationQueue::didReceiveData(handle=%p) (%s)", m_handle, m_handle->firstRequest().url().string().utf8().data());
- m_handle->client()->didReceiveBuffer(m_handle, SharedBuffer::create(data), originalLength);
+ m_handle->client()->didReceiveBuffer(m_handle, SharedBuffer::wrapCFData(data), originalLength);
}
CFRelease(data);
Modified: trunk/Source/WebCore/platform/network/cf/SynchronousResourceHandleCFURLConnectionDelegate.cpp (215660 => 215661)
--- trunk/Source/WebCore/platform/network/cf/SynchronousResourceHandleCFURLConnectionDelegate.cpp 2017-04-22 02:01:55 UTC (rev 215660)
+++ trunk/Source/WebCore/platform/network/cf/SynchronousResourceHandleCFURLConnectionDelegate.cpp 2017-04-22 02:23:45 UTC (rev 215661)
@@ -184,7 +184,7 @@
LOG(Network, "CFNet - SynchronousResourceHandleCFURLConnectionDelegate::didReceiveData(handle=%p, bytes=%ld) (%s)", m_handle, CFDataGetLength(data), m_handle->firstRequest().url().string().utf8().data());
if (ResourceHandleClient* client = m_handle->client())
- client->didReceiveBuffer(m_handle, SharedBuffer::create(data), originalLength);
+ client->didReceiveBuffer(m_handle, SharedBuffer::wrapCFData(data), originalLength);
}
void SynchronousResourceHandleCFURLConnectionDelegate::didFinishLoading()
Modified: trunk/Source/WebCore/platform/network/mac/WebCoreResourceHandleAsDelegate.mm (215660 => 215661)
--- trunk/Source/WebCore/platform/network/mac/WebCoreResourceHandleAsDelegate.mm 2017-04-22 02:01:55 UTC (rev 215660)
+++ trunk/Source/WebCore/platform/network/mac/WebCoreResourceHandleAsDelegate.mm 2017-04-22 02:23:45 UTC (rev 215661)
@@ -174,7 +174,7 @@
// FIXME: https://bugs.webkit.org/show_bug.cgi?id=19793
// -1 means we do not provide any data about transfer size to inspector so it would use
// Content-Length headers or content size to show transfer size.
- m_handle->client()->didReceiveBuffer(m_handle, SharedBuffer::create(data), -1);
+ m_handle->client()->didReceiveBuffer(m_handle, SharedBuffer::wrapNSData(data), -1);
}
- (void)connection:(NSURLConnection *)connection didSendBodyData:(NSInteger)bytesWritten totalBytesWritten:(NSInteger)totalBytesWritten totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite
Modified: trunk/Source/WebCore/platform/network/mac/WebCoreResourceHandleAsOperationQueueDelegate.mm (215660 => 215661)
--- trunk/Source/WebCore/platform/network/mac/WebCoreResourceHandleAsOperationQueueDelegate.mm 2017-04-22 02:01:55 UTC (rev 215660)
+++ trunk/Source/WebCore/platform/network/mac/WebCoreResourceHandleAsOperationQueueDelegate.mm 2017-04-22 02:23:45 UTC (rev 215661)
@@ -223,7 +223,7 @@
// FIXME: https://bugs.webkit.org/show_bug.cgi?id=19793
// -1 means we do not provide any data about transfer size to inspector so it would use
// Content-Length headers or content size to show transfer size.
- m_handle->client()->didReceiveBuffer(m_handle, SharedBuffer::create(data), -1);
+ m_handle->client()->didReceiveBuffer(m_handle, SharedBuffer::wrapNSData(data), -1);
});
}
Modified: trunk/Source/WebCore/platform/soup/SharedBufferSoup.cpp (215660 => 215661)
--- trunk/Source/WebCore/platform/soup/SharedBufferSoup.cpp 2017-04-22 02:01:55 UTC (rev 215660)
+++ trunk/Source/WebCore/platform/soup/SharedBufferSoup.cpp 2017-04-22 02:23:45 UTC (rev 215661)
@@ -27,10 +27,10 @@
namespace WebCore {
SharedBuffer::SharedBuffer(SoupBuffer* soupBuffer)
+ : m_buffer(*new DataBuffer)
+ , m_soupBuffer(soupBuffer)
{
ASSERT(soupBuffer);
- m_size = soupBuffer->length;
- m_segments.append(DataSegment::create(GUniquePtr<SoupBuffer>(soupBuffer)));
}
Ref<SharedBuffer> SharedBuffer::wrapSoupBuffer(SoupBuffer* soupBuffer)
@@ -40,6 +40,11 @@
GUniquePtr<SoupBuffer> SharedBuffer::createSoupBuffer(unsigned offset, unsigned size)
{
+ if (m_soupBuffer && !offset && !size) {
+ GUniquePtr<SoupBuffer> buffer(soup_buffer_copy(m_soupBuffer.get()));
+ return buffer;
+ }
+
ref();
GUniquePtr<SoupBuffer> buffer(soup_buffer_new_with_owner(data() + offset, size ? size : this->size(), this, [](void* data) {
static_cast<SharedBuffer*>(data)->deref();
@@ -47,6 +52,57 @@
return buffer;
}
+void SharedBuffer::clearPlatformData()
+{
+ m_soupBuffer.reset();
+}
+
+void SharedBuffer::maybeTransferPlatformData()
+{
+ if (!m_soupBuffer)
+ return;
+
+ ASSERT(!m_size);
+
+ // Hang on to the m_soupBuffer pointer in a local pointer as append() will re-enter maybeTransferPlatformData()
+ // and we need to make sure to early return when it does.
+ GUniquePtr<SoupBuffer> soupBuffer;
+ soupBuffer.swap(m_soupBuffer);
+
+ append(soupBuffer->data, soupBuffer->length);
+}
+
+bool SharedBuffer::hasPlatformData() const
+{
+ return m_soupBuffer.get();
+}
+
+const char* SharedBuffer::platformData() const
+{
+ return m_soupBuffer->data;
+}
+
+unsigned SharedBuffer::platformDataSize() const
+{
+ return m_soupBuffer->length;
+}
+
+bool SharedBuffer::maybeAppendPlatformData(SharedBuffer&)
+{
+ return false;
+}
+
+bool SharedBuffer::tryReplaceContentsWithPlatformBuffer(SharedBuffer& newContents)
+{
+ if (!newContents.hasPlatformData())
+ return false;
+
+ clear();
+ // FIXME: Use GRefPtr instead of GUniquePtr for the SoupBuffer.
+ m_soupBuffer.swap(newContents.m_soupBuffer);
+ return true;
+}
+
} // namespace WebCore
#endif
Modified: trunk/Source/WebKit/mac/ChangeLog (215660 => 215661)
--- trunk/Source/WebKit/mac/ChangeLog 2017-04-22 02:01:55 UTC (rev 215660)
+++ trunk/Source/WebKit/mac/ChangeLog 2017-04-22 02:23:45 UTC (rev 215661)
@@ -1,3 +1,15 @@
+2017-04-21 Michael Catanzaro <mcatanz...@igalia.com>
+
+ Unreviewed, rolling out r215608.
+
+ Hundreds of test failures on GTK bot
+
+ Reverted changeset:
+
+ "Reduce copies and allocations in SharedBuffer::append"
+ https://bugs.webkit.org/show_bug.cgi?id=170956
+ http://trac.webkit.org/changeset/215608
+
2017-04-21 Alex Christensen <achristen...@webkit.org>
Reduce copies and allocations in SharedBuffer::append
Modified: trunk/Source/WebKit/mac/WebView/WebArchive.mm (215660 => 215661)
--- trunk/Source/WebKit/mac/WebView/WebArchive.mm 2017-04-22 02:01:55 UTC (rev 215660)
+++ trunk/Source/WebKit/mac/WebView/WebArchive.mm 2017-04-22 02:23:45 UTC (rev 215661)
@@ -200,7 +200,7 @@
#endif
_private = [[WebArchivePrivate alloc] init];
- auto coreArchive = LegacyWebArchive::create(SharedBuffer::create(data));
+ auto coreArchive = LegacyWebArchive::create(SharedBuffer::wrapNSData(data));
if (!coreArchive) {
[self release];
return nil;
Modified: trunk/Source/WebKit/mac/WebView/WebFrame.mm (215660 => 215661)
--- trunk/Source/WebKit/mac/WebView/WebFrame.mm 2017-04-22 02:01:55 UTC (rev 215660)
+++ trunk/Source/WebKit/mac/WebView/WebFrame.mm 2017-04-22 02:23:45 UTC (rev 215661)
@@ -2493,7 +2493,7 @@
ResourceRequest request(baseURL);
ResourceResponse response(responseURL, MIMEType, [data length], encodingName);
- SubstituteData substituteData(WebCore::SharedBuffer::create(data), [unreachableURL absoluteURL], response, SubstituteData::SessionHistoryVisibility::Hidden);
+ SubstituteData substituteData(WebCore::SharedBuffer::wrapNSData(data), [unreachableURL absoluteURL], response, SubstituteData::SessionHistoryVisibility::Hidden);
_private->coreFrame->loader().load(FrameLoadRequest(_private->coreFrame, request, ShouldOpenExternalURLsPolicy::ShouldNotAllow, substituteData));
}
Modified: trunk/Source/WebKit/mac/WebView/WebResource.mm (215660 => 215661)
--- trunk/Source/WebKit/mac/WebView/WebResource.mm 2017-04-22 02:01:55 UTC (rev 215660)
+++ trunk/Source/WebKit/mac/WebView/WebResource.mm 2017-04-22 02:23:45 UTC (rev 215661)
@@ -149,7 +149,7 @@
return nil;
}
- auto coreResource = ArchiveResource::create(SharedBuffer::create(data), url, mimeType, textEncoding, frameName, response);
+ auto coreResource = ArchiveResource::create(SharedBuffer::wrapNSData(data), url, mimeType, textEncoding, frameName, response);
if (!coreResource) {
[self release];
return nil;
@@ -301,7 +301,7 @@
return nil;
}
- auto coreResource = ArchiveResource::create(SharedBuffer::create(copyData ? [[data copy] autorelease] : data), URL, MIMEType, textEncodingName, frameName, response);
+ auto coreResource = ArchiveResource::create(SharedBuffer::wrapNSData(copyData ? [[data copy] autorelease] : data), URL, MIMEType, textEncodingName, frameName, response);
if (!coreResource) {
[self release];
return nil;
Modified: trunk/Source/WebKit2/ChangeLog (215660 => 215661)
--- trunk/Source/WebKit2/ChangeLog 2017-04-22 02:01:55 UTC (rev 215660)
+++ trunk/Source/WebKit2/ChangeLog 2017-04-22 02:23:45 UTC (rev 215661)
@@ -1,3 +1,15 @@
+2017-04-21 Michael Catanzaro <mcatanz...@igalia.com>
+
+ Unreviewed, rolling out r215608.
+
+ Hundreds of test failures on GTK bot
+
+ Reverted changeset:
+
+ "Reduce copies and allocations in SharedBuffer::append"
+ https://bugs.webkit.org/show_bug.cgi?id=170956
+ http://trac.webkit.org/changeset/215608
+
2017-04-21 Andy Estes <aes...@apple.com>
[macOS] Enable media selection button on AVTouchBarScrubber
Modified: trunk/Source/WebKit2/NetworkProcess/cocoa/NetworkSessionCocoa.mm (215660 => 215661)
--- trunk/Source/WebKit2/NetworkProcess/cocoa/NetworkSessionCocoa.mm 2017-04-22 02:01:55 UTC (rev 215660)
+++ trunk/Source/WebKit2/NetworkProcess/cocoa/NetworkSessionCocoa.mm 2017-04-22 02:23:45 UTC (rev 215661)
@@ -386,7 +386,7 @@
auto storedCredentials = _withCredentials ? WebCore::StoredCredentials::AllowStoredCredentials : WebCore::StoredCredentials::DoNotAllowStoredCredentials;
if (auto* networkDataTask = _session->dataTaskForIdentifier(dataTask.taskIdentifier, storedCredentials))
- networkDataTask->didReceiveData(WebCore::SharedBuffer::create(data));
+ networkDataTask->didReceiveData(WebCore::SharedBuffer::wrapNSData(data));
}
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location
Modified: trunk/Source/WebKit2/Platform/IPC/DataReference.cpp (215660 => 215661)
--- trunk/Source/WebKit2/Platform/IPC/DataReference.cpp 2017-04-22 02:01:55 UTC (rev 215660)
+++ trunk/Source/WebKit2/Platform/IPC/DataReference.cpp 2017-04-22 02:23:45 UTC (rev 215661)
@@ -47,8 +47,13 @@
encoder.reserve(bufferSize + sizeof(uint64_t));
encoder << bufferSize;
- for (const auto& segment : *m_buffer)
- encoder.encodeFixedLengthData(reinterpret_cast<const uint8_t*>(segment->data()), segment->size(), 1);
+ const char* partialData;
+ unsigned position = 0;
+ while (position < bufferSize) {
+ unsigned bytesToWrite = m_buffer->getSomeData(partialData, position);
+ encoder.encodeFixedLengthData(reinterpret_cast<const uint8_t*>(partialData), bytesToWrite, 1);
+ position += bytesToWrite;
+ }
}
} // namespace IPC
Modified: trunk/Source/WebKit2/Shared/ShareableResource.cpp (215660 => 215661)
--- trunk/Source/WebKit2/Shared/ShareableResource.cpp 2017-04-22 02:01:55 UTC (rev 215660)
+++ trunk/Source/WebKit2/Shared/ShareableResource.cpp 2017-04-22 02:23:45 UTC (rev 215661)
@@ -87,7 +87,7 @@
#if USE(CF)
RetainPtr<CFAllocatorRef> deallocator = adoptCF(createShareableResourceDeallocator(this));
RetainPtr<CFDataRef> cfData = adoptCF(CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, reinterpret_cast<const UInt8*>(data()), static_cast<CFIndex>(size()), deallocator.get()));
- return SharedBuffer::create(cfData.get());
+ return SharedBuffer::wrapCFData(cfData.get());
#elif USE(SOUP)
return SharedBuffer::wrapSoupBuffer(soup_buffer_new_with_owner(data(), size(), this, [](void* data) { static_cast<ShareableResource*>(data)->deref(); }));
#else
Modified: trunk/Source/WebKit2/UIProcess/API/Cocoa/WKURLSchemeHandlerTask.mm (215660 => 215661)
--- trunk/Source/WebKit2/UIProcess/API/Cocoa/WKURLSchemeHandlerTask.mm 2017-04-22 02:01:55 UTC (rev 215660)
+++ trunk/Source/WebKit2/UIProcess/API/Cocoa/WKURLSchemeHandlerTask.mm 2017-04-22 02:23:45 UTC (rev 215661)
@@ -70,7 +70,7 @@
- (void)didReceiveData:(NSData *)data
{
- auto result = _urlSchemeHandlerTask->task().didReceiveData(WebCore::SharedBuffer::create(data));
+ auto result = _urlSchemeHandlerTask->task().didReceiveData(WebCore::SharedBuffer::wrapNSData(data));
raiseExceptionIfNecessary(result);
}
Modified: trunk/Source/WebKit2/WebProcess/InjectedBundle/API/mac/WKWebProcessPlugInBrowserContextController.mm (215660 => 215661)
--- trunk/Source/WebKit2/WebProcess/InjectedBundle/API/mac/WKWebProcessPlugInBrowserContextController.mm 2017-04-22 02:01:55 UTC (rev 215660)
+++ trunk/Source/WebKit2/WebProcess/InjectedBundle/API/mac/WKWebProcessPlugInBrowserContextController.mm 2017-04-22 02:23:45 UTC (rev 215661)
@@ -646,7 +646,7 @@
auto dataByType = [m_controller->_editingDelegate.get() _webProcessPlugInBrowserContextController:m_controller pasteboardDataForRange:wrapper(*InjectedBundleRangeHandle::getOrCreate(range).get())];
for (NSString *type in dataByType) {
pasteboardTypes.append(type);
- pasteboardData.append(SharedBuffer::create(dataByType[type]));
+ pasteboardData.append(SharedBuffer::wrapNSData(dataByType[type]));
};
}
Modified: trunk/Source/WebKit2/WebProcess/Plugins/PDF/PDFPlugin.mm (215660 => 215661)
--- trunk/Source/WebKit2/WebProcess/Plugins/PDF/PDFPlugin.mm 2017-04-22 02:01:55 UTC (rev 215660)
+++ trunk/Source/WebKit2/WebProcess/Plugins/PDF/PDFPlugin.mm 2017-04-22 02:23:45 UTC (rev 215661)
@@ -916,7 +916,7 @@
RetainPtr<NSURLResponse> response = adoptNS([[NSHTTPURLResponse alloc] initWithURL:m_sourceURL statusCode:200 HTTPVersion:(NSString*)kCFHTTPVersion1_1 headerFields:headers]);
ResourceResponse synthesizedResponse(response.get());
- RefPtr<ArchiveResource> resource = ArchiveResource::create(SharedBuffer::create(m_data.get()), m_sourceURL, "application/pdf", String(), String(), synthesizedResponse);
+ RefPtr<ArchiveResource> resource = ArchiveResource::create(SharedBuffer::wrapCFData(m_data.get()), m_sourceURL, "application/pdf", String(), String(), synthesizedResponse);
pluginView()->frame()->document()->loader()->addArchiveResource(resource.releaseNonNull());
}
@@ -1756,7 +1756,7 @@
if (!pdfData)
return nullptr;
- return SharedBuffer::create(pdfData);
+ return SharedBuffer::wrapNSData(pdfData);
}
bool PDFPlugin::pluginHandlesContentOffsetForAccessibilityHitTest() const
@@ -1827,7 +1827,7 @@
RetainPtr<NSString> plainTextString = adoptNS([[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
webProcess.parentProcessConnection()->sendSync(Messages::WebPasteboardProxy::SetPasteboardStringForType(pasteboardName, type, plainTextString.get()), Messages::WebPasteboardProxy::SetPasteboardStringForType::Reply(newChangeCount), 0);
} else {
- RefPtr<SharedBuffer> buffer = SharedBuffer::create(data);
+ RefPtr<SharedBuffer> buffer = SharedBuffer::wrapNSData(data);
if (!buffer)
continue;
Modified: trunk/Source/WebKit2/WebProcess/Plugins/PluginView.cpp (215660 => 215661)
--- trunk/Source/WebKit2/WebProcess/Plugins/PluginView.cpp 2017-04-22 02:01:55 UTC (rev 215660)
+++ trunk/Source/WebKit2/WebProcess/Plugins/PluginView.cpp 2017-04-22 02:23:45 UTC (rev 215661)
@@ -1311,8 +1311,14 @@
// Deliver the data.
if (m_manualStreamData) {
- for (const auto& segment : *m_manualStreamData)
- manualLoadDidReceiveData(segment->data(), segment->size());
+ const char* data;
+ unsigned position = 0;
+
+ while (unsigned length = m_manualStreamData->getSomeData(data, position)) {
+ manualLoadDidReceiveData(data, length);
+ position += length;
+ }
+
m_manualStreamData = nullptr;
}
Modified: trunk/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebDragClientMac.mm (215660 => 215661)
--- trunk/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebDragClientMac.mm 2017-04-22 02:01:55 UTC (rev 215660)
+++ trunk/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebDragClientMac.mm 2017-04-22 02:23:45 UTC (rev 215661)
@@ -165,7 +165,7 @@
SharedMemory::Handle archiveHandle;
size_t archiveSize = 0;
if (data) {
- RefPtr<SharedBuffer> archiveBuffer = SharedBuffer::create((NSData *)data.get());
+ RefPtr<SharedBuffer> archiveBuffer = SharedBuffer::wrapNSData((NSData *)data.get());
RefPtr<SharedMemory> archiveSharedMemoryBuffer = SharedMemory::allocate(archiveBuffer->size());
if (!archiveSharedMemoryBuffer)
return;
Modified: trunk/Source/WebKit2/WebProcess/WebPage/mac/WebPageMac.mm (215660 => 215661)
--- trunk/Source/WebKit2/WebProcess/WebPage/mac/WebPageMac.mm 2017-04-22 02:01:55 UTC (rev 215660)
+++ trunk/Source/WebKit2/WebProcess/WebPage/mac/WebPageMac.mm 2017-04-22 02:23:45 UTC (rev 215661)
@@ -709,7 +709,7 @@
RefPtr<SharedBuffer> WebPage::cachedResponseDataForURL(const URL& url)
{
- return SharedBuffer::create([cachedResponseForURL(this, url) data]);
+ return SharedBuffer::wrapNSData([cachedResponseForURL(this, url) data]);
}
bool WebPage::platformCanHandleRequest(const WebCore::ResourceRequest& request)
Modified: trunk/Tools/ChangeLog (215660 => 215661)
--- trunk/Tools/ChangeLog 2017-04-22 02:01:55 UTC (rev 215660)
+++ trunk/Tools/ChangeLog 2017-04-22 02:23:45 UTC (rev 215661)
@@ -1,3 +1,15 @@
+2017-04-21 Michael Catanzaro <mcatanz...@igalia.com>
+
+ Unreviewed, rolling out r215608.
+
+ Hundreds of test failures on GTK bot
+
+ Reverted changeset:
+
+ "Reduce copies and allocations in SharedBuffer::append"
+ https://bugs.webkit.org/show_bug.cgi?id=170956
+ http://trac.webkit.org/changeset/215608
+
2017-04-21 Wenson Hsieh <wenson_hs...@apple.com>
[WK2] Add delegate hooks for overriding unhanded data interaction operations
Modified: trunk/Tools/TestWebKitAPI/Tests/WebCore/cocoa/SharedBuffer.mm (215660 => 215661)
--- trunk/Tools/TestWebKitAPI/Tests/WebCore/cocoa/SharedBuffer.mm 2017-04-22 02:01:55 UTC (rev 215660)
+++ trunk/Tools/TestWebKitAPI/Tests/WebCore/cocoa/SharedBuffer.mm 2017-04-22 02:23:45 UTC (rev 215661)
@@ -59,8 +59,8 @@
buffer->append((CFDataRef)worldData);
expectDataArraysEqual(@[ helloData, worldData ], buffer->createNSDataArray().get());
- expectDataArraysEqual(@[ helloData ], SharedBuffer::create(helloData)->createNSDataArray().get());
- expectDataArraysEqual(@[ worldData ], SharedBuffer::create((CFDataRef)worldData)->createNSDataArray().get());
+ expectDataArraysEqual(@[ helloData ], SharedBuffer::wrapNSData(helloData)->createNSDataArray().get());
+ expectDataArraysEqual(@[ worldData ], SharedBuffer::wrapCFData((CFDataRef)worldData)->createNSDataArray().get());
expectDataArraysEqual(@[ [NSData dataWithContentsOfFile:tempFilePath()] ], SharedBuffer::createWithContentsOfFile(tempFilePath())->createNSDataArray().get());
}